Kubernetes的Pod進階(十一)
- 2022 年 1 月 27 日
- 筆記
- Kubernetes
一、Lifecycle
官網://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
通過前面的分享,關於pod是什麼相信看過前面的文章的朋友已經很清楚了,有開發經驗的朋友很清楚,對象的創建是具有生命周期的,對於Pod也一樣,他也有它的生命周期,接下來就是分享pod的創建、銷毀、以及他的狀態是什麼;簡單的來說,就是分享pod的生命周期。

下圖是官網對Pod生命周期階段的描述

通過官網可以發現有一個Running狀態,相信大家也非常喜歡Running狀態,因為這玩意就表示創建成功正常運行,但有時候創建pod時也有不隨人願的時候,因為有時pod偏偏會有一些奇怪的狀態,比哪下面幾個狀態
- 掛起(Pending):Pod 已被 Kubernetes 系統接受,但有一個或者多個容器鏡像尚未創建。等待時間包括調度 Pod 的時間和通過網路下載鏡像的時間,這可能需要花點時間。
- 運行中(Running):該 Pod 已經綁定到了一個節點上,Pod 中所有的容器都已被創建。至少有一個容器正在運行,或者正處於啟動或重啟狀態。
- 成功(Succeeded):Pod 中的所有容器都被成功終止,並且不會再重啟。
- 失敗(Failed):Pod 中的所有容器都已終止了,並且至少有一個容器是因為失敗終止。也就是說,容器以非0狀態退出或者被系統終止。
- 未知(Unknown):因為某些原因無法取得 Pod 的狀態,通常是因為與 Pod 所在主機通訊失敗。
其實對這Pod五大狀態了解後有問題時就可以很好解決了,因為知道狀態後就可以通過kubectl describe pod pod-name -n namespace去查看pod日誌了解為什麼出現這狀態了。
二、重啟策略
- Always:容器失效時,即重啟
- OnFailure:容器終止運行且退出碼不為0時重啟
- Never:永遠不重啟

三、靜態Pod
四、健康檢查
官網://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
經過前面幾個步驟,pod有生命周期了,有重啟策略了,也有固定ip了,接下來pod在進行創建的時候還需要進行健康檢查才能夠進行正常的創建,下面是官網對健康檢查的說明

健康檢查是通過兩個屬性進行的:
- LivenessProbe探針:判斷容器是否存活
- ReadinessProbe探針:判斷容器是否啟動完成
五、ConfifigMap
官網://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

官網的介紹說白了就是用來保存配置數據的鍵值對,也可以保存單個屬性,也可以保存配置文件。所有的配置內容都存儲在etcd中,創建的數據可以供Pod使用。下面來分享下三種創建的方式
5.1、命令行創建
創建一個名稱為my-config的ConfigMap,key值時db.port,value值是3306
kubectl create configmap my-config --from-literal=db.port='3306'
通過命令查看,會發現在系統的默認空間下創建了一個my-config
kubectl get configmap
查看yaml文件對應的格式
kubectl get configmap myconfig -o yaml
5.2、從配置文件中創建
創建一個文件,名稱為app.properties,然後在創建的文件中加入下面兩句話
name=ghy age=2
然後根據文件去創建
kubectl create configmap app --from-file=./app.properties
通過命令查看,會發現在系統的默認空間下創建了一個app
kubectl get configmap
查看yaml文件對應的格式
kubectl get configmap app -o yaml
5.3、通過yaml文件創建
新建一個configmaps.yaml,並把文件放進去
apiVersion: v1 kind: ConfigMap metadata: name: special-config namespace: default data: special.how: very --- apiVersion: v1 kind: ConfigMap metadata: name: env-config namespace: default data: log_level: INFO
啟動yaml文件
kubectl apply -f configmaps.yaml
通過命令查看,會發現在系統的默認空間下創建了一個env-config和special-config兩個
kubectl get configmap
創建CONFIGMAP的動作完成後接下來就是去使用他了。
5.4、ConfigMap的使用
使用方式:
- 通過環境變數的方式,直接傳遞給pod
- 使用configmap中指定的key
- 使用configmap中所有的key
- 通過在pod的命令行下運行的方式(啟動命令中)
- 作為volume的方式掛載到pod內
注意
- ConfigMap必須在Pod使用它之前創建
- 使用envFrom時,將會自動忽略無效的鍵
- Pod只能使用同一個命名空間的ConfigMap
5.4.1、作為volume掛載使用
將創建的ConfigMap直接掛載至Pod的/etc/config目錄下,其中每一個key-value鍵值對都會生成一個文件,key為文件名,value為內容。
創建一個pod-configmap.yaml文件
apiVersion: v1 kind: Pod metadata: name: pod-configmap2 spec: containers: - name: test-container image: busybox command: [ "/bin/sh", "-c", "ls /etc/config/" ] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: special-config restartPolicy: Never
上面的意思很簡單就是pod裡面有一個busybox的containers,他會往虛擬機的/etc/config目錄下把configMap的key和value以目錄的形式掛載進去;
啟動腳本
kubectl apply -f pod-myconfigmap.yml
可以用下面命令看是否創建成功
kubectl get pods
進入容器目錄然後會找到上面說的東西
kubectl exec -it pod-configmap2 bash
六、Secret
官網://kubernetes.io/docs/concepts/configuration/secret/
這塊內容是關於數據安全性東西,前面的ConfigMap的配置文件什麼的大家也看了,但現在的文件配置都是明文的,如果有些東西不想明文展示,那怎麼搞呢

6.1、Secret類型
secret一共有三種類型:
- Opaque:使用base64編碼存儲資訊,可以通過`base64 --decode`解碼獲得原始數據,因此安全性弱。
- kubernetes.io/dockerconfigjson:用於存儲docker registry的認證資訊。
- kubernetes.io/service-account-token:用於被 serviceaccount 引用。serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。Pod 如果使用了 serviceaccount,對應的 secret 會自動掛載到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目錄中。
6.2、Opaque Secret
Opaque類型的Secret的value為base64位編碼後的值
6.2.1、 從文件中創建
echo -n "admin" > ./username.txt echo -n "1f2d1e2e67df" > ./password.txt
kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
kubectl get secret
6.2.2、 使用yaml文件創建
(1)對數據進行64位編碼
echo -n 'admin' | base64 echo -n '1f2d1e2e67df' | base64
(2)定義mysecret.yaml文件
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm
(3)根據yaml文件創建資源並查看
kubectl create -f ./secret.yaml
kubectl get secret
kubectl get secret mysecret -o yaml
6.3 Secret使用
通過6.2.2的方式就得到了一個secret文件,接下來就這個文件使用進行說明下。他的使用有兩種方式
- 以Volume方式
- 以環境變數方式
6.3.1、 將Secret掛載到Volume中
(1)創建mypod.yaml文件
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo secret: secretName: mysecret
(2)用命令啟動
kubectl apply -f mypod.yaml
(3)進入容器裡面
kubectl exec -it mypod bash
(4)進入在配置文件定義的目錄會發現目錄是創建成功的
cd /etc/foo
(5)也可以用如下命令看創建的內容
cat /etc/foo/username
cat /etc/foo/password
6.3.2、 將Secret設置為環境變數
(1)配置文件如下,重要環境變數配置我標記出來了
apiVersion: v1 kind: Pod metadata: name: secret-env-pod spec: containers: - name: mycontainer image: redis env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password restartPolicy: Never
6.4 、kubernetes.io/dockerconfigjson
kubernetes.io/dockerconfigjson用於存儲docker registry的認證資訊,可以直接使用`kubectl create secret`命令創建
6.5、 kubernetes.io/service-account-token
這個是用於被 serviceaccount 引用。serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。Pod 如果使用了 serviceaccount,對應的 secret 會自動掛載到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目錄中。
kubectl get secret # 可以看到service-account-token kubectl run nginx --image nginx kubectl get pods kubectl exec -it nginx-pod-name bash ls /run/secrets/kubernetes.io/serviceaccount
kubectl get secret kubectl get pods pod-name -o yaml # 找到volumes選項,定位到-name,secretName # 找到volumeMounts選項,定位到mountPath: /var/run/secrets/kubernetes.io/serviceaccount
總結:
無論是ConfigMap,Secret,還是DownwardAPI,都是通過ProjectedVolume實現的,可以通過APIServer將資訊放到Pod中進行使用。
七、指定Pod所運行的Node
(1)給node打上label
kubectl get nodes
kubectl label nodes worker02-kubeadm-k8s name=ghy
(2)查看node是否有上述label
kubectl describe node worker02-kubeadm-k8s
(3)部署一個mysql的pod
vi mysql-pod.yaml
apiVersion: v1 kind: ReplicationController metadata: name: mysql-rc labels: name: mysql-rc spec: replicas: 1 selector: name: mysql-pod template: metadata: labels: name: mysql-pod spec: nodeSelector: name: ghy containers: - name: mysql image: mysql imagePullPolicy: IfNotPresent ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "mysql" --- apiVersion: v1 kind: Service metadata: name: mysql-svc labels: name: mysql-svc spec: type: NodePort ports: - port: 3306 protocol: TCP targetPort: 3306 name: http nodePort: 32306 selector: name: mysql-pod
(4)查看pod運行詳情
kubectl apply -f mysql-pod.yaml
kubectl get pods -o wide

