(K8s學習筆記五)Pod的使用詳解


1.Pod用法

K8s里使用的容器不能使用啟動命令是后台執行程序,如:nohup ./start.sh &,該腳本運行完成后kubelet會認為該Pod執行結束,將立刻銷毀該Pod,如果該Pod定義了RC/RS,則執行完該腳本,系統監控會認為該Pod已經終止,之后根據RC/RS定義中的副本數量生成一個新的Pod,一旦創建新的Pod,就在執行完啟動命令后陷入無限循環的過程中,所以,K8s里使用的容器只能是前台命令作為啟動命令。對於無法改為前台執行的應用,可以使用Supervisor工具輔助進行前台運行。

一個Pod由兩個容器應用為緊耦合示例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-tomcat
  labels:
    name: test
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
  - name: tomcat
    image: tomcat:latest
    ports:
    - containerPort: 8080

 屬於同一個Pod的多個容器應用間相互訪問僅需通過localhost,一個Pod里多個容器時kubectl get pods時READY會按容器數量顯示值,例如上例會顯示2/2

2.創建靜態Pod

靜態Pod是由kubelet進行創建和管理的僅存放於特定的Node上的Pod,不能通過API Server管理,無法與RC/RS、Deployment或DaemonSet進行關聯,且kubelet無法對它們進行健康檢查。

1)配置文件方式:需設置kubelet啟動參數"--config",指定kubelet需要監控的配置文件所在目錄,kubelet會定期掃描該目錄,並根據目錄下的.yaml或.json文件進行創建,例如,配置文件目錄/opt/files,配置啟動參數"--config=/opt/files",在該目錄下放入.yaml文件。

靜態Pod在Master上執行刪除會顯示Pending狀態,且不會被真正刪除,只能到該Pod所在的Node上將其.yaml或.json文件從掃描目錄下刪除即可。

2)HTTP方式:需設置kubelet啟動參數"--manifest-url",kubelet將定期從該url地址下載Pod的定義文件,並以.yaml或.json的格式進行解析,然后創建Pod,刪除方方法通配置文件方式。

3.Pod容器共享Volume

同一個Pod中的多個容器能共享Pod級別的存儲卷Volume,如例:

apiVersion: v1
kind: Pod metadata: name: nginx
-busybox labels: name: test spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: app-logs mountPath: /var/log/nginx - name: busybox image: busybox:latest command: ["sh","-c","tail -f /logs/access.log"] volumeMounts: - name: app-logs mountPath: /logs volumes: - name: app-logs emptyDir: {}

# 查看busybox容器的輸出
kubectl logs nginx-busybox -c busybox

# 登錄nginx容器進行查看
kubectl exec -it nginx-busybox -c nginx -- ls /var/log/nginx/access.log
kubectl exec -it nginx-busybox -c nginx -- tail /var/log/nginx/access.log

定義的Volume名為app-logs,掛載到nginx容器內的/var/log/nginx目錄,同時掛載到busybox容器的/logs目錄,nginx容器啟動后會想/var/log/nginx目錄里寫入文件,busybox容器就可讀取其中的文件。

4.configMap使用

configMap的用法

  • 生成為容器內的環境變量
  • 設置容器啟動命令的啟動參數(需設置為環境變量)
  • 以Volume的形式掛載為容器內部的文件或目錄

1)通過YAML文件方式創建

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appconfig
data:
  apploglevel: info
  appdatadir: /var/log/data

# 創建該ConfigMap
kubectl create -f cm-appconfig.yaml

# 查看該ConfigMap
kubectl get configmap
kubectl describe configmap cm-appconfig

# 以yaml形式輸入詳細內容
kubectl get configmap cm-appconfig -o yaml

# 將兩個配置文件server.xml和logging.properties定義為ConfigMap的用法,設置key為配置文件的別名,value則是配置文件的全部文本內容
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-configfiles
data:
  key-serverxml: |
    .............
  key-loggingproperties: | 
    ...........

2)通過kubectl命令行方式創建

通過kubectl create configmap創建,可使用參數--from-file或--from-literal指定內容,且可以在一行命令中指定多個參數

# 通過--from-file參數從文件中進行創建,可以指定key的名稱,也可以在一個命令行創建包含多個key的ConfiMap
kubectl create configmap {NAME} --from-file=[key=]source --from-file=[key=]source

# 通過--from-file參數從目錄中進行創建,該目錄下的每個配置文件名都被設置為key,文件的內容被設置為value
kubectl create configmap {NAME} --from-file={config file dir}

# 使用--from-literal時會從文本中進行創建,直接將指定的key#=value#創建為ConfigMap的內容
kubectl create configmap {NAME} --from-literal={key1}={value1} --from-literal={key2}={value2} 

# 示例:
在當前目錄下含有server.xml時
kubectl create configmap cm-server.xml --from-file=server.xml
kubectl describe configmap cm-server.xml

