用户数从 0 到亿,我的 K8s 踩坑血泪史
作者 |?平名 阿里服務端開發技術專家
導讀:容器服務 Kubernetes 是目前炙手可熱的云原生基礎設施,作者過去一年上線了一個用戶數極速增長的應用:該應用一個月內日活用戶從零至四千萬,用戶數從零到一億的裂變式增長,充分享受了容器服務快速簡便的擴容操作和高可用特性。作者使用容器服務 Kubernetes 集群將公司內系統完全上云 1 年多,本篇文章記錄了其中的踩坑與優化記錄。
關注“阿里巴巴云原生”公眾號,回復關鍵詞“資料”,即可獲得 2019 全年meetup 活動 PPT 合集及 K8s 最全知識圖譜。
創建集群
創建集群時,做好規劃,選擇優化好的集群配置,可以大大減少后期運維工作,其中部分集群的配置在建立后再也沒法修改或者修改極其麻煩。
集群規劃
- 網絡規劃:
- 網絡類型: Flannel、Terway
? ? ? ? ? ? Terway 是阿里云容器服務自研的網絡插件,功能上完全兼容 Flannel,如果保守,還是使用 Flannel??
- Pod 網絡 CIDR
默認 16 的大網段,有效的網段或者其子網 10.0.0.0/8,172.16-31.0.0/12-16,192.168.0.0/16
- Service CIDR
- 默認 20 的網段,可選:10.0.0.0/16-24,172.16-31.0.0/16-24,192.168.0.0/16-24
- 網段不能沖突重復,建立后沒法修改;
- 多個區域的多個交換機。
- 公網訪問 ApiServer
- 對于線上等安全要求高的集群,可以選擇不暴露 apiserver, 只有私網 SLB, 但是這樣沒法使用云效發布;
- 日常預發等集群,可以暴露公網 SLB 到 apiserver, 集群建立后立即為 slb 建立訪問控制,限制 slb 只能云效訪問;
注: K8s 每次安全漏洞幾乎都與 ApiServer 有關,對于線上 K8s 集群,要及時升級補丁,或者不開放公網 apiserver,使用嚴格的安全組和訪問控制。
- 安全組
- 設置安全組限定訪問范圍,為 master 與 worker 機器使用。
?
- Master 機器規劃
? ?為了高可用,一般使用 3 節點,Master 選擇規則如下:
| 1-5個 | 4C8G |
| 6-20個節點 | 4C16G |
| 21-100個節點 | 8C32G |
| 100-200個節點 | 16C64G |
master 機器的存儲建議高性能的 50-100G SSD,因為會運行 ETCD,操作系統占用不超過 8G。
- Worker 機器規劃
- 阿里云首推神龍機器,沒有神龍機器的區域,選用高配 ECS,配置規格根據部署的 POD 規格乘以一定倍數,比如 Java 應用 pod 一般選擇 4C8G,ECS 則購買 32C64G 或者 64C128G 為好,設置部署的時候為 pod 設置固定的 request/limit;
- 我們選用的機器配置:
- 32C64G ECS
- 存儲。系統盤:100G SSD,? 數據盤:400G 高效云盤
- 操作系統:centos 7.4 64 位
集群建立與配置
建立集群時設置:
- 通過控制臺建立集群,阿里云容器服務提供的非常簡易的一鍵部署集群功能,通過向導完成 K8S 集群的建立;
- 按照以上規劃設置 master,worker 節點,掛載 /var/lib/docker 到數據盤;
- 設置合理的 Pod 網絡 CIDR, Service CIDR ip 網段;
- 設置合理的安全策略,是否暴露 apiserver(需要直接云效發布的,需要開放公網暴露,并做嚴格的訪問控制);
- ingress 選擇安全,可以使用內網,如果需要公網,可以在控制臺很方便建立,同時做好訪問控制;
- kube-proxy 模式,因為 iptables 模式在更新一條規則時把 iptables 鎖住引發的性能問題,建議使用 IPVS 模式;
- 節點 POD 數量,默認 128 太大,一個節點不可能部署這么多,建議改為 64;
- 節點服務端口訪問 (NodePort,SLB),可以適當擴大,默認的也一般足夠用。
集群配置修改:
- 集群擴容,添加已有節點(節點配置參考上文,掛載數據盤使用 /var/lib/docker)? ? ?
- Master 機器升配:
- worker 節點變配或者移除:
- kubectl drain --ignore-daemonsets {node.name}
- kubectl delete node {node.name}
- ECS 升配變配
- 添加已有節點到集群
- 命名空間:?
- 按照應用分組建立 namespace,對于資源占用厲害需要限制的應用分組,設置該 NameSpace 的資源配額與限制;
- 授權:
- 子賬號如何給其他子賬號進行 RBAC 授權
- 通過堡壘機按應用人員設置權限
部署設置
無狀態部署
使用無狀態部署 Deployment,參考這篇文章實現分批發布。優化設置模板:?
apiVersion: apps/v1beta2 kind: Deployment metadata:annotations:deployment.kubernetes.io/revision: '34' # 標簽,映射 servicelabels:app: {app_name}-aonename: {app_name}-aone-1namespace: {app_name} spec:progressDeadlineSeconds: 600replicas: 1revisionHistoryLimit: 10selector:matchLabels:app: {app_name}-aone # 批量重啟更新策略 strategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatetemplate:metadata:labels:app: {app_name}-aonespec:containers:# 環境變量增加時區- env:- name: TZvalue: Asia/Shanghai- image: >-registry-vpc.cn-north-2-gov-1.aliyuncs.com/{namespace}/{app_name}:20190820190005imagePullPolicy: Always# 啟動前執行優雅下線摘除 服務注冊lifecycle:preStop:exec:command:- sudo- '-u'- admin- /home/{user_name}/{app_name}/bin/appctl.sh- {app_name}- stop# 存活檢查,強烈建議設置 livenessProbe:failureThreshold: 10initialDelaySeconds: 30periodSeconds: 10successThreshold: 1tcpSocket:port: 5900timeoutSeconds: 1name: {app_name}-aone# 就緒檢查,強烈建議設置readinessProbe:failureThreshold: 10initialDelaySeconds: 30periodSeconds: 10successThreshold: 1tcpSocket:port: 5900timeoutSeconds: 1# 資源限制,這個一定要合理設置 resources:limits:cpu: '4'memory: 8Girequests:cpu: '4'memory: 8GiterminationMessagePath: /dev/termination-logterminationMessagePolicy: File# 日志存放目錄,映射到節點的/var/lib/docker/logs 數據盤,應用日志目錄設置到/home/{user_name}/logs 下volumeMounts:- mountPath: /home/{user_name}/logsname: volume-1553755418538dnsPolicy: ClusterFirst## 私有鏡像倉庫的密鑰,從保密字段獲取imagePullSecrets:- name: {app_name}-987restartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30# 日志存放目錄,映射到節點的/var/lib/docker/logs 數據盤volumes:- hostPath:path: /var/lib/docker/logs/{app_name}type: ''name: volume-1553755418538?
服務設置
因為容器服務的 Cloud Controller Manager 會同步刪除 service 建立關聯的 SLB,為了防止 service 配置修改誤刪除 slb 故障,并導致域名、安全等配置需要修改的坑,強烈建議 service 與 slb 解耦,service 采用 NodePort 的方式,slb 另外建立后端服務器指向集群節點,如果需要透傳真實 IP,并考慮負載均衡,需要遵守一定的配置規則和方法,參考這個文章。
NodePort:
apiVersion: v1 kind: Service metadata:name: {app_name}namespace: {namespaces} spec:clusterIP: 10.1.50.65 ## 策略關系到是否透傳真實 IPexternalTrafficPolicy: Clusterports:- name: {app_name}-80-7001nodePort: 32653port: 80protocol: TCPtargetPort: 7001- name: {app_name}-5908-5908nodePort: 30835port: 5108protocol: TCPtargetPort: 5108selector:app: {app_name}sessionAffinity: Nonetype: NodePort status:loadBalancer: {}然后在負載均衡管理頁面,選擇后端服務器指向集群的 worker 機器,設置端口為以上服務的端口:32653,完成配置,這樣在集群 service 修改或者刪除重建的時候,slb 不會被集群的 CCM 刪除,不會涉及到域名,安全等配置修改。同時,可以設置一些策略,需要升級修改服務配置時,分批切流等。
總結
阿里云容器服務控制臺雖然是云上新產品,提供了極其簡單的一鍵部署功能,以及簡便的控制臺管理。過去一年中,筆者一路見識阿里云容器服務控制臺從簡陋向強大的轉變過程,雖然多次踩坑,但阿里云容器服務同學認真負責和極好的服務態度讓人佩服。
容器服務管理控制臺還需要更多的考慮實際運維需求,并緊密結合已有的云產品,比如云效、EDAS、云監控、日志服務等,以應用為單位,提供更好服務。
掃描下方二維碼添加小助手,與 8000 位云原生愛好者討論技術趨勢,實戰進階!
進群暗號:公司-崗位-城市
**
總結
以上是生活随笔為你收集整理的用户数从 0 到亿,我的 K8s 踩坑血泪史的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云原生生态周报 Vol. 17 | He
- 下一篇: Serverless 与容器决战在即?有