上一節發佈了一個容器到 K8S 中,但其實實際操做的是 Pod ,那麼爲何是 Pod,而不是容器。html
Pod 包裝了一個或多個容器。
Pod 是 K8S 的最小執行單元。
Pod 是 K8S 中的一個進程。
Pod 可包裝 Docker,也支持包裝其餘類型容器。
Pod 包含封裝的容器、存儲資源、網絡資源、以及指導容器如何運行的配置。node
能夠把容器理解爲一個無掛鉤的光禿禿的集裝箱,K8S 這艘大船沒法直接掛載它,經過給集裝箱(容器)加裝掛鉤(IP地址)等造成一個 Pod,方便 K8S 來操做。python
也能夠把 Pod 理解爲傳統的虛擬機,而容器是傳統虛擬機中運行的程序,只不過虛擬機是一個實體,而 Pod 是一個邏輯概念。linux
K8S 經過編排 Pod 來調度容器,而不是直接操做容器,K8S 沒法直接操縱容器。nginx
Pod 爲其中運行的多容器提供共享的網絡、存儲資源、命名空間。shell
Pod 具備惟一 IP 地址,Pod 中的多個容器共享一個 IP 地址和網絡端口等網絡資源
Pod 中多容器可以使用 localhost 通訊
Pod 中容器和外部通訊時候,多容器須要協調網絡端口
Pod 中的容器獲取的系統主機名與爲 Pod 配置的 name 相同api
Pod 可指定一組存儲卷
Pod 中多容器都可以訪問該存儲卷,以便互相共享數據
Pod 中的共享卷能夠持久保存,防止容器重啓丟失數據安全
若是使用 kind: Pod 的 yaml 文件來建立 Pod,當前節點服務器出現問題後,Pod 不能被自動調度到其餘可用服務器。bash
通常使用 kind: Deployment 的 yaml 來建立 Pod。服務器
Deployment 是一種控制器,能夠用來建立、管理 Pod。如建立多副本 Pod,滾動更新 Pod。
當 Pod 所在節點出現問題,Deployment 控制器能夠在集羣中其餘節點啓動新 Pod。
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
不具體指定的狀況下,imagePullPolicy 是 Always,即 kubelet 會嘗試從指定的倉庫拉取每一個鏡像。
若是容器屬性 imagePullPolicy 設置爲 IfNotPresent , 則會優先使用本地鏡像。
若是容器屬性 imagePullPolicy 設置爲 IfNotPresent Never, 則會必定使用本地鏡像。
apiVersion: v1 kind: Pod metadata: name: private-image-test-1 spec: containers: - name: uses-private-image image: nginx imagePullPolicy: Always command: [ "echo", "SUCCESS" ]
功能:將 Pod 與 Node 綁定
apiVersion: v1 kind: Pod ... spec: nodeSelector: disktype: ssd
該 Pod 只能運行在攜帶了「disktype:ssd」標籤(Label)的節點上,若是沒有這種標籤的節點,調度將失敗。
該字段通常由調度器設置,但咱們測試時候能夠手工設置該字段,讓調度器認爲該 Pod 已經被調度過了。
給 Pod 裏各容器的 /etc/hosts 文件設置內容
apiVersion: v1 kind: Pod ...... spec: hostAliases: - ip: "10.20.20.20" hostnames: - "test1.com" - "test2.com"
進容器檢查一下
[root@master01 ~]# kubectl exec -it nginx -- bash root@nginx:/# cat /etc/hosts ...... # Entries added by HostAliases. 10.20.20.20 test1.com test2.com
定義參數 shareProcessNamespace=true,那麼該 Pod 中全部容器將共享 PID Namespace
建立一個包含兩個容器的 Pod
[root@master01 ~]# cat nginx.yaml apiVersion: v1 kind: Pod metadata: name: nginx spec: shareProcessNamespace: true containers: - name: nginx image: nginx - name: shell image: busybox stdin: true tty: true
查看運行狀況
[root@master01 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 2/2 Running 0 117s 192.10.137.131 work03 <none> <none>
進入到 Pod nginx 中的名爲 shell 的容器中
[root@master01 ~]# kubectl attach -it nginx -c shell If you don't see a command prompt, try pressing enter. / # ps aux PID USER TIME COMMAND 1 root 0:00 /pause 6 root 0:00 nginx: master process nginx -g daemon off; 33 101 0:00 nginx: worker process 34 root 0:00 sh 39 root 0:00 ps aux
能夠看到,shell 容器中能夠看到 nginx 容器的進程
咱們能夠預先設置好一些通用的配置,當用戶提交本身的個性化 Pod 配置時,PodPreset 就能夠自動附加通用配置到對應的 Pod 上。PodPreset 裏定義的內容,只會在 Pod API 對象被建立以前追加在這個對象自己 上,而不會影響任何 Pod 的控制器的定義。
好比,咱們如今提交的是一個 nginx-deployment,那麼這個 Deployment 對象自己是永遠不會被 PodPreset 改變的,被修改的只是這個 Deployment 建立出來的全部 Pod。
未啓用 PodPreset 特性時
# kubectl get podpresets error: the server doesn't have a resource type "podpresets"
啓用 PodPreset 特性
修改 [/etc/kubernetes/manifests/kube-apiserver.yaml] 中的 spec.containers.command: 修改原 - --runtime-config=api/all=true 爲 - --runtime-config=api/all=true,settings.k8s.io/v1alpha1=true 新加一行 - --enable-admission-plugins=PodPreset 3臺MASTER均執行重啓 kubelet systemctl restart kubelet
預設值配置 preset.yaml
apiVersion: settings.k8s.io/v1alpha1 kind: PodPreset metadata: name: allow-tz-env spec: selector: matchLabels: env: - name: TZ value: Asia/Shanghai
Pod配置 nginx.yaml
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx
建立 PodPreset
# kubectl get podpreset No resources found in default namespace. # kubectl apply -f podpreset.yaml podpreset.settings.k8s.io/allow-tz-env created # kubectl get podpreset NAME CREATED AT allow-tz-env
建立 Pod
[root@master01 ~]# kubectl apply -f nginx.yaml pod/nginx created
查看該 Pod 是否被注入
# kubectl get pod nginx -o yaml ...省略 spec: containers: - env: - name: TZ value: Asia/Shanghai image: nginx imagePullPolicy: Always name: nginx resources: {} ...省略
能夠看到 Pod 被注入了名爲 TZ 的 env
建立 Pod 的 YAML 文件:
cat myapp.yaml
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
建立 mydb 和 myservice 兩個 Service 的 YAML 文件:
cat myservice.yaml
kind: Service apiVersion: v1 metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- kind: Service apiVersion: v1 metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377
要啓動這個 Pod,能夠執行以下命令:
kubectl apply -f myapp.yaml pod/myapp-pod created
檢查其狀態:
kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 6m
使用下面命令查看更詳細的信息:
kubectl describe -f myapp.yaml Name: myapp-pod Namespace: default [...] Labels: app=myapp Status: Pending [...] Init Containers: init-myservice: [...] State: Running [...] init-mydb: [...] State: Waiting Reason: PodInitializing Ready: False [...] Containers: myapp-container: [...] State: Waiting Reason: PodInitializing Ready: False [...]
查看Pod內 Init 容器的日誌
$ kubectl logs myapp-pod -c init-myservice $ kubectl logs myapp-pod -c init-mydb
此時,Init 容器將會等待直到發現名稱爲mydb和myservice的 Service。
建立mydb和myservice的 service:
$ kubectl create -f services.yaml service "myservice" created service "mydb" created
能夠看到這些 Init 容器執行完畢,隨後my-app的Pod轉移進入 Running 狀態:
$ kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 1/1 Running 0 9m
只有咱們啓動了 mydb 和 myservice 這兩個 Service,Init 容器完成,myapp-pod 才能被建立。
若是 Pod 被終止,可經過以下命令查看緣由
kubectl describe pod pod名稱 kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' pod名稱
Pod 包裝了容器,K8S 經過操做 Pod 來操做容器。
Pod 能夠包含多個應用容器和多個 Init 容器。
人工直接建立的 Pod 在服務器節點故障時,沒有自愈能力,須要使用控制器來解決這個問題。
微信公衆號:zuolinux_com