1. 程式人生 > >Kubernetes系列:(1) 初探

Kubernetes系列:(1) 初探

1. 背景

在部門內容組織了一次K8s的培訓,普及了下K8s的概念、框架、操作等,為便於後期查閱,也為了進一步深究K8s,因此開展K8s系列,週期不定…

2. 概念

(1) 含義:來自希臘語,意為”舵手”,又稱K8s

(2) 歷史:2014年由Google建立,是十多年大規模容器管理技術Borg的開源版

(3) 功能:為容器化應用提供資源排程,即容器編排

嚴格意義:容器是將程式碼以及所有的依賴打包,以便應用能夠快速執行,以及在環境間的可靠移植。

通俗意義:容器就像一個集裝箱,將應用封裝起來。這樣應用和應用之間,就因為有了邊界而不至於相互干擾;而被裝進集裝箱的應用,可以被方便的搬來搬去。

3. K8s Vs Docker Swarm

image

4. 架構

K8s並未將Docker作為整個架構的核心,僅僅把它作為最底層的一個容器執行時

image

(1) master

a. controller-manager:容器編排

b. uapi-server:提供api服務

c. scheduler:負責排程

(2) Etcd:用於a: K8s叢集持久化資料; b: 由api-server處理後儲存

(3) worker

1) kubelet

a. 負責同容器執行時打交道,定義容器執行時的各種操作

b. 依賴CRI遠端呼叫介面(Container Runtime Interface)

c. 通過api-server同master通訊

2) Container Runtime

a.同底層OS互動,將CRI請求轉化為對Linux OS的呼叫

b. 依賴OCI協議(Open Container Interface)

3) Device Plugin

a. kubelet通過gRPC與Device plugin互動

b. 管理GPU宿主機物理裝置,用於機器學習、高效能作業

4) Networking

a. kubelet呼叫網路外掛為容器配置網路

b. 通過CNI協議(Container Networking Interface)互動

5) Volume Plugin

a. kubelet呼叫儲存外掛為容器配置持久化儲存

b. 通過CSI協議(Container Storeage Interface)互動

5. 核心

(1) 設計思想:從更巨集觀的角度,以統一的方式來定義任務之間的各種關係

image

1) Pod

a. K8s的最小、最簡單的單元

b. 代表叢集中的執行程序

c. K8s可將多個容器劃分為一個Pod,Pod中的容器共享同一個Network,同一組資料卷

2) Service

a. 對於容器來說,IP地址資訊並非固定,Service宣告IP地址與Pod繫結,提供固定IP地址

b. 作為Pod的代理入口,代替Pod對外暴露一個固定網路地址,以提供外部訪問

3) Deployment

a. 管理Pod,如啟動多個應用例項

4) Secret

a. 將鑑權資訊(資料庫密碼)以Secret方式儲存在Etcd中的鍵值對

b. 啟動Pod應用時,可自動把Secret中的資料以Volume的方式掛載到容器中

5) Job

a. 描述一次性執行任務,如大資料任務

6) DaemonSet

a. 每個宿主機上必須且只能執行一個副本的守護程序服務

7) CronJob

a. 定時任務

8) Ingress

a. 為K8s的Service配置HTTP負載均衡器,將服務暴露給K8s叢集外的客戶端

9) StatefulSet

a. 管理有狀態應用,提供Pod唯一標識

b. 保證部署和擴充套件Pod的順序

10) ConfigMap

a. 容器應用的配置管理

6. 安裝

a. https://github.com/opsnull/follow-me-install-kubernetes-cluster

b. https://git.xfyun.cn/container/kdeploy

c. https://kubernetes.io/docs/setup/independent/install-kubeadm/

d. https://kubernetes.io/docs/tasks/tools/install-minikube/

7. 實踐

(1) Cluster

image

1) 主節點

a. 管理叢集: 排程應用、維護應用所需狀態、應用滾動更新

2) 工作節點

a. kubelet: 管理工作節點,並負責與主節點通訊,處理容器操作

3) 工作節點與主節點通過api-server通訊,開發者也可呼叫api-server

4) 命令:

kubectl version # 查詢版本
kubectl cluster-info #查詢叢集的細節
kubectl get nodes #查詢叢集節點資訊

(2) Deployment

image

1) 執行格式:kubectl action resources

2) 執行流程

a. 尋找合適工作節點執行應用例項

b. 排程應用在該節點上執行

c. 需要時在新節點上重新排程例項

3) 當工作節點上的應用掛掉或刪除,K8s將替換並重啟一個

4) 命令:

kubectl -n test run hello-world --replicas=2 --labels=“run=load-balancer-example” --image=anjia0532/google-samples.node-hello:1.0 --port=8080  # 建立Deployment
kubectl –n test get deployments #查詢當前Deployment
(3) Pod

image    image

1) 一個Pod可以有多個容器,共享儲存、網路等資訊

2) 每個Pod具有獨立且唯一的網路IP

a. 叢集內的Pod和Service相互可見,叢集外不可見