在/opt/configfiles目錄下包含兩個文件server.xml和logging.properties時
kubectl create configmap cm-appconf --from-file=/opt/configfiles
kubectl describe configmap cm-appconf

使用from-literal參數創建
kubectl create configmap cm-appenv --from-literal=loglevel=info --from-literal=appdatadir=/var/log/data

5.在Pod中使用configMap

1)通過環境變量的方式使用

# vi cm-appconfig.yaml    # 創建ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appconfig
data:
  apploglevel: info
  appdatadir: /opt/data

# vi test-pod.yaml        # 創建Pod
apiVersion: v1 
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["bin/sh", "-c", "env | grep APP"]
    env:
    - name: APPLOGLEVEL     # 定義環境變量名稱
      valueFrom:            # key "apploglevel"對應的值
        configMapkeyRef:
          name: cm-appconfig     # 環境變量的值取自cm-appconfig
          key: apploglevel       # key為apploglevel
    - name: APPDATADIR      # 定義環境變量的名稱
      valueFrom:            # key "appdatadir"對應的值
        configMapKeyRef:
          name: cm-appconfig     # 環境變量的值取自cm-appconfig
          key: appdatadir        # key為appdatadir

或着使用自動生成環境變量的方法
# vi test-pod.yaml        # 創建Pod
apiVersion: v1 
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["bin/sh", "-c", "env | grep APP"]
    envFrom:                  # 根據cm-appconfig中的key=value自動生成環境變量 
    - configMapRef:
      name: cm-appconfig  

2)通過volumeMount使用ConfigMap

在ConfigMap文件中包含兩個定義文件server.xml和logging.properties
# vi cm-appconfig.yaml    # 創建ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appconfig
data:
  key-serverxml: |
  ...........
  key-loggingproperties: .......

將ConfigMap中的內容以文件的形式mount到容器內部的/config_files目錄下
# vi test-pod.yaml        # 創建Pod
apiVersion: v1 
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["bin/sh", "-c", "env | grep APP"]
    volumeMounts:
    - name: serverxml             # 引用volume的名稱
      mountPath: /config_files    # 掛載到容器內的目錄
  volumes:
  - name: serverxml               # 定義volume的名稱
    configMap:
      name: cm-appconfig          # 使用ConfigMap文件
      items:
      - key: key-serverxml        # key=key-serverxml
        path: server.xml          # value將server.xml文件名進行掛載
      - key: key-loggingproperties
        path: logging.properties

或者不指定items,在容器內的目錄下為每個item都生成一個文件名為key的文件
# vi test-pod.yaml        # 創建Pod
apiVersion: v1 
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["bin/sh", "-c", "env | grep APP"]
    volumeMounts:
    - name: serverxml             # 引用volume的名稱
      mountPath: /config_files    # 掛載到容器內的目錄
  volumes:
  - name: serverxml               # 定義volume的名稱
    configMap:
      name: cm-appconfig          # 使用ConfigMap文件

此時在容器內的/config_files目錄下會生成key-serverxml和key-loggingproperties兩個key文件,內容為ConfigMap文件中的value值

注:ConfigMap文件必須在創建Pod文件前創建;ConfigMap只能在同一Namespace中使用;靜態Pod不能使用ConfiMap;ConfigMap掛載到容器內的指定目錄時會覆蓋目錄內的其他問題,如要保留掛載目錄的原文件,可將ConfigMap先掛載到臨時目錄,然后通過啟動腳本cp或link命令到指定目錄中。

6.在Pod容器內部或得Pod名稱、Pod IP、所在Namespace等信息(Downward API)

1)環境變量注入方式

將Pod信息(Pod IP、名稱和所在Namespace)注入為環境變量
# dapi-pod-vars.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-pod-vars
spec:
  containers:
    - name: busybox
      image: busybox:latest
      command: ["/bin/sh", "-c", "env"]
      env:
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name     # 獲取生成Pod后的name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace   # 獲取Pod所在的namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP      # 獲取生存Pod后Pod IP

將容器的資源請求和限制信息注入到容器的環境變量中
# dapi-pod-vars.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-pod-vars
spec:
  containers:
    - name: busybox
      image: busybox:latest
      command: ["/bin/sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_CPU_REQUEST MY_CPU_LIMIT;
          printenv MY_MEM_REQUEST MY_MEM_LIMIT;
          sleep 3600;
        done;
      resources:
        requests:
          memory: "16Mi"
          cpu: "100m"
        limits:
          memory: "512Mi"
          cpu: "800m"
      env:
        - name: MY_CPU_REQUEST
          valueFrom:
            resourceFieldRef:
              containerName: busybox
              resource: requests.cpu         # 獲取容器CPU的請求值
        - name: MY_CPU_LIMIT
           valueFrom:
            resourceFieldRef:
              containerName: busybox
              resource: limits.cpu           # 獲取容器CPU的限制值
        - name: MY_MEM_REQUEST
          valueFrom:
            resourceFieldRef:
              containerName: busybox
              resource: requests.memory      # 獲取容器內存的請求值
        - name: MY_MEM_LIMIT
           valueFrom:
            resourceFieldRef:
              containerName: busybox
              resource: limits.memory        # 獲取容器內存的限制值

2)Volume掛載注入方式

