国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【K8s】Pod一文詳解

這篇具有很好參考價(jià)值的文章主要介紹了【K8s】Pod一文詳解。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、Pod介紹

1、Pod結(jié)構(gòu)

【K8s】Pod一文詳解
每個(gè)Pod中都可以包含一個(gè)或者多個(gè)容器,這些容器可以分為兩類:

1)用戶容器:用戶程序所在的容器,數(shù)量可多可少

2)根容器:Pause容器,由Kubernetes創(chuàng)建,這是每個(gè)Pod都會(huì)有的一個(gè)根容器,它的作用有兩個(gè):

  • 可以以它為依據(jù),評估整個(gè)Pod的健康狀態(tài)
  • 可以在根容器上設(shè)置Ip地址,其它容器都共享此Ip(Pod IP),以實(shí)現(xiàn)Pod內(nèi)部的網(wǎng)絡(luò)通信
注意上面說的是Pod內(nèi)部的通訊,Pod的之間的通訊采用虛擬二層網(wǎng)絡(luò)技術(shù)來實(shí)現(xiàn),我們當(dāng)前環(huán)境用的是Flannel

2、Pod的定義

下面是Pod的資源清單:(常用的)

apiVersion: v1     #必選,版本號,例如v1
kind: Pod         #必選,資源類型,例如 Pod
metadata:         #必選,元數(shù)據(jù)
  name: string     #必選,Pod名稱
  namespace: string  #Pod所屬的命名空間,默認(rèn)為"default"
  labels:           #自定義標(biāo)簽列表
    - name: string                 
spec:  #必選,Pod中容器的詳細(xì)定義
  containers:  #必選,Pod中容器列表
  - name: string   #必選,容器名稱
    image: string  #必選,容器的鏡像名稱
    imagePullPolicy: [ Always|Never|IfNotPresent ]  #獲取鏡像的策略 
    command: [string]   #容器的啟動(dòng)命令列表,如不指定,使用打包時(shí)使用的啟動(dòng)命令
    args: [string]      #容器的啟動(dòng)命令參數(shù)列表
    workingDir: string  #容器的工作目錄
    volumeMounts:       #掛載到容器內(nèi)部的存儲(chǔ)卷配置
    - name: string      #引用pod定義的共享存儲(chǔ)卷的名稱,需用volumes[]部分定義的的卷名
      mountPath: string #存儲(chǔ)卷在容器內(nèi)mount的絕對路徑,應(yīng)少于512字符
      readOnly: boolean #是否為只讀模式
    ports: #需要暴露的端口庫號列表
    - name: string        #端口的名稱
      containerPort: int  #容器需要監(jiān)聽的端口號
      hostPort: int       #容器所在主機(jī)需要監(jiān)聽的端口號,默認(rèn)與Container相同
      protocol: string    #端口協(xié)議,支持TCP和UDP,默認(rèn)TCP
    env:   #容器運(yùn)行前需設(shè)置的環(huán)境變量列表
    - name: string  #環(huán)境變量名稱
      value: string #環(huán)境變量的值
    resources: #資源限制和請求的設(shè)置
      limits:  #資源限制的設(shè)置
        cpu: string     #Cpu的限制,單位為core數(shù),將用于docker run --cpu-shares參數(shù)
        memory: string  #內(nèi)存限制,單位可以為Mib/Gib,將用于docker run --memory參數(shù)
      requests: #資源請求的設(shè)置
        cpu: string    #Cpu請求,容器啟動(dòng)的初始可用數(shù)量
        memory: string #內(nèi)存請求,容器啟動(dòng)的初始可用數(shù)量
    lifecycle: #生命周期鉤子
        postStart: #容器啟動(dòng)后立即執(zhí)行此鉤子,如果執(zhí)行失敗,會(huì)根據(jù)重啟策略進(jìn)行重啟
        preStop: #容器終止前執(zhí)行此鉤子,無論結(jié)果如何,容器都會(huì)終止
    livenessProbe:  #對Pod內(nèi)各容器健康檢查的設(shè)置,當(dāng)探測無響應(yīng)幾次后將自動(dòng)重啟該容器
      exec:         #對Pod容器內(nèi)檢查方式設(shè)置為exec方式
        command: [string]  #exec方式需要制定的命令或腳本
      httpGet:       #對Pod內(nèi)個(gè)容器健康檢查方法設(shè)置為HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #對Pod內(nèi)個(gè)容器健康檢查方式設(shè)置為tcpSocket方式
         port: number
       initialDelaySeconds: 0       #容器啟動(dòng)完成后首次探測的時(shí)間,單位為秒
       timeoutSeconds: 0          #對容器健康檢查探測等待響應(yīng)的超時(shí)時(shí)間,單位秒,默認(rèn)1秒
       periodSeconds: 0           #對容器監(jiān)控檢查的定期探測時(shí)間設(shè)置,單位秒,默認(rèn)10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged: false
  restartPolicy: [Always | Never | OnFailure]  #Pod的重啟策略
  nodeName: <string> #設(shè)置NodeName表示將該P(yáng)od調(diào)度到指定到名稱的node節(jié)點(diǎn)上
  nodeSelector: obeject #設(shè)置NodeSelector表示將該P(yáng)od調(diào)度到包含這個(gè)label的node上
  imagePullSecrets: #Pull鏡像時(shí)使用的secret名稱,以key:secretkey格式指定
  - name: string
  hostNetwork: false   #是否使用主機(jī)網(wǎng)絡(luò)模式,默認(rèn)為false,如果設(shè)置為true,表示使用宿主機(jī)網(wǎng)絡(luò)
  volumes:   #在該pod上定義共享存儲(chǔ)卷列表
  - name: string    #共享存儲(chǔ)卷名稱 (volumes類型有很多種)
    emptyDir: {}       #類型為emtyDir的存儲(chǔ)卷,與Pod同生命周期的一個(gè)臨時(shí)目錄。為空值
    hostPath: string   #類型為hostPath的存儲(chǔ)卷,表示掛載Pod所在宿主機(jī)的目錄
      path: string                #Pod所在宿主機(jī)的目錄,將被用于同期中mount的目錄
    secret:          #類型為secret的存儲(chǔ)卷,掛載集群與定義的secret對象到容器內(nèi)部
      scretname: string  
      items:     
      - key: string
        path: string
    configMap:         #類型為configMap的存儲(chǔ)卷,掛載預(yù)定義的configMap對象到容器內(nèi)部
      name: string
      items:
      - key: string
        path: string

配置項(xiàng)很多,可以通過指令來查看每種資源的可配置項(xiàng):

# 查看某種資源可以配置的一級屬性
kubectl explain 資源類型      

# 查看屬性的子屬性   
kubectl explain 資源類型.屬性     
# explain:解釋
[root@k8s-master01 ~] kubectl explain pod
KIND:     Pod
VERSION:  v1
FIELDS:
   apiVersion   <string>
   kind 		<string>
   metadata     <Object>
   spec 		<Object>
   status       <Object>

[root@k8s-master01 ~] kubectl explain pod.metadata
KIND:     Pod
VERSION:  v1
RESOURCE: metadata <Object>
FIELDS:
   annotations  <map[string]string>
   clusterName  <string>
   creationTimestamp    <string>
   deletionGracePeriodSeconds   <integer>
   deletionTimestamp    <string>
   finalizers   <[]string>
   generateName <string>
   generation   <integer>
   labels       <map[string]string>
   managedFields        <[]Object>
   name <string>
   namespace    <string>
   ownerReferences      <[]Object>
   resourceVersion      <string>
   selfLink     <string>
   uid  <string>

Kubernetes中,基本所有資源的一級屬性都是一樣的,有五部分:

  • apiVersion:版本,由kubernetes內(nèi)部定義,版本號必須可以用 kubectl api-versions 查詢到所有,explain查看當(dāng)前
  • kind:類型,由kubernetes內(nèi)部定義,版本號必須可以用 kubectl api-resources 查詢到所有,explain查看當(dāng)前
  • metadata:元數(shù)據(jù),主要是資源標(biāo)識和說明,常用的有name、namespace、labels等
  • spec:描述,這是配置中最重要的一部分,里面是對各種資源配置的詳細(xì)描述
  • status:狀態(tài)信息,里面的內(nèi)容不需要定義,由kubernetes自動(dòng)生成

先重點(diǎn)看spec的常用子屬性:

  • containers <Object[ ]> : 容器列表,用于定義容器的詳細(xì)信息
  • nodeName: 根據(jù)nodeName的值將pod調(diào)度到指定的Node節(jié)點(diǎn)上,不指定則由schedule調(diào)度分配
  • nodeSelector <map[]>: 根據(jù)NodeSelector中定義的信息選擇將該P(yáng)od調(diào)度到包含這些label的Node 上
  • hostNetwork: 是否使用主機(jī)網(wǎng)絡(luò)模式,默認(rèn)為false,如果設(shè)置為true,表示使用宿主機(jī)網(wǎng)絡(luò),多個(gè)副本pod就端口沖突了,不建議
  • volumes <Object[]> :存儲(chǔ)卷,用于定義Pod上面掛載的存儲(chǔ)信息
  • restartPolicy :重啟策略,表示Pod在遇到故障的時(shí)候的處理策略

二、Pod配置:spec.containers

[root@k8s-master01 ~] kubectl explain pod.spec.containers
KIND:     Pod
VERSION:  v1
RESOURCE: containers <[]Object>   # 數(shù)組,代表可以有多個(gè)容器
FIELDS:
   name  <string>     # 容器名稱
   image <string>     # 容器需要的鏡像地址
   imagePullPolicy  <string> # 鏡像拉取策略 
   command  <[]string> # 容器的啟動(dòng)命令列表,如不指定,使用打包時(shí)使用的啟動(dòng)命令
   args     <[]string> # 容器的啟動(dòng)命令需要的參數(shù)列表
   env      <[]Object> # 容器環(huán)境變量的配置
   ports    <[]Object>     # 容器需要暴露的端口號列表
   resources <Object>      # 資源限制和資源請求的設(shè)置

1、基本配置 name和image

創(chuàng)建個(gè)yaml文件pod-base.yaml 測試name和image:

apiVersion: v1
kind: Pod
metadata:
  name: pod-base
  namespace: dev
  labels:
    user: 9527
spec:
  containers:
  # - 即數(shù)組
  - name: nginx
    image: nginx:1.17.1
  - name: busybox
    image: busybox:1.30

以上即定義一個(gè)pod,包含兩個(gè)容器:

  • nginx:用1.17.1版本的nginx鏡像創(chuàng)建,(nginx是一個(gè)輕量級web容器)
  • busybox:用1.30版本的busybox鏡像創(chuàng)建,(busybox是一個(gè)小巧的linux命令集合)
[root@k8s-master01 pod] kubectl apply -f pod-base.yaml
pod/pod-base created
# READY 1/2 : 表示當(dāng)前Pod中有2個(gè)容器,其中1個(gè)準(zhǔn)備就緒,1個(gè)未就緒
# RESTARTS  : 重啟次數(shù),因?yàn)橛?個(gè)容器故障了,Pod一直在重啟試圖恢復(fù)它
[root@k8s-master01 pod] kubectl get pod -n dev
NAME       READY   STATUS    RESTARTS   AGE
pod-base   1/2     Running   4          95s

2、鏡像拉取策略 imagePullpolicy

鏡像拉取策略有三種:

  • Always:總是從遠(yuǎn)程倉庫拉取鏡像(一直遠(yuǎn)程下載)
  • IfNotPresent:本地有則使用本地鏡像,本地沒有則從遠(yuǎn)程倉庫拉取鏡像(本地有就本地 本地沒遠(yuǎn)程下載)
  • Never:只使用本地鏡像,從不去遠(yuǎn)程倉庫拉取,本地沒有就報(bào)錯(cuò) (一直使用本地)

關(guān)于策略默認(rèn)值:

  • 若鏡像tag為具體版本號,則默認(rèn)策略是:IfNotPresent
  • 若鏡像tag為latest(最終版本),則默認(rèn)always

創(chuàng)建pod-imagepullpolicy.yaml文件做測試:

apiVersion: v1
kind: Pod
metadata:
  name: pod-imagepullpolicy
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: IfNotPresent # 用于設(shè)置鏡像拉取策略
  - name: busybox
    image: busybox:1.30

創(chuàng)建pod:

[root@k8s-master01 pod] kubectl create -f pod-imagepullpolicy.yaml
pod/pod-imagepullpolicy created

# 查看Pod詳情
# 此時(shí)明顯可以看到nginx鏡像有一步Pulling image "nginx:1.17.1"的過程
[root@k8s-master01 pod] kubectl describe pod pod-imagepullpolicy -n dev
......
Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  <unknown>         default-scheduler  Successfully assigned dev/pod-imagePullPolicy to node1
  Normal   Pulling    32s               kubelet, node1     Pulling image "nginx:1.17.1"
  Normal   Pulled     26s               kubelet, node1     Successfully pulled image "nginx:1.17.1"
  Normal   Created    26s               kubelet, node1     Created container nginx
  Normal   Started    25s               kubelet, node1     Started container nginx
  Normal   Pulled     7s (x3 over 25s)  kubelet, node1     Container image "busybox:1.30" already present on machine
  Normal   Created    7s (x3 over 25s)  kubelet, node1     Created container busybox
  Normal   Started    7s (x3 over 25s)  kubelet, node1     Started container busybox

3、啟動(dòng)命令 command

上面busybox容器一直沒有成功運(yùn)行,因?yàn)閎usybox并不是一個(gè)程序,而是類似于一個(gè)工具類的集合,kubernetes集群啟動(dòng)管理后,容器中就沒有進(jìn)程了,它會(huì)自動(dòng)關(guān)閉。解決方法就是讓其一直在運(yùn)行 ? command

command,用于在pod中的容器初始化完畢之后運(yùn)行一個(gè)命令

創(chuàng)建pod-command.yaml文件做測試:

apiVersion: v1
kind: Pod
metadata:
  name: pod-command
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]

命令解釋:

"/bin/sh","-c", 使用sh執(zhí)行命令

touch /tmp/hello.txt; 創(chuàng)建一個(gè)/tmp/hello.txt 文件

while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done; 每隔3秒向文件中寫入當(dāng)前時(shí)間
[root@k8s-master01 pod] kubectl create  -f pod-command.yaml
pod/pod-command created

# 此時(shí)發(fā)現(xiàn)兩個(gè)pod都正常運(yùn)行了
[root@k8s-master01 pod] kubectl get pods pod-command -n dev
NAME          READY   STATUS   RESTARTS   AGE
pod-command   2/2     Runing   0          2s


補(bǔ)充一個(gè)命令:進(jìn)入容器,在容器內(nèi)部執(zhí)行命令

 kubectl exec  pod名稱 -n 命名空間 -it -c 容器名稱 /bin/sh  
# 進(jìn)入pod中的busybox容器,查看文件內(nèi)容
[root@k8s-master01 pod] kubectl exec pod-command -n dev -it -c busybox /bin/sh

/: tail -f /tmp/hello.txt
14:44:19
14:44:22
14:44:25

最后:kubernetes中的command、args兩項(xiàng)其實(shí)是實(shí)現(xiàn)覆蓋Dockerfile中ENTRYPOINT的功能

  • 如果command和args均沒有寫,那么用Dockerfile的配置。
  • 如果command寫了,但args沒有寫,那么Dockerfile默認(rèn)的配置會(huì)被忽略,執(zhí)行輸入的command
  • 如果command沒寫,但args寫了,那么Dockerfile中配置的ENTRYPOINT的命令會(huì)被執(zhí)行,使用當(dāng)前args的參數(shù)
  • 如果command和args都寫了,那么Dockerfile的配置被忽略,執(zhí)行command并追加上args參數(shù)

4、環(huán)境變量 env

env,環(huán)境變量,通過name-value的鍵值對,用于在pod中的容器設(shè)置環(huán)境變量。創(chuàng)建pod-env.yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: pod-env
  namespace: dev
spec:
  containers:
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
    env: # 設(shè)置環(huán)境變量列表
    - name: "username"
      value: "admin"
    - name: "password"
      value: "123456"

創(chuàng)建pod:

# 創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-env.yaml
pod/pod-env created

# 進(jìn)入容器,輸出環(huán)境變量
[root@k8s-master01 ~] kubectl exec pod-env -n dev -c busybox -it /bin/sh
/  echo $username
admin
/  echo $password
123456

5、端口設(shè)置 ports

容器的端口設(shè)置,先看ports下的子屬性:

[root@k8s-master01 ~] kubectl explain pod.spec.containers.ports
KIND:     Pod
VERSION:  v1
RESOURCE: ports <[]Object>
FIELDS:
   name         <string>  # 端口名稱,如果指定,必須保證name在pod中是唯一的		
   containerPort<integer> # 容器要監(jiān)聽的端口(0<x<65536)
   hostPort     <integer> # 容器要在主機(jī)上公開的端口,如果設(shè)置,主機(jī)上只能運(yùn)行容器的一個(gè)副本(一般省略) 
   hostIP       <string>  # 要將外部端口綁定到的主機(jī)IP(一般省略)
   protocol     <string>  # 端口協(xié)議。必須是UDP、TCP或SCTP。默認(rèn)為“TCP”。

關(guān)于hostPort:創(chuàng)建一個(gè)二副本的deploy,兩個(gè)pod的IP分別為1.1和1.2,此時(shí)使用podIP + 容器Port正常。但容器端口都是80,此時(shí)都想映射到主機(jī)端口,比如映射到主機(jī)80,就會(huì)沖突。

【K8s】Pod一文詳解
編寫一個(gè)測試案例,創(chuàng)建pod-ports.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-ports
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: # 設(shè)置容器暴露的端口列表
    - name: nginx-port
      containerPort: 80
      protocol: TCP

創(chuàng)建pod:

# 創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-ports.yaml
pod/pod-ports created

# 查看pod
# 在下面可以明顯看到配置信息
[root@k8s-master01 ~] kubectl get pod pod-ports -n dev -o yaml
......
spec:
  containers:
  - image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - containerPort: 80
      name: nginx-port
      protocol: TCP
......

訪問容器中的程序需要使用的是PodIp:containerPort

6、資源配額 resources

容器中的程序要運(yùn)行,要占用一定資源,比如cpu和內(nèi)存等,如果不對某個(gè)容器的資源做限制,那么它就可能吃掉大量資源,導(dǎo)致其它容器無法運(yùn)行。因此kubernetes提供了對內(nèi)存和cpu的資源進(jìn)行配額的機(jī)制 ? resources:

  • resources.limits:上限。用于限制運(yùn)行時(shí)容器的最大占用資源,當(dāng)容器占用資源超過limits時(shí)會(huì)被終止,并進(jìn)行重啟
  • resources.requests:下限。用于設(shè)置容器需要的最小資源,如果環(huán)境資源不夠,容器將無法啟動(dòng)

寫個(gè)測試配置文件pod-resources.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-resources
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    resources: # 資源配額
      limits:  # 限制資源(上限)
        cpu: "2" # CPU限制,單位是core數(shù)
        memory: "10Gi" # 內(nèi)存限制
      requests: # 請求資源(下限)
        cpu: "1"  # CPU限制,單位是core數(shù)
        memory: "10Mi"  # 內(nèi)存限制

關(guān)于單位:

  • cpu:core數(shù),可以為整數(shù)或小數(shù)
  • memory: 內(nèi)存大小,可以使用Gi、Mi、G、M等形式
# 運(yùn)行Pod
[root@k8s-master01 ~] kubectl create  -f pod-resources.yaml
pod/pod-resources created

# 查看發(fā)現(xiàn)pod運(yùn)行正常
[root@k8s-master01 ~] kubectl get pod pod-resources -n dev
NAME            READY   STATUS    RESTARTS   AGE  
pod-resources   1/1     Running   0          39s   

# 接下來,停止Pod
[root@k8s-master01 ~] kubectl delete  -f pod-resources.yaml
pod "pod-resources" deleted

停止pod后,更改內(nèi)存最低配額為10Gi(虛擬機(jī)配置不夠了)

# 編輯pod,修改resources.requests.memory的值為10Gi
[root@k8s-master01 ~] vim pod-resources.yaml

# 再次啟動(dòng)pod
[root@k8s-master01 ~] kubectl create  -f pod-resources.yaml
pod/pod-resources created

# 查看Pod狀態(tài),發(fā)現(xiàn)Pod啟動(dòng)失敗
[root@k8s-master01 ~] kubectl get pod pod-resources -n dev -o wide
NAME            READY   STATUS    RESTARTS   AGE          
pod-resources   0/1     Pending   0          20s    


pod狀態(tài)為pending(待定、掛起):

# 查看pod詳情會(huì)發(fā)現(xiàn),如下提示
[root@k8s-master01 ~] kubectl describe pod pod-resources -n dev
......
Warning  FailedScheduling  35s   default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 Insufficient memory.(內(nèi)存不足)

調(diào)度失?。]有節(jié)點(diǎn)滿足這個(gè)最低配置),Insufficient memory.(內(nèi)存不足)

三、Pod的生命周期

pod從創(chuàng)建至終止,有這幾個(gè)階段:

1)pod創(chuàng)建過程

2)運(yùn)行初始化容器(init container)過程

3)運(yùn)行主容器(main container)

  • 容器啟動(dòng)后鉤子(post start)、容器終止前鉤子(pre stop)
  • 容器的存活性探測(liveness probe)、就緒性探測(readiness probe)

4)pod終止過程

【K8s】Pod一文詳解
在整個(gè)生命周期中,Pod會(huì)出現(xiàn)5種狀態(tài)(相位):

  • 掛起(Pending):apiserver已經(jīng)創(chuàng)建了pod資源對象,但它尚未被調(diào)度完成或者仍處于下載鏡像的過程中
  • 運(yùn)行中(Running):pod已經(jīng)被調(diào)度至某節(jié)點(diǎn),并且所有容器都已經(jīng)被kubelet創(chuàng)建完成
  • 成功(Succeeded):pod中的所有容器都已經(jīng)成功終止并且不會(huì)被重啟
  • 失?。‵ailed):所有容器都已經(jīng)終止,但至少有一個(gè)容器終止失敗,即容器返回了非0值的退出狀態(tài)
  • 未知(Unknown):apiserver無法正常獲取到pod對象的狀態(tài)信息,通常由網(wǎng)絡(luò)通信失敗所導(dǎo)致

1、創(chuàng)建和終止

Pod創(chuàng)建的過程

  • 用戶執(zhí)行kubectl指令提交pod信息給apiServer
  • apiServer生成pod信息,存入etcd,并返回確認(rèn)信息給客戶端
  • apiServer開始反饋pod的變化信息,其它組件使用watch機(jī)制來跟蹤檢查apiServer上的變動(dòng)
  • scheduler發(fā)現(xiàn)有新的pod要?jiǎng)?chuàng)建,開始為Pod分配主機(jī)并將結(jié)果信息更新至apiServer
  • node節(jié)點(diǎn)上的kubelet發(fā)現(xiàn)有pod調(diào)度過來,嘗試調(diào)用docker啟動(dòng)容器,并將結(jié)果回送至apiServer
  • apiServer將接收到的pod狀態(tài)信息存入etcd中

【K8s】Pod一文詳解

Pod終止過程

  • 用戶向apiServer發(fā)送刪除pod命令
  • apiServcer中的pod對象信息會(huì)隨著時(shí)間的推移而更新,在寬限期內(nèi)(默認(rèn)30s),pod被視為dead
  • 將pod標(biāo)記為terminating狀態(tài)
  • kubelet在監(jiān)控到pod對象轉(zhuǎn)為terminating狀態(tài)的同時(shí)啟動(dòng)pod關(guān)閉過程
  • 端點(diǎn)控制器監(jiān)控到pod對象的關(guān)閉行為時(shí)將其從所有匹配到此端點(diǎn)的service資源的端點(diǎn)列表中移除
  • 如果當(dāng)前pod對象定義了preStop鉤子處理器,則在其標(biāo)記為terminating后即會(huì)以同步的方式啟動(dòng)執(zhí)行
  • pod對象中的容器進(jìn)程收到停止信號
  • 寬限期結(jié)束后,若pod中還存在仍在運(yùn)行的進(jìn)程,那么pod對象會(huì)收到立即終止的信號
  • kubelet請求apiServer將此pod資源的寬限期設(shè)置為0從而完成刪除操作,此時(shí)pod對于用戶已不可見

2、初始化容器

初始化容器是在pod的主容器啟動(dòng)之前要運(yùn)行的容器,主要做著容器啟動(dòng)前的前置工作。特點(diǎn)是:

  • 初始化容器必須運(yùn)行完成直至結(jié)束,若某初始化容器運(yùn)行失敗,那么kubernetes需要重啟它直到成功完成
  • 初始化容器必須按照定義的順序執(zhí)行,當(dāng)且僅當(dāng)前一個(gè)成功之后,后面的一個(gè)才能運(yùn)行

初始化容器的應(yīng)用場景有兩個(gè):

  • 提供主容器鏡像中不具備的工具程序或自定義代碼
  • 初始化容器要先于應(yīng)用容器串行啟動(dòng)并運(yùn)行完成,因此可用于延后應(yīng)用容器的啟動(dòng)直至其依賴的條件得到滿足

案例:

假設(shè)要以主容器來運(yùn)行nginx,但是要求在運(yùn)行nginx之前先要能夠連接上mysql和redis所在服務(wù)器:

# 服務(wù)器的地址假設(shè)如下:

mysql: 192.168.90.14
redis: 192.168.90.15

創(chuàng)建pod-initcontainer.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-initcontainer
  namespace: dev
spec:
  containers:
  - name: main-container
    image: nginx:1.17.1
    ports: 
    - name: nginx-port
      containerPort: 80
  initContainers:  # 注意初始化容器和主容器平級
  - name: test-mysql
    image: busybox:1.30  # 初始化容器的鏡像用busybox這個(gè)工具包
    # ?。。。。?!
    command: ['sh', '-c', 'until ping 192.168.90.14 -c 1 ; do echo waiting for mysql...; sleep 2; done;']
  - name: test-redis
    image: busybox:1.30
    command: ['sh', '-c', 'until ping 192.168.90.15 -c 1 ; do echo waiting for reids...; sleep 2; done;']

上面定義了兩個(gè)初始化容器,一個(gè)啟動(dòng)后ping MySQL,另一個(gè)ping Redis:

# 創(chuàng)建pod
[root@k8s-master01 ~] kubectl create -f pod-initcontainer.yaml
pod/pod-initcontainer created

# 查看pod狀態(tài)
# 發(fā)現(xiàn)pod卡在初始化容器test-mysql創(chuàng)建后,后面的容器不會(huì)運(yùn)行
root@k8s-master01 ~] kubectl describe pod  pod-initcontainer -n dev
........
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  49s   default-scheduler  Successfully assigned dev/pod-initcontainer to node1
  Normal  Pulled     48s   kubelet, node1     Container image "busybox:1.30" already present on machine
  Normal  Created    48s   kubelet, node1     Created container test-mysql
  Normal  Started    48s   kubelet, node1     Started container test-mysql

-w動(dòng)態(tài)查看pod,和watch一個(gè)意思。

# 動(dòng)態(tài)查看pod
# init:0/2 即兩個(gè)初始化容器都卡住了
[root@k8s-master01 ~] kubectl get pods pod-initcontainer -n dev -w
NAME                             READY   STATUS     RESTARTS   AGE
pod-initcontainer                0/1     Init:0/2   0          15s

為當(dāng)前服務(wù)器新增兩個(gè)ip,使得能ping通那兩個(gè)IP,同時(shí)觀察pod的變化:

[root@k8s-master01 ~] ifconfig ens33:1 192.168.90.14 netmask 255.255.255.0 up
[root@k8s-master01 ~] ifconfig ens33:2 192.168.90.15 netmask 255.255.255.0 up

pod狀態(tài)的變化:

