企業級容器云平臺的落地與實踐
原創隨著IT行業的發展和變遷,IT應用的底層支持也從大型機、小型機、PC服務器、虛擬化技術,到如今的容器化。基于敏捷開發的持續迭代,持續部署,以及多樣化的技術棧,傳統的底層架構變得越來越冗雜,運維管理越來越力不從心,運維人員也逐步陷落在無盡的“救火”運維模式。
容器技術的出現,從根本上改變了這一切。而容器高效的編排與管理,才是讓其風光無限的前提條件。Kubernetes經過多年的發展,已經成為行業的事實標準。而如何利用好Kubernetes,為企業的發展助力,成為很多企業,尤其是初創企業無法忽略的一道難題。
本文將介紹利用Amazon EKS打造企業級容器云平臺,通過一系列的實踐操作,讓大家直觀地了解亞馬遜云科技是如何幫助企業高效地部署、管理容器化應用。
1. 傳統應用架構的容器化之路
說到“傳統”二字,大家第一反應,就是“落后”,“守舊”,然而現實情況卻是----絕大部分傳統應用,依然在良好地運行在這些傳統架構中。這些被服務的對象不會因為某些因素對整個系統資源的需求發生很大變化,也不會有頻繁的系統功能的迭代開發需求。
但是隨著互聯網、大數據、AI等技術的發展,各行各業都在努力地從信息化向智能化轉型。而轉型的過程中,越來越多的應用場景,和頻繁地迭代開發,也讓“傳統”架構越來越龐大。隨之而來的是運維人員疲于奔命的“救火”,系統服務越來越不穩定,以及系統成本的失控飛漲。
如何才能從根本上一勞永逸地解決這些問題? 容器化/微服務化是很多企業寄予厚望的方向。
容器化真的那么有效嗎?
我們以下圖為例。這是一個很通用的架構,在多臺服務器上分別部署Tomcat,使用反向代理軟件(Nginx)把請求均勻分發到每個Tomcat中。假定由于11.11促銷,我們需要將現有的3臺Tomcat擴充到10臺,運維人員需要完成哪些工作?(假設服務器硬件已經準備好)
傳統系統的擴容步驟:
- 安裝OS,設置安全和權限相關
- 分配IP,聯網
- 部署Tomcat
- 以上動作做7遍
僅僅一個擴容,就需要一個資深的運維人員花費幾個小時才能完成。如果要擴充到100個節點呢,工作量成倍增加。
容器化系統擴容步驟:
如果我們使用容器化技術來完成剛剛這件事,就會節省很多人力。
1. 安裝OS,并由Kubernetes統一管理
2. 一條命令足以,并且在秒級完成擴展
- kubectl scale rc tomcat --replicas=10
3. 完成
簡單的一個對比,即可發現,在資源分配,系統穩定(自愈),運維管理等多個方面,容器化技術都可有效地降低企業的成本和運維壓力,并且讓企業保持技術的敏捷性和先進性。
2. 容器化應用場景
剛剛討論過容器化對于企業的價值,接下來要繼續分析哪些場景適合容器化。
容器化很重要的特點,就是輕量化和無狀態。而像傳統的企業應用軟件,承載業務模塊眾多,功能流程繁瑣,因此并不適合容器化改造。具體哪些應用場景比較適合呢?主要包含以下幾種場景(當然,這只是幾種常見情況,業務場景滿足輕量化、無狀態的特點都是可以嘗試容器化技術)
2.1 應用打包
2.2 多版本混合部署
2.3 升級回滾
2.4 多租戶資源隔離
2.5 內部開發環境
我們一直在說容器化(Docker為代表)的各種優勢,但是企業在真正的生產環境中,如果只是通過Docker來實現容器化,是無法滿足高可用、彈性擴展和高并發等場景需求。而Kubernetes的出現,才讓Docker真正在生產環境中被大規模使用起來。Kubernetes提供了應用部署、規劃、更新、維護的一種機制,讓容器化應用的部署和管理更簡單、更高效,。
Kubernetes的特點:
- 可移植: 支持公有云,私有云,混合云,多云(multi-cloud)
- 可擴展: 模塊化,插件化,可掛載,可組合
- 自動化: 自動部署,自動重啟,自動復制,自動伸縮/擴展
Kubernetes結合Docker,讓企業容器化之路變得更加容易,從而更快地滿足業務需求。 但是,事物都是有兩面性,并不是所有項目都適合容器化改造,而且任何的改動都有可能產生未知的影響,要對技術保持敬畏,對生產保持敬畏,才能在容器化的道路上走的更穩。
Kubernetes雖好,但是對于很多初創企業,和沒有太多相關技術積累的傳統企業,Kubernetes的學習成本過高,企業會在底層架構的高可用性、網絡、機房等方面遇到一系列問題,從而讓容器化之路滿是荊棘。
3. Amazon EKS助力企業快速實現容器化轉型
如何快速、高效地擁有自己的容器化平臺呢?下面一段,就是亞馬遜云科技官網上Amazon EKS的介紹:
Amazon EKS 是一項托管服務,可讓您在 亞馬遜云科技上輕松運行 Kubernetes,而無需安裝、操作和維護您自己的 Kubernetes 控制層面或節點。Kubernetes 是一個用于實現容器化應用程序的部署、擴展和管理的自動化的開源系統。
Amazon EKS 跨多個可用區運行 Kubernetes 控制層面實例以確保高可用性。Amazon EKS 可以自動檢測和替換運行狀況不佳的控制層面實例,并為它們提供自動版本升級和修補。
Amazon EKS 與許多 亞馬遜云科技服務集成以便為您的應用程序提供可擴展性和安全性,包括:
- 用于容器鏡像的 Amazon ECR
- 用于負載分配的 Elastic Load Balancing
- 用于身份驗證的 IAM
- 用于隔離的 Amazon VPC
Amazon EKS 運行最新版本的開源 Kubernetes 軟件,因此您可以使用 Kubernetes 社區中的所有現有插件和工具。在 Amazon EKS 上運行的應用程序與在任何標準 Kubernetes 環境中運行的應用程序完全兼容,無論此類環境是在本地數據中心還是在公有云中運行都是如此。這意味著,您可以輕松地將任何標準 Kubernetes 應用程序遷移到 Amazon EKS,而無需修改任何代碼。
4. 理論結合實際,讓容器化更直觀
理論說了一大堆,不如動手玩起來。下面,我設計一個場景,在Amazon EKS上逐步完成容器化部署,并逐步在每個環節介紹技術細節。
1) 通過Nginx,做三個頁面web1,web2,web3
2)將三個web頁面作為一組服務,由Amazon EKS管理。
3) 通過http訪問,輪詢到三個不同的頁面,來看到效果。
注釋:web1,web2,web3實際生產應該是一個業務,只不過為了顯示實驗效果,通過不同的頁面,展示輪詢的效果
4.1 環境準備:
4.1.1. 需要一個亞馬遜云科技賬號
4.1.2. 賬號資源限制檢查,確保有足夠的IGW,VPC,EIP等。
4.1.3. 安裝Amazon cli(包含eksctl)及配置kubectl:
4.1.3. 1. Amazon cli安裝:
- curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
- unzip awscliv2.zip
- sudo ./aws/install
檢查安裝結果
- $ aws --version
安裝方法參考鏈接:
https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-chap-install.html
4.1.3. 2 配置kubectl,
- aws eks --region cn-northwest-1 update-kubeconfig --name my-zhy-eks
官方配置方法鏈接:
https://docs.amazonaws.cn/eks/latest/userguide/create-kubeconfig.html
4.2 創建Amazon EKS集群:
4.2.1 創建命令
#命令,參數注釋
--node-type 工作節點類型
--nodes 工作節點數量
CLUSTER_NAME 集群名稱
AWS_REGION cn-northwest-1:寧夏區; cn-north-1:北京區
~~~~~~~~~~創建命令~~~~~~~~~~~·
- AWS_REGION=cn-northwest-1
- AWS_DEFAULT_REGION=cn-northwest-1
- CLUSTER_NAME=my-zhy-eks
- eksctl create cluster --name=${CLUSTER_NAME} --version 1.15 --nodes=3 --node-type t3.medium --managed --alb-ingress-access --region=${AWS_REGION}
4.22 成功執行的輸出:
- ##################
- eksctl create cluster --name=${CLUSTER_NAME} --version 1.15 --nodes=3 --node-type t3.medium --managed --alb-ingress-access --region=${AWS_REGION}
- [ℹ] eksctl version 0.32.0
- [ℹ] using region cn-northwest-1
- [ℹ] setting availability zones to [cn-northwest-1b cn-northwest-1c cn-northwest-1a]
- [ℹ] subnets for cn-northwest-1b - public:192.168.0.0/19 private:192.168.96.0/19
- [ℹ] subnets for cn-northwest-1c - public:192.168.32.0/19 private:192.168.128.0/19
- [ℹ] subnets for cn-northwest-1a - public:192.168.64.0/19 private:192.168.160.0/19
- [ℹ] using Kubernetes version 1.15
- [ℹ] creating EKS cluster "my-zhy-eks" in "cn-northwest-1" region with managed nodes
- [ℹ] will create 2 separate CloudFormation stacks for cluster itself and the initial managed nodegroup
- [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=cn-northwest-1 --cluster=my-zhy-eks'
- [ℹ] CloudWatch logging will not be enabled for cluster "my-zhy-eks" in "cn-northwest-1"
- [ℹ] you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=cn-northwest-1 --cluster=my-zhy-eks'
- [ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "my-zhy-eks" in "cn-northwest-1"
- [ℹ] 2 sequential tasks: { create cluster control plane "my-zhy-eks", 2 sequential sub-tasks: { no tasks, create managed nodegroup "ng-e5146e45" } }
- [ℹ] building cluster stack "eksctl-my-zhy-eks-cluster"
- [ℹ] deploying stack "eksctl-my-zhy-eks-cluster"
- [ℹ] building managed nodegroup stack "eksctl-my-zhy-eks-nodegroup-ng-e5146e45"
- [ℹ] deploying stack "eksctl-my-zhy-eks-nodegroup-ng-e5146e45"
- [ℹ] waiting for the control plane availability...
- [✔] saved kubeconfig as "/root/.kube/config"
- [ℹ] no tasks
- [✔] all EKS cluster resources for "my-zhy-eks" have been created
- [ℹ] nodegroup "ng-e5146e45" has 3 node(s)
- [ℹ] node "ip-192-168-5-37.cn-northwest-1.compute.internal" is ready
- [ℹ] node "ip-192-168-58-97.cn-northwest-1.compute.internal" is ready
- [ℹ] node "ip-192-168-65-234.cn-northwest-1.compute.internal" is ready
- [ℹ] waiting for at least 3 node(s) to become ready in "ng-e5146e45"
- [ℹ] nodegroup "ng-e5146e45" has 3 node(s)
- [ℹ] node "ip-192-168-5-37.cn-northwest-1.compute.internal" is ready
- [ℹ] node "ip-192-168-58-97.cn-northwest-1.compute.internal" is ready
- [ℹ] node "ip-192-168-65-234.cn-northwest-1.compute.internal" is ready
- [ℹ] kubectl command should work with "/root/.kube/config", try 'kubectl get nodes'
- [✔] EKS cluster "my-zhy-eks" in "cn-northwest-1" region is ready
- ##############
4.2.3 Eksctl執行之后,需要等待10分鐘左右。模式很簡單的步驟,其實是亞馬遜云科技通過調用cloudformation在后臺做了許多工作才完成的。下圖是cloudformation的stack步驟:
圖片來源于亞馬遜云科技全球網站截圖
4.2.4 Amazon EKS完成后的,cloudformation狀態
圖片來源于亞馬遜云科技全球網站截圖
4.2.5 查詢node狀態信息
- # kubectl get node
- NAME STATUS ROLES AGE VERSION
- ip-192-168-5-37.cn-northwest-1.compute.internal Ready <none> 11m v1.15.12-eks-31566f
- ip-192-168-58-97.cn-northwest-1.compute.internal Ready <none> 11m v1.15.12-eks-31566f
- ip-192-168-65-234.cn-northwest-1.compute.internal Ready <none> 11m v1.15.12-eks-31566f
4.2.6. 擴展集群節點方法
我們之前通過eksctl創建了一個3節點的集群,如果由于業務的增加,希望擴容的話,如何操作呢?具體命令參考如下,將當前集群,擴容到10個節點:
- NODE_GROUP=$(eksctl get nodegroup --cluster ${CLUSTER_NAME} --region=${AWS_REGION} -o json | jq -r '.[].Name')
- eksctl scale nodegroup --cluster=${CLUSTER_NAME} --nodes=10 --name=${NODE_GROUP} --region=${AWS_REGION}
檢查結果
- eksctl get nodegroup --cluster ${CLUSTER_NAME} --region=${AWS_REGION}
- eksctl get cluster
- NAME REGION
- my-zhy-eks cn-northwest-1
4.3. Amazon ECR的使用
針對一個企業,很多image都是定制化的,而定制化的私有image管理,在亞馬遜云科技是如何操作的呢? Amazon ECR,讓image的管理,變得更簡單易用。下面通過httpd的image,定制化并生成私有httpdok的image之后,并上傳到Amazon ECR,作為步驟演示:
4.31. 首先創建一個Amazon ECR Repositories,選擇并點擊View push commands.
圖片來源于亞馬遜云科技全球網站截圖
4.3.2.根據”View puhs commands”步驟,將本地創建好的image,上傳到Amazon ECR。
圖片來源于亞馬遜云科技全球網站截圖
具體命令步驟:
- # aws ecr get-login-password --region cn-northwest-1 | docker login --username AWS --password-stdin <account_id>.dkr.ecr.cn-northwest-1.amazonaws.com.cn
查看本地鏡像
- # docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- httpdok v1 df353399ffe4 7 seconds ago 299MB
為鏡像打標簽
- # docker tag httpdok:latest <account_id>.dkr.ecr.cn-northwest-1.amazonaws.com.cn/httpdok:latest
在查看本地Docker的images,可以看到已經出現一個新的,有ECR連接串的image
- # docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- <account_id>.dkr.ecr.cn-northwest-1.amazonaws.com.cn/httpdok latest 9028c4373343 4 minutes ago 299MB
- httpdok latest 9028c4373343 4 minutes ago 299MB
推送image到ECR上
- # docker push <account_id>.dkr.ecr.cn-northwest-1.amazonaws.com.cn/httpdok:latest
- The push refers to repository [<account_id>.dkr.ecr.cn-northwest-1.amazonaws.com.cn/httpdok]
回到亞馬遜云科技控制臺,已經可以看到上傳的image
圖片來源于亞馬遜云科技全球網站截圖
4.4 Amazon EKS實例演示
下面開始部署容器到Amazon EKS中,通過Nginx來演示如何部署image到Amazon EKS,并輪詢訪問.
4.4.1.啟動三個nginx pod 的 ReplicaSet
準備yaml文件
- cat <<EOF > nginx-deployment.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: nginx-deployment
- labels:
- app: nginx
- spec:
- replicas: 3
- selector:
- matchLabels:
- app: nginx
- template:
- metadata:
- labels:
- app: nginx
- spec:
- containers:
- - name: nginx
- image: nginx:1.14.2
- ports:
- - containerPort: 80
- EOF
執行以下命令,進行部署
- kubectl apply -f nginx-deployment.yaml
檢查創建狀態
- kubectl get pods -o wide
4.4.2.創建LoadBalancer 服務
準備yaml文件
- cat <<EOF > loadbalancer.yaml
- apiVersion: v1
- kind: Service
- metadata:
- name: nginx-service
- spec:
- type: LoadBalancer
- selector:
- app: nginx
- ports:
- - protocol: TCP
- port: 80
- targetPort: 80
- EOF
執行以下命令,進行部署
- kubectl create -f loadbalancer.yaml
檢查創建狀態
- kubectl get service
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- nginx-service LoadBalancer 10.100.212.244 ae8e75d7e149044eb905b6bbff796e7e-629951941.cn-northwest-1.elb.amazonaws.com.cn 80:31248/TCP 7m53s
監測網頁顯示情況
- curl -silent ae8e75d7e149044eb905b6bbff796e7e-629951941.cn-northwest-1.elb.amazonaws.com.cn | grep title
- <title>Welcome to nginx!</title>
至此,我們已經開始使用EKS上的Nginx集群了。但是為了建議Load balance的工作效果。我們繼續下面的小實驗,可以更好的觀察load balance的效果
4.5. 輪詢效果展示
4.5.1.獲取pod信息
- kubectl get pod
- NAME READY STATUS RESTARTS AGE
- nginx-deployment-574b87c764-92jbs 1/1 Running 0 10h
- nginx-deployment-574b87c764-hmz9t 1/1 Running 0 10h
- nginx-deployment-574b87c764-nqpmc 1/1 Running 0 10h
以下命令是確定pod中nginx的歡迎界面的index.html位置
- kubectl exec -it nginx-deployment-574b87c764-92jbs -- /usr/sbin/nginx -t
- kubectl exec -it nginx-deployment-574b87c764-92jbs -- cat /etc/nginx/nginx.conf
- kubectl exec -it nginx-deployment-574b87c764-92jbs -- ls /usr/share/nginx/html
- kubectl exec -it nginx-deployment-574b87c764-92jbs -- cat /usr/share/nginx/html/index.html
- kubectl exec -it nginx-deployment-574b87c764-92jbs -- cp/usr/share/nginx/html/index.html /usr/share/nginx/html/index.html.bk
注釋:kubectl exce的格式如下:
- kubectl exec -it <podName> -c <containerName> -n <namespace> -- shell comand
4.5.3.更改index.html內容
在本地編輯文件name.html,然后上傳到3個Pod的容器中,
kubectl cp name.html nginx-deployment-574b87c764-nqpmc:usr/share/nginx/html/index.html
注釋: pod和本地之間傳輸文件命令格式
- Pod下載文件到本地
- kubectl cp -n NAMESPACE_name POD_name:Pod_FILE_name Local_FILE_name
本地上傳文件到Pod
- kubectl cp Local_FILE_name -n NAMESPACE_name POD_name:Pod_FILE_name
最終查詢輸出結果,多次查詢,可以看到load balance會將連接隨機分配到不同Pod節點
- curl -silent ae8e75d7e149044eb905b6bbff796e7e-629951941.cn-northwest-1.elb.amazonaws.com.cn | grep Node
5. 總結
通過本文,大家已經對容器化有一個初步的了解,并且針對Amazon EKS打造的企業容器化平臺也有了初步認知。Docker,Kubernetes對于企業的系統和業務的發展,有著不可忽視的“助推力”。
然而,Kubernetes的學習曲線,以及企業的Kubernetes人才的積累,都是需要較長的“時間”成本。而借助云計算供應商的成熟平臺和產品,可以降低企業的技術人才的積累成本,從而達到事半功倍的效果。
我們通過這次實戰的演練,可以看到,基于Amazon EKS創建容器化平臺,只需一條命令。Amazon EKS讓Kubernetes的創建,運行與維護變得簡單、可靠。通過AWS Fargate,企業甚至可以完全省去虛擬機(EC2)的管理,只關注Kubernetes頂層業務架構的邏輯即可,進而可以將更多的“時間”專注在業務的開發,而不是被底層架構的種種問題所拖累,也可以讓運維人員逃離無盡的“救火”式運維模式。
你,準備好了嗎? 容器化巨輪已經啟航!來,讓我們一起探索更多可能!
參考文檔:
https://docs.amazonaws.cn/eks/latest/userguide/what-is-eks.html
https://eksctl.io/usage/creating-and-managing-clusters/
https://github.com/liangruibupt/EKS-Workshop-China
https://docs.amazonaws.cn/en_us/eks/latest/userguide/create-kubeconfig.html
https://amazonaws-china.com/cn/premiumsupport/knowledge-center/eks-kubernetes-services-cluster/
https://www.eksworkshop.com/beginner/130_exposing-service/ingress_controller_alb/
https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/alb-ingress.html
【責任編輯:張燕妮 TEL:(010)68476606】