在 《k8s 云集群混搭模式, 可能帮你节省 50% 以上的服务成本》一文中, 介绍了使用 k8s + 虚拟节点混合集群的方式, 为负载具有时间段波峰, 波谷交替规律的业务节约成本, 提高服务伸缩效率的部署方案. 本文对该方案的具体落地步骤与基本运行维护进行分享, 为有此需求者提供参考.
部署要求
应能 24 小时不间断提供服务
在业务高峰期到来前能自动扩展指定数量的容器 (提前对业务负载进行评估与压测, 确定容器数)
在业务高峰期过后能自动收缩到指定数量的容器
能根据服务负载情况自动弹性伸缩, 避免业务突发情况下服务能力跟不上
基本概念
Docker
容器: 应用运行的形式
镜像: 容器的定义, 或打包形式
容器镜像服务: 镜像仓库
k8s 云混合集群
集群 -- 托管版, 专有版, Serverless 版
节点 -- Master Node,Worker Node
命名空间 (Namespace)
Pod
副本控制器 (Replication Controller)
副本集 (Replica Set)
部署 (Deployment)
服务 (Service)
标签 (Labels)
存储卷 (Volume)-- PV,PVC
Ingress
镜像准备
Dockerfile 定义, 这里因为涉及到分布式 session 的支持 (参考 [redission-tomcat: 快速实现从单机部署到多机部署]), 所以加了一些相应的 jar 依赖与替换配置, 根据自身实际情况编写 Dockerfile.
- FROM tomcat:8.5.43-jdk8-openjdk
- # 清除无用或需替换的文件, 修改容器时区为上海时区
- RUN rm -rf /usr/local/tomcat/webapps/* && \
- rm -f /usr/local/tomcat/conf/context.xml && \
- cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
- # 复制配置文件
- COPY ./target/classes/redisson-tomcat/*/usr/local/tomcat/conf/
- # 复制需要依赖的 jar 包
- COPY ./dockerimage-depends/*.jar /usr/local/tomcat/lib/
- # 替换 catalina.sh 解决时区问题
- COPY ./dockerimage-depends/catalina.sh /usr/local/tomcat/bin/
- # 复制部署 war 包
- COPY ./target/biz-server.war /usr/local/tomcat/webapps/EXPOSE 8080
- # 启动时运行 tomcat, 覆盖默认的启动指令
- # 使用 catalina.sh run 则 catalina.out 中日志打印不充分, 使用 startup.sh 因为是后台运行, 执行就退出了, docker 容器也退出了, 所以添加 tail -F 让其保持前台运行
- #CMD ["catalina.sh", "run"]
- CMD /usr/local/tomcat/bin/startup.sh && tail -F /usr/local/tomcat/logs/catalina.out
创建集群 (托管版)
参考: https://help.aliyun.com/document_detail/85903.html
专有网络 VPC: 同一个专有网络中的节点之间, Pod 之间可互联
虚拟交换机: 多选择几个不同可用区的虚拟交换机
SNAT: 如果 VPC 不具备公网访问能力, 选中配置 SNAT 会创建 NAT 网关并自动配置 SNAT 规则. 如果使用云数据库需要配置 IP 白名单, 或微信公众号配置 IP 白名单, 则服务需要公网 IP, 有些 ECS 节点具有公网 IP 会优先使用, 对于没有公网 IP 的节点或虚拟节点, 需要配置 SNAT 获取公网 IP.
添加节点
参考: https://help.aliyun.com/document_detail/86919.html
只能添加同一个地域的 ECS 节点
自动添加: 会替换系统盘, 原系统盘会被释放 (谨慎!)
手动添加: 需在 ECS 上执行指定命令安装必要的软件依赖
下图所示在集群中添加了三个 ECS 节点与一个虚拟节点 (virtual-kubelet)
添加虚拟节点
参考: https://help.aliyun.com/document_detail/118970.html
添加虚拟节点时指定虚拟交换机, 则只能使用指定虚拟交换机所在的可用区资源 (如虚拟交换机在杭州 G 区, 则在虚拟节点上调度 Pod 时只能调度到 G 区的服务资源, 不能调度到 H 区或其它区的资源)
虚拟节点配置信息可随时更新 (如更换虚拟交换机)
虚拟节点是通过在应用目录中添加 ack-virtual-node 实现
创建应用 (Deployment)
镜像创建: 参考 https://help.aliyun.com/document_detail/90406.html
根据模板创建 (YAML 模板): 参考 https://help.aliyun.com/document_detail/86512.html
如下图所示创建了部署要求中的业务服务, 及视觉服务的两层服务
负载均衡
有三种方式可实现某一层服务集群的负载均衡
虚拟集群 IP: 集群中 Pod 或 Node 上可访问, 集群外不能访问
内网负载均衡: 分配内网 IP,VPC 中可访问, 不一定在集群中
外网负载均衡: 分配外网 IP, 外部可访问
对于业务服务, 需要外网访问, 所以创建外网负载均衡, 将域名解析到外网 IP; 对于两层视觉服务, 只需要在集群中提供访问, 可以使用虚拟集群 IP(比内网负载均衡效率高)
存储管理
目前虚拟节点只支持挂载 emptyDir(临时), NFS(NAS), ConfigFile
NAS 参考: https://help.aliyun.com/document_detail/27518.html
NAS 可挂载到 ECS 上, 通过 SSH 到 ECS 来访问
下图示例了如何将 NAS 目录挂载到容器下的某个目录
手动伸缩
手动对 Deployment 的 Pod 进行横向扩展或缩放
自动伸缩
根据 CPU 与内存的负载自动进行伸缩
因为一般检测到负载超过阈值及启动容器都需要时间, 延迟可能对业务造成影响, 所以一方面可对负载阈值设置低一点, 另一方面如果规律性较高, 使用定时伸缩.
定时伸缩
通过 cronhpa-controller 实现
参考: https://github.com/AliyunContainerService/kubernetes-cronhpa-controller
通过模板创建一个定时伸缩应用 (注意默认是 GMT 时间, 配置时需要减 8 小时)
目前没有提供控制台管理, 更新指令参考:
- # 查看
- kubectl describe cronhpa cronhpa-herpes-slave
- # 编辑
- kubectl edit cronhpa/cronhpa-herpes-slave -n default
- # 删除
- kubectl delete cronhpa/cronhpa-herpes-slave -n default
快速构建
首先需要在 deployment 上创建一个重新部署的触发器, 创建完后会生成一个 url, 只需要 get 请求这个 url 就可以触发 deployment 重新拉取镜像完成部署.
借助 jenkins, 实现服务的快速构建.
部署脚本参考
- #!/bin/bash
- work_dir=/var/lib/jenkins/workspace/$1
- depends_dir=/home/jenkins/dockerimage-depends/
- # 将额外的依赖 jar 包复制到 docker build 的上下文中, 便于复制到镜像里的 tomcat 目录下
- cp -R $depends_dir $work_dir
- # 在本地打镜像
- cd $work_dir
- docker build -t biz-server:latest .
- # 将镜像 push 到阿里云镜像仓库服务
- sudo docker tag biz-server:latest registry.cn-hangzhou.aliyuncs.com/biz/biz-server:latest
- sudo docker push registry.cn-hangzhou.aliyuncs.com/biz/biz-server:latest
- # 通过触发器触发重新部署完成上线
- curl https://cs.console.aliyun.com/hook/trigger?token=xxxxxxxxxxxxxxxx
容器访问
1. 获取容器名称 (见下图)
2. 在配置有 Kubernetes 访问权限的 ECS 上执行如下命令即可进入容器
kubectl exec -it herpes-master-6447d58c4b-cqznf bash
数据访问
1. SSH 连接到挂载 NAS 云盘的 ECS 上
2. 进入对应挂载目录查看, 目前有业务服务的日志, 视觉服务的图片与日志
部署结构
应用相应组件最终搭建符合开头部署要求的集群结构如下
总结
该部署方案对于不具备一定容器基础的人来说门槛相对较高, 并且可能服务推出时间不长, 文档方面还不是太完善, 笔者在实践过程中也踩了不少坑, 目前集群服务运行稳定, 节约成本在 2/3 以上, 并且伸缩非常方便. 如果你刚好也有这样的业务场景与需求, 可以关注公众号 "空山新雨的技术空间" 交流. 本文也有 ppt 版本, 如有需要可以在公众号主页发送 "k8s" 获取下载方式.
来源: https://www.cnblogs.com/spec-dog/p/11462914.html