项目容器化改造心得
source link: https://www.tuicool.com/articles/2iyYvur
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
概述
背景
近来和同事共同开发的迁移平台项目想进行容器化改造,顺应大趋势往容器化这边靠,项目前端平台利用Django开发,后端Restful API利用高性能Web框架Tornado完成,Agent端利用Flask开发,各取了几个大Python框架的优势。
之前CI/CD测试环境用的是GitLab CI,Master提交merge request后自动构建部署,正式环境通过Jenkins Pipeline手动拉去release部署,容器化改造将Jenkins托管在Kubernetes之上,Master接受Job请求,动态生成slave来完成Job任务。
此文记录了容器化改造中自己遇到的一些心得,可能自己研究的还不够,以下均为个人理解,大佬不喜勿喷,在本次利用Kubernetes将项目容器化过程中,决定Python项目有点大材小用,但是通过这次改造,理解了不少容器化的特征,不断的提升自己IT技术,丰富自己的技能栈。 如果你想和更多Kubernetes技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态 。
容器化改造优势
- 更省:极大的资源利用效率, 最大限度榨取和共享物理资源,多项目更能体现出容器化多优势,节约部署IT成本。
- 更快:秒级启动,实现业务系统更快的开发迭代和交付部署。
- 弹性:可根据业务负载进行弹性容器伸缩,弹性扩展。
- 方便:容器化业务部署支持蓝绿/灰度/金丝雀等发布,回滚,更加灵活方便。
- 灵活:监控底层Node节点健康状态,灵活调度至最优节点部署。
- 强一致性:容器将环境和代码打包在镜像内,保证了测试与生产环境的强一致性。
容器化改造的要求
- 开发人员熟悉Docker虚拟化技术,熟练编写Dockerfile。
- 熟悉Kubernetes容器化编排系统, 熟悉各组件资源清单编写。
- 开发需要考虑后期容器编排部署的需求来组织结构和编写代码。
- 部署人员需要熟悉Kubernetes资源清单各参数含义,需要总体把控架构中到从上到下架构。
- 考虑高可用架构和rbac安全策略,外部流量引入及后期扩容伸缩。
工具
云原生生态
一入云原生深似海,下图为我们更好的全局性了解云原生生态。
工具应用
本次项目改造用到的一些工具和应用与大家分享(后期有时间将各个工具应用单独写出来分享)。
- 代码托管:GitLab服务器进行代码托管,及GitLab CI/CD,后期可以将其托管至Kubernetes集群之上。
- 私有镜像托管:利用Harbor进行镜像存储,审计管理及镜像检查,后期可托管至Kubernetes之上。
-
集群管理:
- kubernetes-dashboard部署,Web界面方便各组件查看管理,简单容器Terminal管理,日志分享查看。
- Rancher部署,导入私有化Kubernetes平台,方便集群管理及app安装部署。
-
存储管理:
- Ceph到mgr分布式集群Web界面管理。
- minio/chartmuseum对象存储,方便chart存储管理。
- 集成发布:Jenkins进行持续集成,持续发布,后期可以将其托管至Kubernetes集群之上。
- 日志监控:EFK进行Kubernetes集群容器日志监控管理,F为Flutend容器化监控利器。
- Helm仓库管理:KubeApps进行Chart,Registry添加,方便Helm安装部署。
- 容器内APP监控:Prometheus + Grafana,各个APP内进行export出来,进行单个APP到matric监控。
-
下图为导航页,直观的展示用的这些工具
改造的要求
程序要求
项目结构
将配置文件单独创建config文件夹,方便后期Kubernetes创建ConfigMap进行资源映射。
如果后期部署为deployment无状态应用,应该将共享的数据存储单独创建目录,方便后去volume挂载。
项目结果目录下单独创建deploy目录存放。
例如次项目,分为创建configmap/deployment/service已经拉去私有仓库代码的Secret。
项目下均适用entrypoint.sh为容器入口,最后添加exec "$@",方便后期添加配置扩展。
代码要求
配置文件尽可能使用yaml语言编写,方便后期加载为ConfigMap中便于修改读写。
由于后期方便容器监控,采用Fluentd配合EL进行集群及应用监控,监控容器目录为/var/lib/docker/containers/*.log,需要将日志输出到stdout,所以对于需要监控到日志,可以定向到标准输出/标准错误输出已经日志文件内。
架构要求
基础资源
- 计算,利用云服务器搭建部署Kubernetes集群,提供计算与内存资源。
- 存储,需要利用云服务器磁盘部署Ceph分布式存储系统,为Kubernetes提供底层存储资源。
-
网络,前段需要LB,为应用代理到NodePort,Kubernetes集群内部使用Flannel网络,Node到Node之前通过VPC私有网络通讯。
- 容器间通信:同一个Pod内多个容器间的通信,使用lo网卡通信
- Pod间通信:Pod IP直接与Pod IP通信
- Pod与Service:Pod IP直接与Cluster IP
- Service与集群外部客户端的通信,Ingress、NodePort、Loadbacer
流量引入
需要结合部署在公有化/私有化,还是裸机上,需要提前规划好前段时云LB就可以借助其部署证书,七层加载证书。
如果没有云产品就需要考虑Ingress流量引入集群加载证书。
项目部分示例
存储类
利用Ceph集群,构建存储类,同时利用CephFS来解决跨Node挂载的应用。
存储类ceph-storageclass.yaml:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ceph-rdb provisioner: ceph.com/rbd reclaimPolicy: Retain parameters: monitors: 10.xx.xx.xx:6789 pool: kube adminId: admin adminSecretName: ceph-admin-secret adminSecretNamespace: kube-system userId: kube userSecretName: ceph-client-secret userSecretNamespace: kube-system fsType: xfs imageFormat: "2" imageFeatures: "layering"
Ceph认证ceph-secret.yaml:
apiVersion: v1 kind: Secret metadata: name: ceph-admin-secret namespace: kube-system type: "kubernetes.io/rbd" data: # ceph auth get-key client.admin |base64 key: QVFCRitmUmM1c1FxxxxxxxxxxxxxxxxxxxxxxxxHFoQVh6NlRvQ2c9PQ==
对于共享目录:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: go2cloud-api-pvc namespace: default spec: storageClassName: "ceph-rdb" accessModes: - ReadWriteOnce resources: requests: storage: 8Gi
配置文件通过ConfigMap挂载:
apiVersion: v1 data: config.yaml: | --- DB_ENGINE: mysql DB_HOST: mariadb-cluster-mariadb-master.default.svc.cluster.local DB_PORT: 3306 DB_USER: go2clouduser DB_PASSWORD: go2xxxxxxxxx DB_NAME: go2cxxxxxxxx # Use Redis as cache # Redis配置,连接replication的master节点 REDIS_HOST: redis-cluster-redis-ha-announce-0.default.svc.cluster.local REDIS_PORT: 6379 REDIS_PASSWORD: go2cloxxxxxxxx # go2cloud-platform 监听端口 HTTP_LISTEN_PORT: 8088 # callback url API_MIGRATE_SERVER_URL: http://go2cloud-api-service.default.svc.cluster.local:8004 PLATFORM_CALLBACK_URL: http://go2cloud-platform-service.default.svc.cluster.local:8088 kind: ConfigMap metadata: name: go2cloud-platform-cm
应用相关资源
go2cloud-platform-deployment.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: go2cloud-platform namespace: default spec: selector: matchLabels: # 匹配下面选择的template 中的label.app名称 app: go2cloud-platform replicas: 2 template: metadata: labels: app: go2cloud-platform release: latest spec: imagePullSecrets: - name: registry-secret containers: - name: go2cloud-platform image: 10.234.xxx.xxx/go2cloud/go2cloud-plaxxxxx:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8088 protocol: TCP volumeMounts: # 必须匹配volumes的名称 - name: go2cloud-platform-config mountPath: /data/config readOnly: true resources: requests: cpu: 250m memory: 520Mi limits: cpu: 500m memory: 1024Mi livenessProbe: tcpSocket: port: 8088 initialDelaySeconds: 20 volumes: # 定义逻辑卷的名称 - name: go2cloud-platform-config configMap: # 使用configmap资源的名称 name: go2cloud-platform-cm items: # 使用configmap中到那个key - key: config.yaml # 使用configmap中到key映射到容器中到文件名称 path: config.yaml mode: 0644
go2cloud-platform-service.yaml:
apiVersion: v1 kind: Service metadata: name: go2cloud-platform-service namespace: default spec: selector: app: go2cloud-platform type: NodePort ports: - name: http nodePort: 30020 port: 8088 targetPort: 8088 protocol: TCP
registry-secret.yaml:
apiVersion: v1 kind: Secret metadata: name: registry-secret type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxMC4yMzQuMi4yMTgiOiB7CgkJCSJhdXRoIjogIllXNWphRzVsZERwWWVIcDRRRGM0T1E9PSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2Vyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Dockerfile:
FROM python:latest LABEL maintainer="kaliarch" ENV BASE_ROOT="/data" ADD . ${BASE_ROOT} RUN pip install --default-timeout=100 -r ${BASE_ROOT}/requirements/requirements.txt \ && ln -s ${BASE_ROOT}/entrypoint.sh /bin/entrypoint.sh EXPOSE 8088/tcp ENTRYPOINT ["/bin/sh","/bin/entrypoint.sh"] CMD ["python","/data/runserver","start","all"]
entrypoint.sh:
#!/bin/sh # config go2cloud-api configfile exec "$@"
反思
- 个人决定云原生后期会成为大趋势,提前掌握容器化编排技术,不至于技术栈落伍。
- 充分利用云生态应用切合自身项目特点进行容器化改造会快速不少。
- 觉得云原生是将来的大趋势,尽快入门,拥抱云原生。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK