# Kubernetes 進階 > [name=翁維甫] > [time=Thur, Sep 22, 2020 4:00 PM] --- # Agenda * Deployment * Service * StatefulSet * DaemonSet * ConfigMap * Secret * Volumes * Resource Quotas * CronJob --- ## Deployment * Deployment 為 pod 和 replicaset 提供了一個宣告式的設定與更新方式,應用場景: * 定義 Deployment 來創建 Pod 和 ReplicaSet * 滾動更新及回溯應用 * 擴充和縮編 * 暫停和繼續佈署 --- ### ![](https://i.imgur.com/4RUdfbq.png) --- ### 建立 Deployment 編輯文件檔 ```linux= vim deployment.yaml ``` ```yaml= # 該元件的版本號 apiVersion: apps/v1 # 該元件是什麼屬性 kind: Deployment metadata: # deployment name name: nginx-deployment # deployment 標籤 labels: app: nginx spec: # 同時建立 3 個 nginx 的 pod replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: # 設定給 pod 的 label 資訊 app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 ``` --- 以文件檔佈署 ```linux= kubectl apply -f deployment.yaml --record ``` ![](https://i.imgur.com/3HK4vnX.png) 查詢佈署相關資訊 ```linux= kubectl get all ``` ![](https://i.imgur.com/owblSzI.png) --- 檢視細節 ```linux= kubectl describe deployment nginx-deployment ``` ![](https://i.imgur.com/wvt57F8.png) --- ### 更新 Deployment 更新 nginx 版本 ```linux= kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record ``` ![](https://i.imgur.com/S2ZdZTM.png) 檢視 replicaset 的狀態 ```linux= kubectl get rs ``` ![](https://i.imgur.com/jUK06n2.png) --- 檢視更新後細節 ```linux= kubectl describe deployment nginx-deployment ``` ![](https://i.imgur.com/GWKiCqj.png) --- 更新錯誤的版本 ```linux= kubectl set image deployment nginx-deployment nginx=nginx:1.99 --record ``` ![](https://i.imgur.com/hvVwlyV.png) 檢視 replicaset 的狀態 ```linux= kubectl get rs ``` ![](https://i.imgur.com/Wxa1uEp.png) --- ### Deployment 版本回溯 查詢下過的指令 ```linux= kubectl rollout history deployment nginx-deployment ``` ![](https://i.imgur.com/MS2heeg.png) 檢視 rollout hsitory 的細節 ```linux= kubectl rollout history deployment nginx-deployment --revision=3 ``` ![](https://i.imgur.com/6ogdE7U.png) --- 發現版本錯誤,故可退回前一版,也就是 revision=2 ```linux= kubectl rollout undo deployment nginx-deployment --to-revision=2 ``` ![](https://i.imgur.com/3v09iV3.png) 檢視 replicaset 的狀態 ```linux= kubectl get rs ``` ![](https://i.imgur.com/jm5iwiN.png) --- ### Deployment 擴充 將 pod 增加到 5 ```linux= kubectl scale deployment nginx-deployment --replicas=5 ``` ![](https://i.imgur.com/HY5T5YN.png) 查詢狀態 ```linux= kubectl get all ``` ![](https://i.imgur.com/9xxJmVz.png) --- ### 自動擴充 ```linux= kubectl autoscale deployment nginx-deployment --min=3 --max=10 --cpu-percent=80 ``` ![](https://i.imgur.com/L3881oh.png) 查詢設定狀況 ```linux= kubectl get hpa ``` ![](https://i.imgur.com/TuDeqPO.png) --- ### 暫停 Deployment 暫停 rollout ```linux= kubectl rollout pause deployment nginx-deployment ``` ![](https://i.imgur.com/wKoGqYN.png) 恢復 rollout ```linux= kubectl rollout resume deploy nginx-deployment ``` ![](https://i.imgur.com/VMvHNea.png) --- ### Deployment 狀態 * Deployment 的生命週期有三種狀態: * Progressing * Complete * Fail to progress --- #### Progressing * Kubernetes 將執行過下列任務其中之一的 Deployment 標記為 Progressing * 正在建立新的 ReplicaSet * 正在擴充一個已經有的 ReplicaSet * 正在縮編一個已經有的 ReplicaSet * 新的 Pod 狀態變成 ready or available --- #### Complete * Kubernetes 將包括以下特性的 Deployment 標記為 Complete * 所有與該 Deployment 相關的 ReplicaSet 都已經更新到指定版本 * 所有相關的 Pod 的狀態都是 available * 沒有舊版本的 Pod 還在執行中 --- #### Fail to progress * Deployment 執行到一半發生問題或是卡住而無法完成任務,以下因素:  * Readiness probe 診斷失敗 * 映像檔拉取發生錯誤 * 權限不足 * 集群資源不足 * 超過資源限制範圍 * 應用程式本身造成的錯誤 --- #### Fail to progress 預設時間修改 * progressDeadlineSeconds 預設時間為 600 秒 * 修改指令,範例修改為 60 秒 ```linux= kubectl patch deployments nginx-deployment -p '{ "spec": { "progressDeadlineSeconds": 60 }}' ``` --- ## Service * Kubernetes Service 是個抽象化的概念,主要定義了邏輯上的一群 Pod 以及如何存取他們的規則 --- ### Service Types * ClusterIP * 內部 Client 端存取用 * NodePort * 外部 Client 端存取用,可指定一個或多個 NodePort 節點的 IP * LoadBalancer * 外部 Client 端存取用,同時也建立了負載平衡的機制來分散流量 * ExternalName * 內部 Client 端使用的 DNS 別名 * 主要用途為把 Service 導向指定的 DNS name --- ### NodePort 建立 Service ```linux= vim service.yaml ``` ```yaml= kind: Service apiVersion: v1 metadata: name: nginx-service spec: # 將 type 設定為 NodePort type: NodePort # 選擇帶有 "app=nginx" 的 pod selector: app: nginx # Service 實際對外服務的設定 ports: # 若不指定,預設為 TCP - protocol: TCP port: 80 # 若不指定,預設與 port 相同 targetPort: 9123 # 指定 NodePort number(.spec.ports[*].nodePort) # 也可不指定(30000~32767) nodePort: 30077 ``` --- 以文件檔建立 ```linux= kubectl apply -f service.yaml ``` ![](https://i.imgur.com/H75EpRL.png) 檢查狀態 ```linux= kubectl get svc ``` ![](https://i.imgur.com/0d9cQt7.png) --- ### Load Balancer * 目前僅有在 public cloud or OpenStack 上才有支援 * MetalLB --- ### Headless Service * Service 需要將 spec.clusterIP 設置成 None * 不會分配 ClusterIP,而是將 Endpoints 返回 --- ## StatefulSet * 可當成有狀態的 Deployment ,有固定的識別資訊,應用場景: * 需要穩定且唯一的網路識別 * 需要穩定持久儲存 * 有順序性的佈署和擴充 * 有順序性的滾動更新 --- ### 如何分辨 StatefulSet 產生的 Pod ? * Pod 會有自己獨一無二的 hostname,命名規則為 $ (statefulset name)-$ (ordinal index) * 透過 Headless Service 來維持 Pod domain name 是固定指到 Pod IP , domain name 格式為 $ (service name).$ (namespace).svc.cluster.local --- ### 建立 StatefulSet 編輯文件檔 ```linux= vim statefulset.yaml ``` ```yaml= apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web # clusterIP 設置為 None clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx-headless image: nginx:1.7.9 ports: - containerPort: 80 name: web ``` --- 以文件檔佈署 ```linux= kubectl apply -f statefulset.yaml --record ``` ![](https://i.imgur.com/3QhOIzZ.png) 查詢服務 ```linux= kubectl get pods -o wide | grep web ``` ![](https://i.imgur.com/II22wkc.png) --- 查詢 K8S DNS 的 IP ```linux= kubectl get svc -n kube-system | grep dns ``` ![](https://i.imgur.com/iwMAZjT.png) 測試 Service 域名是否解析出兩個 Pod IP ```linux= nslookup nginx.default.svc.cluster.local 10.96.0.10 ``` ![](https://i.imgur.com/TYoY9Ru.png) --- 測試 Pod 域名是否解析出對應的 Pod IP ```linux= nslookup web-0.nginx.default.svc.cluster.local 10.96.0.10 ``` ![](https://i.imgur.com/xQKmYkF.png) ```linux= nslookup web-1.nginx.default.svc.cluster.local 10.96.0.10 ``` ![](https://i.imgur.com/P44o02B.png) --- ## DaemonSet --- ## Volumes * Volumes 可以當成是 Kubernetes Cluster 中用來儲存資料的地方 * 能將 Container 的資料儲存下來,也可以透過掛載( mounting )的方式,供許多個 Pods 同時存取 * 常用的 Volume 類型: * emptyDir * hostPath * Cloud Storage * NFS( Network FileSystem ) --- ### emptyDir * 當 Pod 建立後,該 Volume 也會一併被建立,並賦予讀寫的權限,其生命週期與 Pod 一致,當 Pod 中的容器掛掉時,emptyDir Volume 中的內容不會被清除,容器重啟後數據依然可見,只有當 Pod 被刪除,emptyDir Volume 中的內容才會被清除,適合存放不重要的資料 --- ![](https://i.imgur.com/RLml1qV.png) --- #### Demo emptyDir 編輯文件檔 ```linux= vim emptydir.yaml ``` ```yaml= apiVersion: v1 kind: Pod metadata: name: emptydir-pod spec: # 定義 emptyDir 名稱 volumes: - name: my-emptydir-vol emptyDir: {} containers: - name: busybox-1 image: busybox:latest command: - "sleep" - "3600" # 將 my-emptydir-vol Mount 到容器中 volumeMounts: - name: my-emptydir-vol # 容器中目錄 mountPath: /data-1 - name: busybox-2 image: busybox:latest command: - "sleep" - "3600" # 將 my-emptydir-vol Mount 到容器中 volumeMounts: - name: my-emptydir-vol mountPath: /data-2 ``` --- 以文件檔建立 ```linux= kubectl apply -f emptydir.yaml --record ``` ![](https://i.imgur.com/9QdCVib.png) 查詢服務 ```linux= kubectl get pods ``` ![](https://i.imgur.com/x5EMeRz.png) --- 確認一下 Volume ```linux= kubectl describe pod ``` ![](https://i.imgur.com/RmdnXF9.png) ![](https://i.imgur.com/ARf3yi9.png) ![](https://i.imgur.com/LdowzCY.png) 此部分只截取 Volume 相關部分 --- 進入容器 busybox-1 ```linux= kubectl exec -it emptydir-pod -c busybox-1 sh ``` ![](https://i.imgur.com/ZedhcWx.png) 在 data-1 資料夾中建立一個文件 ```linux= cd /data-1 echo "5566" > 5566.txt ``` ![](https://i.imgur.com/OErtg1q.png) --- 進入容器 busybox-2 ```linux= kubectl exec -it emptydir-pod -c busybox-2 sh ``` ![](https://i.imgur.com/t7O9sOa.png) 確認是否可以查看剛剛在 busybox-1 建立的文件 ```linux= cat /data-2/5566.txt ``` ![](https://i.imgur.com/gYm9Pu6.png) --- * emptyDir Volume 會存放在 Node 節點,會有一個臨時目錄 查詢 Pod 所在的 Node ```linux= kubectl get pods -o yaml | grep nodename ``` 查詢 Pod 的 uid ```linux= kubectl get pods -o yaml | grep uid ``` 查看剛剛建立的文件 ```linux= cat /var/lib/kubelet/pods/$(uid)/volumes/kubernetes.io~empty-dir/my-emptydir-vol/5566.txt ``` ---
{"metaMigratedAt":"2023-06-15T13:51:04.290Z","metaMigratedFrom":"YAML","title":"Kubernetes 進階","breaks":true,"contributors":"[{\"id\":\"f7df1304-fff3-4f97-80d7-e2ae0a04d33f\",\"add\":9463,\"del\":464},{\"id\":\"4f5c5dc0-df78-40b6-8b4c-d0c83c7416cb\",\"add\":1,\"del\":1}]"}
    314 views
   Owned this note