# 動(dòng)態(tài)查看pod
[root@k8s-master01 ~] kubectl get pods pod-initcontainer -n dev -w
NAME                             READY   STATUS     RESTARTS   AGE
pod-initcontainer                0/1     Init:0/2   0          15s
pod-initcontainer                0/1     Init:1/2   0          52s
pod-initcontainer                0/1     Init:1/2   0          53s
pod-initcontainer                0/1     PodInitializing   0          89s
pod-initcontainer                1/1     Running           0          90s
# 最后runing1/1即pod啟動(dòng)成功,副本一個(gè),也成功一個(gè)

3、鉤子函數(shù)

直白講就是一些特殊時(shí)機(jī),想Java靜態(tài)代碼塊一樣,是一種時(shí)機(jī)。在這里可以執(zhí)行用戶自己的行為代碼。鉤子函數(shù)有兩種:

  • post start:即容器創(chuàng)建之后執(zhí)行,如果失敗了會(huì)重啟容器
  • pre stop :即容器終止之前執(zhí)行,執(zhí)行完成之后容器將成功終止,在其執(zhí)行完之前會(huì)阻塞刪除容器的操作

鉤子處理器支持使用下面三種方式定義動(dòng)作:

  • Exec命令:在容器內(nèi)執(zhí)行一次命令
……
  lifecycle:
    postStart: 
      exec:
        command:
        - cat
        - /tmp/healthy
……
  • TCPSocket:在當(dāng)前容器嘗試訪問指定的socket
……      
  lifecycle:
    postStart:
      tcpSocket:
        port: 8080
……
  • HTTPGet:在當(dāng)前容器中向某url發(fā)起http請求
……
  lifecycle:
    postStart:
      httpGet:
        path: / #URI地址
        port: 80 #端口號
        host: 192.168.5.3 #主機(jī)地址
        scheme: HTTP #支持的協(xié)議,http或者h(yuǎn)ttps
……

以exec方式為例,創(chuàng)建pod-hook-exec.yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: pod-hook-exec
  namespace: dev
spec:
  containers:
  - name: main-container
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    lifecycle:
      postStart: 
        exec: # 在容器啟動(dòng)的時(shí)候執(zhí)行一個(gè)命令,修改掉nginx的默認(rèn)首頁內(nèi)容
          command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
      preStop:
        exec: # 在容器停止之前停止nginx服務(wù)
          command: ["/usr/sbin/nginx","-s","quit"]

啟動(dòng)pod

# 創(chuàng)建pod
[root@k8s-master01 ~] kubectl create -f pod-hook-exec.yaml
pod/pod-hook-exec created

# 查看pod,取podIP
[root@k8s-master01 ~] kubectl get pods  pod-hook-exec -n dev -o wide
NAME           READY   STATUS     RESTARTS   AGE    IP            NODE    
pod-hook-exec  1/1     Running    0          29s    10.244.2.48   node2   

# 訪問pod
[root@k8s-master01 ~] curl 10.244.2.48
postStart...

4、容器探測

直白講就是測測這個(gè)實(shí)例健康不,實(shí)例的狀態(tài)不符合預(yù)期,那么kubernetes就會(huì)把該問題實(shí)例" 摘除 ",不承擔(dān)業(yè)務(wù)流量。
【K8s】Pod一文詳解
探針有兩種:

  • liveness probes:存活性探針,用于檢測應(yīng)用實(shí)例當(dāng)前是否處于正常運(yùn)行狀態(tài),不是則k8s會(huì)重啟容器
  • readiness probes:就緒性探針,用于檢測應(yīng)用實(shí)例當(dāng)前是否可以接收請求,不能則k8s不會(huì)轉(zhuǎn)發(fā)流量

livenessProbe 決定是否重啟容器,readinessProbe 決定是否將請求轉(zhuǎn)發(fā)給容器

舉個(gè)形象例子:

公司來了一個(gè)高級后端開發(fā),剛來公司第一天,要熟悉代碼,裝環(huán)境等等。這個(gè)時(shí)候,他"存活",但不"就緒"!暫時(shí)不能給他分配工作任務(wù)。

這兩種探針都有三種實(shí)現(xiàn)方式:

  • Exec命令:在容器內(nèi)執(zhí)行一次命令,如果命令執(zhí)行的退出碼為0,則認(rèn)為程序正常,否則不正常
……
  livenessProbe:
    exec:
      command:
      - cat
      - /tmp/healthy
……
  • TCPSocket:將會(huì)嘗試訪問一個(gè)用戶容器的端口,如果能夠建立這條連接,則認(rèn)為程序正常,否則不正常
……      
  livenessProbe:
    tcpSocket:
      port: 8080
……
  • HTTPGet:調(diào)用容器內(nèi)Web應(yīng)用的URL,如果返回的狀態(tài)碼在200和399之間,則認(rèn)為程序正常,否則不正常
……
  livenessProbe:
    httpGet:
      path: / #URI地址
      port: 80 #端口號
      host: 127.0.0.1 #主機(jī)地址
      scheme: HTTP #支持的協(xié)議,http或者h(yuǎn)ttps
……

探針效果演示:

方式一:liveness+Exec

創(chuàng)建pod-liveness-exec.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-exec
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: 
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      exec:
        command: ["/bin/cat","/tmp/hello.txt"] # 執(zhí)行一個(gè)查看文件的命令

創(chuàng)建pod,發(fā)現(xiàn)它一直在重啟,狀態(tài)CrashLoopBackOff

# 創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-liveness-exec.yaml
pod/pod-liveness-exec created

# 查看Pod詳情
[root@k8s-master01 ~] kubectl describe pods pod-liveness-exec -n dev
......
  Normal   Created    20s (x2 over 50s)  kubelet, node1     Created container nginx
  Normal   Started    20s (x2 over 50s)  kubelet, node1     Started container nginx
  Normal   Killing    20s                kubelet, node1     Container nginx failed liveness probe, will be restarted
  Warning  Unhealthy  0s (x5 over 40s)   kubelet, node1     Liveness probe failed: cat: can't open '/tmp/hello11.txt': No such file or directory
  
# 觀察上面的信息就會(huì)發(fā)現(xiàn)nginx容器啟動(dòng)之后就進(jìn)行了健康檢查
# 檢查失敗之后,容器被kill掉,然后嘗試進(jìn)行重啟(這是重啟策略的作用,后面講解)
# 稍等一會(huì)之后,再觀察pod信息,就可以看到RESTARTS不再是0,而是一直增長
[root@k8s-master01 ~] kubectl get pods pod-liveness-exec -n dev
NAME                READY   STATUS             RESTARTS   AGE
pod-liveness-exec   0/1     CrashLoopBackOff   2          3m19s

# 當(dāng)然接下來,可以修改成一個(gè)存在的文件,cat指令執(zhí)行成功,則健康檢查通過,pod開始running

方式二:TCPSocket + liveness

創(chuàng)建pod-liveness-tcpsocket.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-tcpsocket
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: 
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      tcpSocket:
        port: 8080 # 嘗試訪問用戶容器中的8080端口,而用戶容器我只開啟了80端口

創(chuàng)建pod,查看效果:

# 創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-liveness-tcpsocket.yaml
pod/pod-liveness-tcpsocket created

# 查看Pod詳情
[root@k8s-master01 ~] kubectl describe pods pod-liveness-tcpsocket -n dev
......
  Normal   Scheduled  31s                            default-scheduler  Successfully assigned dev/pod-liveness-tcpsocket to node2
  Normal   Pulled     <invalid>                      kubelet, node2     Container image "nginx:1.17.1" already present on machine
  Normal   Created    <invalid>                      kubelet, node2     Created container nginx
  Normal   Started    <invalid>                      kubelet, node2     Started container nginx
  Warning  Unhealthy  <invalid> (x2 over <invalid>)  kubelet, node2     Liveness probe failed: dial tcp 10.244.2.44:8080: connect: connection refused
  
# 觀察上面的信息,發(fā)現(xiàn)嘗試訪問8080端口,但是失敗了
# 稍等一會(huì)之后,再觀察pod信息,就可以看到RESTARTS不再是0,而是一直增長
[root@k8s-master01 ~] kubectl get pods pod-liveness-tcpsocket  -n dev
NAME                     READY   STATUS             RESTARTS   AGE
pod-liveness-tcpsocket   0/1     CrashLoopBackOff   2          3m19s

# 當(dāng)然接下來,可以修改成一個(gè)可以訪問的端口,比如80,再試,結(jié)果就正常了......

注意TCPSocket是嘗試訪問一個(gè)用戶容器的端口

【K8s】Pod一文詳解

方式三:HTTPGet + liveness

創(chuàng)建pod-liveness-httpget.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-httpget
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      httpGet:  # 其實(shí)就是訪問http://127.0.0.1:80/hello  
        scheme: HTTP #支持的協(xié)議,http或者h(yuǎn)ttps
        port: 80 #端口號
        path: /hello #URI地址

創(chuàng)建pod查看效果:

# 創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-liveness-httpget.yaml
pod/pod-liveness-httpget created

# 查看Pod詳情
[root@k8s-master01 ~] kubectl describe pod pod-liveness-httpget -n dev
.......
  Normal   Pulled     6s (x3 over 64s)  kubelet, node1     Container image "nginx:1.17.1" already present on machine
  Normal   Created    6s (x3 over 64s)  kubelet, node1     Created container nginx
  Normal   Started    6s (x3 over 63s)  kubelet, node1     Started container nginx
  Warning  Unhealthy  6s (x6 over 56s)  kubelet, node1     Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing    6s (x2 over 36s)  kubelet, node1     Container nginx failed liveness probe, will be restarted
  
# 觀察上面信息,嘗試訪問路徑,但是未找到,出現(xiàn)404錯(cuò)誤
# 稍等一會(huì)之后,再觀察pod信息,就可以看到RESTARTS不再是0,而是一直增長
[root@k8s-master01 ~] kubectl get pod pod-liveness-httpget -n dev
NAME                   READY   STATUS    RESTARTS   AGE
pod-liveness-httpget   1/1     Running   5          3m17s

# 當(dāng)然接下來,可以修改成一個(gè)可以訪問的路徑path,比如/,再試,結(jié)果就正常了......

最后,關(guān)于容器探針的其他子屬性,如:容器啟動(dòng)后多久執(zhí)行一次探測

[root@k8s-master01 ~] kubectl explain pod.spec.containers.livenessProbe
FIELDS:
   exec <Object>  
   tcpSocket    <Object>
   httpGet      <Object>
   initialDelaySeconds  <integer>  # 容器啟動(dòng)后等待多少秒執(zhí)行第一次探測
   timeoutSeconds       <integer>  # 探測超時(shí)時(shí)間。默認(rèn)1秒,最小1秒
   periodSeconds        <integer>  # 執(zhí)行探測的頻率。默認(rèn)是10秒,最小1秒
   failureThreshold     <integer>  # 連續(xù)探測失敗多少次才被認(rèn)定為失敗。默認(rèn)是3。最小值是1
   successThreshold     <integer>  # 連續(xù)探測成功多少次才被認(rèn)定為成功。默認(rèn)是1

舉例:

[root@k8s-master01 ~]# more pod-liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-httpget
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      httpGet:
        scheme: HTTP
        port: 80 
        path: /9527
      initialDelaySeconds: 30 # 容器啟動(dòng)后30s開始探測
      timeoutSeconds: 5 # 探測超時(shí)時(shí)間為5s

35秒后:

【K8s】Pod一文詳解

5、重啟策略

一旦容器探測出現(xiàn)了問題,kubernetes就會(huì)對容器所在的Pod進(jìn)行重啟,怎么重啟由重啟策略決定:

  • Always :容器失效時(shí),自動(dòng)重啟該容器,這也是默認(rèn)值
  • OnFailure : 容器終止運(yùn)行且退出碼不為0時(shí)重啟
  • Never : 不論狀態(tài)為何,都不重啟該容器

注意:

重啟策略適用于pod對象中的所有容器,首次需要重啟的容器,將在其需要時(shí)立即進(jìn)行重啟,隨后再次需要重啟的操作將由kubelet延遲一段時(shí)間后進(jìn)行,且反復(fù)的重啟操作的延遲時(shí)長以此為10s、20s、40s、80s、160s和300s,300s是最大延遲時(shí)長,到300以后不再加時(shí)長。階梯增加重啟的前搖,不然本來就跑不起來,你頻繁重啟只會(huì)浪費(fèi)系統(tǒng)資源。

做驗(yàn)證:

apiVersion: v1
kind: Pod
metadata:
  name: pod-restartpolicy
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      httpGet:
        scheme: HTTP
        port: 80
        path: /hello
  restartPolicy: Never # 設(shè)置重啟策略為Never

運(yùn)行pod:

# 創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-restartpolicy.yaml
pod/pod-restartpolicy created

# 查看Pod詳情,發(fā)現(xiàn)nginx容器失敗
[root@k8s-master01 ~] kubectl  describe pods pod-restartpolicy  -n dev
......
  Warning  Unhealthy  15s (x3 over 35s)  kubelet, node1     Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing    15s                kubelet, node1     Container nginx failed liveness probe
  
# 多等一會(huì),再觀察pod的重啟次數(shù),發(fā)現(xiàn)一直是0,并未重啟   
[root@k8s-master01 ~] kubectl  get pods pod-restartpolicy -n dev
NAME                   READY   STATUS    RESTARTS   AGE
pod-restartpolicy      0/1     Running   0          5min42s

四、Pod調(diào)度

在默認(rèn)情況下,一個(gè)Pod在哪個(gè)Node節(jié)點(diǎn)上運(yùn)行,是由Scheduler組件采用相應(yīng)的算法計(jì)算出來的,當(dāng)然也可進(jìn)行人為干預(yù),這和調(diào)度方式有關(guān):

  • 自動(dòng)調(diào)度:運(yùn)行在哪個(gè)節(jié)點(diǎn)上完全由Scheduler經(jīng)過一系列的算法計(jì)算得出
  • 定向調(diào)度:NodeName、NodeSelector
  • 親和性調(diào)度:NodeAffinity、PodAffinity、PodAntiAffinity
  • 污點(diǎn)(容忍)調(diào)度:Taints、Toleration

1、定向調(diào)度

就是直接在pod的yaml文件中聲明一下去哪個(gè)節(jié)點(diǎn)(nodeName),或者去有哪個(gè)標(biāo)簽的節(jié)點(diǎn)(nodeSelector)。

這里直接跳過Scheduler的調(diào)度邏輯,強(qiáng)制調(diào)度,即使要調(diào)度的目標(biāo)Node不存在,也會(huì)向上面進(jìn)行調(diào)度,只不過pod運(yùn)行失敗而已。

# 創(chuàng)建一個(gè)pod-nodename.yaml文件
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeName: node1 # 指定調(diào)度到node1節(jié)點(diǎn)上
  # 集群中節(jié)點(diǎn)名稱可以kubectl get nodes

創(chuàng)建pod,查看效果:

#創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-nodename.yaml
pod/pod-nodename created

#查看Pod調(diào)度到NODE屬性,確實(shí)是調(diào)度到了node1節(jié)點(diǎn)上
[root@k8s-master01 ~] kubectl get pods pod-nodename -n dev -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP            NODE      ......
pod-nodename   1/1     Running   0          56s   10.244.1.87   node1     ......   

# 接下來,刪除pod,修改nodeName的值為node3(并沒有node3節(jié)點(diǎn))
[root@k8s-master01 ~] kubectl delete -f pod-nodename.yaml
pod "pod-nodename" deleted
[root@k8s-master01 ~] vim pod-nodename.yaml
[root@k8s-master01 ~] kubectl create -f pod-nodename.yaml
pod/pod-nodename created

#再次查看,發(fā)現(xiàn)已經(jīng)向Node3節(jié)點(diǎn)調(diào)度,但是由于不存在node3節(jié)點(diǎn),所以pod無法正常運(yùn)行
[root@k8s-master01 ~] kubectl get pods pod-nodename -n dev -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP       NODE    ......
pod-nodename   0/1     Pending   0          6s    <none>   node3   ......           

接下來測試NodeSelector,即將pod調(diào)度到添加了指定標(biāo)簽的node節(jié)點(diǎn)上。它是通過kubernetes的label-selector機(jī)制實(shí)現(xiàn)的,也就是說,在pod創(chuàng)建之前,會(huì)由scheduler使用MatchNodeSelector調(diào)度策略進(jìn)行l(wèi)abel匹配,找出目標(biāo)node,然后將pod調(diào)度到目標(biāo)節(jié)點(diǎn),該匹配規(guī)則是強(qiáng)制約束。

先為node節(jié)點(diǎn)添加標(biāo)簽
[root@k8s-master01 ~] kubectl label nodes node1 nodeenv=pro
node/node2 labeled
[root@k8s-master01 ~] kubectl label nodes node2 nodeenv=test
node/node2 labeled

創(chuàng)建一個(gè)pod-nodeselector.yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeSelector: 
    nodeenv: pro # 指定調(diào)度到具有nodeenv=pro標(biāo)簽的節(jié)點(diǎn)上

創(chuàng)建pod,查看效果:

#創(chuàng)建Pod
[root@k8s-master01 ~] kubectl create -f pod-nodeselector.yaml
pod/pod-nodeselector created

#查看Pod調(diào)度到NODE屬性,確實(shí)是調(diào)度到了node1節(jié)點(diǎn)上
[root@k8s-master01 ~] kubectl get pods pod-nodeselector -n dev -o wide
NAME               READY   STATUS    RESTARTS   AGE     IP          NODE    ......
pod-nodeselector   1/1     Running   0          47s   10.244.1.87   node1   ......

# 接下來,刪除pod,修改nodeSelector的值為nodeenv: xxxx(不存在打有此標(biāo)簽的節(jié)點(diǎn))
[root@k8s-master01 ~] kubectl delete -f pod-nodeselector.yaml
pod "pod-nodeselector" deleted
[root@k8s-master01 ~] vim pod-nodeselector.yaml
[root@k8s-master01 ~] kubectl create -f pod-nodeselector.yaml
pod/pod-nodeselector created

#再次查看,發(fā)現(xiàn)pod無法正常運(yùn)行,Node的值為none
[root@k8s-master01 ~] kubectl get pods -n dev -o wide
NAME               READY   STATUS    RESTARTS   AGE     IP       NODE    
pod-nodeselector   0/1     Pending   0          2m20s   <none>   <none>

# 查看詳情,發(fā)現(xiàn)node selector匹配失敗的提示
[root@k8s-master01 ~] kubectl describe pods pod-nodeselector -n dev
.......
Events:
  Type     Reason            Age        From               Message
  ----     ------            ----       ----               -------
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.

2、親和性調(diào)度

形象的說,就是想去哪些節(jié)點(diǎn)、想去有哪個(gè)pod的節(jié)點(diǎn),不想去有哪個(gè)pod的節(jié)點(diǎn)。就像分座位,想去哪幾個(gè)班、想去有某位同學(xué)的班級、不去有哪位同學(xué)的班級。

和定向調(diào)度的強(qiáng)制性相比,親和性調(diào)度更溫柔,使得調(diào)度更靈活了。親和性Affinity主要分三類:

  • nodeAffinity(node親和性): 以node為目標(biāo),解決pod可以調(diào)度到哪些node的問題 ==> 想去哪幾個(gè)班
  • podAffinity(pod親和性) : 以pod為目標(biāo),解決pod可以和哪些已存在的pod部署在同一個(gè)拓?fù)溆蛑械膯栴} ==> 想去有某位同學(xué)的班級
  • podAntiAffinity(pod反親和性) : 以pod為目標(biāo),解決pod不能和哪些已存在pod部署在同一個(gè)拓?fù)溆蛑械膯栴} ==> 不去有哪位同學(xué)的班級

關(guān)于親和性和反親和性的使用場景:

親和性:

如果兩個(gè)pod需要頻繁交互,如mysql和tomcat,那就有必要利用親和性讓兩個(gè)應(yīng)用的盡可能的靠近(同一節(jié)點(diǎn)),這樣可以減少因網(wǎng)絡(luò)通信而帶來的性能損耗。

反親和性:

當(dāng)應(yīng)用的采用多副本部署時(shí),有必要采用反親和性讓各個(gè)應(yīng)用實(shí)例打散分布在各個(gè)node上,這樣可以提高服務(wù)的高可用性。(別一個(gè)節(jié)點(diǎn)掛了,某個(gè)服務(wù)的副本pod被一鍋端了。)

2.1 node親和性調(diào)度

查看NodeAffinity的配置項(xiàng):

[root@k8s-master01 ~]kubectl explain pod.spec.affinity.nodeAffinity

---------
  requiredDuringSchedulingIgnoredDuringExecution  Node節(jié)點(diǎn)必須滿足指定的所有規(guī)則才可以調(diào)度成功,相當(dāng)于硬限制
    nodeSelectorTerms  節(jié)點(diǎn)選擇列表
      matchFields   按節(jié)點(diǎn)字段列出的節(jié)點(diǎn)選擇器要求列表
      matchExpressions   按節(jié)點(diǎn)標(biāo)簽列出的節(jié)點(diǎn)選擇器要求列表(推薦)
        key    鍵
        values 值
        operat or 關(guān)系符 支持Exists, DoesNotExist, In, NotIn, Gt, Lt
---------
  preferredDuringSchedulingIgnoredDuringExecution 優(yōu)先調(diào)度到滿足指定的規(guī)則的Node,相當(dāng)于軟限制 (傾向)
    preference   一個(gè)節(jié)點(diǎn)選擇器項(xiàng),與相應(yīng)的權(quán)重相關(guān)聯(lián)
      matchFields   按節(jié)點(diǎn)字段列出的節(jié)點(diǎn)選擇器要求列表
      matchExpressions   按節(jié)點(diǎn)標(biāo)簽列出的節(jié)點(diǎn)選擇器要求列表(推薦)
        key    鍵
        values 值
        operator 關(guān)系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt
	weight 傾向權(quán)重,在范圍1-100。

關(guān)于關(guān)系符的使用:

- matchExpressions:
  - key: nodeenv              # 匹配存在標(biāo)簽的key為nodeenv的節(jié)點(diǎn)
    operator: Exists
  - key: nodeenv              # 匹配標(biāo)簽的key為nodeenv,且value是"xxx"或"yyy"的節(jié)點(diǎn)
    operator: In
    values: ["xxx","yyy"]
  - key: nodeenv              # 匹配標(biāo)簽的key為nodeenv,且value大于"xxx"的節(jié)點(diǎn)
    operator: Gt
    values: "xxx"

創(chuàng)建一個(gè)pod-nodeaffinity-required.yaml文件來舉例看看:

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:  #親和性設(shè)置
    nodeAffinity: #設(shè)置node親和性
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
        nodeSelectorTerms:
        - matchExpressions: # 匹配key為nodeenv,值在["xxx","yyy"]中的標(biāo)簽的節(jié)點(diǎn)
          - key: nodeenv
            operator: In
            values: ["xxx","yyy"]

啟動(dòng)pod,查看效果:

# 創(chuàng)建pod
[root@k8s-master01 ~] kubectl create -f pod-nodeaffinity-required.yaml
pod/pod-nodeaffinity-required created

# 查看pod狀態(tài) (運(yùn)行失?。?/span>
[root@k8s-master01 ~] kubectl get pods pod-nodeaffinity-required -n dev -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP       NODE    ...... 
pod-nodeaffinity-required   0/1     Pending   0          16s   <none>   <none>  ......

# 查看Pod的詳情,pending
# 發(fā)現(xiàn)調(diào)度失敗,提示node選擇失敗
[root@k8s-master01 ~] kubectl describe pod pod-nodeaffinity-required -n dev
......
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.

由于我只設(shè)置了硬限制,所以調(diào)度失敗,修改一下配置文件:

#停止pod
[root@k8s-master01 ~] kubectl delete -f pod-nodeaffinity-required.yaml
pod "pod-nodeaffinity-required" deleted

# 修改文件,將values: ["xxx","yyy"]------> ["pro","yyy"]
[root@k8s-master01 ~] vim pod-nodeaffinity-required.yaml

# 再次啟動(dòng)
[root@k8s-master01 ~] kubectl create -f pod-nodeaffinity-required.yaml
pod/pod-nodeaffinity-required created

# 此時(shí)查看,發(fā)現(xiàn)調(diào)度成功,已經(jīng)將pod調(diào)度到了node1上
[root@k8s-master01 ~] kubectl get pods pod-nodeaffinity-required -n dev -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE  ...... 
pod-nodeaffinity-required   1/1     Running   0          11s   10.244.1.89   node1 ......

接下來測試使用節(jié)點(diǎn)親和性的軟限制,創(chuàng)建pod-nodeaffinity-preferred.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-preferred
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:  #親和性設(shè)置
    nodeAffinity: #設(shè)置node親和性
      preferredDuringSchedulingIgnoredDuringExecution: # 軟限制
      - weight: 1
        preference:
          matchExpressions: # 優(yōu)先匹配env的值在["xxx","yyy"]中的標(biāo)簽(當(dāng)前集群沒有),匹配不到可考慮其他
          - key: nodeenv
            operator: In
            values: ["xxx","yyy"]

創(chuàng)建pod查看:

# 創(chuàng)建pod
[root@k8s-master01 ~] kubectl create -f pod-nodeaffinity-preferred.yaml
pod/pod-nodeaffinity-preferred created

# 查看pod狀態(tài) (運(yùn)行成功)
[root@k8s-master01 ~] kubectl get pod pod-nodeaffinity-preferred -n dev
NAME                         READY   STATUS    RESTARTS   AGE
pod-nodeaffinity-preferred   1/1     Running   0          40s

幾個(gè)注意點(diǎn):

NodeAffinity規(guī)則設(shè)置的注意事項(xiàng):
    1 如果同時(shí)定義了nodeSelector和nodeAffinity,那么必須兩個(gè)條件都得到滿足,Pod才能運(yùn)行在指定的Node上
    2 如果nodeAffinity指定了多個(gè)nodeSelectorTerms,那么只需要其中一個(gè)能夠匹配成功即可
    3 如果一個(gè)nodeSelectorTerms中有多個(gè)matchExpressions ,則一個(gè)節(jié)點(diǎn)必須滿足所有的才能匹配成功
    4 如果一個(gè)pod所在的Node在Pod運(yùn)行期間其標(biāo)簽發(fā)生了改變,不再符合該P(yáng)od的節(jié)點(diǎn)親和性需求,則系統(tǒng)將忽略此變化,不會(huì)二次調(diào)度

2.2 pod親和性調(diào)度

讓新創(chuàng)建的Pod跟參照pod在一個(gè)區(qū)域的功能,去有某同學(xué)的那個(gè)班級。

kubectl explain pod.spec.affinity.podAffinity
----------
  requiredDuringSchedulingIgnoredDuringExecution  硬限制
    namespaces       指定參照pod的namespace
    topologyKey      指定調(diào)度作用域
    labelSelector    標(biāo)簽選擇器
      matchExpressions  按節(jié)點(diǎn)標(biāo)簽列出的節(jié)點(diǎn)選擇器要求列表(推薦)
        key    鍵
        values 值
        operator 關(guān)系符 支持In, NotIn, Exists, DoesNotExist.
      matchLabels    指多個(gè)matchExpressions映射的內(nèi)容


----------
  preferredDuringSchedulingIgnoredDuringExecution 軟限制
    podAffinityTerm  選項(xiàng)
      namespaces      
      topologyKey
      labelSelector
        matchExpressions  
          key    鍵
          values 值
          operator
        matchLabels 
    weight 傾向權(quán)重,在范圍1-100