b. 通過kubectl proxy代理轉發,實現外界與叢集內Pod通訊

3) 命令:

kubectl get object # 顯示指定物件
kubectl describe object # 物件具體細節
kubectl logs pod #列印pod容器中的日誌
kubectl exec pod #執行Pod容器命令

(4) Service

image

1) 定義一組邏輯Pod及訪問Pod的策略,4種類型

a. ClusterIP(預設): 叢集內為Service保留IP,僅叢集內訪問

b. NodePort: 使用NAT在叢集的每個節點同一埠公開,可通過<NodeIp>:<NodePort>在叢集外部訪問

c. LoadBalancer: 外部負載均衡,為Service指定固定外部IP

d. ExternalName: 通過返回帶有名稱CNAME記錄,使用任意名稱公開服務,需kube-dns支撐

2) 命令:

kubectl -n test expose deployments/hello-world --port=8080 --type=“NodePort” # 公開服務
kubectl -n test get services # 檢視服務
kubectl -n test describe service hello-world # 檢視服務詳情
curl 192.168.86.156:39018 #測試服務
kubectl -n test delete service hello-world #刪除Service
kubectl -n test exec -ti hello-world-7b97bf7768-cldrm curl localhost:8080 # 驗證容器內的服務仍在執行

(5) Label

1) 使用鍵值對儲存,用途:

a. 指定測試、開發、生產環境的物件

b. 嵌入版本標籤

c. 使用標籤分類物件

2) 命令:

kubectl -n test get pods -l run=load-balancer-example # 使用標籤查詢Pod
kubectl -n test get services -l run=load-balancer-example # 使用標籤查詢Service
kubectl -n test label pod hello-world-7b97bf7768-cldrm app=v1 # 為Pod打新的標籤

(6) Scale

image   image

1) 流量增加時,需對應用進行擴充套件

2) K8s基於Deployment中的副本數實現擴充套件

3) 命令

kubectl -n test scale deployments/hello-world --replicas=4 # 擴充套件副本集
kubectl -n test get pods -o wide #檢視擴充套件
kubectl -n test describe deployments/hello-world # 檢視deployment詳情
kubectl -n test expose deployments/hello-world --port=8080 --type=“NodePort“ # 公開服務
kubectl -n test describe service hello-world # 檢視暴露的埠
curl 192.168.86.1:11235

(7) Rollout Update

imageimage

imageimage

1) Deployment滾動更新時,Service將流量負載均衡至可用狀態的Pod

2) Rollout Update時,Pods的最大可用數和新的Pod的最大建立你數,預設均為1,但可以設定

3) 滾動更新版本化,任何Deployment更新均可還原之前的版本

4) 支援如下操作

a. 將應用從一個環境推廣到另一個環境

b. 回溯至以前的版本

c. 應用的CI/CD

5) 命令:

kubectl -n test describe pod hello-world-7b97bf7768-lftt5 # 顯示Pod中的映象
kubectl –n test set image deployments/hello-world hello-world=anjia0532/google-samples.hello-app:2.0 #通知Deployment使用不同映象,滾動更新
kubectl -n test rollout status deployments/hello-world # 驗證更新
kubectl -n test describe pod hello-world-855cb96d-qx827 #檢視映象是否更新
kubectl -n test rollout undo deployments/hello-world #版本還原
kubectl -n test describe pod hello-world-7b97bf7768-sbmq4

(8) ConfigMap

1) 允許配置與映象內容分離,進而保持容器應用可移植性

2) 建立格式:kubectl create configmap <map-name> <data-source>

a. data-source: 可來自於檔案、目錄或字面值,均以鍵值對錶示

3) 命令:

kubectl -n test create configmap game-config2 --from-file=game.properties --from-file=ui.properties
kubectl -n test get configmap game-config2 -o yaml
kubectl -n test describe configmap game-config2
kubectl -n test create configmap game-config-env-file --from-env-file=game-env-file.properties
kubectl -n test get configmap game-config-env-file -o yaml
kubectl -n test create configmap special-config --from-literal=special.how=very --from-literal=special.type=charmükubectl -n test create configmap game-config2 --from-file=game.properties --from-file=ui.properties

kubectl -n test get configmap game-config2 -o yaml
kubectl -n test describe configmap game-config2
kubectl -n test create configmap game-config-env-file --from-env-file=game-env-file.properties
kubectl -n test get configmap game-config-env-file -o yaml
kubectl -n test create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
kubectl -n test create configmap env-config --from-literal=log_level=INFO
kubectl -n test get configmap special-config -o yaml

(9)  基於yaml檔案配置

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
  namespace: test
spec:
  containers:
    - name: test-container
      image: anjia0532/google-containers.busybox:1.27.2
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
  restartPolicy: Never

命令:

kubectl apply –f dapi-test-pod.yaml
kubectl –n test describe pod dapi-test-pod
kubectl –n test logs pods/dapi-test-pod

8. 參考

1) --help/-h: 如果對於某個命令不熟悉,可以直接在命令後增加--help或-h,檢視用途及示例

2) 線上教程

a. https://www.katacoda.com/courses/kubernetes/

b. https://training.play-with-kubernetes.com/kubernetes-workshop/

9. 命令彙總

  1 1. Cluster
  2 # 檢視K8s的版本
  3 kubectl version
  4 
  5 #檢視叢集資訊
  6 kubectl cluster-info
  7 
  8 # 檢視當前叢集節點資訊
  9 kubectl get nodes
 10 
 11 
 12 2. Deployment
 13 # 建立deployment
 14 kubectl -n test run hello-world --image=anjia0532/google-samples.node-hello:1.0
 15 # 查詢當前deployments(完成部署時AVAILABLE才會為2)
 16 kubectl -n test get deployments
 17 
 18 
 19 3. Pod
 20 # 顯示Pods
 21 kubectl -n test get pods
 22 
 23 # 顯示指定Pod詳情
 24 kubectl -n test describe pod hello-world-9d675f6bf-dg4bh
 25 
 26 # 列印容器日誌(應用通常傳送給STDOUT的任何內容,均會成為Pod容器中的日誌)
 27 kubectl -n test logs hello-world-9d675f6bf-dg4bh
 28 
 29 # 檢視容器內部的資訊
 30 kubectl -n test exec hello-world-9d675f6bf-dg4bh env
 31 kubectl -n test exec hello-world-9d675f6bf-dg4bh -it bash
 32 
 33 # 檢視服務
 34 curl localhost:8080
 35 
 36 
 37 4. Service
 38 # 使用NodePort方式公開服務
 39 kubectl -n test expose deployments/hello-world --port=8080 --type="NodePort"
 40 
 41 # 檢視服務
 42 kubectl -n test get services
 43 
 44 # 檢視服務詳情
 45 kubectl -n test describe services hello-world
 46 
 47 # 驗證公開服務 <NodeIp>:<NodePort>
 48 curl 192.168.86.156:29463
 49 
 50 # 刪除Service
 51 kubectl -n test delete service hello-world
 52 
 53 # 檢視Service
 54 kubectl -n test get services
 55 
 56 # 叢集內的服務仍在執行
 57 kubectl -n test exec hello-world-675c948d88-c6df2 -it curl localhost:8080
 58 
 59 5. Label
 60 # 使用標籤查詢Pod
 61 kubectl -n test get pods -l run=hello-world
 62 
 63 # 使用標籤查詢Service
 64 kubectl -n test get services -l run=hello-world
 65 
 66 # 為Pod建立新的標籤
 67 kubectl -n test label pod hello-world-675c948d88-c6df2 app=v1
 68 
 69 6. Scale
 70 # 擴充套件副本集
 71 kubectl -n test scale deployments/hello-world --replicas=2
 72 
 73 # 檢視Pod
 74 kubectl -n test get pods -o wide
 75 
 76 # 檢視Deployments的詳情
 77 kubectl -n test describe deployment hello-world
 78 
 79 # 公開服務
 80 kubectl -n test expose deployments/hello-world --port=8080 --type="NodePort"
 81 
 82 # 檢視公開的埠
 83 kubectl -n test get service -o wide
 84 
 85 # 測試負載均衡
 86 curl 192.168.86.156:18047
 87 
 88 7. Rollout Update
 89 # 查詢Deployment中的映象
 90 kubectl -n test describe deployment hello-world
 91 
 92 # 更新應用映象,使用set image命令
 93 kubectl -n test set image deployments/hello-world hello-world=anjia0532/google-samples.hello-app:2.0
 94 
 95 # 驗證更新
 96 kubectl -n test describe deployment hello-world
 97 kubectl -n test rollout status deployment hello-world
 98 
 99 # 版本還原(滾動更新異常,如映象無法拉取等)
100 kubectl -n test rollout undo deployments/hello-world
101 
102 # 檢視還原後的版本
103 kubectl -n test describe deployment hello-world
104 
105 8. ConfigMap
106 # 基於檔案建立ConfigMap
107 kubectl -n test create configmap game-config --from-file=game.properties --from-file=ui.properties
108 
109 # 檢測建立結果
110 kubectl -n test get configmap game-config -o yaml
111 
112 # 基於環境變數配置檔案建立
113 kubectl -n test create configmap game-config-env-file --from-env-file=game-env-file.properties --from-env-file=ui-env-file.properties
114 
115 # 檢視建立結果(當多次使用多個數據來源通過--from-env-file建立時,只有最後一個生效)
116 kubectl -n test get configmap game-config-env-file -o yaml
117 
118 # 基於字面值建立
119 kubectl -n test create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
120 kubectl -n test create configmap env-config --from-literal=log_level=INFO
121 
122 # 檢視字面值建立
123 kubectl -n test get configmap special-config  -o json
124 
125 # 基於yaml檔案配置
126 kubectl apply -f dapi-test-pod.yaml
127 
128 # 檢視該Pod
129 kubectl -n test describe pod dapi-test-pod
130 
131 # 檢視輸出日誌是否生效
132 kubectl -n test logs pods/dapi-test-pod
View Code