k8s學習 - 概念 - Pod


k8s學習 - 概念 - Pod

這篇繼續看概念,主要是 Pod 這個概念,這個概念非常重要,是 k8s 集群的最小單位。

怎么才算是理解好 pod 了呢,基本上把 pod 的所有 describe 和配置文件的配置項都能看懂就算是對 pod 比較了解了。

Pod

我們通過調用一個kubectl describe pod xxx 可以查看某個 pod 的具體信息。

describe 的信息我們用注釋的形式來解讀。

Name:         task-pv-pod
Namespace:    default // 沒有指定namespace的就是default
Node:         docker-for-desktop/192.168.65.3 // Pod所在的節點
Start Time:   Mon, 08 Jul 2019 14:05:52 +0800 // pod啟動的時間
Labels:       <none> // 說明沒有設置標簽
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"task-pv-pod","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":... // 注釋信息
Status:       Running // pod的狀態
IP:           10.1.0.103 // pod的集群ip
Containers: // 其中包含的容器
  task-pv-container:
    Container ID:   docker://3e9a2ee6b0a13ccee534ec3ffe781adcbff42a7f1851d57e3b374a047a654590
    Image:          nginx // 容器鏡像名稱
    Image ID:       docker-pullable://nginx@sha256:96fb261b66270b900ea5a2c17a26abbfabe95506e73c3a3c65869a6dbe83223a
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 08 Jul 2019 14:05:58 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts: // 這個容器掛載的兩個volume
      /usr/share/nginx/html from task-pv-storage (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-tw8wk (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  task-pv-storage: // 掛載的數據卷
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) // 這個數據卷是共享持久卷
    ClaimName:  task-pv-claim // 使用的聲明
    ReadOnly:   false // 數據卷是否只讀
  default-token-tw8wk:
    Type:        Secret (a volume populated by a Secret) // 這個數據卷是保存密鑰
    SecretName:  default-token-tw8wk
    Optional:    false
QoS Class:       BestEffort // Qos的三個級別,Guaranteed/Burstable/BestEffort,分別對pod的資源限制從嚴到弱
Node-Selectors:  <none> // pod是可以選擇部署在哪個node上的,比如部署在有ssd的node上。
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s  // 節點親和性,它使得pod能有傾向性地分配到不同節點上。
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events: // 這個pod發生的一些事件
  Type    Reason                 Age   From                         Message
  ----    ------                 ----  ----                         -------
  Normal  Scheduled              21s   default-scheduler            Successfully assigned task-pv-pod to docker-for-desktop
  Normal  SuccessfulMountVolume  20s   kubelet, docker-for-desktop  MountVolume.SetUp succeeded for volume "task-pv-volume"
  Normal  SuccessfulMountVolume  20s   kubelet, docker-for-desktop  MountVolume.SetUp succeeded for volume "default-token-tw8wk"
  Normal  Pulling                19s   kubelet, docker-for-desktop  pulling image "nginx"
  Normal  Pulled                 15s   kubelet, docker-for-desktop  Successfully pulled image "nginx"
  Normal  Created                15s   kubelet, docker-for-desktop  Created container
  Normal  Started                14s   kubelet, docker-for-desktop  Started container

下面我們就看 pod 的配置文件。有的時候我們可能會忘記了我們啟動的pod的yaml配置文件地址,我們可以通過kubectl get pod task-pv-pod -o=yaml命令來獲取某個已經啟動的 pod 的配置文件,這里的配置文件會比我們配置的配置項全很多,因為我們寫配置文件的時候,很多配置項沒有設置實際上就是使用默認的配置值來實現。

kubectl get pod task-pv-pod -o=yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"task-pv-pod","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":"task-pv-container","ports":[{"containerPort":80,"name":"http-server"}],"volumeMounts":[{"mountPath":"/usr/share/nginx/html","name":"task-pv-storage"}]}],"volumes":[{"name":"task-pv-storage","persistentVolumeClaim":{"claimName":"task-pv-claim"}}]}}
  creationTimestamp: 2019-07-08T06:05:51Z
  name: task-pv-pod
  namespace: default
  resourceVersion: "1439249"
  selfLink: /api/v1/namespaces/default/pods/task-pv-pod
  uid: 7090642e-a146-11e9-89ff-025000000001
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: task-pv-container
    ports:
    - containerPort: 80
      name: http-server
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: task-pv-storage
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-tw8wk
      readOnly: true
  dnsPolicy: ClusterFirst
  nodeName: docker-for-desktop
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: task-pv-storage
    persistentVolumeClaim:
      claimName: task-pv-claim
  - name: default-token-tw8wk
    secret:
      defaultMode: 420
      secretName: default-token-tw8wk
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2019-07-08T06:05:52Z
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: 2019-07-08T06:05:58Z
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: 2019-07-08T06:05:51Z
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://3e9a2ee6b0a13ccee534ec3ffe781adcbff42a7f1851d57e3b374a047a654590
    image: nginx:latest
    imageID: docker-pullable://nginx@sha256:96fb261b66270b900ea5a2c17a26abbfabe95506e73c3a3c65869a6dbe83223a
    lastState: {}
    name: task-pv-container
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2019-07-08T06:05:58Z
  hostIP: 192.168.65.3
  phase: Running
  podIP: 10.1.0.103
  qosClass: BestEffort
  startTime: 2019-07-08T06:05:52Z

幾個比較復雜的配置項我們單獨伶出來理解。

spec.container.imagePullPolicy

spec.container.imagePullPolicy: 這個是容器的鏡像獲取策略,有幾種策略:

  • IfNotPresent: 如果本地沒有,就去遠程 pull 鏡像
  • Always: 每次pod啟動都去遠程pull鏡像
  • Never: 只去本地獲取鏡像

在局域網本地化搭建鏡像的時候,應該設置為 Never 。如果 imagePullPolicy 沒有設置,如果設置了鏡像的 tag,且 tag 不為 :lastest ,就是相當於使用 IfNotPresent。如果 imagePullPolicy 沒有設置,且tag為 :lastest,就相當於是 Always.

spec.container.terminationMessagePath

spec.container.terminationMessagePath: 容器的終止日志文件。

spec.container.volumeMounts

spec.container.volumeMounts 其中一個 /usr/share/nginx/html根據 task-pv-storage 掛載到 task-pv-claim 這個共享存儲中。這個pvc 是對應哪個共享存儲呢?
我們可以查看 kubectl get pvc

NAME            STATUS    VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
task-pv-claim   Bound     task-pv-volume   1Gi        RWO            manual         5h

再通過 kubectl get pv 對應到 pv:

NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                   STORAGECLASS   REASON    AGE
task-pv-volume   1Gi        RWO            Retain           Bound     default/task-pv-claim   manual                   5h

再查看這個 pv 的詳細情況:kubectl describe pv task-pv-volume

Name:            task-pv-volume
Labels:          type=local
Annotations:     kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"labels":{"type":"local"},"name":"task-pv-volume","namespace":""},"spec":{"ac...
                 pv.kubernetes.io/bound-by-controller=yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    manual
Status:          Bound
Claim:           default/task-pv-claim
Reclaim Policy:  Retain
Access Modes:    RWO
Capacity:        1Gi
Node Affinity:   <none>
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /Users/yejianfeng/Documents/workspace/kubernets_example/data
    HostPathType:
Events:            <none>

看到這個pv對應的是宿主機 HostPath 中的 /Users/yejianfeng/Documents/workspace/kubernets_example/data 這個目錄。

所以共享存儲的映射關系是 pod -- volume -- pvc -- pv。

其實這里我們之所以說是共享存儲,就是說這個存儲應該是一個共享網盤,比如 cephFS,而不應該僅僅只是宿主機上的一個目錄。宿主機上的目錄只是為了調試方便而已。

說說另外一個 volumeMounts: /var/run/secrets/kubernetes.io/serviceaccount

這個serviceaccount里面存儲的是什么呢?我們可以直接kubectl exec -it task-pv-pod -- /bin/sh 到 pod 里面查看

~  kubectl exec -it task-pv-pod -- /bin/sh
# cd /var/run/secrets/kubernetes.io/serviceaccount
# ls
ca.crt	namespace  token

里面存放的就是 token 。這個 token 是每個 namespace 一個,它表示的是在這個命名空間的用戶權限。這個是給 Pod 里面的進程使用的,如果 pod 里面的進程需要調用這個命名空間里面的 K8s 的 api 或者其他服務,它就可以通過獲取這個 token 來發起 http/https 的調用。這個 service account 里面存儲的 token/ca.crt 就代表這個命名空間的管理員用戶。

dnsPolicy

這個是 pod 的 dns 策略,可以設置有如下值:

  • Default : 和宿主機的DNS完全一致
  • ClusterFirst: 把集群的DNS寫入到Pod的DNS配置,但是如果設置了HostNetwork=true,就會強制設置為Default
  • ClusterFirstWithHostNet: 把集群的DNS寫入到Pod的DNS配置,不管是否設置HostNetwork
  • None: 忽略所有的DNS配置,一般來說,設置了None之后會自己手動再設置dnsConfig

這里需要了解,k8s 中的服務發現機制,有幾種方式,一種是通過 service ip,一個服務在集群中統一存在一個 clusterIP, 所有其他服務需要使用這個服務的時候,就通過調用這個 clusterIP 來進行訪問。另外一種是通過 dns,通過給service 設置 subdomain 來給一個服務設置一個域名,而這個域名解析就需要全集群一致。而這里的 dnsPolicy 就是做這個用處的。

restartPolicy

pod 的狀態一共有五種,掛起/運行中/成功/失敗/未知。

前一節說node上有個進程 kubelet 會檢測當前 node 上的 pod 是否存活,如果檢測到容器的狀態為失敗,那么就會啟動重啟策略,這個重啟策略就是這里 restartPolicy 設置的。

  • always: 容器失效時,自動重啟容器
  • OnFailure: 容器終止運行,且退出碼不為0時候重啟
  • Never: 不重啟

這里提到一個退出碼,如果這個pod是處於失敗狀態,那么通過 kubectl describe pod 也是能看到 pod 的退出狀態的。這個退出碼0為正常,非0是不正常。

schedulerName

上節說過,調度器是在 master 節點,控制 pod 應該在哪個 node 上啟動等。這里就是指定調度器的名字。默認是 default。

securityContext

定義容器 pod 或者 container 的權限和訪問控制。比如可以控制 pod 使用某個用戶來訪問其內部的文件,是否開 selinux 等。

serviceAccount

這個概念在 volumeMounts 說過了,存儲的是 pod 要訪問集群內其他服務的時候的 token。

terminationGracePeriodSeconds

優雅重啟,如果 k8s 要升級,或者由於某個原因要重啟 pod,那么會先啟動新的P od,然后發送 SIGTERM 信號,並且等待 terminationGracePeriodSeconds 個時長,再結束老的 pod。

tolerations

前面也說過,這個是設置 pod 的親緣性,讓調度器把 pod 更好的分配到 node 上去。

status.conditions

這里再提一下 pod 的生命周期,pod 在初始化,到 pending,到分配到 node 的所有過程,都有個記錄,這里的 status.conditions 就是這個記錄,記錄各種狀態變更的時間節點:

type字段是一個包含以下可能值的字符串:

  • PodScheduled:Pod 已被安排到一個節點;
  • Ready:Pod 能夠提供請求,應該添加到所有匹配服務的負載均衡池中;
  • Initialized:所有 init 容器 都已成功啟動;
  • Unschedulable:調度程序現在無法調度 Pod,例如由於缺少資源或其他限制;
  • ContainersReady:Pod 中的所有容器都已准備就緒。

lastTransitionTime 字段提供 Pod 最后從一個狀態轉換到另一個狀態的時間戳。

qosClass

Qos的三個級別,Guaranteed/Burstable/BestEffort,分別對pod的資源限制從嚴到弱。


免責聲明!

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



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