大型企業級項目容器化改造心得

歡迎關注我的頭條號:Wooola,10年Java軟件開發及架構設計經驗,專注於Java、Golang、微服務架構,致力於每天分享原創文章、快樂編碼和開源技術。 

一. 概述

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/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 "$@"
複製代碼

五. 反思

  • 個人決定雲原生後期回成為大趨勢,提前掌握容器化編排技術,不至於技術棧落伍。
  • 充分利用雲生態應用切合自身項目特點進行容器化改造會快速不少。
  • 覺得雲原生是將來的大趨勢,儘快入門,擁抱雲原生。


分享到:


相關文章: