导读:SaaS 服务随着业务的发展,会遇到很多非常特殊的问题。比如解决客户定制需求、满足客户网络安全结构、数据安全合规性、集团内部系统集成等等。为了更好地助力客户内生成长,自然而然地衍生出了 SasS 私有化的业务。针对私有化的业务场景,如何快速的帮助客户部署一套稳定的系统呢?通过本文,希望能给读者一些思路和方法。
在 SaaS 私有化业务展开的过程中,必然会遇到许许多多的问题。从市面上的一些 SaaS 私有化的产品中,我们能借鉴到知识。比如最近冲上热搜的“成都核酸系统事件”,各种事故原因众说纷纭,最终开发方也是以网络的原因来归结这次事故。这事件的始末我们不去细究,我们就此事件来看看私有化部署的服务,应该具备哪些配套设施?
那么 SaaS 私有化中,我们能用什么技术帮助我们快速实现上述配套设施?
源码部署就是把代码打成可执行的 tar 或者 war,直接放在宿主机上进行启动部署。这种部署方式有很大的弊端:
容器化部署相比于源码部署有着很多优点:
容器化部署的时候,我们肯定会遇到各种问题:
如何协调、调度和管理这些容器?举个例子,如果某天服务负载过高,需要扩容,刚刚好这个服务如果是一个 gateway 服务,直接挂在 ng 后面,这个时候就需要我们找一台机器,部署新应用,然后修改 ng 把服务节点添加进去。操作非常繁琐,需要专门的人员进行操作。
如何在升级应用程序时不中断服务?举个例子,白天业务需要 hotfix 发布,我们需要把一组任务,手动进行划分,一台一台的重启,一个服务还好,如果涉及到大面积发布的时候,效率非常低。
如何监视应用程序的运行状况?需要 metricbeat,在每个应用镜像中添加,通过 metricbeat 采集系统指标。
如何回退代码?需要修改部署脚本,手动替换版本号,涉及人工操作并且没有任何操作记录,可能出现人工误操作的问题,线上代码质量没法保证。
那么如何编排这些容器呢,我们自然而然的会想到大名鼎鼎的 Kubernetes。
Kubernetes 是什么?Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。白话讲,Kubernetes 就是用来管理容器的,负责编排容器的系统。
SaaS 私有化使用 Kubernetes 的难点
在 SaaS 私有化交付过程中,我们需要完善私有化交付的工具,如果我们使用原生的 Kubernetes,对开发人员的运维能力有一定的要求,同时在部署运维过程,不仅仅只需要使用 Kubernetes,我们还需要其他一系列的云原生工具,比如在日志采集的场景,需要维护ELK,在持续集成与发布流的场景,需要维护 Jenkins 等,在构建容器的可观察性平台,需要维护 Grafana,prometheus 等。在 SaaS 私有化部署中,我们需要的是一个平台化的,全家桶式的工具,能够帮助我们快速的部署维护一套开发运维平台,方便我们的私有化业务的开展。
Kubesphere 是在 Kubernetes 之上构建的面向云原生应用的分布式操作系统,完全开源,支持多云与多集群管理,提供全栈的 IT 自动化运维能力,简化企业的 DevOps 工作流。KubeSphere 为用户提供构建企业级 Kubernetes 环境所需的多项功能,例如多云与多集群管理、Kubernetes 资源管理、DevOps、应用生命周期管理、微服务治理(服务网格)、日志查询与收集、服务与网络、多租户管理、监控告警、事件与审计查询、存储管理、访问权限控制、GPU 支持、网络策略、镜像仓库管理以及安全管理等。
Kubesphere 把开发与运维的操作统一到一个平台中,可以非常方便地安装与管理用户最常用的云原生工具,从业务视角提供了一致的用户体验来降低复杂性。为了不影响底层 Kubernetes 本身的灵活性,也为了让用户能够按需安装,KubeSphere 所有功能组件都是可插拔的。可以根据不同的业务场景,定制安装不同的组件,满足不同私有化客户的需求。提供简单的图形化交互界面设计,简化 Kubernetes 运维成本,让业务人员更好的聚焦业务代码。
sudo apt-get updatesudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io docker-compose-pluginsudo service docker start详见:官方文档http://docs.docker.com/engine/install/
Docker 离线安装
安装目录下面,上传containerd.io-<VERSION_STRING>.rpm,docker-ce-cli-<VERSION_STRING>.rpm,docker-ce-<VERSION_STRING>.rpm 的rpm包
执行下面命令
sudo -iu root mkdir /etc/docker && chmod 777 /etc/docker/ && cd /etc/docker/
yum install -y containerd.io-<VERSION_STRING>.rpmyum install -y docker-ce-cli-<VERSION_STRING>.rpmyum install -y docker-ce-<VERSION_STRING>.rpm
配置 Docker 日志滚动
vi /etc/docker/daemon.json { "data-root":"/u/var/lib/docker", "log-driver":"json-file", "log-opts":{ "max-size" :"300m", "max-file":"1" }}systemctl restart docker
sudo systemctl enable docker
可以选择 docker registry 或者 harbor,本文档使用 harbor ,因为 harbor 提供了管理用户界面、基于角色访问控制、AD/LDAP 集成以及审计日志等功能,可以更好的管理镜像。由于内网情况,没有设置 http,外网直接不可以访问
mv /tmp/docker/docker-compose-xxx /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-composedocker-compose -v
tar -xvf harbor-offline-installer-v1.10.10.tgzmv harbor /opt
data_volume: /u/data/harborlog: local: location: /u/log/harbor
echo '127.0.0.1 localhost xxxxx' >> /etc/hostsecho '{ "insecure-registries":["xxxxx:8090"] }' > /etc/docker/daemon.jsonsystemctl restart dockerdocker login xxxxx:8090 -p Harbor12345 -u admin
安装 conntrack
yum install -y conntrack
用 KubeKey 安装 Kubesphere&k8s
额外需要下载的包,放到 KubeKey 目录下 Kubekeyv1.2.1 (具体情况根据自己版本定)
(http://get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz)
(http://github.com/coreos/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gz)
(http://download.docker.com/linux/static/stable/x86_64/docker-20.10.8.tgz)
(http://github.com/kubernetes-sigs/cri-tools/releases/download/v1.22.0/crictl-v1.22.0-linux-amd64.tar.gz)
配置文件如下,由于 Kubesphere 提供非常多的组件功能,都是可以同 yaml 制定的,由于环境的原因,如果全部开启,会非常消耗性能,大家根据实际的项目情况,按需开启。
apiVersion: kubekey.kubesphere.io/v1alpha1kind: Clustermetadata: name: samplespec: hosts: - {name: localhost1, address: 127.0.0.1, internalAddress: 127.0.0.1, user: root, password: root} - {name: localhost2, address: 127.0.0.2, internalAddress: 127.0.0.2, user: root, password: root} - {name: localhost3, address: 127.0.0.3, internalAddress: 127.0.0.3, user: root, password: root} roleGroups: etcd: - localhost1 master: - localhost1 worker: - localhost2 - localhost3 controlPlaneEndpoint: domain: lb.kubesphere.local address: "" port: 6443 kubernetes: version: v1.17.9 clusterName: cluster.local network: plugin: flannel kubePodsCIDR: 10.26.0.0/16 kubeServiceCIDR: 10.27.0.0/16 registry: registryMirrors: [] insecureRegistries: [] privateRegistry: "loaclhost:8090/registry" addons: []
devOps组件,基于 Jenkins 的 KubeSphere DevOps 系统是专为 Kubernetes 中的 CI/CD 工作流设计的,它提供了一站式的解决方案,帮助开发和运维团队用非常简单的方式构建、测试和发布应用到 Kubernetes。它还具有插件管理、Binary-to-Image (B2I)、Source-to-Image (S2I)、代码依赖缓存、代码质量分析、流水线日志等功能。
console 组件,基础控制台组件
alerting 组件,是可观测性的重要组成部分,与监控和日志密切相关。KubeSphere 中的告警系统与其主动式故障通知 (Proactive Failure Notification) 系统相结合,使用户可以基于告警策略了解感兴趣的活动。当达到某个指标的预定义阈值时,会向预先配置的收件人发出告警。因此,您需要预先配置通知方式,包括邮件、Slack、钉钉、企业微信和 Webhook。有了功能强大的告警和通知系统,您就可以迅速发现并提前解决潜在问题,避免您的业务受影响。
---apiVersion: installer.kubesphere.io/v1alpha1kind: ClusterConfigurationmetadata: name: ks-installer namespace: kubesphere-system labels: version: v3.1.1spec: persistence: storageClass: "" authentication: jwtSecret: "" zone: "" local_registry: "localhost:8090/registry" etcd: monitoring: false endpointIps: localhost port: 2379 tlsEnable: true common: monitoring: endpoint: http://prometheus-operated.kubesphere-monitoring-system.svc:9090 console: enableMultiLogin: true port: 30880 alerting: enabled: false devops: enabled: false jenkinsMemoryLim: 2Gi jenkinsMemoryReq: 1500Mi jenkinsVolumeSize: 8Gi jenkinsJavaOpts_Xms: 512m jenkinsJavaOpts_Xmx: 512m jenkinsJavaOpts_MaxRAM: 2g
·资源注节点管理,设置污点节点,禁止 master 节点调度应用负载
·集群资源监控管理,集群资源监控,集群 API Server 指标监控,物理资源监控等等
·帐户管理及帐号角色,可以定义丰富的资源隔离角色,给不同的团队成员赋予不同的访问资源的权限。
3.工作负载管理
工作负载定义
应用的实际运行载体,是对 Pod 的抽象模型。
工作负载管理
·可视化配置模式 和 编辑模式,降低操作成本,选择可视化配置模式。
·设置 CPU 和内存限制,限制单个应用的资源上限制,最小资源影响 k8s 对应用就行调度的过程,如果不配置最小限制,可能会导致应用调度到一个资源很少的机器上,可能导致该节点异常调度,从而使整个集群不稳定,建议配置内存按实际jvm的内存配置进行配置,如果是 cpu 密集型的,按实际实际情况分配 CPU 的配置
·环境变量设置,通过项目级别的配置,可以在项目内应用公共的配置,减少配置成本
·容器的健康检查,配置应用的状态检测和心跳检测接口,让容器滚动发布的时候,能够监测到容器能够正常提供服务,从而可以满足下一步的滚动发布。
·更新策略,选择滚动更新,更新容器组数量,根据实际情况填写,保证第一次就启动一个容器,比如容器组有4台应用,就可以设置25%。
·提供4种部署模式,其中三种系统,一种自定义的模式,默认策略,分散部署,聚合部署,没有特殊情况,就按照默认部署即可
·自定义部署模式,可以认为策略 + 类型 + 应用组成,策略分为 “远离目标部署”,”与目标部署到一起“,类型分为”尽可能满足“,“必须满足”,应用即选择实际应用,还可以添加多个自定义策略
·容器日志需要挂在到本地,从而避免容器日志在容器重建之后,就找不到的尴尬情况,需要谨慎对待,日志需要滚动覆盖,避免把机器上的磁盘打满的情况
·私有化部署纯内网的情况下,难免需要涉及到代理的问题,需要给访问外部请求的应用设置代理域名,通过代理地址访问外部域名,改配置在可视化配置里面没有,需要使用编辑模式 spec - 》template -> spec ->hostAliases
4.服务管理
定义了一类容器组(Pod)的逻辑集合和一个用户访问他们的策略
可以创建无状态服务,有状态服务,外部服务,自定义创建。通常情况下, 我们先创建工作负载,通过选定工作负载来创建服务。
访问类型有2种,虚拟 IP 访问和 Headless,虚拟 IP :基于集群生成的唯一 IP。集群内部可以通过该 IP 访问服务。此访问类型适用于大多数服务。此外,集群外部也可以通过 NodePort 和 LoadBalancer 访问服务。Headless 访问:集群不为服务生成 IP 地址,在集群内通过服务的后端容器组 IP 直接访问服务。此访问类型适用于后端异构服务,例如需要区分 master 和 agent 的服务。大部分还是使用虚拟 IP,设置集群内暴露的端口和实际负载暴露的端口。
访问方式 分为 NodePort 和 LoadBalancer ,NodePort 方式存在一下问题