將Pod的Label、Annotation聲明通過Volume掛載為容器中的一個文件,容器使用echo命令將文件內容輸出
# dapi-pod-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-pod-volume
  labels:
    zone: test-zone01
    cluster: test-cluster
    rack: rack-01
  annotations:
    build: one
    builder: jason
spec:
  containers:
    - name: busybox
      image: busybox:latest
      command: ["/bin/sh", "-c"]
      args:
      - while true; do 
          if [[ -e /etc/labels ]]; then 
            echo -en '\n\n'; cat /etc/labels; fi;
          if [[ -e /etc/annotations ]]; then 
            echo -en '\n\n'; cat /etc/annotations; fi;
          sleep 3600;
        done;
      volumeMounts:
        - name: pod-info
          mountPath: /etc
          readOnly: false
  volumes:
    - name: pod-info
      downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels   # 獲取容器metadata.labels的信息
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations   # 獲取容器metadata.annotations的信息
系統根據items.path的名稱在
/etc目錄下生成文件

7.Pod的生命周期和重啟策略

1)Pod的狀態說明:

  • Pending:創建Pod后,在Pod內還有一個或多個容器的鏡像沒有創建,包括正在下載鏡像的過程
  • Running:Pod內所有容器均已創建,且至少有一個容器處於正在運行或正在重啟狀態
  • Succeeded:Pod內所有容器均成功執行后退出,且不會再重啟
  • Failed:Pod內所有容器均已退出,但至少有一個容器退出失敗
  • Unknown:由於某種原因無法獲取該Pod的狀態,可能由於網絡不暢導致

2)Pod的重啟策略(RestartPolicy)

  • Always:當容器失敗時,由kubelet自動重啟該容器
  • OnFailure:當容器終止運行且退出碼不為0時,由kubelet自動重啟該容器
  • Never:不論容器運行狀態如何,kubelet都不會重啟該容器

3)每種控制器對Pod重啟策略的要求

  • RC/RS和DaemonSet:必須設置為Always,需要保證該容器持續運行
  • Job:OnFailure或Never,確保容器執行完成后不再重啟
  • kubelet:在Pod失效時自動重啟,不論RestartPolicy設為何值,且也不會對Pod進行健康檢查

8.Pod健康和服務可用性檢查

1)kubelet診斷容器健康狀態探針

  • LivenessProbe探針:用於判斷容器是否是Running狀態,如果不是則kubelet會殺掉該容器,並根據RestartPolicy值處理容器。如果容器不包含此探針,那么kubelet認為該容器LivenessProbe返回值永遠是Success
  • ReadinessProbe探針:用於判斷容器是否時Ready狀態,如果在運行中Ready狀態變為False,則系統自動將其從Service的后端Endpoint列表中隔離出去,后續再把恢復Ready狀態的Pod加回后端Endpoint列表,這樣就能保證訪問Service是流量不會被轉發到不可用的Pod上

2)LivenessProbe和ReadinessProbe可配置三種實現方式

1.ExecAction方式:在容器內部執行一條命令,如果該命令的返回碼為0,則表明容器健康
apiVersion: v1 
kind: Pod
metadata:
  name: liveness-exec-test
spec:
  containers:
  - name: busybox
    image: busybox:latest
    args:
    - /bin/sh
    - -c 
    - echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 300;
    livenessProbe:
      exec:
        command:
        - cat 
        - /tmp/health 
      initialDelaySeconds: 15    # 啟動容器后進行首次chk的等待時間,單位s
      timeoutSeconds: 1          # 健康檢查發送請求后等待響應的超時時間,單位s,如超級,kubelet會認為容器無法服務,將會重啟容器
cat /tmp/health命令判讀容器狀態,在Pod運行后,創建完/tmp/health文件后10s將其刪除,livenessProbe的探測時間initialDelaySeconds為15s,探測結果Ready

2.TCPsocketAction方式:通過容器的IP和Port執行TCP檢查,如果能建立TCP連接,則表明容器健康
apiVersion: v1 
kind: Pod
metadata:
  name: healthcheck-test
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 15 # 每隔15s chk容器內localhost:80,如存活則表明容器健康
      timeoutSeconds: 1

3.HTTPGetAction方式:通過容器的IP、Port和路徑調用HTTP Get方式,如果返回碼>=200且<400,則認為容器健康
apiVersion: v1 
kind: Pod
metadata:
  name: healthcheck-test
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
      - containerPort: 80
      livenessProbe:
        httpGetL:
          path: /chk_test/test.html
          port: 80
        initialDelaySeconds: 15 # 每隔15s chk容器內localhost:80/chk_test/test.html,如返回碼200則表明容器健康
        timeoutSeconds: 1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM