k8s(pod,控制器,service)詳解

来源:https://www.cnblogs.com/qw77/p/18173479
-Advertisement-
Play Games

一:Pod介紹 pod資源的各種配置和原理 關於很多yaml文件的編寫,都是基於配置引出來的 1:pod的結構和定義 每個Pod中都可以包含一個或者多個容器,這些容器可以分為2大類: 1:用戶所在的容器,數量可多可少(用戶容器) 2:pause容器,這是每個pod都會有的一個跟容器,作用有2個 1、 ...


一:Pod介紹

pod資源的各種配置和原理

關於很多yaml文件的編寫,都是基於配置引出來的

1:pod的結構和定義

 每個Pod中都可以包含一個或者多個容器,這些容器可以分為2大類:

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

  2:pause容器,這是每個pod都會有的一個跟容器,作用有2個

    1、可以以它為根據,評估整個pod的健康狀態

    2、可以在根容器上面設置ip地址,其他容器都以此ip,實現Pod內部的網路通信

      這裡的Pod內部通訊是,pod之間採用二層網路技術來實現

      ;其他容器都共用這個根容器的ip地址,外界訪問這個根容器ip地址+埠即可

2:pod定義

pod的資源清單:

屬性,依次類推的進行查找

[root@master /]# kubectl  explain pod
#查看二級屬性
[root@master /]# kubectl  explain pod.metadata

 

介紹

apiVersion 版本
#查看所有的版本
[root@master /]# kubectl  api-versions
admissionregistration.k8s.io/v1
apiextensions.k8s.io/v1
apiregistration.k8s.io/v1
apps/v1
authentication.k8s.io/v1
authorization.k8s.io/v1
autoscaling/v1
autoscaling/v2
batch/v1
certificates.k8s.io/v1
coordination.k8s.io/v1
discovery.k8s.io/v1
events.k8s.io/v1
flowcontrol.apiserver.k8s.io/v1beta2
flowcontrol.apiserver.k8s.io/v1beta3
networking.k8s.io/v1
node.k8s.io/v1
policy/v1
rbac.authorization.k8s.io/v1
scheduling.k8s.io/v1
storage.k8s.io/v1
v1

kind 類型
#查看資源的類型
[root@master /]# kubectl  api-resources 

metadata  元數據,資源的名字,標簽等等
[root@master /]# kubectl  explain  pod.metadata 

status   狀態信息,自動的進行生成,不需要自己定義
[root@master /]# kubectl  get pods -o yaml

spec  定義資源的詳細信息,
下麵的子屬性
containers:object  容器列表,用於定義容器的詳細信息
nodename:string   根據nodename的值將pod的調度到指定的node節點,pod部署在哪個Pod上面
nodeselector:pod標簽選擇器,可以將pod調度到包含這些label的Node上
hostnetwork:預設是false,k8s自動的分配一個ip地址,如果設置為true,就使用宿主機的ip
volumes:存儲捲,用於定義pod上面掛載的存儲信息
restartpolicy:重啟策略,表示pod在遇到故障的時候處理的策略

3:pod配置

主要關於pod.spec.containers屬性

裡面有的是數組,就是可以選擇多個值,在裡面的話,有的只是一個值,看情況進行區分

[root@master /]# kubectl  explain pod.spec.containers
KIND:       Pod
VERSION:    v1

name:容器名稱
image:容器需要的鏡像地址
imagePullPolicy:鏡像拉取策略  本地的還是遠程的
command:容器的啟動命令列表,如不指定,使用打包時使用的啟動命令  string
args:容器的啟動命令需要的參數列表,也就是上面的列表的命令   string
env:容器環境變數的配置   object
ports:容器需要暴露的埠列表   object
resources:資源限制和資源請求的設置   object

1、基本配置

[root@master ~]# cat pod-base.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-base
  namespace: dev
  labels:
    user: qqqq
spec:
   containers:
     - name: nginx
       image: nginx:1.17.1
     - name: busybox
       image: busybox:1.30

簡單的Pod的配置,裡面有2個容器
nginx輕量級的web軟體
busybox:就是一個小巧的Linux命令集合

[root@master ~]# kubectl create  -f pod-base.yaml 
pod/pod-base created

#查看Pod狀態,
ready:只有裡面有2個容器,但是只有一個是準備就緒的,還有一個沒有啟動
restarts:重啟的次數,因為有一個容器故障了,Pod一直重啟試圖恢復它
[root@master ~]# kubectl get pods -n dev
NAME       READY   STATUS             RESTARTS      AGE
pod-base   1/2     CrashLoopBackOff   4 (29s ago)   2m36s

#可以查看pod詳情
[root@master ~]# kubectl describe  pods pod-base -n dev
Events:
  Type     Reason     Age                   From               Message
  ----     ------     ----                  ----               -------
  Normal   Scheduled  4m51s                 default-scheduler  Successfully assigned dev/pod-base to node2
  Normal   Pulling    4m51s                 kubelet            Pulling image "nginx:1.17.1"
  Normal   Pulled     4m17s                 kubelet            Successfully pulled image "nginx:1.17.1" in 33.75s (33.75s including waiting)
  Normal   Created    4m17s                 kubelet            Created container nginx
  Normal   Started    4m17s                 kubelet            Started container nginx
  Normal   Pulling    4m17s                 kubelet            Pulling image "busybox:1.30"
  Normal   Pulled     4m9s                  kubelet            Successfully pulled image "busybox:1.30" in 8.356s (8.356s including waiting)
  Normal   Created    3m27s (x4 over 4m9s)  kubelet            Created container busybox
  Normal   Started    3m27s (x4 over 4m9s)  kubelet            Started container busybox
  Warning  BackOff    2m59s (x7 over 4m7s)  kubelet            Back-off restarting failed container busybox in pod pod-base_dev(2e9aeb3f-2bec-4af5-853e-2d8473e115a7)
  Normal   Pulled     2m44s (x4 over 4m8s)  kubelet            Container image "busybox:1.30" already present on machine  

之後再來進行解決

2、鏡像拉取

imagePullPolicy

就是pod裡面有個容器,一個有本地鏡像,一個沒有,可以使用這個參數來進行控制是本地還是遠程的

imagePullPolicy的值,

  Always:總是從遠程倉庫進行拉取鏡像(一直用遠程下載)

  ifNotPresent:本地有則使用本地的鏡像,本地沒有則使用從遠程倉庫拉取鏡像

  Never:一直使用本地的,不使用遠程下載

如果鏡像的tag為具體的版本號:預設值是ifNotPresent,

 如果是latest:預設策略是always

[root@master ~]# cat pod-policy.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-imagepullpolicy
  namespace: dev
  labels:
    user: qqqq
spec:
   containers:
     - name: nginx
       image: nginx:1.17.2
       imagePullPolicy: Never
     - name: busybox
       image: busybox:1.30

[root@master ~]# kubectl create -f pod-policy.yaml 
pod/pod-imagepullpolicy created

#查看pods狀態
[root@master ~]# kubectl get pods -n dev
NAME                  READY   STATUS             RESTARTS        AGE
pod-base              1/2     CrashLoopBackOff   9 (3m59s ago)   25m
pod-imagepullpolicy   0/2     CrashLoopBackOff   1 (9s ago)      19s

#查看詳細的信息
[root@master ~]# kubectl describe  pods pod-imagepullpolicy -n dev 
Events:
  Type     Reason             Age                From               Message
  ----     ------             ----               ----               -------
  Normal   Scheduled          64s                default-scheduler  Successfully assigned dev/pod-imagepullpolicy to node1
  Normal   Pulling            64s                kubelet            Pulling image "busybox:1.30"
  Normal   Pulled             56s                kubelet            Successfully pulled image "busybox:1.30" in 8.097s (8.097s including waiting)
  Normal   Created            39s (x3 over 56s)  kubelet            Created container busybox
  Normal   Started            39s (x3 over 56s)  kubelet            Started container busybox
  Normal   Pulled             39s (x2 over 55s)  kubelet            Container image "busybox:1.30" already present on machine
  Warning  ErrImageNeverPull  38s (x6 over 64s)  kubelet            Container image "nginx:1.17.2" is not present with pull policy of Never
  Warning  Failed             38s (x6 over 64s)  kubelet            Error: ErrImageNeverPull
  Warning  BackOff            38s (x3 over 54s)  kubelet            Back-off restarting failed container busybox in pod pod-imagepullpolicy_dev(38d5d2ff-6155-4ff3-ad7c-8b7f4a370107)

#直接報了一個錯誤,就是鏡像拉取失敗了

#解決的措施,修改裡面的策略為ifnotpresent即可
[root@master ~]# kubectl  delete  -f pod-policy.yaml 
[root@master ~]# kubectl  apply  -f pod-policy.yaml 
[root@master ~]# kubectl  get pods -n dev
[root@master ~]# kubectl  get pods -n dev
NAME                  READY   STATUS             RESTARTS         AGE
pod-base              1/2     CrashLoopBackOff   11 (2m34s ago)   34m
pod-imagepullpolicy   1/2     CrashLoopBackOff   4 (63s ago)      2m55s
這樣就拉取成功了

3、啟動命令

command:容器啟動的命令列表,如果不指定的話,使用打包時使用的啟動命令

args:容器的啟動命令需要的參數列表

為什麼沒有busybox運行了,busybox並不是一個程式,而是類似於一個工具類的集合,他會自動的進行關閉,解決的方法就是讓其一直的運行,這就要使用command命令了

[root@master ~]# cat 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/hell0.txt;sleep 3;done;"]


#/bin/sh  命令行腳本
-c  之後的字元串作為一個命令來執行
向這個文件裡面執行時間,然後執行結束後,休息3秒鐘,這個就是一個進程一直在運行

[root@master ~]# kubectl  create -f command.yaml 
pod/pod-command created

#這樣就好了,都啟動了
[root@master ~]# kubectl get pods -n dev
NAME          READY   STATUS    RESTARTS   AGE
pod-command   2/2     Running   0          6s

#進入這個容器
[root@master ~]# kubectl  exec pod-command -n dev -it -c busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # 

這樣就成功的進入裡面去了
/ # cat /tmp/hell0.txt ,因為有這個進程的存在,就不是關閉掉

  

說明:發現command已經完成啟動命令後和傳遞參數後的功能,為什麼還需要提供一個args的選項了,用於傳遞參數呢,這其實跟docker有點關係,整個個就是覆蓋dockerfile中的entrypoint的功能

k8s拉取鏡像的時候,裡面有一個dockerfile來構建鏡像,然後k8s的command和args會替換

情況:

  1,如果command和args沒有寫,那麼用dockerfile的配置

  2、如果command寫了,但是args沒有寫,那麼用dockerfile預設配置會被忽略,執行輸入的command命令

  3、如果command沒寫,但是args寫了,那麼dockerfile中的配置的entrypoint命令會被執行,使用當前的args的參數

  4、如果都寫了,那麼dockerfile的配置被忽略,執行command並追上args參數

 4、環境變數(瞭解即可)

env向容器裡面傳入環境變數,object類型的數組

鍵值對,就是一個鍵加上一個值即可

[root@master ~]# cat pod-env.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/hell0.txt;sleep 3;done;"]
       env:
       - name: "username"
          vaule : "admin"
       - name: "password"
         vaule: "123456"


#創建Pod
[root@master ~]# kubectl create -f pod-env.yaml 
pod/pod-command created
[root@master ~]# kubectl get pods -n dev
NAME          READY   STATUS    RESTARTS   AGE
pod-command   2/2     Running   0          47s


#進入容器裡面
-c選項,只有一個容器的話,可以省略掉即可
[root@master ~]# kubectl  exec -ti pod-command -n dev -c busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # echo $username
admin
/ # echo password
password

5、埠設置(ports)

查看埠一些選項  

[root@master ~]# kubectl  explain  pod.spec.containers.ports
ports 
   name:埠的名稱,必須是在Pod中是唯一的
   containerport 容器要監聽的埠
   hostport 容器要在主機上公開的埠,如果設置,主機上只能運行容器的一個副本,會有衝突,多個Pod會占用一個埠
   hostip  要將外部埠綁定到主機的Ip(一般省略了)
   protocol  埠協議,預設是TCP,UTP,SCTP
   

 

案例:

[root@master ~]# cat pod-port.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-ports
  namespace: dev
spec:
   containers:
   - name: nginx
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
       protocol: TCP

kubectl create -f pod-port.yaml 
[root@master ~]# kubectl get pod -n dev -o wide
NAME          READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
pod-command   2/2     Running   0          27m     10.244.1.2   node2   <none>           <none>
pod-ports     1/1     Running   0          2m58s   10.244.2.2   node1   <none>           <none>

#訪問容器裡面的程式的話,需要使用Pod的ip加上容器的埠即可,進行訪問
[root@master ~]# curl 10.244.2.2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

6、資源限制(resources)

因為容器的運行需要占用一些資源,就是對某些容器進行資源的限制,如果某個資源突然大量的值記憶體的話,其他的容器就不能正常的工作了,就會出現問題

就是規定A容器只需要600M記憶體,如果大於的話,就出現了問題,進行重啟容器的操作

有2個字選項:

limits:用於限制運行時容器的最大占用資源,當容器占用的資源超過了limits會被終止,並就進行重啟(上限)

requests:用於設置容器需要的最小資源,如果環境資源不夠的話,容器無法進行啟動(下限)  

  作用:

    1、只針對cpu,記憶體

案例:

[root@master ~]# cat pod-r.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-resources
  namespace: dev
spec:
   containers:
   - name: nginx
     image: nginx:1.17.1
     resources:
        limits:
           cpu: "2"
           memory: "10Gi"
        requests:
            cpu: "1"
            memory: "10Mi"

kubectl create -f pod-r.yaml 
[root@master ~]# kubectl get pods -n dev
NAME            READY   STATUS    RESTARTS   AGE
pod-command     2/2     Running   0          41m
pod-ports       1/1     Running   0          16m
pod-resources   1/1     Running   0          113s


#規定最少需要10G才能啟動容器,但是不會進行啟動
[root@master ~]# cat pod-r.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-resources
  namespace: dev
spec:
   containers:
   - name: nginx
     image: nginx:1.17.1
     resources:
        limits:
           cpu: "2"
           memory: "10Gi"
        requests:
            cpu: "1"
            memory: "10G"
[root@master ~]# kubectl create -f pod-r.yaml 
pod/pod-resources created

#查找狀態
[root@master ~]# kubectl get pods -n dev
NAME            READY   STATUS    RESTARTS   AGE
pod-command     2/2     Running   0          44m
pod-ports       1/1     Running   0          19m
pod-resources   0/1     Pending   0          89s

#查看詳細的信息
[root@master ~]# kubectl  describe  pods pod-resources -n dev

cpu和記憶體的單位
cpu為整數
記憶體為Gi Mi  G M等形式

二:pod生命周期    

 1:概念

一般是指Pod對象從創建至終的時間範圍稱為pod的生命周期,主要包含一下過程

  1、pod創建過程

  2、運行初始化容器過程,它是容器的一種,可多可少,一定在主容器運行之前執行

  3、運行主容器過程

    容器啟動後鉤子,容器終止前鉤子,就是啟動之後的一些命令,2個特殊的點

    容器的存活性探測,就緒性探測

  4、pod終止過程

在整個生命周期中,pod會出現5中狀態

掛起(pending):apiserver,已經創建了pod資源對象,但它尚未被調度,或者仍然處於下載鏡像的過程中;創建一個pod,裡面有容器,需要拉取

運行中(running):pod已經被調度至某一個節點,並且所有的容器都已經被kubelet創建完成

成功(succeeded):Pod中的所有容器都已經被成功終止,並且不會被重啟;就是運行一個容器,30秒後,列印,然後退出

失敗(failed):所有容器都已經被終止,但至少有一個容器終止失敗,即容器返回非0的退出狀態

未知(unknown):apiserver無法正常的獲取到pod對象的狀態信息,通常由網路通信失敗所導致的

2:pod創建和終止

pod的創建過程:

都監聽到apiserver上面了 

開始創建就已經返回一個信息了,給etcd了,

scheduler:開始為pod分配主機,將結果告訴apiserver

node節點上面發現有pod調度過來,調用docker啟動容器,並將結果告訴apiserver

apiserver將接收的信息pod狀態信息存入etcd中

pod的終止過程:

service就是Pod的代理,訪問pod通過service即可

 向apiserver發送一個請求,apiserver更新pod的狀態,將pod標記為terminating狀態,kubelet監聽到為terminating,就啟動關閉pod過程

3:初始化容器

主要做的就是主容器的前置工作(環境的準備),2個特點

  1、初始化容器必須運行在完成直至結束,若某初始化容器運行失敗了,那麼k8s需要重啟它知道成功完成

  2、初始化容器必須按照定義的順序執行,當且僅當前一個成功了,後面的一個才能運行,否則不運行

初始化容器應用場景:

  提供主容器進行不具備工具程式或自定義代碼

  初始化容器需要先於應用容器串列啟動並運行成功,因此,可應用容器的啟動直至依賴的條件得到滿足

      nginx,mysql,redis,  先連mysql,不成功,則會一直處於連接, 一直連成功了,就會去連接redis,這2個條件都滿足了,nginx這個主容器就會啟動了

測試:

規定mysql 192.168.109.201  redis 192.168.109.202

 

[root@master ~]# cat pod-init.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-init
   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
     command: ['sh','-c','util ping 192.168.109.201 -c 1;do echo waiting for mysql;sleep 2;done;']
   - name: test-redis
     image: busybox:1.30
     command: ['sh','-c','util ping 192.168.109.202 -c 1;di echo waiting for redis;sleep 2;done']
#由於沒有地址,所以的話,初始化失敗
[root@master ~]# kubectl get pods -n dev
NAME       READY   STATUS                  RESTARTS      AGE
pod-init   0/1     Init:CrashLoopBackOff   3 (27s ago)   83s

#添加地址,第一個初始化容器就能運行了
[root@master ~]# ifconfig  ens33:1 192.168.109.201 netmask 255.255.255.0 up

#再次添加地址,第二個初始化容器也能運行了
[root@master ~]# ifconfig  ens33:2 192.168.109.202 netmask 255.255.255.0 up
[root@master ~]# kubectl get pods -n dev -w
NAME       READY   STATUS     RESTARTS   AGE
pod-init   0/1     Init:0/2   0          6s
pod-init   0/1     Init:1/2   0          13s
pod-init   0/1     Init:1/2   0          14s
pod-init   0/1     PodInitializing   0          27s
pod-init   1/1     Running           0          28s

主容器就運行成功了

4:主容器鉤子函數

就是主容器上面的一些點,能夠允許用戶使用一些代碼

2個點  

post start:容器啟動後鉤子,容器啟動之後會立即的執行,成功了,則啟動,否則,會重啟

prestop:容器終止前鉤子,容器在刪除之前執行,就是terming狀態,會阻塞容器刪除,執行成功了,就會刪除

1、鉤子處理器(三種方式定義動作)

exec命令:在容器內執行一次命令

用的最多的exec方式

lifecycle:
   podstart:
     exec:
       command:
        - cat
        - /tmp/healthy 

tcpsocket:在當前容器內嘗試訪問指定socket,在容器內部訪問8080埠

lifecycle:
   podstart:
      tcpsocket:
         port:8080   #會嘗試連接8080埠  

httpget:在當前容器中向某url發起http請求

lifecycle:
   poststart:
    httpGet:
     path: url地址
     port:   80
     host: 主機地址
     schme: HTTP 支持的協議  

案例:

apiVersion: v1
kind: Pod
metadata:
   name: pod-exec
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80  #容器內部的埠,一般是service將公開pod埠,將pod埠映射到主機上面
     lifecycle:
       postStart:
         exec:   ###在啟動的時候,執行一個命令,修改預設網頁內容
            command: ["/bin/sh","-c","echo poststart > /usr/share/nginx/html/index.html"]
       preStop:
          exec:    ###停止容器的時候,-s傳入一個參數,優雅的停止nginx服務
             command: ["/usr/sbin/nginx","-s","quit"]

[root@master ~]# kubectl create -f pod-exec.yaml 
pod/pod-exec created
[root@master ~]# kubectl get pods -n dev -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
pod-exec   1/1     Running   0          53s   10.244.1.7   node1   <none>           <none>
pod-init   1/1     Running   0          27m   10.244.1.6   node1   <none>           <none>

訪問一下pod裡面容器的服務即可
格式為pod的ip+容器的埠
[root@master ~]# curl 10.244.1.7:80
poststart

5:容器探測  

主容器探測:用於檢測容器中的應用實例是否正常的工作,是保障業務可用性的一種傳統機制,如果經過了探測,實例的狀態不符合預期,那麼k8s就會把問題的實例摘除,不承擔業務的流量,k8s提供了2種探針來實現容器探測,

分別是:

  liveness probes:存活性探針,用於檢測應用實例,是否處於正常的運行狀態,如果不是,k8s會重啟容器;用於決定是否重啟容器

  readiness probes:就緒性探針,用於檢測應用實例是否可以接受請求,如果不能,k8s不會轉發流量;nginx需要讀取很多的web文件,在讀取的過程中,service認為nginx已經成功了,如果有個請求的話,那麼就無法提供了服務;所以就不會將請求轉發到這裡了

就是一個service來代理許多的pod,請求來到了pod,如果有一個pod出現了問題,如果沒有了探針的話,就會出現了問題

作用

  1、找出這些出了問題的pod

  2、服務是否已經準備成功了

三種探測方式:

exec:退出碼為0,則正常

livenessProbe
   exec:
     command:
       - cat
       - /tmp/healthy

tcpsocket:

livenessProbe:
    tcpSocket:
       port: 8080

httpget:

返回的狀態碼在200個399之間,則認為程式正常,否則不正常

livenessProbe:
    httpGet:
      path: /  url地址
       port:80  主機埠
       host:主機地址
       scheme:http
      

案例:

exec案例:

[root@master ~]# cat pod-live-exec.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-liveness-exec
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
     livenessProbe:
        exec:
          command: ["/bin/cat","/tmp/hello.txt"]   #由於沒有這個文件,所以就會一直進行重啟

#出現了問題,就會處於一直重啟的狀態
[root@master ~]# kubectl get pods -n dev
NAME                READY   STATUS    RESTARTS      AGE
pod-exec            1/1     Running   0             38m
pod-init            1/1     Running   0             65m
pod-liveness-exec   1/1     Running   2 (27s ago)   97s

#查看pod的詳細信息
[root@master ~]# kubectl describe  pod -n dev pod-liveness-exec 
Events:
  Type     Reason     Age                 From               Message
  ----     ------     ----                ----               -------
  Normal   Scheduled  2m13s               default-scheduler  Successfully assigned dev/pod-liveness-exec to node2
  Normal   Pulling    2m12s               kubelet            Pulling image "nginx:1.17.1"
  Normal   Pulled     2m                  kubelet            Successfully pulled image "nginx:1.17.1" in 12.606s (12.606s including waiting)
  Normal   Created    33s (x4 over 2m)    kubelet            Created container main-container
  Normal   Started    33s (x4 over 2m)    kubelet            Started container main-container
  Warning  Unhealthy  33s (x9 over 113s)  kubelet            Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory
  Normal   Killing    33s (x3 over 93s)   kubelet            Container main-container failed liveness probe, will be restarted
  Normal   Pulled     33s (x3 over 93s)   kubelet            Container image "nginx:1.17.1" already present on machine

#一直在重啟
[root@master ~]# kubectl get pods -n dev
NAME                READY   STATUS             RESTARTS      AGE
pod-exec            1/1     Running            0             39m
pod-init            1/1     Running            0             66m
pod-liveness-exec   0/1     CrashLoopBackOff   4 (17s ago)   2m57s


#一個正常的案例
[root@master ~]# cat pod-live-exec.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-liveness-exec
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
     livenessProbe:
        exec:
          command: ["/bin/ls","/tmp/"]
[root@master ~]# kubectl create -f pod-live-exec.yaml 
pod/pod-liveness-exec created

#就不會一直重啟了
[root@master ~]# kubectl get pods -n dev
NAME                READY   STATUS    RESTARTS   AGE
pod-exec            1/1     Running   0          42m
pod-init            1/1     Running   0          69m
pod-liveness-exec   1/1     Running   0          56s

#查看詳細的信息,發現沒有錯誤

  

tcpsocket:  

[root@master ~]# cat tcp.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-liveness-tcp
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
     livenessProbe:
        tcpSocket:
           port: 8080    訪問容器的8080埠


kubectl create -f tcp.yaml
#發現一直在進行重啟,沒有訪問到8080埠
[root@master ~]# kubectl get pods -n dev
NAME               READY   STATUS    RESTARTS      AGE
pod-liveness-tcp   1/1     Running   5 (72s ago)   3m43s

#查看詳細的信息
[root@master ~]# kubectl describe  pod -n dev pod-liveness-tcp  
Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Scheduled  3m22s                  default-scheduler  Successfully assigned dev/pod-liveness-tcp to node2
  Normal   Pulled     112s (x4 over 3m22s)   kubelet            Container image "nginx:1.17.1" already present on machine
  Normal   Created    112s (x4 over 3m22s)   kubelet            Created container main-container
  Normal   Started    112s (x4 over 3m22s)   kubelet            Started container main-container
  Normal   Killing    112s (x3 over 2m52s)   kubelet            Container main-container failed liveness probe, will be restarted
  Warning  Unhealthy  102s (x10 over 3m12s)  kubelet            Liveness probe failed: dial tcp 1

正常的案例:

[root@master ~]# cat tcp.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-liveness-tcp
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
     livenessProbe:
        tcpSocket:
           port: 80 

#查看效果,沒有任何的問題
[root@master ~]# kubectl describe  pods -n dev  pod-liveness-tcp 
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  27s   default-scheduler  Successfully assigned dev/pod-liveness-tcp to node2
  Normal  Pulled     28s   kubelet            Container image "nginx:1.17.1" already present on machine
  Normal  Created    28s   kubelet            Created container main-container
  Normal  Started    28s   kubelet            Started container main-container

httpget

[root@master ~]# cat tcp.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-liveness-http
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
     livenessProbe:
        httpGet:
           scheme: HTTP
           port: 80
           path: /hello   # http://127.0.0.1:80/hello


#發現一直在進行重啟的操作
[root@master ~]# kubectl describe pod  -n dev  pod-liveness-http 
[root@master ~]# kubectl get pods -n dev
NAME                READY   STATUS    RESTARTS      AGE
pod-liveness-http   1/1     Running   1 (17s ago)   48s
pod-liveness-tcp    1/1     Running   0             4m21s

#正常的情況
[root@master ~]# cat tcp.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-liveness-http
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
     livenessProbe:
        httpGet:
           scheme: HTTP
           port: 80
           path: /
[root@master ~]# kubectl describe  pods -n dev pod-liveness-http 
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  21s   default-scheduler  Successfully assigned dev/pod-liveness-http to node1
  Normal  Pulled     22s   kubelet            Container image "nginx:1.17.1" already present on machine
  Normal  Created    22s   kubelet            Created container main-container
  Normal  Started    22s   kubelet            Started container main-container

容器探測補充

[root@master ~]# kubectl explain pod.spec.containers.livenessProbe
initialDelaySeconds	<integer>  容器啟動後等待多少秒執行第一次探測
timeoutSeconds	<integer>   探測超時時間,預設是1秒,最小1秒
periodSeconds	<integer>   執行探測的頻率,預設是10秒,最小是1秒
failureThreshold	<integer>    連續探測失敗多少次後才被認為失敗,預設是3,最小值是1
successThreshold	<integer>  連續探測成功多少次後才被認定為成功,預設是1

案例:

6:重啟策略

就是容器探測出現了問題,k8s就會對容器所在的Pod進行重啟,這個由pod的重啟策略決定的,pod的重啟策略有三種

  always:容器失效時,自動重啟該容器,預設值

  onfailure:容器終止運行且退出碼不為0時重啟,異常終止

  never:不論狀態為何,都不重啟該容器

重啟策略適用於Pod對象中的所有容器,首次需要重啟的容器,將在需要時立即重啟,隨後再次需要重啟的操作由kubelet延遲一段時間進行,且反覆的重啟操作的延遲時長為10S,20S,300s為最大的延遲時長

案例:

apiVersion: v1
kind: Pod
metadata:
   name: restart-pod
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
     - name: nginx-port
       containerPort: 80
     livenessProbe:
        httpGet:
           scheme: HTTP
           port: 80
           path: /hello   # http://127.0.0.1:80/hello
   restartPolicy: Always

#會一直進行重啟

#改為Never
容器監聽失敗了,就不會進行重啟,直接停止了
狀態是完成的狀態,
[root@master ~]# kubectl get pods -n dev
NAME                READY   STATUS      RESTARTS      AGE
pod-liveness-http   1/1     Running     1 (16h ago)   16h
pod-liveness-tcp    1/1     Running     1 (22m ago)   16h
restart-pod         0/1     Completed   0             41s

[root@master ~]# kubectl describe  pod -n dev  restart-pod 

Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  84s                default-scheduler  Successfully assigned dev/restart-pod to node1
  Normal   Pulled     84s                kubelet            Container image "nginx:1.17.1" already present on machine
  Normal   Created    84s                kubelet            Created container main-container
  Normal   Started    84s                kubelet            Started container main-container
  Warning  Unhealthy  55s (x3 over 75s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing    55s                kubelet            Stopping container main-container

三:pod調度

預設的情況下,一個Pod在哪個節點上面運行,是有scheduler組件採用相應的演算法計算出來,這個過程是不受人工控制的,但是在實際中,這不滿足需求,需要控制pod在哪個節點上面運行,這個就需要調度的規則了,四大類調度的方式

自動調度:經過演算法自動的調度

定向調度:通過nodename屬性(node的名字),nodeselector(標簽)

親和性調度:nodeAffinity(node的親和性),podAffinity(pod的親和性),podANtiAffinity(這個就是跟Pod的親和性差,所以就去相反的一側)

污點(容忍調度):站在node節點上面完成的,有一個污點,別人就不能在;容忍站在pod上面來說的,可以在node上面的污點進行就是容忍調度

1:定向調度

指定的是pod聲明nodename,或者nodeselector,依次將pod調度到指定的node節點上面,這個是強制性的,即使node不存在,也會被調度,只不過是pod運行失敗而已

1、nodename

強制的調度,直接跳過了scheduler的調度邏輯,直接將pod調度到指定的節點上面

[root@master ~]# cat pod-nodename.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-nodename
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
     ports:
   nodeName: node1

[root@master ~]# kubectl create  -f pod-nodename.yaml 
pod/pod-nodename created
#運行在node1上面運行
[root@master ~]# kubectl get pods -n dev -o wide
NAME                READY   STATUS    RESTARTS      AGE   IP            NODE    NOMINATED NODE   READINESS GATES
pod-liveness-http   1/1     Running   1 (16h ago)   17h   10.244.2.8    node1   <none>           <none>
pod-liveness-tcp    1/1     Running   1 (42m ago)   17h   10.244.1.7    node2   <none>           <none>
pod-nodename        1/1     Running   0             41s   10.244.2.10   node1   <none>           <none>

#將節點改為不存在的,pod會失敗而已
[root@master ~]# kubectl get pods -n dev -o wide
NAME                READY   STATUS    RESTARTS      AGE   IP           NODE    NOMINATED NODE   READINESS GATES
pod-liveness-http   1/1     Running   1 (16h ago)   17h   10.244.2.8   node1   <none>           <none>
pod-liveness-tcp    1/1     Running   1 (43m ago)   17h   10.244.1.7   node2   <none>           <none>
pod-nodename        0/1     Pending   0             9s    <none>       node3   <none>           <none>  

2、nodeselector

看的就是節點上面的標簽,標簽選擇器,強制性的

[root@master ~]# kubectl label  nodes node1 nodeenv=pro
node/node1 labeled
[root@master ~]# kubectl label  nodes node2 nodeenv=test
node/node2 labeled
[root@master ~]# cat pod-selector.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-select
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
   nodeSelector:
       nodeenv: pro

[root@master ~]# kubectl get pods -n dev -o wide
NAME                READY   STATUS    RESTARTS      AGE     IP            NODE    NOMINATED NODE   READINESS GATES
pod-liveness-http   1/1     Running   1 (17h ago)   17h     10.244.2.8    node1   <none>           <none>
pod-liveness-tcp    1/1     Running   1 (51m ago)   17h     10.244.1.7    node2   <none>           <none>
pod-select          1/1     Running   0             2m16s   10.244.2.11   node1   <none>           <none>

#不存在的標簽
改為pr1,調度失敗
[root@master ~]# kubectl get pods -n dev
NAME                READY   STATUS    RESTARTS      AGE
pod-liveness-http   1/1     Running   1 (17h ago)   17h
pod-liveness-tcp    1/1     Running   1 (51m ago)   17h
pod-select          0/1     Pending   0             5s

2:親和性調度

上面的問題,就是強制性的調度,就是如果沒有節點的話,Pod就會調度失敗

就是聲明一個調度的節點,如果找到了,就調度,否則,找其他的;這個就是親和性

  nodeAffinity:node的親和性,以node為目標,主要就是標簽()

  podAffinity:pod的親和性,以pod為目標,就是以正在運行的pod為目標,就是一個web的pod需要和一個mysql的pod在一起,向其中一個打個標簽,另外一個就會來找他

  podAntAffinity:pod的反親和性,以pod為目標,討厭和誰在一起,就選擇其他的

 

場景的說明:

如果2個應用時頻繁交互,那麼就有必要利用親和性讓2個應用儘可能的靠近,這樣就能減少因為網路通信帶來的性能損耗了,調度到了pod1上面就都在一個節點上面,通信的性能就損耗減少了

 

反親和性的應用:

當應用的採用多副本部署時,有必要採用反親和性讓各個應用實列打散分佈在各個node上面,這樣就能提高服務的高可用性

應用的功能是相同的,使用反親和性,都分佈在不同的節點上面,高可用性,就是壞了一個節點,其他的節點也能正常的提供工作

參數:

[root@master ~]# kubectl explain pod.spec.affinity.nodeAffinity

requiredDuringSchedulingIgnoredDuringExecution  node節點必須滿足的指定的所有規劃才可以,相當於硬限制
   nodeSelectorTerms:節點選擇列表
       matchFields:按節點欄位列出的節點選擇器要求列表
       matchExpressions  按節點標簽列出的節點選擇器要求列表(標簽)
         key:
         vaules:
         operator:關係符,支持in, not exists

如果有符合的條件,就調度,沒有符合的條件就調度失敗

preferredDuringSchedulingIgnoredDuringExecution 	<NodeSelector>  軟限制,優先找這些滿足的節點
    preference    一個節點選擇器,以相應的權重相關聯
            matchFields:按節點欄位列出的節點選擇器要求列表
            matchExpressions  按節點標簽列出的節點選擇器要求列表  
                 key:鍵
                 vaules:
                 operator:
    weight:傾向權重,1~100  ##就是傾向調度   
 

如果找不到的話,就從其他的節點調度上去

關係符
 - key:nodedev   匹配存在標簽的key為noddev的節點
    operator: exists  
- key:  nodedev   匹配標簽的key為nodedev,且vaule是xxx或者yyy的節點
   operator:in
   vaules:['xxx','yyy']    

  

1、nodeAffinity

node的親和性,2大類,硬限制,軟限制,節點上面的標簽作為選擇

[root@master ~]# cat pod-aff-re.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-aff
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
   affinity:
       nodeAffinity:   ##親和性設置
          requiredDuringSchedulingIgnoredDuringExecution:  #設置node親和性,硬限制
             nodeSelectorTerms:     
                  matchExpressions:     匹配nodeenv的值在[xxx,yyy]中的標簽
                    - key: nodeenv
                      operator: In
                      vaules: ["xxx","yyy"] 
[root@master ~]# kubectl create -f pod-aff-re.yaml 
pod/pod-aff created
[root@master ~]# kubectl get pod -n dev
NAME                READY   STATUS    RESTARTS      AGE
pod-aff             0/1     Pending   0             23s
pod-liveness-http   1/1     Running   1 (17h ago)   18h
pod-liveness-tcp    1/1     Running   1 (94m ago)   18h
pod-select          0/1     Pending   0             43m

#調度失敗

#值改為pro,就能在node1上面調度了
[root@master ~]# kubectl create -f pod-aff-re.yaml 
pod/pod-aff created
[root@master ~]# kubectl get pods -n dev
NAME                READY   STATUS    RESTARTS      AGE
pod-aff             1/1     Running   0             5s
pod-liveness-http   1/1     Running   1 (17h ago)   18h
pod-liveness-tcp    1/1     Running   1 (96m ago)   18h
pod-select          0/1     Pending   0             45m

  

軟限制

#軟限制
[root@master ~]# cat pod-aff-re.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: pod-aff
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
   affinity:
     nodeAffinity:
       preferredDuringSchedulingIgnoredDuringExecution:   #軟限制
       - weight: 1    
         preference:
            matchExpressions:
            - key: nodeenv
              operator: In
              values: ["xxx","yyy"] 

#直接調度在node2上面了
[root@master ~]# kubectl get pods -n dev -o wide
NAME                READY   STATUS    RESTARTS       AGE   IP           NODE     NOMINATED NODE   READINESS GATES
pod-aff             1/1     Running   0              41s   10.244.1.9   node2    <none>           <none>
pod-liveness-http   1/1     Running   1 (17h ago)    18h   10.244.2.8   node1    <none>           <none>
pod-liveness-tcp    1/1     Running   1 (102m ago)   18h   10.244.1.7   node2    <none>           <none>
pod-select          0/1     Pending   0              50m   <none>       <none>   <none>           <none>

 

註意:

如果同時定義了nodeSelector和nodeAffinity,那麼必須滿足這2個條件,pod才能在指定的node上面運行
如果nodeaffinity指定了多個nodeSelectorTerms,那麼只要有一個能夠匹配成功即可
如果一個nodeSelectorTerms中有多個matchExpressions,則一個節點必須滿足所有的才能匹配成功
如果一個Pod所在node在pod運行期間標簽發生了改變,不符合該pod的節點親和性需求,則系統將忽略此變化

 這個調度就是只在調度的時候生效,所以的話,就是如果調度成功後,標簽發生了變化,不會對這個pod進行什麼樣的變化

2、podAffinitly

就是以正在運行的pod為參照,硬限制和軟限制

kubectl explain pod.spec.affinity.podAffinity

requiredDuringSchedulingIgnoredDuringExecution   硬限制
    namespace:指定參照pod的名稱空間,如果不指定的話,預設的參照物pod就跟pod一眼的
    topologkey:調度的作用域,靠近到節點上,還是網段上面,操作系統了
                        ###hostname的話,就是以node節點為區分的範圍,調度到node1的節點上面
                                os的話,就是以操作系統為區分的,調度到跟pod1操作系統上一樣的
     labeSelector:標簽選擇器
          matchExpressions: 按節點列出的節點選擇器要求列表
               key:
               vaules:
               operator:
          matchLbales:   指多個matchExpressions映射的內容
preferredDuringSchedulingIgnoredDuringExecution  軟限制
    namespace:指定參照pod的名稱空間,如果不指定的話,預設的參照物pod就跟pod一眼的
    topologkey:調度的作用域,靠近到節點上,還是網段上面,操作系統了
                        ###hostname的話,就是以node節點為區分的範圍,調度到node1的節點上面
                                os的話,就是以操作系統為區分的,調度到跟pod1操作系統上一樣的
     labeSelector:標簽選擇器
          matchExpressions: 按節點列出的節點選擇器要求列表
               key:
               vaules:
               operator:
          matchLbales:   指多個matchExpressions映射的內容
    weight:傾向權重1~100

 

案例:

軟親和性:

apiVersion: v1
kind: Pod
metadata:   #元數據的信息
   name: pods-1   #pod的名字
   namespace: dev   #名稱空間
spec:   
  containers:   #容器
    - name: my-tomcat   #鏡像的名字
      image: tomcat    #拉取的鏡像
      imagePullPolicy: IfNotPresent   #策略為遠程和本地都有
  affinity:
     podAffinity:   #pod的親和性
       preferredDuringSchedulingIgnoredDuringExecution:   #軟限制
       - weight: 1    #權重為1
         podAffinityTerm:    #定義了具體的pod親和性的條件
          labelSelector:    #標簽選擇器
             matchExpressions:   #一個或者多個標簽匹配式
                 - key: user   #標簽的鍵
                   operator: In   
                   values:    #標簽的值
                      - "qqqq"
          topologyKey: kubernetes.io/hostname   #按照主機進行區分


就是這個pod會被調度到節點上面有pod,並且標簽為user=qqqq這個節點上面去

 

硬親和性:

apiVersion: v1
kind: Pod
metadata:
   name: pod-5
   namespace: dev
spec:
  containers:
    - name: my-tomcat
      image: tomcat
      imagePullPolicy: IfNotPresent
  affinity:
     podAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:  #軟限制
         - labelSelector:   #標簽選擇器
             matchExpressions:    #匹配列表
                 - key: user   
                   operator: In
                   values: ["qqqq"]   
           topologyKey: kubernetes.io/hostname    #按照主機來進行劃分

  

  

3、反親和性

就是不在這個pod上面進行調度,在另外的一個pod上面進行調度即可

案例:

[root@master mnt]# cat podaff.yaml 
apiVersion: v1
kind: Pod
metadata:
   name: podaff
   namespace: dev
spec:
   containers:
   - name: main-container
     image: nginx:1.17.1
   affinity:
     podAntiAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:
       - labelSelector:
           matchExpressions:
           - key: podenv
             operator: In
             values: ["pro"]
         topologyKey: kubernets.io/hostname

發現在node2節點上面創建了
[root@master mnt]# kubectl get pods -n dev -o wide
NAME         READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
pod-podaff   1/1     Running   0          61m     10.244.2.14   node1   <none>           <none>
podaff       1/1     Running   0          2m57s   10.244.1.12   node2   <none>           <none>

 3:污點(taints)

 前面都是站在pod的角度上面來進行配置的屬性,那麼就是可以站在node的節點上面,是否允許這些pod調度過來,這些在node上面的信息就是被稱為了污點

就是一個拒絕的策略

污點作用:

  可以將拒絕Pod調度過來

  甚至還可以將已經存在的pod趕出去

污點的格式:

key=value:effect

key和value:是污點的標簽,effect描述污點的作用

effect三種的選項為:

  PreferNoSchedule:k8s儘量避免把Pod調度到具有該污點的node上面,除非沒有其他的節點可以調度了

  NoSchedule:k8s不會把pod調度到該具有污點node上面,但不會影響當前node上已經存在的pod

  NoExecue:k8s將不會把Pod調度該具有污點的node上面,同時也會將node已經存在的Pod驅離,一個pod也沒有了

 設置污點:

#設置污點
[root@master mnt]# kubectl taint  nodes node1 key=vaule:effect

#去除污點
[root@master mnt]# kubectl taint  nodes node1 key:effect-

#去除所有的污點
[root@master mnt]# kubectl taint  nodes node1 key-

  

案例:

準備節點node1,先暫時停止node2節點
為node1節點一個污點,tag=heima:PreferNoSchedule;  然後創建pod1
修改node1節點設置一個污點;tag=heima:NoSchedule: 然後創建pod2,不在接收新的pod,原來的也不會離開
修改node1節點設置一個污點;tag=heima:NoExecute;然後創建pod3,pod3也不會被創建,都沒有了pod了

#關掉node2節點即可

#設置node1污點
[root@master mnt]# kubectl taint  nodes node1 tag=heima:PreferNoSchedule
node/node1 tainted
#查看污點
[root@master mnt]# kubectl describe  nodes -n dev node1| grep heima
Taints:             tag=heima:PreferNoSchedule

#第一個pod可以進行運行
[root@master mnt]# kubectl run taint1 --image=nginx:1.17.1 -n dev
pod/taint1 created
[root@master mnt]# kubectl  get pods -n dev 
NAME         READY   STATUS        RESTARTS   AGE
pod-podaff   1/1     Running       0          90m
podaff       1/1     Terminating   0          31m
taint1       1/1     Running       0          6s

#修改node1的污點
[root@master mnt]# kubectl taint  nodes node1 tag=heima:PreferNoSchedule-
node/node1 untainted

[root@master mnt]# kubectl taint  nodes node1 tag=heima:NoSchedule
node/node1 tainted

#第一個正常的運行,第二個運行不了
[root@master mnt]# kubectl run taint2 --image=nginx:1.17.1 -n dev
pod/taint2 created
[root@master mnt]# kubectl get pods -n dev
NAME         READY   STATUS        RESTARTS   AGE
pod-podaff   1/1     Running       0          94m
podaff       1/1     Terminating   0          35m
taint1       1/1     Running       0          3m35s
taint2       0/1     Pending       0          3s

#第三種污點的級別
[root@master mnt]# kubectl taint  nodes node1 tag=heima:NoSchedule-
node/node1 untainted
設置級別
[root@master mnt]# kubectl taint  nodes node1 tag=heima:NoExecute
node/node1 tainted
#新的pod也會不能創建了
[root@master mnt]# kubectl run taint3 --image=nginx:1.17.1 -n dev
pod/taint3 created
[root@master mnt]# kubectl get pods -n dev
NAME     READY   STATUS        RESTARTS   AGE
podaff   1/1     Terminating   0          39m
taint3   0/1     Pending       0          4s

  

為什麼創建pod的時候,不能往master節點上面進行調度了,因為有污點的作用

4、容忍

 容忍就是忽略,node上面有污點,但是pod上面有容忍,進行忽略,可以進行調度

 案例:

apiVersion: v1
kind: Pod
metadata:
   name: pod-aff
   namespace: dev
spec:
   containers:    
   - name: main-container
     image: nginx:1.17.1
   tolerations:     #添加容忍
   - key: "tag"    #要容忍的key
     operator: "Equal"     #操作符
     values: "heima"            #容忍的污點
     effect: "NoExecute"    #添加容忍的規劃,這裡必須和標記的污點規則相同

#首先創建一個沒有容忍的pod,看能不能進行創建
#無法進行創建
[root@master mnt]# kubectl get pods -n dev
NAME      READY   STATUS        RESTARTS   AGE
pod-aff   0/1     Pending       0          6s
podaff    1/1     Terminating   0          55m

#有容忍的創建
[root@master mnt]# kubectl create -f to.yaml 
pod/pod-aff created
[root@master mnt]# kubectl get pods -n dev
NAME      READY   STATUS        RESTARTS   AGE
pod-aff   1/1     Running       0          3s
podaff    1/1     Terminating   0          57m

  

容忍的詳細信息

Key:對應的容忍的污點的值,空意味著匹配的所有的鍵
value:對應著容忍的污點的值
operator:key-value的運算符,支持Equal和Exists(預設),對於所有的鍵進行操作,跟值就沒有關係了
effect:對應的污點的effect,空意味著匹配所有的影響
tolerationSeconds    容忍的時間,當effect為NoExecute時生效,表示pod在node上停留的時間

  

 四:pod控制器

1、pod的控制器的介紹

1:pod的分類:

  自主式pod,k8s直接創建出來的pod,這種pod刪除後就沒有了。也不會重建

  控制器創建的pod,通過控制器創建的Pod,這種pod刪除後,還會自動重建

作用

 pod控制器管理pod的中間層,使用了pod控制器後,我們需要告訴pod控制器,想要多少個pod即可,他會創建滿足條件的pod並確保pod處於用戶期望的狀態,如果pod運行中出現了故障,控制器會基於策略重啟或者重建pod

 

2:控制器類型

replicaSet:保證指定數量的pod運行支持數量變更

deployment:通過控制replicaSet來控制pod,支持滾動升級,版本回退的功能

horizontal pod autoscaler:可以根據集群負載均衡自動調整pod的數量

 

 2:控制器的詳細介紹

replicaSet(rs)

:創建的數量的Pod能夠正常的運行,會持續監聽pod的運行狀態

支持對pod數量的擴容縮容,

案例:副本數量

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: pc-replicaset   #pod控制器的名字
  namespace: dev  
spec:
   replicas: 3   #創建的pod的數量,
   selector:   #pod標簽選擇器規則,選擇app=nginx-pod的pod的標簽用來進行管理,用來管理pod上面有相同的標簽
     matchLabels:    #標簽選擇器規則
      app: nginx-pod  
   template:   副本,也就是創建pod的模版
     metadata:    #pod元數據的信息
       labels:    #pod上面的標簽
         app: nginx-pod    
     spec:    
       containers:   #容器裡面的名字
         - name: nginx   
           image: nginx:1.17.1  


#查看控制器
[root@master ~]# kubectl get rs -n dev
NAME            DESIRED   CURRENT   READY   AGE
pc-replicaset   3         3         3       70s
RESIRED 期望的pod數量
CURRENT:當前有幾個
READY:準備好提供服務的有多少

#查看pod
[root@master ~]# kubectl get rs,pods -n dev
NAME                            DESIRED   CURRENT   READY   AGE
replicaset.apps/pc-replicaset   3         3         3       2m31s

NAME                      READY   STATUS    RESTARTS      AGE
pod/pc-replicaset-448tq   1/1     Running   0             2m31s
pod/pc-replicaset-9tdhd   1/1     Running   0             2m31s
pod/pc-replicaset-9z64w   1/1     Running   0             2m31s
pod/pod-pod-affinity      1/1     Running   1 (47m ago)   12h  

案例2:實現擴縮容的pod

#編輯yaml文件 edit
[root@master ~]# kubectl edit rs -n dev pc-replicaset 
replicaset.apps/pc-replicaset edited
[root@master ~]# kubectl get pods -n dev
NAME                  READY   STATUS    RESTARTS      AGE
pc-replicaset-448tq   1/1     Running   0             10m
pc-replicaset-9tdhd   1/1     Running   0             10m
pc-replicaset-9z64w   1/1     Running   0             10m
pc-replicaset-q6ps9   1/1     Running   0             94s
pc-replicaset-w5krn   1/1     Running   0             94s
pc-replicaset-zx8gw   1/1     Running   0             94s
pod-pod-affinity      1/1     Running   1 (55m ago)   12h
[root@master ~]# kubectl get rs -n dev
NAME            DESIRED   CURRENT   READY   AGE
pc-replicaset   6         6         6       10m


#第二種方式
[root@master ~]# kubectl scale  rs -n dev pc-replicaset --replicas=2 -n dev
replicaset.apps/pc-replicaset scaled
[root@master ~]# kubectl get rs,pod -n dev 
NAME                            DESIRED   CURRENT   READY   AGE
replicaset.apps/pc-replicaset   2         2         2       12m

NAME                      READY   STATUS    RESTARTS      AGE
pod/pc-replicaset-448tq   1/1     Running   0             12m
pod/pc-replicaset-9tdhd   1/1     Running   0             12m
pod/pod-pod-affinity      1/1     Running   1 (57m ago)   12h

 

案例3、鏡像的版本的升級

#編輯鏡像的版本
[root@master ~]# kubectl edit rs -n dev pc-replicaset 
replicaset.apps/pc-replicaset edited
[root@master ~]# kubectl get rs -n dev pc-replicaset -o wide
NAME            DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR
pc-replicaset   2         2         2       15m   nginx        nginx:1.17.2   app=nginx-pod

#命令來進行編輯,但是一般使用edit來進行編輯即可
[root@master ~]# kubectl get rs -n dev -o wide
NAME            DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR
pc-replicaset   2         2         2       17m   nginx        nginx:1.17.1   app=nginx-pod

  

案例4、刪除replicaSet

就是先刪除pod再來刪除控制器

#文件來進行刪除
root@master ~]# kubectl delete -f replicas.yaml 
replicaset.apps "pc-replicaset" deleted
[root@master ~]# kubectl get rs -n dev
No resources found in dev namespace.

