鎮(zhèn)江網站推廣南寧seo外包要求
目錄
一、理論
1.pod
2.pod容器分類
3.鏡像拉取策略(image PullPolicy)
二、實驗
1.Pod容器的分類
2.鏡像拉取策略
三、問題
1.apiVersion 報錯
2.pod v1版本資源未注冊
3.取行顯示指定pod信息
四、總結
一、理論
1.pod
(1)? 概念
?Pod是kubernetes中最小的資源管理組件,Pod也是最小化運行容器化應用的資源對象。一個Pod代表著集群中運行的一個進程。kubernetes中其他大多數組件都是圍繞著Pod來進行支撐和擴展Pod功能的,例如,用于管理Pod運行的StatefulSet和Deployment等控制器對象,用于暴露Pod應用的Service和Ingress對象,為Pod提供存儲的PersistentVolume存儲資源對象等。
pod:
node:
service:
(2)K8S集群中Pod兩種使用方式
①??一個Pod中運行一個容器
? ? ? ? “每個Pod中一個容器”的模式是最常見的用法;在這種使用方式中,你可以把Pod想象成是單個容器的封裝,kuberentes管理的是Pod而不是直接管理容器。
②??在一個Pod中同時運行多個容器。
? ? ? ? 一個Pod中也可以同時封裝幾個需要緊密耦合互相協(xié)作的容器,它們之間共享資源。這些在同一個Pod中的容器可以互相協(xié)作成為一個service單位,比如一個容器共享文件,另一個“sidecar”容器來更新這些文件。Pod將這些容器的存儲資源作為一個實體來管理。
? ? ? ? 一個Pod下的容器必須運行于同一節(jié)點上。現(xiàn)代容器技術建議一個容器只運行一個進程,該進程在容器中PID命令空間中的進程號為1,可直接接收并處理信號,進程終止時容器生命周期也就結束了。若想在容器內運行多個進程,需要有一個類似Linux操作系統(tǒng)init進程的管控類進程,以樹狀結構完成多進程的生命周期管理。運行于各自容器內的進程無法直接完成網絡通信,這是由于容器間的隔離機制導致,k8s中的Pod資源抽象正是解決此類問題,Pod對象是一組容器的集合,這些容器共享Network、UTS及IPC命令空間,因此具有相同的域名、主機名和網絡接口,并可通過IPC直接通信。
? ? ? ? Pod資源中針對各容器提供網絡命令空間等共享機制的是底層基礎容器pause,基礎容器(也可稱為父容器)pause就是為了管理Pod容器間的共享操作,這個父容器需要能夠準確地知道如何去創(chuàng)建共享運行環(huán)境的容器,還能管理這些容器的生命周期。為了實現(xiàn)這個父容器的構想,kubernetes中,用pause容器來作為一個Pod中所有容器的父容器。這個pause容器有兩個核心的功能,一是它提供整個Pod的Linux命名空間的基礎。二來啟用PID命名空間,它在每個Pod中都作為PID為1進程(init進程),并回收僵尸進程。
(3)pause
? ? pause容器使得Pod中的所有容器可以共享兩種資源:網絡和存儲。
①?網絡:
? ? ? ? 每個Pod都會被分配一個唯一的IP地址。Pod中的所有容器共享網絡空間,包括IP地址和端口。Pod內部的容器可以使用localhost互相通信。Pod中的容器與外界通信時,必須分配共享網絡資源(例如使用宿主機的端口映射)。
②?存儲:
? ? ? ?Pod可以指定多個共享的Volume。Pod中的所有容器都可以訪問共享的Volume。Volume也可以用來持久化Pod中的存儲資源,以防容器重啟后文件丟失。
?③?小結
? ? ? ? 每個Pod都有一個特殊的被稱為“基礎容器”的Pause容器。Pause容器對應的鏡像屬于Kubernetes平臺的一部分,除了Pause容器,每個Pod還包含一個或者多個緊密相關的用戶應用容器。
(4)pause容器功能
①??在pod中擔任Linux命名空間(如網絡命令空間)共享的基礎;
②??啟用PID命名空間,開啟init進程。
(5)pod設計特殊組成結構目的
①?原因一:在一組容器作為一個單元的情況下,難以對整體的容器簡單地進行判斷及有效地進行行動。比如,一個容器死亡了,此時是算整體掛了么?那么引入與業(yè)務無關的Pause容器作為Pod的基礎容器,以它的狀態(tài)代表著整個容器組的狀態(tài),這樣就可以解決該問題。
②?原因二:Pod里的多個應用容器共享Pause容器的IP,共享Pause容器掛載的Volume,這樣簡化了應用容器之間的通信問題,也解決了容器之間的文件共享問題。
(6)pod分類
通常把Pod分為兩類:
1.自主式Pod
1)創(chuàng)建方式(類似自營)kubectl run pod 用于創(chuàng)建一個自主/靜態(tài)pod
注意:它就是創(chuàng)建一個pod,這個pod一旦掛了就不會在node上拉起來,這個pod式靜態(tài)pod,它不是存在etcd,二十存在node當中
2)概念這種Pod本身是不能自我修復的,當Pod被創(chuàng)建后(不論是由你直接創(chuàng)建還是被其他Controller),都會被Kuberentes調度到集群的Node上。直到Pod的進程終止、被刪掉、因為缺少資源而被驅逐、或者Node故障之前這個Pod都會一直保持在那個Node上。Pod不會自愈。如果Pod運行的Node故障,或者是調度器本身故障,這個Pod就會被刪除。同樣的,如果Pod所在Node缺少資源或者Pod處于維護狀態(tài),Pod也會被驅逐。2.控制器管理的Pod
1)創(chuàng)建方式(類似有人管)kubectl create deployment 用于創(chuàng)建deployment控制管理器的pod
注意:這種pod是在控制管理器當中,舉例:比如pod運行在node1上,控制器會保證pod的數量,如果node1掛了,它會在node2或者其他node節(jié)點重新拉取pod的數量
2)概念Kubernetes使用更高級的稱為Controller的抽象層,來管理Pod實例。Controller可以創(chuàng)建和管理多個Pod,提供副本管理、滾動升級和集群級別的自愈能力。例如,如果一個Node故障,Controller就能自動將該節(jié)點上的Pod調度到其他健康的Node上。雖然可以直接使用Pod,但是在Kubernetes中通常是使用Controller來管理Pod的。
2.pod容器分類
(1)基礎容器(infrastructure?container)
維護整個 Pod 網絡和存儲空間
node 節(jié)點中操作
啟動一個容器時,k8s會自動啟動一個基礎容器
cat /opt/kubernetes/cfg/kubelet
每次創(chuàng)建 Pod 時候就會創(chuàng)建,運行的每一個容器都有一個 pause-amd64 的基礎容器自動會運行,對于用戶是透明的
docker ps -a
(2)初始化容器(initcontainers)
?Init容器必須在應用程序容器啟動之前運行完成,而應用程序容器是并行運行的,所以Init容器能夠提供了一種簡單的阻塞或延遲應用容器的啟動的方法。
Init 容器與普通的容器非常像,除了以下兩點:
●Init 容器總是運行到成功完成為止●每個 Init 容器都必須在下一個 Init 容器啟動之前成功完成啟動和退出
如果 Pod 的 Init 容器失敗,k8s 會不斷地重啟該 Pod,直到 Init 容器成功為止。然而,如果 Pod 對應的重啟策略(restartPolicy)為 Never,它不會重新啟動。
Init 的容器作用
因為init容器具有與應用容器分離的單獨鏡像,其啟動相關代碼具有如下優(yōu)勢:
●Init 容器可以包含一些安裝過程中應用容器中不存在的實用工具或個性化代碼。例如,沒有必要僅為了在安裝過程中使用類似 sed、 awk、 python 或 dig 這樣的工具而去FROM 一個鏡像來生成一個新的鏡像?!馡nit 容器可以安全地運行這些工具,避免這些工具導致應用鏡像的安全性降低?!駪苗R像的創(chuàng)建者和部署者可以各自獨立工作,而沒有必要聯(lián)合構建一個單獨的應用鏡像?!馡nit 容器能以不同于Pod內應用容器的文件系統(tǒng)視圖運行。因此,Init容器可具有訪問 Secrets 的權限,而應用容器不能夠訪問。●由于 Init 容器必須在應用容器啟動之前運行完成,因此 Init 容器提供了一種機制來阻塞或延遲應用容器的啟動,
直到滿足了一組先決條件。一旦前置條件滿足,Pod內的所有的應用容器會并行啟動。
(3)??應用容器(Maincontainer)
并行啟動官網示例:
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels:app: myapp
spec:containers:- name: myapp-containerimage: busybox:1.28command: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: busybox:1.28command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']- name: init-mydbimage: busybox:1.28command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
這個例子是定義了一個具有 2 個 Init 容器的簡單 Pod。 第一個等待 myservice 啟動, 第二個等待 mydb 啟動。 一旦這兩個 Init容器都啟動完成,Pod 將啟動 spec 中的應用容器。
kubectl describe pod myapp-podkubectl logs myapp-pod -c init-myservice
vim myservice.yaml
apiVersion: v1
kind: Service
metadata:name: myservice
spec:ports:- protocol: TCPport: 80targetPort: 9376kubectl create -f myservice.yamlkubectl get svckubectl get pods -n kube-systemkubectl get podsvim mydb.yaml
apiVersion: v1
kind: Service
metadata:name: mydb
spec:ports:- protocol: TCPport: 80targetPort: 9377
kubectl create -f mydb.yamlkubectl get pods
特別說明:
●在Pod啟動過程中,Init容器會按順序在網絡和數據卷初始化之后啟動。每個容器必須在下一個容器啟動之前成功退出。
●如果由于運行時或失敗退出,將導致容器啟動失敗,它會根據Pod的restartPolicy指定的策略進行重試。然而,如果Pod的restartPolicy設置為Always,Init容器失敗時會使用RestartPolicy策略。
●在所有的Init容器沒有成功之前,Pod將不會變成Ready狀態(tài)。Init容器的端口將不會在Service中進行聚集。正在初始化中的Pod處于Pending狀態(tài),但應該會將Initializing狀態(tài)設置為true。
●如果Pod重啟,所有Init容器必須重新執(zhí)行。
●對Init容器spec的修改被限制在容器image字段,修改其他字段都不會生效。更改Init容器的image字段,等價于重啟該Pod。
●Init容器具有應用容器的所有字段。除了readinessProbe,因為Init容器無法定義不同于完成(completion)的就緒(readiness)之外的其他狀態(tài)。這會在驗證過程中強制執(zhí)行。
●在Pod中的每個app和Init容器的名稱必須唯一;與任何其它容器共享同一個名稱,會在驗證時拋出錯誤。
3.鏡像拉取策略(image PullPolicy)
? ? ? ? Pod 的核心是運行容器,必須指定容器引擎,比如 Docker,啟動容器時,需要拉取鏡像,k8s 的鏡像拉取策略可以由用戶指定:
1、IfNotPresent:在鏡像已經存在的情況下,kubelet 將不再去拉取鏡像,僅當本地缺失時才從倉庫中拉取,默認的鏡像拉取策略2、Always:每次創(chuàng)建 Pod 都會重新拉取一次鏡像;3、Never:Pod 不會主動拉取這個鏡像,僅使用本地鏡像。
注意:對于標簽為“:latest”的鏡像文件,其默認的鏡像獲取策略即為“Always”;而對于其他標簽的鏡像,其默認策略則為“IfNotPresent”。
(1) 官方示例
https://kubernetes.io/docs/concepts/containers/imageskubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:name: private-image-test-1
spec:containers:- name: uses-private-imageimage: $PRIVATE_IMAGE_NAMEimagePullPolicy: Alwayscommand: [ "echo", "SUCCESS" ]
EOF
(2) master01 上操作:
kubectl edit deployment/nginx-deployment
......template:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:1.15.4imagePullPolicy: IfNotPresent #鏡像拉取策略為 IfNotPresentname: nginxports:- containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: Always #Pod的重啟策略為 Always,默認值schedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30
......
(3)? 創(chuàng)建測試案例
mkdir /opt/demo
cd /opt/demovim pod1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-test1
spec:containers:- name: nginximage: nginximagePullPolicy: Alwayscommand: [ "echo", "SUCCESS" ]kubectl create -f pod1.yamlkubectl get pods -o wide
pod-test1 0/1 CrashLoopBackOff 4 3m33s
此時 Pod 的狀態(tài)異常,原因是 echo 執(zhí)行完進程終止,容器生命周期也就結束了
kubectl describe pod pod-test1
......
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 4m44s default-scheduler Successfully assigned default/pod-test1 to node02Normal Pulled 3m34s (x4 over 4m40s) kubelet, node02 Successfully pulled image "nginx"Normal Created 3m34s (x4 over 4m40s) kubelet, node02 Created container nginxNormal Started 3m34s (x4 over 4m40s) kubelet, node02 Started container nginxWarning BackOff 3m4s (x8 over 4m32s) kubelet, node02 Back-off restarting failed containerNormal Pulling 2m50s (x5 over 4m43s) kubelet, node02 Pulling image "nginx"
可以發(fā)現(xiàn) Pod 中的容器在生命周期結束后,由于 Pod 的重啟策略為 Always,容器再次重啟了,并且又重新開始拉取鏡像
修改 pod1.yaml 文件
cd /opt/demo
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-test1
spec:containers:- name: nginximage: nginx:1.14 #修改 nginx 鏡像版本imagePullPolicy: Always#command: [ "echo", "SUCCESS" ] #刪除
刪除原有的資源
kubectl delete -f pod1.yaml
更新資源
kubectl apply -f pod1.yaml
查看 Pod 狀態(tài)
[root@master demo]# kubectl get pods -o wide | awk 'NR==1 || NR==12'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test1 1/1 Running 0 4m42s 10.244.1.37 node02 <none> <none>
在任意 node 節(jié)點上使用 curl 查看頭部信息
[root@node01 ~]# curl -I http://10.244.1.37
HTTP/1.1 200 OK
Server: nginx/1.21.5
......
二、實驗
1.Pod容器的分類
(1)基礎容器(infrastructure?container)
2.鏡像拉取策略
(1)?創(chuàng)建測試案例
生成容器:
獲取信息:
此時 Pod 的狀態(tài)異常,原因是 echo 執(zhí)行完進程終止,容器生命周期也就結束了
查看詳細信息
修改 pod1.yaml 文件
刪除原有的資源
更新資源
查看 Pod 狀態(tài)
在任意 node 節(jié)點上使用 curl 查看頭部信息
三、問題
1.apiVersion 報錯
(1)報錯
error: error validating "pod1.yaml": error validating data: apiVersion not set; if you choose to ignore these errors, turn validation off with --validate=false
(2)原因分析
apiVersion 未正確設置
(3)解決方法
修改前:
修改后:
2.pod v1版本資源未注冊
(1)報錯
Error from server (BadRequest): error when creating "pod1.yaml": pod in version "v1" cannot be handled as a Pod: no kind "pod" is registered for version "v1" in scheme "k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go:30"
(2)原因分析
報了版本的錯誤,一查以為是沒有pod這種v1版本的資源,沒注冊
最后才發(fā)現(xiàn)是yaml文件中的pod的首字母需要大寫Pod
(3)解決方法
修改前:
修改后:
成功
3.取行顯示指定pod信息
(1)需求
只需求截取第1行標題欄和第12行信息
(2)問題
grep命令缺失標題欄
(3)解決方法
用awk命令取行取列
[root@master demo]# kubectl get pods -o wide | awk 'NR==1 || NR==12'
用sed命令取行
[root@master demo]# kubectl get pods -o wide | sed -n '1p;12p'
[root@master demo]# kubectl get pods -o wide | sed -n '/test1/p'
pod-test1 1/1 Running 0 53m 10.244.1.37 node02 <none> <none>
(4)awk小結
awk里的行與列,一般不叫行與列:行叫記錄(Record),列叫字段(Field)
①指定行號(第1行、第3行)
[root@master demo]# kubectl get pods -o wide | awk 'NR==1'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
[root@master demo]# kubectl get pods -o wide | awk 'NR==2'
nginx-65fc77987d-2b6b9 1/1 Running 2 46h 10.244.2.22 node01 <none> <none>
[root@master demo]#
②?取范圍(3行以內的)
[root@master demo]# kubectl get pods -o wide | awk 'NR<=3'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-65fc77987d-2b6b9 1/1 Running 2 46h 10.244.2.22 node01 <none> <none>
nginx-6cbd4b987c-6t2nt 1/1 Running 2 46h 10.244.2.27 node01 <none> <none>
[root@master demo]# kubectl get pods -o wide | awk 'NR==1,NR==3'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-65fc77987d-2b6b9 1/1 Running 2 46h 10.244.2.22 node01 <none> <none>
nginx-6cbd4b987c-6t2nt 1/1 Running 2 46h 10.244.2.27 node01 <none> <none>
③取指定行(第1行和第3行)
[root@master demo]# kubectl get pods -o wide | awk 'NR==1 || NR==3'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6cbd4b987c-6t2nt 1/1 Running 2 46h 10.244.2.27 node01 <none> <none>
④ 取包含nginx字符串行
[root@master demo]# kubectl get pods -o wide | awk '/nginx/'
nginx-65fc77987d-2b6b9 1/1 Running 2 46h 10.244.2.22 node01 <none> <none>
nginx-6cbd4b987c-6t2nt 1/1 Running 2 46h 10.244.2.27 node01 <none> <none>
nginx-6cbd4b987c-bqtfp 1/1 Running 2 46h 10.244.1.34 node02 <none> <none>
nginx-6cbd4b987c-g4xxm 1/1 Running 2 46h 10.244.1.35 node02 <none> <none>
nginx-deployment-6959f4b694-nds9n 1/1 Running 2 3d19h 10.244.2.23 node01 <none> <none>
nginx-deployment-6959f4b694-qm5p9 1/1 Running 2 3d19h 10.244.1.32 node02 <none> <none>
nginx-deployment-6959f4b694-qmpd6 1/1 Running 2 3d19h 10.244.2.24 node01 <none> <none>
nginx-test-86bdc44976-5kj74 1/1 Running 1 26h 10.244.1.31 node02 <none> <none>
nginx-test-86bdc44976-kvgb4 1/1 Running 1 26h 10.244.2.26 node01 <none> <none>
nginx-test-86bdc44976-s24d6 1/1 Running 1 26h 10.244.2.25 node01 <none> <none>
⑤?取包含deployment字符串行到test字符串的行
[root@master demo]# kubectl get pods -o wide | awk '/deployment/,/test1/'
nginx-deployment-6959f4b694-nds9n 1/1 Running 2 3d19h 10.244.2.23 node01 <none> <none>
nginx-deployment-6959f4b694-qm5p9 1/1 Running 2 3d19h 10.244.1.32 node02 <none> <none>
nginx-deployment-6959f4b694-qmpd6 1/1 Running 2 3d19h 10.244.2.24 node01 <none> <none>
nginx-test-86bdc44976-5kj74 1/1 Running 1 26h 10.244.1.31 node02 <none> <none>
nginx-test-86bdc44976-kvgb4 1/1 Running 1 26h 10.244.2.26 node01 <none> <none>
nginx-test-86bdc44976-s24d6 1/1 Running 1 26h 10.244.2.25 node01 <none> <none>
pod-test1 1/1 Running 0 33m 10.244.1.37 node02 <none> <none>
⑥?包含deployment的行和test1的行
[root@master demo]# kubectl get pods -o wide | awk '/deployment|test1/'
nginx-deployment-6959f4b694-nds9n 1/1 Running 2 3d19h 10.244.2.23 node01 <none> <none>
nginx-deployment-6959f4b694-qm5p9 1/1 Running 2 3d19h 10.244.1.32 node02 <none> <none>
nginx-deployment-6959f4b694-qmpd6 1/1 Running 2 3d19h 10.244.2.24 node01 <none> <none>
pod-test1 1/1 Running 0 43m 10.244.1.37 node02 <none> <none>
效果同grep -E
[root@master demo]# kubectl get pods -o wide | grep -E 'deployment|test1'
nginx-deployment-6959f4b694-nds9n 1/1 Running 2 3d19h 10.244.2.23 node01 <none> <none>
nginx-deployment-6959f4b694-qm5p9 1/1 Running 2 3d19h 10.244.1.32 node02 <none> <none>
nginx-deployment-6959f4b694-qmpd6 1/1 Running 2 3d19h 10.244.2.24 node01 <none> <none>
pod-test1 1/1 Running 0 40m 10.244.1.37 node02 <none> <n
(5)sed小結
sed命令提取指定的行
①?提取第1行
[root@master demo]# kubectl get pods -o wide | sed -n '1p'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
②?提取第1行到第3行
[root@master demo]# kubectl get pods -o wide | sed -n '1,3p'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-65fc77987d-2b6b9 1/1 Running 2 46h 10.244.2.22 node01 <none> <none>
nginx-6cbd4b987c-6t2nt 1/1 Running 2 46h 10.244.2.27 node01 <none> <none>
③只提取第1行和第12行
[root@master demo]# kubectl get pods -o wide | sed -n '1p;12p'
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test1 1/1 Running 0 51m 10.244.1.37 node02 <none> <none>
④提取奇數行
⑤提取偶數行
⑥提取匹配test1的行
[root@master demo]# kubectl get pods -o wide | sed -n '/test1/p'
pod-test1 1/1 Running 0 53m 10.244.1.37 node02 <none> <none>
⑦提取同時匹配pod和test1的行
[root@master demo]# kubectl get pods -o wide | sed -n '/pod\|test1/p'
pod-test1 1/1 Running 0 55m 10.244.1.37 node02 <none> <none>
四、總結
Pod是kubernetes中最小的資源管理組件,Pod也是最小化運行容器化應用的資源對象。
K8S集群中Pod兩種使用方式:
①??一個Pod中運行一個容器②??在一個Pod中同時運行多個容器。
? pause容器使得Pod中的所有容器可以共享兩種資源:網絡和存儲。