K8S資源清單 ---- Kubernetes

1. K8S中的資源
1.1 什麼是資源

K8S中所有的內容都抽象爲資源,資源實例化後叫做對象。實例化的含義的是指資源被調用執行。

1.2 資源分類

名稱空間級別的資源:僅在指定名稱空間下生效,kuberadm安裝K8S集羣默認把所有的系統組件放在kube-system名稱空間下運行,通過命令 kubect get pod 是獲取不到系統Pod的信息,這裏 kubect get pod 等價於kubect get pod -n default,只會獲取默認的名稱空間中的資源。

集羣級別的資源:不管什麼名稱下定義,在其它名稱空間下都能看得到,其實在定義的時候根本沒有指定名稱空間。一旦經過定義以後,在全集羣中都是可見的並且可以被調用的。

元數據型的資源:如HPA可以通過CPU的當前利用率進行平滑擴展,也就是通過指標進行操作

1.3 名稱空間級別資源

工作負載資源:Pod,ReplicaSet,Deploment,StatefulSet,DaemonSet,Job,CronJob(ReplicationController在v1.11版本中被廢棄)

服務發現及負載均衡型資源:Service,Ingress。這兩個都是爲了 把服務暴露出去

配置與存儲資源:Volume(存儲卷),CSI(容器存儲接口,可以擴展各種各樣的第三方存儲卷)在K8S中,很多資源比較靈活地能夠提供給所需要的容器運行,只要存儲資源複合存儲規範,K8S中的Pod就可以調用存儲資源。

特殊類型的存儲卷:ConfigMap(通過其存儲配置文件達到i熱更新的狀態,當作配置中心來使用的資源類型),Secret(保護敏感數據),DownloadAPT(把外部環境中的信息輸出給容器)

1.3 集羣級別的資源

Namespace,Node,Role,ClusterRole,RoleBinding,CluserRoleBinding

1.4 元數據型資源

HPA,PodTemplate,LimitRange,也就是需要根據指標進行對應的操作

2. 資源清單

在K8S中一般 使用yaml格式的文件來創建符合我們期望的Pod,這樣的yaml文件一般被稱之爲資源清單。

2.1 簡單說明

YAML文件是一個可讀性高,用來表達數據序列的格式。YAML的意思其實是:仍然是一種標記語言,但是爲了強調這種語言以數據爲中心,而不是以標記語言爲中心。

2.2 基本語法

縮進時不允許使用Tab,只能夠使用空格

縮進的空格數不重要,只要相同層級的元素左側對齊即可

#標識註釋,從這個字符一直到尾行都會被解釋器忽略

2.3 YAML支持的數據結構

對象:鍵值對集合,又稱爲映射/字典/哈希

數組:一組按照次序排列的值,又稱爲序列/列表

純量:單個的、不可再分的值

2.4 對象類型

對象的一組鍵值對使用冒號來表示:

name:Erics
age:23

也允許另外一種寫法,把所有的鍵值對寫成一個行內對象:

hash:{name:Erics,age:23}
2.5 數組類型

一組連詞線開頭的行構成一個數組:

animal:
- cat
- dog

數組也可以採用行內寫法:

animal:[cat,dog]
2.6 複合結構

對象和數組可以結合使用形成複合結構:

languages:
- Python
- Java
- C
websites:
YAML:yaml.org
Python:python.org
2.7 純量

純量時最基本的不可再分的值,以下都屬於純量:

# 字符串 布爾值 整數 浮點數 null 時間 日期
# 數值直接以字面量的形式表示:
number:123
# 布爾值以true和false標識:
isSet:true
# null用~表示,不寫也代表null:
parent:~
# 時間採用ISO8601格式:
ISO8601:2020-06-16t15:17:20.10-05:00
# 日期採用複合ISO8601格式的年、月、日表示:
date:2020-06-18
# YAML允許使用兩個!!強制轉換類型
e:!!str 123
f:!!str true
2.8 字符串

字符串不使用引號表示,

str:字符串

如果字符串之間包含空格,需要使用引號:

str:'字符串 ' 

單引號和雙引號都可以使用,雙引號不會對特殊字符轉義

s1:'\n'
s2:"\n"

單引號之中如果還有單引號,必須再加一個單引號轉義:

str:'labor''s day'

字符串可以寫成多行,從第二行開始必須有一個單空格縮進。換行符會被轉成空格:

str:第一行
 第二行
 第三行

多行字符串可以使用|保留換行符,也可以使用>摺疊換行:

this:|
Foo
Bar
that:>
Foo
Bar

+表示文字塊末尾的換行(默認),-表示刪除字符串末尾的換行:

s1:|
 Foo
s2:|+
 Foo
s3:|-
 Foo
3. 常用字段解釋說明
3.1 必須存在的屬性

在這裏插入圖片描述

3.2 主要對象

主要對象不寫也可以,會使用默認值:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

3.3 額外的參數項

在這裏插入圖片描述

3.4 自定義Pod模板

可以使用命令去查看這些參數的解釋:

[root@k8s-master-01 ~]# kubectl explain pod
[root@k8s-master-01 ~]# kubectl explain pod.spec
[root@k8s-master-01 ~]# kubectl explain pod.spec.containers
...

自己寫一個Pod模板:

pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: default
  labels:
    app: myapp
    version: v1
spec:
  containers:
  - name: app
    image: hub.atguigu.com/library/myapp:v1
  - name: test
    image: hub.atguigu.com/library/myapp:v1

Pod創建成功:

[root@k8s-master-01 ~]# kubectl apply -f pod.yaml 
pod/myapp-pod created
[root@k8s-master-01 ~]# kubectl get pod
NAME                               READY   STATUS        RESTARTS   AGE
myapp-pod                          0/2     Pending       0          2m13s
# 查看Pod的信息
[root@k8s-master-01 ~]# kubectl describe pod myapp-pod
# 查看容器運行日誌
[root@k8s-master-01 ~]# kubectl log myapp-pod -c app
[root@k8s-master-01 ~]# kubectl log myapp-pod -c test

第一個容器 app 運行正常,但是 test 不能正常運行,因爲 app 容器已經佔用了80端口。同一個Pod中的容器共享網絡棧。下面修改 yaml 文件,把 test 容器刪除:

[root@k8s-master-01 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: default
  labels:
    app: myapp
    version: v1
spec:
  containers:
  - name: app
    image: hub.atguigu.com/library/myapp:v1
# 刪除pod
[root@k8s-master-01 ~]# kubectl delete pod myapp-pod
# 按照yaml文件創建pod
[root@k8s-master-01 ~]# kubectl apply -f pod.yaml 
# 查看pod的詳細信息
[root@k8s-master-01 ~]# kubectl get pod -o wide
NAME                               READY   STATUS        RESTARTS   AGE     IP            NODE          NOMINATED NODE   READINESS GATES
myapp-pod                          1/1     Running       0          12s     10.244.1.20   k8s-node-01   <none>           <none>
[root@k8s-master-01 ~]# curl 10.244.1.20
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
4. Pod生命週期

Pod在創建經歷了哪些過程,理解了這些過程才能直到如何探測。Pod裏面有兩個容器,如果兩個容器中的進程已經死亡或意外中斷了,由於某種故障這個Pod並沒有退出,造成這個Pod還處於運行狀態。這時候服務是不可用的,但是這個Pod還是處於可用狀態。這個時候就會出現問題,那麼如何來做探查?不着急,首先要了解容器是如何初始化的。Pod的生命週期:
在這裏插入圖片描述
一開始當我們的請求指令被下達到api接口被調度到kuberlet上,kuberlet操作對應的CRI去做容器環境的初始化,會先啓動Pause容器(基本容器,同一Pod容器的容器之間網絡和存儲卷共享)。進入Pod生命週期內部,Pod創建的時候首先需要進行Init C(初始化容器)的創建過程,創建完成之後Init C就會死亡。不能同時運行兩個甚至多個Init C,只能前面一個Init C運行結束後運行下一個Init C。要在Init C之前。Init C完成之後就會進入主容器,主容器可以有多個。在主容器運行之前和之後都可以運行指令,即:Start和Stop操作,執行命令或者腳本

在這裏插入圖片描述
readiness,即就緒檢測模塊,可以根據命令或TCP連接或HTTP協議獲取狀態,判斷Pod中服務是否可用,如果可用纔會把運行狀態改爲Running,防止雖然處於Running狀態,但是無法提供給外網訪問。

liveness,即生存檢測模塊。如果Pod裏面運行一個主容器,主容器中運行一個Nginx的進程,但是處於假死狀態(殭屍進程)。進程沒有死掉,則這個主容器就會運行着,Pod的狀態就會顯示Running,能夠繼續爲外網提供訪問。我們需要需要有種機制,當發現容器內部(Nginx)不能提供對外訪問的時候,可以 重啓進程或者重建Pod等操作,這就用到了liveness。
在這裏插入圖片描述

5. Init 容器
5.1 Init 容器概述

Pod能夠具有多個容器,應用運行在容器裏面,但是它也可能有一個或多個先於應用容器啓動的Init容器,Init容器與普通的容器非常像,除了如下兩點:

① Init容器總是運行到成功完成爲止
② 每個Init容器都必須在下一個Init容器啓動之前成功完成

對應 Init 容器和主容器是不一樣的,主容器如果退出,Pod也就結束了。Init C的退出與Pod生命週期沒有關係,Pod並不會結束。但是,Init C如果不是正常退出,就到達不了主容器。並且,如果Init C如果如果沒有正常退出,Pod是需要進行對應的流程處理,比如Pod重啓。

如果Pod的Init容器失敗,Kubernetes會不斷地重啓該Pod,直到Init容器成功爲止。然而,如果Pod對應的restartPolicy爲Never,它不會重新啓動

5.2 Init容器的作用

因爲Init容器具有與應用程序容器分離的單獨鏡像,所以它們的啓動相關代碼具有如下優勢:

① 它們可以包含並運行實用工具,但是出於安全考慮,是不建議在應用程序容器鏡像中包含這些實用工具的(安全性

② 它們可以包含使用工具和定製化代碼來安裝,但是不能出現在應用程序鏡像中。例如,創建鏡像沒必要FROM另一個鏡像,只需要在安裝過程中使用類似sed、awk、python或dig這樣的工具。(冗餘性)

把主容器要使用的工具寫入Init C,在初始化的時候把主容器需要的文件提前創建出來。主容器不需要包含這些文件,這些工具並不是主容器一直都要用的,防止造成冗餘

③ 應用程序鏡像可以分離出創建和部署的角色,而沒有必要聯合它們構建一個單獨的鏡像

④ Init容器使用LinuxNamespace,所以相對應用程序容器來說具有不同的文件系統視圖。因此,它們能夠具有訪問Secret的權限,而應用程序容器則不能

有一些需要主容器去調用的文件,但是主容器(Main C)對這些文件沒有訪問權限。這個文件所在的目錄還有其它重要的文件,如果把這個文件的目錄賦予權限給主容器,那麼主容器就可以隨便調用目錄下的所有文件。這樣安全性就出現隱患,這個時候完全可以把權限賦予給Init C,讓Init C獲取文件後寫入到主容器,Init C寫入文件後就退出了。主容器沒有獲取文件的權限,主容器安全性就會提高。這是採用分權限進行處理。

⑤ 它們必須在應用程序容器啓動之前運行完成,而 應用程序容器是並行運行的,所以Init容器能夠提供了一種簡單的阻塞或延遲應用容器的啓動的方法,直到滿足了一組先決條件

如有兩個主容器,一個是Apache+PHP,另外一個是MySQL。要求啓動mysql後再啓動Apache+PHP容器,這是爲了防止Apache+PHP容器連接MySQL連接不上,認爲容器有問題就退出容器,然後不斷重啓。這種情況下可以在Apache+PHP容器加入的Init C,可以探測MySQL連接是否正常,如果正常啓動,Init C會退出容器,主容器啓動連接MySQL。

5.3 Init 容器實例

node1和node2下載busybox鏡像,也可以不下載等待自動下載:

[root@k8s-node-01 ~]# docker pull busybox
[root@k8s-node-02 ~]# docker pull busybox
[root@k8s-master-01 ~]# vim init-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh','-c','echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox
    command: ['sh','-c','until nslookup myservice; do echo waiting for myservice; sleep 2;done;']
  - name: init-mydb
    image: busybox
    command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
# deployment和pod默認使用的名稱空間是default
[root@k8s-master-01 ~]# kubectl delete deployment --all
[root@k8s-master-01 ~]# kubectl delete pod --all
# 刪除svc
[root@k8s-master-01 ~]# kubectl get svc
[root@k8s-master-01 ~]# kubectl delete svc nginx-deployment
# grace-period表示過渡存活期,默認30s,在刪除POD之前允許POD慢慢終止其上的容器進程,從而優雅退出,0表示立即終止POD
[root@k8s-master-01 ~]# kubectl delete pod --all  --force --grace-period=0
[root@k8s-master-01 ~]# kubectl create -f init-pod.yaml 
pod/myapp-pod created
[root@k8s-master-01 ~]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          3s
[root@k8s-master-01 ~]# kubectl describe pod myapp-po
[root@k8s-master-01 ~]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          101s
# 查看init-myservice 初始化容器的日誌,發現解析不成功
[root@k8s-master-01 ~]# kubectl log myapp-pod -c init-myservice

創建svc:

[root@k8s-master-01 ~]# vim myservice.yaml
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
[root@k8s-master-01 ~]# kubectl create -f myservice.yaml 
[root@k8s-master-01 ~]# vim myservice.yaml
[root@k8s-master-01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   7d2h
myservice    ClusterIP   10.107.163.130   <none>        80/TCP    85s
# 其中一個初始化容器已經運行成功並退出
[root@k8s-master-01 ~]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:1/2   0          10m

創建一個名字爲myservice的service,myservice創建之後會被本機集羣內部解析。也就是說,內部的所有容器會把兩臺機器的內部IP配置成DNS服務器。myapp-pod會請求這個DNS服務器,又沒有名字爲myservice的svc,如果創建了svc,就會被寫入到DNS。DNS就會返回對應的數據,成功之後,初始化容器檢測到就退出。

# coredns-5c98db65d4-dc5h7是DNS
[root@k8s-master-01 ~]# kubectl get pod -n kube-system
NAME                                    READY   STATUS        RESTARTS   AGE
coredns-5c98db65d4-dc5h7                1/1     Running       0          10m
coredns-5c98db65d4-f2lbc                1/1     Running       0          10m
coredns-5c98db65d4-r6sbc                1/1     Terminating   17         7d2h
coredns-5c98db65d4-zq2xf                1/1     Terminating   17         7d2h
etcd-k8s-master-01                      1/1     Running       18         7d2h
kube-apiserver-k8s-master-01            1/1     Running       18         7d2h
kube-controller-manager-k8s-master-01   1/1     Running       1          7d2h
kube-flannel-ds-amd64-gd55v             1/1     Running       12         7d1h
kube-flannel-ds-amd64-l8xtd             1/1     Running       21         7d2h
kube-flannel-ds-amd64-xcwmt             1/1     Running       7          6d23h
kube-proxy-5gm9j                        1/1     Running       18         7d2h
kube-proxy-n2gkx                        1/1     Running       8          6d23h
kube-proxy-zl82c                        1/1     Running       12         7d1h
kube-scheduler-k8s-master-01            1/1     Running       27         7d2h

第二個Init C檢測的是mydb,所以需要創建一個mydb的svc:

[root@k8s-master-01 ~]# vim mydb.yaml
kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377
[root@k8s-master-01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   7d3h
mydb         ClusterIP   10.106.42.42     <none>        80/TCP    32s
myservice    ClusterIP   10.107.163.130   <none>        80/TCP    13m
[root@k8s-master-01 ~]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
myapp-pod   1/1     Running   0          21m
# 如果出錯可以查看
[root@k8s-master-01 ~]# kubectl decribe pod myapp-pod

busybox在沒有指定版本的情況下,默認用latest來ag,在K8S中如果使用latest標籤來保存,每次在使用鏡像的時候都會從倉庫去下載。latest在不同時期代表不同版本。

4.4 特殊說明

① 在Pod啓動過程中,Init容器會按順序在網絡和數據卷初始化(在pause中完成)之後啓動。每個容器必須在下一個容器啓動之前成功退出

② 如果由於運行時或失敗退出,將導致容器啓動失敗,它會根據Pod的restartPolicy指定的策略進行重試,直到達到最大上限。然而,如果Pod的restartPolicy設置爲Always,Init容器失敗時會使用RestartPolicy策略

③ 在所有的Init容器沒有成功之前,Pod將不會變成Ready狀態。Init容器的端口將不會在Service中進行聚集。正在初始化中的Pod處於Pending狀態,但應該會將Initializing狀態設置爲true

如果Pod重啓,所有Init容器必須重新執行

⑤ 對Init容器spec的修改被限制在容器image字段,修改其他字段都不會生效。更改Init容器的image字段,等價於重啓該Pod

[root@k8s-master-01 ~]# kubectl edit pod myapp-pod
initContainers:
  - command:
    - sh
    - -c
    - until nslookup myservice; do echo waiting for myservice; sleep 2;done;
    image: busybox	# 其它修改不會生效,但是被修改會觸發init C容器,相當於Pod被重啓了
...

⑥ Init容器具有應用容器的所有字段。除了readinessProbe,因爲Init容器無法定義不同於完成(completion)的就緒(readiness)之外的其他狀態,這會在驗證過程中強制執行。沒有存活檢測和就緒檢測字段,因爲完成之後就退出了,如果有也不會生效。

⑦ 在 Pod中的每個app和Init容器的名稱必須唯一,與任何其它容器共享同一個名稱,會在驗證時拋出錯誤,端口可以是一致的,Init C容器是線性運行的,一個運行結束纔會運行下一個。

6. 容器探針
6.1 探針

探針不是由主服務發起的,而是由每一個Node所在的kubelet對容器執行的定期診斷,這樣主調度的壓力就會更小。要執行診斷,kubelet調用由容器實現的Handler。有三種類型的處理程序:

① ExecAction:在容器內執行指定命令。如果命令退出時返回碼爲0則認爲診斷成功

② TCPSocketAction:對指定端口上的容器的IP地址進行TCP檢查。如果端口打開,則診斷被認爲是成功的

③ HTTPGetAction:對指定的端口和路徑上的容器的IP地址執行HTTPGet請求。如果響應的狀態碼大於等於200且小於400,則診斷被認爲是成功的

每次探測都將獲得以下三種結果之一:

① 成功:容器通過了診斷

② 失敗:容器未通過診斷

③ 未知:診斷失敗,因此不會採取任何行動

6.2 探測方案

livenessProbe:指示容器是否正在運行。如果存活探測失敗,則kubelet會殺死容器,並且容器將受到其重啓策略的影響。如果容器不提供存活探針,則默認狀態爲Success(會跟隨容器整個生命週期,從liveness啓動到Pod結束都會存在,會持續循環地檢測這個容器裏面的應用程序資源是否可用,不可用就會殺死這個容器。

readinessProbe:指示容器是否準備好服務請求。如果就緒探測失敗,端點控制器將從與Pod匹配的所有Service的端點中刪除該Pod的IP地址。初始延遲之前的就緒狀態默認爲Failure。如果容器不提供就緒探針,則默認狀態爲Success(檢測成功之後,主容器才能夠宣佈對外正常訪問。

6.3 就緒檢測

就緒檢測的實現,通過httpget方案:

[root@k8s-node-01 ~]# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
busybox                              latest              1c35c4412082        2 weeks ago         1.22MB
quay.io/coreos/flannel               v0.12.0-amd64       4e9f801d2217        3 months ago        52.8MB
k8s.gcr.io/kube-apiserver            v1.15.1             68c3eb07bfc3        11 months ago       207MB
k8s.gcr.io/kube-scheduler            v1.15.1             b0b3c4c404da        11 months ago       81.1MB
k8s.gcr.io/kube-controller-manager   v1.15.1             d75082f1d121        11 months ago       159MB
k8s.gcr.io/kube-proxy                v1.15.1             89a062da739d        11 months ago       82.4MB
k8s.gcr.io/coredns                   1.3.1               eb516548c180        17 months ago       40.3MB
k8s.gcr.io/etcd                      3.3.10              2c4adeb21b4f        18 months ago       258MB
hub.atguigu.com/library/myapp        v1                  d4a5e0eaa84f        2 years ago         15.5MB
k8s.gcr.io/pause                     3.1                 da86e6ba6ca1        2 years ago         742kB
[root@k8s-master-01 ~]# vim readness.yaml
apiVersion: v1                          # api的版本
kind: Pod                               # kind的類型
metadata:                               # 元數據信息
  name: readiness-httpget-pod           # pod的名稱
  namespace: default                    # pod所在的名稱空間
spec:                                   # 詳細的描述
  containers:                           # 描述容器
  - name: readiness-httpget-container   # 容器的名稱 
    image: hub.atguigu.com/library/myapp:v1       # 容器的鏡像
    imagePullPolicy: IfNotPresent       # 鏡像的下載策略:如果有就不下載了
    readinessProbe:                     # 就緒檢測
      httpGet:                          # 檢測的方案:httpGet
        port: 80                        # 端口,或者寫爲http
        path: /index1.html              # 檢測的路徑
      initialDelaySeconds: 1            # 初始化檢測的延時:容器啓動1s後開始檢測
      periodSeconds: 3                  # 重試的檢測時間:3s後重試檢測
[root@k8s-master-01 ~]# kubectl create -f readness.yaml 
# 雖然是Runngin狀態但是並不是Ready狀態
[root@k8s-master-01 ~]# kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP            NODE          NOMINATED NODE   READINESS GATES
myapp-pod               1/1     Running   4          3h28m   10.244.1.38   k8s-node-01   <none>           <none>
readiness-httpget-pod   0/1     Running   0          4s      10.244.1.42   k8s-node-01   <none>           <none>
# 發現沒有index1.html,即探針檢測出來是404
[root@k8s-master-01 ~]# kubectl describe pod readiness-httpget-pod
  Warning  Unhealthy  3s (x16 over 48s)  kubelet, k8s-node-01  Readiness probe failed: HTTP probe failed with statuscode: 404
# 進入容器中,如果Pod中只有一個容器不需要指定容器名稱,指定的時候加上-c參數,-t交互和打開tty
[root@k8s-master-01 ~]# kubectl exec readiness-httpget-pod -it -- /bin/sh
/ # cd /usr/share/nginx/
/usr/share/nginx # cd html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo '123'>index1.html
/usr/share/nginx/html # ls
50x.html     index.html   index1.html
/usr/share/nginx/html # exit
# 檢測成功
[root@k8s-master-01 ~]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
myapp-pod               1/1     Running   4          3h34m
readiness-httpget-pod   1/1     Running   0          6m49s

如果有個主容器apache+php想檢測mysql狀態,使用Init C是不友好的,Init C作爲環境初始化工具即可。在主容器中使用readinessProbe對mysql進行檢測是比較合適的。

6.4 存活檢測

通過exec的方案來實現存活檢測:

# 刪除默認名稱空間下的所有Pod
[root@k8s-master-01 ~]# kubectl delete pod --all
[root@k8s-master-01 ~]# kubectl delete svc mydb myservice
[root@k8s-master-01 ~]# kubectl create -f liveness.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: busybox  # 如果沒有加版本號,默認爲latest,會從遠程下載(前提條件:默認的,也就是Always) 
    imagePullPolicy: IfNotPresent    # 不是默認,不會去遠程下載
    command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep3600"]
    livenessProbe:      # 和容器綁定
      exec:
        command: ["test","-e","/tmp/live"]     # 檢測這個文件是否存在 
      initialDelaySeconds: 1         # 1s之後纔會進行liveness的檢測
      periodSeconds: 3               # 3s檢測一次
[root@k8s-master-01 ~]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
liveness-exec-pod   1/1     Running   0          15s
[root@k8s-master-01 ~]# kubectl get pod -w
NAME                READY   STATUS             RESTARTS   AGE
liveness-exec-pod   0/1     CrashLoopBackOff   2          3m29s
liveness-exec-pod   1/1     Running            3          3m45s
liveness-exec-pod   0/1     Error              3          4m46s
liveness-exec-pod   0/1     CrashLoopBackOff   3          4m47s
# 已經重啓了4[root@k8s-master-01 ~]# kubectl get pod 
NAME                READY   STATUS    RESTARTS   AGE
liveness-exec-pod   1/1     Running   4          6m2s

容器重啓的方案默認RestartPolicy是always,即總是重啓!

通過httpget的方案來實現存活檢測:

# 因爲防止端口衝突
[root@k8s-master-01 ~]# kubectl delete pod liveness-exec-pod
[root@k8s-master-01 ~]# vim liveness-httpget.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: hub.atguigu.com/library/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:
        port: http               # http可以複用,也就是80   
        path: /index.html        # 檢查能不能訪問到index.html 
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10
[root@k8s-master-01 ~]# kubectl create -f liveness-httpget.yaml 
[root@k8s-master-01 ~]# kubectl get pod -o wide
NAME                   READY   STATUS    RESTARTS   AGE    IP            NODE          NOMINATED NODE   READINESS GATES
liveness-httpget-pod   1/1     Running   0          2m3s   10.244.1.44   k8s-node-01   <none>           <none>
[root@k8s-master-01 ~]# curl 10.244.1.44
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
# 把文件刪除
[root@k8s-master-01 ~]# kubectl exec liveness-httpget-pod -it -- /bin/sh
/ # rm -rf /usr/share/nginx/html/index.html 
/ # exit
# 可以看到重啓次數變爲2
[root@k8s-master-01 ~]# kubectl get pod -w
NAME                   READY   STATUS    RESTARTS   AGE
liveness-httpget-pod   1/1     Running   2          5m15s

通過tcp的方案來實現存活檢測:

[root@k8s-master-01 ~]# vim liveness-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: hub.atguigu.com/library/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 80
# 不指定端口也可以正常運行,和前面方案設置的80端口不衝突
[root@k8s-master-01 ~]# kubectl create -f liveness-tcp.yaml 
[root@k8s-master-01 ~]# kubectl get pod -o wide
NAME                   READY   STATUS    RESTARTS   AGE   IP            NODE          NOMINATED NODE   READINESS GATES
liveness-httpget-pod   1/1     Running   2          10m   10.244.1.44   k8s-node-01   <none>           <none>
probe-tcp              1/1     Running   0          38s   10.244.1.45   k8s-node-01   <none>           <none>
[root@k8s-master-01 ~]# kubectl get pod -w
NAME                   READY   STATUS    RESTARTS   AGE
liveness-httpget-pod   1/1     Running   2          16m
probe-tcp              1/1     Running   0          20s
probe-tcp              1/1     Running   1          30s
probe-tcp              1/1     Running   2          57s
probe-tcp              1/1     Running   3          88s

就緒檢測和存活檢測可以放在一起!就緒檢測值是改狀態,存活檢測只要不是存活就退出容器!

7. 啓動退出動作
[root@k8s-master-01 ~]# vim start_end.yaml
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler >/usr/share/message"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStop handler >/usr/share/message"]
[root@k8s-master-01 ~]# kubectl get pod lifecycle-demo -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE          NOMINATED NODE   READINESS GATES
lifecycle-demo   1/1     Running   0          75s   10.244.1.47   k8s-node-01   <none>           <none>
[root@k8s-master-01 ~]# kubectl exec lifecycle-demo -it -- /bin/sh
# cat /usr/share/message
Hello from the postStart handler
# exit
8. Pod phase
8.1 Pod phase簡介

Pod的status字段是一個PodStatus對象,PodStatus中有一個phase字段。Pod的相位(phase)是Pod在其生命週期中的簡單宏觀概述。該階段並不是對容器或Pod的綜合彙總,也不是爲了做爲綜合狀態機。Pod相位的數量和含義是嚴格指定的。除了本文中列舉的狀態外,不應該再假定Pod有其他的phase值。

8.2 Pod phase可能存在的值

掛起(Pending):Pod已被Kubernetes系統接受,但有一個或者多個容器鏡像尚未創建。等待時間包括調度Pod的時間和通過網絡下載鏡像的時間,這可能需要花點時間

運行中(Running):該Pod已經綁定到了一個節點上,Pod中所有的容器都已被創建。至少有一個容器正在運行,或者正處於啓動或重啓狀態

成功(Succeeded):Pod中的所有容器都被成功終止,並且不會再重啓(顯示在Job和CronJob中

失敗(Failed):Pod中的所有容器都已終止了,並且至少有一個容器是因爲失敗終止。也就是說,容器以非0狀態退出或者被系統終止(Pod中有很多容器,只要有一個容器是非正常退出狀態就是Failed

未知(Unknown):因爲某些原因無法取得Pod的狀態,通常是因爲與Pod所在主機通信失敗

9. 重啓策略

PodSpec中有一個restartPolicy字段,可能的值爲Always、OnFailure和Never。默認爲Always。restartPolicy適用於Pod中的所有容器。restartPolicy僅指通過同一節點上的kubelet重新啓動容器。失敗的容器由kubelet以五分鐘爲上限的指數退避延遲(10秒,20秒,40秒…)重新啓動,並在成功執行十分鐘後重置。如Pod文中所述,一旦綁定到一個節點,Pod將永遠不會重新綁定到另一個節點。

10. Pod hook

Podhook(鉤子)是由Kubernetes管理的kubelet發起的,當容器中的進程啓動前或者容器中的進程終止之前運行,這是包含在容器的生命週期之中。可以同時爲Pod中的所有容器都配置hook。Hook的類型包括兩種:

exec:執行一段命令
HTTP:發送HTTP請求

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章