企業級容器雲平臺的落地與實踐

        隨着IT行業的發展和變遷,IT應用的底層支持也從大型機、小型機、PC服務器、虛擬化技術,到現在的容器化。基於敏捷開發的持續迭代,持續部署,以及多樣化的技術棧,傳統的底層架構變得愈來愈冗雜,運維管理愈來愈力不從心,運維人員也逐步陷落在無盡的「救火」運維模式。html

        容器技術的出現,從根本上改變了這一切。而容器高效的編排與管理,纔是讓其風光無限的前提條件。Kubernetes通過多年的發展,已經成爲行業的事實標準。而如何利用好Kubernetes,爲企業的發展助力,成爲不少企業,尤爲是初創企業沒法忽略的一道難題。node

        本文將介紹利用Amazon EKS打造企業級容器雲平臺,經過一系列的實踐操做,讓你們直觀地瞭解AWS是如何幫助企業高效地部署、管理容器化應用。linux

1.    傳統應用架構的容器化之路nginx

        說到「傳統」二字,你們第一反應,就是「落後」,「守舊」,然而現實狀況倒是----絕大部分傳統應用,依然在良好地運行在這些傳統架構中。這些被服務的對象不會由於某些因素對整個系統資源的需求發生很大變化,也不會有頻繁的系統功能的迭代開發需求。git

        可是隨着互聯網、大數據、AI等技術的發展,各行各業都在努力地從信息化向智能化轉型。而轉型的過程當中,愈來愈多的應用場景,和頻繁地迭代開發,也讓「傳統」架構愈來愈龐大。隨之而來的是運維人員疲於奔命的「救火」,系統服務愈來愈不穩定,以及系統成本的失控飛漲。github

        如何才能從根本上一勞永逸地解決這些問題? 容器化/微服務化是不少企業寄予厚望的方向。web

容器化真的那麼有效嗎?docker

        咱們如下圖爲例。這是一個很通用的架構,在多臺服務器上分別部署Tomcat,使用反向代理軟件(Nginx)把請求均勻分發到每一個Tomcat中。假定因爲11.11促銷,咱們須要將現有的3臺Tomcat擴充到10臺,運維人員須要完成哪些工做?(假設服務器硬件已經準備好)shell

傳統系統的擴容步驟:json

1.    安裝OS,設置安全和權限相關
2.    分配IP,聯網
3.    部署Tomcat
4.    以上動做作7遍

        僅僅一個擴容,就須要一個資深的運維人員花費幾個小時才能完成。若是要擴充到100個節點呢,工做量成倍增長。

容器化系統擴容步驟:

        若是咱們使用容器化技術來完成剛剛這件事,就會節省不少人力。

1.    安裝OS,並由Kubernetes統一管理
2.    一條命令足以,而且在秒級完成擴展

kubectl scale rc tomcat --replicas=10

3.    完成

        簡單的一個對比,便可發現,在資源分配,系統穩定(自愈),運維管理等多個方面,容器化技術均可有效地下降企業的成本和運維壓力,而且讓企業保持技術的敏捷性和先進性。

1.png


 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助力企業快速實現容器化轉型

        如何快速、高效地擁有本身的容器化平臺呢?下面一段,就是AWS官網上Amazon EKS的介紹:

        Amazon EKS 是一項託管服務,可以讓您在 AWS 上輕鬆運行 Kubernetes,而無需安裝、操做和維護您本身的 Kubernetes 控制層面或節點。Kubernetes 是一個用於實現容器化應用程序的部署、擴展和管理的自動化的開源系統。

        Amazon EKS 跨多個可用區運行 Kubernetes 控制層面實例以確保高可用性。Amazon EKS 能夠自動檢測和替換運行情況不佳的控制層面實例,併爲它們提供自動版本升級和修補。

        Amazon EKS 與許多 AWS 服務集成以便爲您的應用程序提供可擴展性和安全性,包括:

·             用於容器鏡像的 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.    須要一個AWS帳號
4.1.2.    帳號資源限制檢查,確保有足夠的IGW,VPC,EIP等
4.1.3.    安裝awscli(包含eksctl)及配置kubectl:

4.1.3.1.        awscli安裝:

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.2.2.    成功執行的輸出:

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分鐘左右。模式很簡單的步驟,實際上是AWS經過調用cloudformation在後臺作了許多工做才完成的。下圖是cloudformation的stack步驟:

2.png


4.2.4.    Amazon EKS完成後的,cloudformation狀態

3.png


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節點的集羣[WHE5] [XX6] ,若是因爲業務的增長,但願擴容的話,如何操做呢?具體命令參考以下,將當前集羣,擴容到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管理,在AWS是如何操做的呢? Amazon ECR,讓image的管理,變得更簡單易用。下面經過httpd的image,定製化並生成私有httpdok的image以後,並上傳到Amazon ECR,做爲步驟演示:

4.3.1.    首先建立一個Amazon ECR Repositories,選擇並點擊View push commands.

4.png

4.3.2.    根據」View puhs commands」步驟,將本地建立好的image,上傳到Amazon ECR。


5.png

具體命令步驟:

# 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]

回到aws控制檯,已經能夠看到上傳的image

6.png

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


4.4.3.    檢查建立狀態

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


4.4.4.    監測網頁顯示狀況

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


4.5.2.    如下命令是肯定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

輸出結果以下:

7.png

5.    總結

        經過本文,你們已經對容器化有一個初步的瞭解,而且針對Amazon EKS打造的企業容器化平臺也有了初步認知。Docker,Kubernetes對於企業的系統和業務的發展,有着不可忽視的「助推力」。

        然而,Kubernetes的學習曲線,以及企業的Kubernetes人才的積累,都是須要較長的「時間」成本。而藉助雲計算供應商的成熟平臺和產品,能夠下降企業的技術人才的積累成本,從而達到事半功倍的效果。

        咱們經過此次實戰的演練,能夠看到,基於Amazon EKS建立容器化平臺,只需一條命令。Amazon EKS讓Kubernetes的建立,運行與維護變得簡單、可靠。經過AWS Fargate,企業甚至能夠徹底省去虛擬機(EC2)的管理,只關注Kubernetes頂層業務架構的邏輯便可,進而能夠將更多的「時間」專一在業務的開發,而不是被底層架構的種種問題所拖累,也可讓運維人員逃離無盡的「救火」式運維模式。

        你,準備好了嗎? 容器化巨輪已經啓航!來,讓咱們一塊兒探索更多可能!

 8.png

參考文檔:

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

相關文章
相關標籤/搜索