1. 程式人生 > >k8s之深入解剖Pod(二)

k8s之深入解剖Pod(二)

目錄:

  Pod配置管理:ConfigMap

  容器內獲取Pod資訊:Downward API

  Pod生命週期和重啟策略

  Pod健康檢查

 

一、ConfigMap

將應用所需的配置資訊與程式進行分離,可以使應用程式更好的被複用,通過不同的配置實現更靈活的功能。如果將應用打包成映象,再用環境變數或者外掛檔案的方式掛載配置,在大型容器叢集中會變得異常繁瑣,所以出現了統一的配置管理:ConfigMap

(1)ConfigMap:容器應用的配置管理

典型用法如下:

1、生成為容器內的環境變數

2、設定容器啟動命令的啟動引數(需設定為環境變數)

3、以Volume的形式掛載為容器內部的檔案或目錄

ConfigMap以一個或多個key:value的形式儲存在k8s系統中供應用使用,既可以用於表示一個變數的值,也可以表示一個完整配置檔案的內容。

 

(2)建立方式

1、通過yaml檔案進行建立

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-1
data:
  home_path: /usr/soft

  

需要將配置定義在data下面,上述yaml檔案中在data中定義了一個key是home_path,value是/usr/soft的配置。

使用如下命令建立:

kubectl create -f cm_1.yaml

  

 

 

檢視建立的ConfigMap:

kubectl get cm
或
kubectl get configmap

  

 

 

檢視ConfigMap的詳細內容:

kubectl describe cm/cm-1

  

 

 

2、通過kubectl命令列建立

直接通過kubectl create configmap,可使用引數--from-file或--from-literal指定內容,並且可以在一行命令中指定多個引數。

(1)通過--from-file引數從檔案中進行建立,可以指定key的名稱,也可以在一個命令列中建立包含多個key的ConfigMap

例如:在當前目錄下建立一個檔名為config_1.conf,檔案內容就是“value1”

使用如下命令建立configmap,名為config-1

kubectl create configmap config-1 --from-file=config_1.conf

  

檢視:其會以檔名為key,檔案內容為value建立一條資料

 

 

(2)通過--from-file引數從目錄中進行建立,該目錄下的每個配置檔名都被設定為key,檔案的內容被設定為value

例如:在configmap目錄下由三個檔案

 

 

使用如下命令建立:

kubectl create configmap cm-name --from-file=file-dir

  

 

 

檢視詳細資料:其會以檔名作為key,檔案內容作為value

 

 

(3)--from-literal從文字中進行建立,直接將指定的key=value建立為configmap的內容

例如:建立一個key為name,value為Liusy的configmap資料

kubectl create configmap cm-3 --from-literal=name=liusy

  

 

 

(3)ConfigMap使用

以上述常見的cm-1為例

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-1
data:
  home_path: /usr/soft

  

1、環境變數方式

本文建立一個Pod執行著nginx例項,在環境變數中使用cm-1的配置

apiVersion: v1
kind: Pod
metadata:
  name: cm-nginx
spec:
  containers:
  - name: cm-nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    env:
    - name: home
      valueFrom:
        configMapKeyRef:
          name: cm-1
          key: home_path

  

建立好Pod後進入容器:

 

 

檢視環境變數:

 

 

可以看到,home環境變數的值正是cm-1中配置的路徑

2、volumeMount模式

比如定義一個Pod,其中定義一個volume,volume中引用名為cm-1的configmap,將key為home_path的value值寫入homtpath.txt檔案中,在容器中的configfiles目錄上掛載這個volume

apiVersion: v1
kind: Pod
metadata:
  name: mount-pod
spec:
  volumes:
  - name: cm-volume
    configMap:
      name: cm-1
      items:
      - key: home_path
        path: homepath.txt
  containers:
  - name: mount-pod
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: cm-volume
      mountPath: /configfiles

  

建立Pod後進入容器:

 

 