#命令來進行刪除
[root@master ~]# kubectl delete rs -n dev pc-replicaset 
replicaset.apps "pc-replicaset" deleted
[root@master ~]# kubectl get rs -n dev
No resources found in dev namespace.  

deployment(deploy)  

支持所有的RS的功能

 

 

保留歷史的版本,就是可以進行回退版本

滾動更新的策略

 更新策略:

案例:創建deployment

[root@master ~]# cat deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
   name: pc-deployment
   namespace: dev
spec:
   replicas: 3
   selector:
      matchLabels:
       app: nginx-pod
   template:
      metadata:
         labels:
           app: nginx-pod
      spec:
        containers:
        - name: nginx
          image: nginx:1.17.1
[root@master ~]# kubectl get deploy -n dev
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
pc-deployment   3/3     3            3           53s

update:最新版本的pod數量
available:當前可用的pod的數量

#所以也會創建一個rs出來
[root@master ~]# kubectl get rs -n dev
NAME                       DESIRED   CURRENT   READY   AGE
pc-deployment-6cb555c765   3         3         3       2m9s  
擴縮容:

基本上和之前的一樣的操作

#命令來進行編輯
[root@master ~]# kubectl scale deployment -n dev pc-deployment --replicas=5 
deployment.apps/pc-deployment scaled
[root@master ~]# kubectl get pods -n dev
NAME                             READY   STATUS    RESTARTS      AGE
pc-deployment-6cb555c765-8qc9g   1/1     Running   0             4m52s
pc-deployment-6cb555c765-8xss6   1/1     Running   0             4m52s
pc-deployment-6cb555c765-m7wdf   1/1     Running   0             4s
pc-deployment-6cb555c765-plkbf   1/1     Running   0             4m52s
pc-deployment-6cb555c765-qh6gk   1/1     Running   0             4s
pod-pod-affinity                 1/1     Running   1 (81m ago)   13h

#編輯文件
[root@master ~]# kubectl edit deployments.apps -n dev pc-deployment 
deployment.apps/pc-deployment edited
[root@master ~]# kubectl get pods -n dev
NAME                             READY   STATUS    RESTARTS      AGE
pc-deployment-6cb555c765-8qc9g   1/1     R

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 前言 Spacesniffer 是一個免費的文件掃描工具,通過使用樹狀圖可視化佈局,可以立即瞭解大文件夾的位置,幫助用戶處理找到這些文件夾 當前系統C盤空間 清理後系統C盤空間 下載 Spacesniffer 下載地址:https://spacesniffer.en.softonic.com/dow ...
  • efcore如何優雅的實現按年分庫按月分表 介紹 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、輕量級針對分表分庫讀寫分離的解決方案,具有零依賴、零學習成本、零業務代碼入侵適配 距離上次發文.net相關的已經有很久了,期間一直在從事java相關的 ...
  • Channel 是乾什麼的 The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consume ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 歡迎ReaLTaiizor是一個用戶友好的、以設計為中心的.NET WinForms項目控制項庫,包含廣泛的組件。您可以使用不同的主題選項對項目進行個性化設置,並自定義用戶控制項,以使您的應用程式更加專業。 項目地址:https://github.com/Taiizor/ReaLTaiizor 步驟1: ...
  • 前言 插件化的需求主要源於對軟體架構靈活性的追求,特別是在開發大型、複雜或需要不斷更新的軟體系統時,插件化可以提高軟體系統的可擴展性、可定製性、隔離性、安全性、可維護性、模塊化、易於升級和更新以及支持第三方開發等方面的能力,從而滿足不斷變化的業務需求和技術挑戰。 一、插件化探索 在WPF中我們想要開 ...
  • tc(Traffic Control)是 Linux 中用於流量控制和網路模擬的強大工具。你可以使用它來模擬網路延遲、帶寬限制、數據包丟失等。 以下是一個使用 tc 模擬網路延遲的基本步驟: 1.查看當前的 qdisc(隊列規則)和 filter(過濾器) 首先,確保你的網路介面沒有設置任何 qdi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...