topologyKey指定調(diào)度作用域,作用域即范圍,調(diào)度到和參照pod同一節(jié)點(diǎn)、同一網(wǎng)段還是同樣的操作系統(tǒng)里。(和你同學(xué)同一個(gè)班級?同一張課桌?同一個(gè)學(xué)校?

topologyKey取值:
    kubernetes.io/hostname,那就是以Node節(jié)點(diǎn)為區(qū)分范圍
	beta.kubernetes.io/os,則以Node節(jié)點(diǎn)的操作系統(tǒng)類型來區(qū)分

舉個(gè)例子說明pod親和性,先創(chuàng)建一個(gè)參照pod,并定向調(diào)度到node1

# pod-podaffinity-target.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-target
  namespace: dev
  labels:
    podenv: pro #設(shè)置標(biāo)簽
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeName: node1 # 將目標(biāo)pod名確指定到node1上
# 啟動(dòng)目標(biāo)pod
[root@k8s-master01 ~] kubectl create -f pod-podaffinity-target.yaml
pod/pod-podaffinity-target created

# 查看pod狀況
[root@k8s-master01 ~] kubectl get pods  pod-podaffinity-target -n dev
NAME                     READY   STATUS    RESTARTS   AGE
pod-podaffinity-target   1/1     Running   0          4s

創(chuàng)建待調(diào)度的pod,配置文件pod-podaffinity-required.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:  #親和性設(shè)置
    podAffinity: #設(shè)置pod親和性
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
      - labelSelector:
          matchExpressions: # 匹配env的值在["xxx","yyy"]中的標(biāo)簽
          - key: podenv
            operator: In
            values: ["xxx","yyy"]
        # 如果找到這種pod了,那就把這個(gè)pod調(diào)度到和匹配成功的pod的同一幾點(diǎn)上    
        topologyKey: kubernetes.io/hostname

上面配置表達(dá)的意思是:新Pod必須要與擁有標(biāo)簽nodeenv=xxx或者nodeenv=yyy的pod在同一Node上,硬限制。

# 啟動(dòng)pod
[root@k8s-master01 ~] kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created

# 查看pod狀態(tài),發(fā)現(xiàn)未運(yùn)行
[root@k8s-master01 ~] kubectl get pods pod-podaffinity-required -n dev
NAME                       READY   STATUS    RESTARTS   AGE
pod-podaffinity-required   0/1     Pending   0          9s

# 查看詳細(xì)信息
[root@k8s-master01 ~] kubectl describe pods pod-podaffinity-required  -n dev
......
Events:
  Type     Reason            Age        From               Message
  ----     ------            ----       ----               -------
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 2 node(s) didn't match pod affinity rules, 1 node(s) had taints that the pod didn't tolerate.

調(diào)度失敗了,稍微修改一下匹配的label:

# 接下來修改  values: ["xxx","yyy"]----->values:["pro","yyy"]
# 意思是:新Pod必須要與擁有標(biāo)簽nodeenv=xxx或者nodeenv=yyy的pod在同一Node上
[root@k8s-master01 ~] vim pod-podaffinity-required.yaml

# 然后重新創(chuàng)建pod,查看效果
[root@k8s-master01 ~] kubectl delete -f  pod-podaffinity-required.yaml
pod "pod-podaffinity-required" de leted
[root@k8s-master01 ~] kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created

# 發(fā)現(xiàn)此時(shí)Pod運(yùn)行正常
[root@k8s-master01 ~] kubectl get pods pod-podaffinity-required -n dev
NAME                       READY   STATUS    RESTARTS   AGE   LABELS
pod-podaffinity-required   1/1     Running   0          6s    <none>

2.3 pod反親和性調(diào)度

PodAntiAffinity主要實(shí)現(xiàn)以運(yùn)行的Pod為參照,讓新創(chuàng)建的Pod跟參照pod不在一個(gè)區(qū)域中的功能。(不和誰一個(gè)班

【K8s】Pod一文詳解

舉個(gè)例子說明,繼續(xù)使用pod親和性中建的pod:

[root@k8s-master01 ~] kubectl get pods -n dev -o wide --show-labels
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE    LABELS
pod-podaffinity-required 1/1     Running   0          3m29s   10.244.1.38   node1   <none>     
pod-podaffinity-target   1/1     Running   0          9m25s   10.244.1.37   node1   podenv=pro

創(chuàng)建pod-podantiaffinity-required.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-podantiaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:  #親和性設(shè)置
    podAntiAffinity: #設(shè)置pod反親和性
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
      - labelSelector:
          matchExpressions: # 匹配podenv的值在["pro"]中的標(biāo)簽
          - key: podenv
            operator: In
            values: ["pro"]
        topologyKey: kubernetes.io/hostname

上面配置表達(dá)的意思是:新Pod必須要與擁有標(biāo)簽nodeenv=pro的pod不在同一Node上

# 創(chuàng)建pod
[root@k8s-master01 ~]# kubectl create -f pod-podantiaffinity-required.yaml
pod/pod-podantiaffinity-required created

# 查看pod
# 發(fā)現(xiàn)調(diào)度到了node2上
[root@k8s-master01 ~] kubectl get pods pod-podantiaffinity-required -n dev -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE   .. 
pod-podantiaffinity-required   1/1     Running   0          30s   10.244.1.96   node2  ..

3、污點(diǎn)和容忍調(diào)度

前面的兩種調(diào)度都是在pod的角度,來說pod要去哪兒,不要去哪兒。接下來站在node的角度,來說允許哪些pod過來,不允許哪些pod過來。(前面是學(xué)生要轉(zhuǎn)校到哪個(gè)學(xué)校,現(xiàn)在是校長貼出告示說明不要哪些學(xué)生

3.1 污點(diǎn)(Taints)

Node被設(shè)置上污點(diǎn)之后就和Pod之間存在了一種相斥的關(guān)系,進(jìn)而拒絕Pod調(diào)度進(jìn)來,甚至可以將已經(jīng)存在的Pod驅(qū)逐出去。

污點(diǎn)的格式為:key=value:effect, key和value是污點(diǎn)的標(biāo)簽,effect描述污點(diǎn)的作用,支持如下三個(gè)選項(xiàng):

【K8s】Pod一文詳解

  • PreferNoSchedule:kubernetes將盡量避免把Pod調(diào)度到具有該污點(diǎn)的Node上,除非沒有其他節(jié)點(diǎn)可調(diào)度

  • NoSchedule:kubernetes將不會(huì)把Pod調(diào)度到具有該污點(diǎn)的Node上,但不會(huì)影響當(dāng)前Node上已存在的Pod

  • NoExecute:kubernetes將不會(huì)把Pod調(diào)度到具有該污點(diǎn)的Node上,同時(shí)也會(huì)將Node上已存在的Pod驅(qū)離

設(shè)置和去除污點(diǎn):

# 設(shè)置污點(diǎn)
kubectl taint nodes node1 key=value:effect

# 去除污點(diǎn)
kubectl taint nodes node1 key:effect-

# 去除所有污點(diǎn)
kubectl taint nodes node1 key-

接下來舉例子演示效果,先停掉node2節(jié)點(diǎn)(關(guān)機(jī)),只留master和node1,先看PreferNoSchedule:

# 為node1設(shè)置污點(diǎn)(PreferNoSchedule)
[root@k8s-master01 ~] kubectl taint nodes node1 tag=code9527:PreferNoSchedule
# 創(chuàng)建pod1
[root@k8s-master01 ~] kubectl run taint1 --image=nginx:1.17.1 -n dev
[root@k8s-master01 ~] kubectl get pods -n dev -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP           NODE   
taint1-7665f7fd85-574h4   1/1     Running   0          2m24s   10.244.1.59   node1   

僅有一個(gè)工作節(jié)點(diǎn),且該節(jié)點(diǎn)設(shè)置了污點(diǎn)PreferNoSchedule,但仍調(diào)度成功。

再看NoSchedule:

# 為node1設(shè)置污點(diǎn)(取消PreferNoSchedule,設(shè)置NoSchedule)
[root@k8s-master01 ~] kubectl taint nodes node1 tag:PreferNoSchedule-
[root@k8s-master01 ~] kubectl taint nodes node1 tag=code9527:NoSchedule

創(chuàng)建pod,發(fā)現(xiàn)pending,且調(diào)度失?。?/p>

# 創(chuàng)建pod2
[root@k8s-master01 ~] kubectl run taint2 --image=nginx:1.17.1 -n dev
[root@k8s-master01 ~] kubectl get pods  -n dev -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP            NODE
taint1-7665f7fd85-574h4   1/1     Running   0          2m24s   10.244.1.59   node1 
taint2-544694789-6zmlf    0/1     Pending   0          21s     <none>        <none>  

再看NoExecute:

# 為node1設(shè)置污點(diǎn)(取消NoSchedule,設(shè)置NoExecute)
[root@k8s-master01 ~] kubectl taint nodes node1 tag:NoSchedule-
[root@k8s-master01 ~] kubectl taint nodes node1 tag=code9527:NoExecute

可以看到已有的pod也被驅(qū)逐了:

# 創(chuàng)建pod3
[root@k8s-master01 ~] kubectl run taint3 --image=nginx:1.17.1 -n dev
# IP全為<none>
[root@k8s-master01 ~] kubectl get pods -n dev -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED 
taint1-7665f7fd85-htkmp   0/1     Pending   0          35s   <none>   <none>   <none>    
taint2-544694789-bn7wb    0/1     Pending   0          35s   <none>   <none>   <none>     
taint3-6d78dbd749-tktkq   0/1     Pending   0          6s    <none>   <none>   <none> 

小提示:

使用kubeadm搭建的集群,默認(rèn)就會(huì)給master節(jié)點(diǎn)添加一個(gè)污點(diǎn)標(biāo)記,所以pod就不會(huì)調(diào)度到master節(jié)點(diǎn)上.
kubectl describe node master
# 查看一下

【K8s】Pod一文詳解

3.2 容忍(Toleration)

在node上添加污點(diǎn)用于拒絕pod調(diào)度上來,但是如果就是想將一個(gè)pod調(diào)度到一個(gè)有污點(diǎn)的node上去,這時(shí)就要使用到容忍。

【K8s】Pod一文詳解

污點(diǎn)就是拒絕,容忍就是忽略,Node通過污點(diǎn)拒絕pod調(diào)度上去,Pod通過容忍忽略拒絕

形象的說,污點(diǎn)就是,相親時(shí),你告訴相親對象,你這人脾氣大,對方說:沒事,我能接收。于是你們在一起了。

創(chuàng)建pod-toleration.yaml做演示:

apiVersion: v1
kind: Pod
metadata:
  name: pod-toleration
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  tolerations:      # 添加容忍
  - key: "tag"        # 要容忍的污點(diǎn)的key
    operator: "Equal" # 操作符
    value: "code9527"    # 容忍的污點(diǎn)的value
    effect: "NoExecute"   # 添加容忍的規(guī)則,這里必須和標(biāo)記的污點(diǎn)規(guī)則相同

上一小節(jié),已經(jīng)在node1節(jié)點(diǎn)上打上了NoExecute的污點(diǎn),此時(shí)pod是調(diào)度不上去的。啟動(dòng)pod看一下加了容忍以后的效果:

# 添加容忍之前的pod
[root@k8s-master01 ~] kubectl get pods -n dev -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED 
pod-toleration   0/1     Pending   0          3s    <none>   <none>   <none>           

# 添加容忍之后的pod
[root@k8s-master01 ~] kubectl get pods -n dev -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED
pod-toleration   1/1     Running   0          3s    10.244.1.62   node1   <none>        

最后看一下容忍的所有子屬性:

[root@k8s-master01 ~] kubectl explain pod.spec.tolerations
......
FIELDS:
   key       # 對應(yīng)著要容忍的污點(diǎn)的鍵,空意味著匹配所有的鍵
   value     # 對應(yīng)著要容忍的污點(diǎn)的值
   operator  # key-value的運(yùn)算符,支持Equal和Exists(默認(rèn)),Exists是對鍵進(jìn)行操作
   effect    # 對應(yīng)污點(diǎn)的effect,空意味著匹配所有影響
   tolerationSeconds   # 容忍時(shí)間, 
				       # 當(dāng)effect為NoExecute時(shí)生效
   					   # 表示pod在Node上的停留時(shí)間

注意最后這個(gè)tolerationSeconds容忍時(shí)間,NoExecute時(shí)生效,NoExcute本來就禁止往上調(diào)度。tolerationSeconds就是忍多久以后跑路。


到此,Pod篇結(jié)束,下來是各種Pod控制器?。?span toymoban-style="hidden">文章來源地址http://www.zghlxwxcb.cn/news/detail-441508.html

到了這里,關(guān)于【K8s】Pod一文詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • k8s --pod詳解

    k8s --pod詳解

    目錄 一、Pod基礎(chǔ)概念 1、pod簡介 2、在Kubrenetes集群中Pod有如下兩種使用方式 3、pause容器使得Pod中的所有容器可以共享兩種資源:網(wǎng)絡(luò)和存儲(chǔ)。 (1)網(wǎng)絡(luò) (2)存儲(chǔ) 4、kubernetes中的pause容器主要為每個(gè)容器提供以下功能 6、Pod分類 (1)自主式Pod? ?(2)控制器管理的Pod ?(3)

    2024年02月13日
    瀏覽(21)
  • k8s之Pod詳解

    k8s之Pod詳解

    Pod是kubernetes中最小的資源管理組件 ,Pod也是最小化運(yùn)行容器化應(yīng)用的資源對象。 一個(gè)Pod代表著集群中運(yùn)行的一個(gè)進(jìn)程 。kubernetes中其他大多數(shù)組件都是圍繞著Pod來進(jìn)行支撐和擴(kuò)展Pod功能的,例如,用于管理Pod運(yùn)行的StatefulSet和Deployment等控制器對象,用于暴露Pod應(yīng)用的Service和

    2024年02月16日
    瀏覽(21)
  • 【K8S系列】Pod詳解

    【K8S系列】Pod詳解

    目錄 序言 1 前言 2 為什么需要pod 3 什么是Pod? 3.1 Pod的組成 3.2 Pod的用途 3.3 Pod的生命周期 3.4 Pod的特點(diǎn) 4 Pod的使用 5 結(jié)論? 任何一件事情,只要堅(jiān)持六個(gè)月以上,你都可以看到質(zhì)的飛躍。 今天學(xué)習(xí)一下K8s-Pod相關(guān)內(nèi)容,希望此文,能幫助讀者對K8s-pod有一個(gè)進(jìn)一步的了解 文章標(biāo)

    2024年02月01日
    瀏覽(17)
  • k8s Pod狀態(tài)詳解

    在 Kubernetes 中,Pod 是最小的可部署的計(jì)算單元,它是一組容器的集合,共享同一個(gè)網(wǎng)絡(luò)命名空間、存儲(chǔ)卷等資源。 Kubernetes 中的 Pod 有以下幾種狀態(tài): Pending(掛起) :Pod 已經(jīng)被 Kubernetes API 接受,但它的容器鏡像還沒有被拉取,或者 Pod 所需的節(jié)點(diǎn)資源(CPU、內(nèi)存等)還沒有滿足

    2024年02月15日
    瀏覽(41)
  • 玩轉(zhuǎn)k8s:Pod詳解

    玩轉(zhuǎn)k8s:Pod詳解

    目錄 1 Pod詳解 1.1 Pod介紹 1.1.1 Pod結(jié)構(gòu) 1.1.2 Pod定義 1.2 Pod配置 1.2.1 基本配置 1.2.2 鏡像拉取 1.2.3 啟動(dòng)命令 1.2.4 環(huán)境變量 1.2.5 端口設(shè)置 1.2.6 資源配額 1.3 Pod生命周期 1.3.1 創(chuàng)建和終止 1.3.2 初始化容器 1.3.3 鉤子函數(shù) 1.3.4 容器探測 1.3.5 重啟策略 1.4 Pod調(diào)度 1.4.1 定向調(diào)度 1.4.2 親和性

    2024年02月06日
    瀏覽(21)
  • K8s(一)Pod資源——Pod介紹、創(chuàng)建Pod、Pod簡單資源配額

    K8s(一)Pod資源——Pod介紹、創(chuàng)建Pod、Pod簡單資源配額

    目錄 Pod概述 pod網(wǎng)絡(luò) pod存儲(chǔ) pod和容器對比 創(chuàng)建pod的方式 pod運(yùn)行方式分類 Pod的創(chuàng)建 Pod的創(chuàng)建過程 通過kubectl run來創(chuàng)建pod 通過yaml文件創(chuàng)建,yaml文件簡單寫法 Pod簡單操作 Pod的標(biāo)簽labels Pod的資源配額resource 測試 Kubernetes Pod | Kubernetes Pod是Kubernetes中的最小調(diào)度單元,k8s都是以p

    2024年01月18日
    瀏覽(52)
  • Kubernetes(k8s)容器編排Pod介紹和使用

    Kubernetes(k8s)容器編排Pod介紹和使用

    Pod是kubernetes中你可以創(chuàng)建和部署的最小也是最簡的單位,一個(gè)Pod代表著集群中運(yùn)行的一個(gè)進(jìn)程。 Pod有兩個(gè)必須知道的特點(diǎn) 通過yaml文件或者json描述Pod和其內(nèi)容器的運(yùn)行環(huán)境和期望狀態(tài),例如一個(gè)最簡單的運(yùn)行nginx應(yīng)用的pod,定義如下 3.1.1 參數(shù)描述 下面簡要分析一下上面的

    2024年02月08日
    瀏覽(119)
  • (二)k8s實(shí)戰(zhàn)-深入Pod詳解

    (二)k8s實(shí)戰(zhàn)-深入Pod詳解

    創(chuàng)建Pod nginx樣例 參數(shù)名 類型 字段說明 apiVersion String K8S APl 的版本,可以用 kubectl api versions 命令查詢 kind String yam 文件定義的資源類型和角色 metadata Object 元數(shù)據(jù)對象,下面是它的屬性 metadata.name String 元數(shù)據(jù)對象的名字,比如 pod 的名字 metadata.namespace String 元數(shù)據(jù)對象的命名

    2024年02月11日
    瀏覽(21)
  • K8S之Pod詳解與進(jìn)階

    1.pod定義 Pod 是 K8S 最小的創(chuàng)建和運(yùn)行管理單元 2.pause容器作用 3.Pod 的 3 種類型 4.Pod 的 3 種容器 5.Pod 的 3 種鏡像拉取策略 6.Pod 的 3 種容器重啟策略 1.資源限制 2.Pod 容器的 3 種探針(健康檢查) 3.探針的 3 種探測方式 探針參數(shù) 4.Pod 應(yīng)用容器生命周期的啟動(dòng)動(dòng)作和退出動(dòng)作

    2024年02月13日
    瀏覽(22)
  • 關(guān)于K8s的Pod的詳解(一)

    關(guān)于K8s的Pod的詳解(一)

    Pod 作為k8s創(chuàng)建,調(diào)度,管理的基本單位。由上級的Controller對Node上安裝的Kubelet發(fā)送指令對Pod進(jìn)行管理,因此我們需要詳細(xì)了解關(guān)于Pod。 其中最為基本的操作就是Pod的創(chuàng)建,刪除,調(diào)度,查看! 對于Pod的創(chuàng)建,相關(guān)聯(lián)的就有,對Pod的資源分配,資源限制;對Pod的創(chuàng)建調(diào)度,基

    2024年02月16日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包