可以看到,configfiles目錄下確實生成了一個homepath.txt檔案,來檢視以下檔案的內容:

 

 

(4)ConfigMap使用限制

  • ConfigMap必須在Pod之前建立
  • ConfigMap有Namespace限制,只有在同一Namespace下才可使用
  • 靜態Pod無法使用ConfigMap

 

二、容器內獲取Pod資訊:Downward API

在Pod建立之後,會被分配唯一的名字、IP地址,並處於某個Namespace中,那麼這些資訊在Pod中應該怎麼獲取呢,就是利用Downward API。

Downward API可以通過以下兩種方式將Pod資訊注入容器內部。

1、環境變數

用於單個變數(也就是在Pod定義中是單值的,非陣列),可以將Pod資訊和Container資訊注 入容器內部。

比如下例中將Pod的name、namespace、ip注入為環境變數

apiVersion: v1
kind: Pod
metadata:
  name: pod-name
  namespace: kube-system
spec:
  containers:
  - name: pod-name
    image: nginx
    imagePullPolicy: IfNotPresent
    env:
    - name: name
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: ns
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: ip
      valueFrom:
        fieldRef:
          fieldPath: status.podIP

  

建立Pod之後進入容器檢視相應的環境變數:

 

 

又比如下例中將resource注入為環境變數

apiVersion: v1
kind: Pod
metadata:
  name: pod-name1
spec:
  containers:
  - name: c1
    image: nginx
    imagePullPolicy: IfNotPresent
    resources:
      requests:
        cpu: "125m"
        memory: "32Mi"
      limits:
        cpu: "250m"
        memory: "64Mi"
    env:
    - name: req_cpu
      valueFrom:
        resourceFieldRef:
          containerName: c1
          resource: requests.cpu
    - name: lim_cpu
      valueFrom:
        resourceFieldRef:
          containerName: c1
          resource: limits.cpu
    - name: lim_me
      valueFrom:
        resourceFieldRef:
          containerName: c1
          resource: limits.memory

  

建立Pod後進入容器檢視:

 

 

2、volume掛載

將陣列類資訊生成為檔案並掛載到容器內部。例如labels、annotations等

例如下例中將label資訊通過volume掛載到容器的label目錄

apiVersion: v1
kind: Pod
metadata:
  name: pod-volume
  labels:
    name: pod-volume
    age: zero
spec:
  containers:
  - name: c1
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: v-l
      mountPath: /labels
      readOnly: false
  volumes:
  - name: v-l
    downwardAPI:
      items:
      - path: "labels"
        fieldRef:
          fieldPath: metadata.labels

  

上述yaml中建立了一個volume,通過items設定,會生成path值的檔案,檔案的內容就是相應的資訊,在容器中將volume掛載到/labels目錄下:

建立之後進入容器檢視檔案:

 

 

三、Pod生命週期和重啟策略

Pod的狀態包括以下幾種:

 

 

Pod的重啟策略應用於Pod內的所有容器,並且僅在Pod所處的Node上有kubelet進行判斷和重啟操作,當某個容器異常退出或者健康檢查失敗時,kubelet將根據RestartPolicy設定進行相應的操作。在spec.restartPolicy中配置相應的重啟策略

重啟策略有如下三個:

spec:
  restartPolicy: [Always|Never|OnFailure]

  

  • Always:Pod一旦終止執行,kubelet都會進行重啟,這也是預設值
  • Never:不會進行重啟
  • OnFailure:容器非正常退出(即是退出碼不為0),kubelet會重啟容器,反之不會重啟。

kubelet重啟失效容器的時間間隔以sync-frequency乘以2n來計算,例如1,2,4,8等,最長延時5分鐘,且在重啟10分鐘之後重置該時間。

Pod的重啟策略與控制方式息息相關,當前可用於管理Pod的控制器包括RC,Job,DaemonSet及直接通過kubelet管理的靜態Pod,每種控制器對Pod的重啟策略如下:

  • RC、DaemonSet:必須設定為Always,保證容器持續執行
  • Job:OnFailure或Never,執行完就退出
  • kubelet:在Pod失效時自動重啟它,不論RestartPolicy是什麼值,並且也不會進行健康檢查。

