千家信息网

项目容器化改造心得

发表于:2025-12-04 作者:千家信息网编辑
千家信息网最后更新 2025年12月04日,一.概述1.1 背景近来和同事共同开发的迁移平台项目想进行容器化改造,顺应大趋势往容器化这边靠,项目前端平台利用Django开发,后端Restful API利用高性能Web框架Tornado完成,Ag
千家信息网最后更新 2025年12月04日项目容器化改造心得

一.概述

1.1 背景

近来和同事共同开发的迁移平台项目想进行容器化改造,顺应大趋势往容器化这边靠,项目前端平台利用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技术,丰富自己的技能栈。

1.2 容器化改造优势

  • 更省:极大的资源利用效率, 最大限度榨取和共享物理资源,多项目更能体现出容器化多优势,节约部署IT成本。
  • 更快:秒级启动,实现业务系统更快的开发迭代 和 交付部署。
  • 弹性:可根据业务负载进行弹性容器伸缩,弹性扩展。
  • 方便:容器化业务部署支持蓝绿/灰度/金丝雀等发布,回滚,更加灵活方便。
  • 灵活:监控底层node节点健康状态,灵活调度至最优节点部署。
  • 强一致性:容器将环境和代码打包在镜像内,保证了测试与生产环境的强一致性。

1.3 容器化改造的要求

  • 开发人员熟悉Docker虚拟化技术,熟练编写Dockerfile。
  • 熟悉kubernetes容器化编排系统, 熟悉各组件资源清单编写。
  • 开发需要考虑后期容器编排部署的需求来组织结构和编写代码。
  • 部署人员需要熟悉kubernetes资源清单各参数含义,需要总体把控架构中到从上到下架构。
  • 考虑高可用架构和rbac安全策略,外部流量引入及后期扩容伸缩。

二.工具

2.1 云原生生态

一入云原生深似海,下图为我们更好的全局性了解云原生生态。

2.2 工具应用

本次项目改造用到的一些工具和应用与大家分享(后期有时间将各个工具应用单独写出来分享)

  • 代码托管

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监控。

  • 下图为导航页,直观的展示用的这些工具

三.改造的要求

3.1 程序要求

3.1.1 项目结构
  • 将配置文件单独创建config文件夹,方便后期kubernetes创建configmap进行资源映射

  • 如果后期部署为deployment无状态应用,应该将共享的数据存储单独创建目录,方便后去volume挂载

  • 项目结果目录下单独创建deploy目录存放

例如次项目,分为创建configmap/deployment/service已经拉去私有仓库代码的Secret。

  • 项目下均适用entrypoint.sh 为容器入口,最后添加exec "$@",方便后期添加配置扩展

3.1.2 代码要求
  • 配置文件尽可能使用yaml语言编写,方便后期加载为configmap中便于修改读写。

  • 由于后期方便容器监控,采用Fluentd配合EL进行集群及应用监控,监控容器目录为/var/lib/docker/containers/*.log,需要将日志输出到stdout,所以对于需要监控到日志,可以定向到标准输出/标准错误输出已经日志文件内。

3.2 架构要求

3.2.1 基础资源
  • 计算

利用云服务器搭建部署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
3.2.2 流量引入
  • 需要结合部署在公有化/私有化,还是裸机上,需要提前规划好前段时云LB就可以借助其部署证书,七层加载证书。
  • 如果没有云产品就需要考虑ingress流量引入集群加载证书。

四.项目部分示例

4.1 存储类

利用ceph集群,构建存储类,同时利用CephFS来解决跨node挂载的应用。

  • 存储类ceph-storageclass.yaml
apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: ceph-rdbprovisioner: ceph.com/rbdreclaimPolicy: Retainparameters:  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: v1kind: Secretmetadata:  name: ceph-admin-secret  namespace: kube-systemtype: "kubernetes.io/rbd_"data:  # ceph auth get-key client.admin |base64  key: QVFCRitmUmM1c1FxxxxxxxxxxxxxxxxxxxxxxxxHFoQVh7NlRvQ2c9PQ==
  • 对于共享目录
apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: go2cloud-api-pvc  namespace: defaultspec:  storageClassName: "ceph-rdb"  accessModes:  - ReadWriteOnce  resources:    requests:      storage: 8Gi
  • 配置文件通过configmap挂载
apiVersion: v1data:  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:8088kind: ConfigMapmetadata:  name: go2cloud-platform-cm

4.2 应用相关资源

  • go2cloud-platform-deployment.yaml
apiVersion: apps/v1kind: Deploymentmetadata:  name: go2cloud-platform  namespace: defaultspec:  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: v1kind: Servicemetadata:  name: go2cloud-platform-service  namespace: defaultspec:  selector:    app: go2cloud-platform  type: NodePort  ports:  - name: http    nodePort: 30020    port: 8088    targetPort: 8088    protocol: TCP
  • registry-secret.yaml
apiVersion: v1kind: Secretmetadata:  name: registry-secrettype: kubernetes.io/dockerconfigjsondata:  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxMC4yMzQuMi4yMTgiOiB7CgkJCSJhdXRoIjogIllXNWphRzVsZERwWWVIcDRRRGM0T1E9PSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2Vyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Dockerfile
FROM python:latestLABEL 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.shEXPOSE 8088/tcpENTRYPOINT ["/bin/sh","/bin/entrypoint.sh"]CMD ["python","/data/runserver","start","all"]
  • entrypoint.sh
#!/bin/sh# config go2cloud-api configfileexec "$@"

五.反思

  • 个人决定云原生后期回成为大趋势,提前掌握容器化编排技术,不至于技术栈落伍。
  • 充分利用云生态应用切合自身项目特点进行容器化改造会快速不少。
  • 觉得云原生是将来的大趋势,尽快入门,拥抱云原生。
0