項目容器化改造心得

一.概述

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進行資源映射

img

  • 如果後期部署爲deployment無狀態應用,應該將共享的數據存儲單獨創建目錄,方便後去volume掛載

img

  • 項目結果目錄下單獨創建deploy目錄存放

img

例如次項目,分爲創建configmap/deployment/service已經拉去私有倉庫代碼的Secret。

  • 項目下均適用entrypoint.sh 爲容器入口,最後添加exec "$@",方便後期添加配置擴展

img

3.1.2 代碼要求

  • 配置文件儘可能使用yaml語言編寫,方便後期加載爲configmap中便於修改讀寫。

項目容器化改造心得

  • 由於後期方便容器監控,採用Fluentd配合EL進行集羣及應用監控,監控容器目錄爲/var/lib/docker/containers/*.log,需要將日誌輸出到stdout,所以對於需要監控到日誌,可以定向到標準輸出/標準錯誤輸出已經日誌文件內。

img

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/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

4.2 應用相關資源

    • 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 "$@"

五.反思

  • 個人決定雲原生後期回成爲大趨勢,提前掌握容器化編排技術,不至於技術棧落伍。
  • 充分利用雲生態應用切合自身項目特點進行容器化改造會快速不少。
  • 覺得雲原生是將來的大趨勢,儘快入門,擁抱雲原生。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章