四、Pod健康檢查

k8s提供了Pod健康檢查機制,對於檢測到故障服務會被及時自動下線,以及通過重啟服務的方式使服務自動恢復。可通過兩類探針來檢查:LivenessProbe和ReadinessProbe

1、LivenessProbe

用於判斷容器是否存活(running狀態),如果探測到容器不健康,則kubelet殺掉此容器,並根據重啟策略做相應的處理。

kubelet定期執行LivenessProbe來判斷容器的健康狀態,有三種實現方式:

(1)ExecAction

在容器內部執行一個命令,如果返回0,則表明容器健康。

apiVersion: v1
kind: Pod
metadata:
  name: live-exec
spec:
  containers:
  - name: live-exec
    image: nginx
    args:
    - /bin/sh
    - -c
    - echo ok > /tmp/health;sleep 10;rm -rf /tmp/health;sleep 1000
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/health
      initialDelaySeconds: 5
      timeoutSeconds: 1

  

上述yaml是在容器啟動時將ok輸出到/tem/health檔案中,10s過後刪除此檔案。看效果:

kubectl describe  pods/live-exec

  

 

 

當檔案被刪除之後,探針探測到容器不健康,所以會進行重啟

(2)TCPSocketAction

通過容器的IP地址和埠號進行TCP檢查,如果能建立TCP連線,則說明容器健康

apiVersion: v1
kind: Pod
metadata:
  name: live-tcp
spec:
  containers:
  - name: live-tcp
    image: nginx
    imagePullPolicy: IfNotPresent
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 15
      timeoutSeconds: 1

  

(3)HttpGetAction

通過容器的IP、埠及路徑呼叫HTTP Get方法,響應碼大於200,小於400,容器健康

apiVersion: v1
kind: Pod
metadata:
  name: live-httpget
spec:
  containers:
  - name: live-httpget
    image: nginx
    imagePullPolicy: IfNotPresent
    livenessProbe:
      httpGet:
        path: /_status/healthz
        port: 80
        host: host
        scheme: HTTP
        httpHeaders:
        - name: string
          value: string
      initialDelaySeconds: 15
      timeoutSeconds: 1

  

2、ReadinessProbe

用於判斷容器是否啟動完成(ready狀態),可接受請求。如果檢測到失敗,則Pod的狀態將被修改。Endpoint Controller將從service的Endpoint中刪除包含該容器所在Pod的Endpoint,此Pod不再接收請求。

此探針使用方式和上述livenessProbe相同。
例如:ExecAction方式

apiVersion: v1
kind: Pod
metadata:
  name: read-exec
spec:
  containers:
  - name: read-exec
    image: nginx
    command: ["/bin/bash","-c","mkdir /health;sleep 10;rm -rf /health;sleep 10;mkdir /health;sleep 600"]
    readinessProbe:
      exec:
        command: ["ls","/health"]
      initialDelaySeconds: 5
      timeoutSeconds: 1

  

上述yaml在容器啟動建立一個目錄,10s後刪除,再10s後建立此目錄,看容器健康檢測情況

 

 

其在檢測出容器啟動失敗後會定時去檢測,不會重啟容器,直至檢測到容器健康。

對於每種探測方式,都需要配置以下兩個引數:

  • initialDelaySeconds:啟動後多久進行健康檢查,單位是秒
  • timeoutSeconds:健康檢查傳送請求後的等待響應的超時時間,單位是s,超時未響應,則會重啟該pod

===============================

我是Liusy,一個喜歡健身的程式設計師。

歡迎關注微信公眾號【Liusy01】,一起交流Java技術及健身,獲取更多幹貨,領取Java進階乾貨,領取最新大廠面試資料,一起成為Java大神。

來都來了,關注一波再溜