k8s之pod管理
Pod是可以創建和管理Kubernetes計算的最小可部署單元,一個Pod代表著集群中運行的一個進程,每個pod都有一個唯一的ip。
一個pod類似一個豌豆莢,包含一個或多個容器(通常是docker),多個容器間共享IPC、Network和UTC namespace。
參考地址:pod命令行管理
一、創建和刪除pod應用
實驗環境:
server1作為本地倉庫,server2作為master,server3,server4作為node節點
實驗前要保證保證倉庫正常運行
節點狀態ready
1 創建pod
此時要保證你所使用的鏡像myapp,在本地倉庫存在才行。
[root@server2 ~]# kubectl run nginx --image=myapp:v1 [root@server2 ~]# kubectl get pod當出現下圖狀態時說明創建成功。
2 查看pod運行在哪個節點上,且查看分配的ip地址
[root@server2 ~]# kubectl get pod -o wide3 訪問分配的ip
集群內部任意節點可以訪問Pod,但集群外部無法直接訪問。
[root@server2 ~]# curl 10.244.2.21
測試:
這時我們再創建一個pod,到容器內進行訪問
這時我們發現容器內的ip和容器外的ip相同
再次進入容器我們訪問剛才myapp的ip,查看結果
4 刪除pod
刪除pod的命令
[root@server2 ~]# kubectl delete pod nginx使用下面命令可以查看正在運行的pod的詳細信息
[root@server2 ~]# kubectl describe pod demo5.查看日志的命令
[root@server2 ~]# kubectl logs demo6 通過控制器創建pod
一般我們不會使用剛才演示的那種單獨創建的方式
[root@server2 ~]# kubectl create deployment nginx --image=myapp:v1 [root@server2 ~]# kubectl get all這里如果我們進行刪除的話,它是不會直接被刪除的,他會刪除之后,自動重新創建出來一個新的副本。只是隨機id發生變化
二、Pod擴容與縮容
[root@server2 ~]# kubectl scale deployment --replicas=2 nginx [root@server2 ~]# kubectl get pod -o wide三、 service(微服務)
service是一個抽象概念,定義了一個服務的多個pod邏輯合集和訪問pod的策略,一般把service稱為微服務。
1.創建service
[root@server2 ~]# kubectl expose deployment nginx --port=80 [root@server2 ~]# kubectl get svc [root@server2 ~]# curl 10.100.138.138此時pod客戶端可以通過service的名稱訪問后端的兩個Pod
ClusterIP: 默認類型,自動分配一個僅集群內部可以訪問的虛擬IP
2 查看svc詳細信息
[root@server2 ~]# kubectl describe svc nginx這里的ip對應pod的副本ip
會根據副本數自動實現副本負載均衡
3.修改暴露類型
NodePort: 在ClusterIP基礎上為Service在每臺機器上綁定一個端口,這樣就可以通過 NodeIP:NodePort 來訪問該服務
[root@server2 ~]# kubectl edit svc nginx將類型改成NodePort
在外部訪問時,用的是節點ip+端口訪問
4 更新及回滾pod鏡像
[root@server2 ~]# kubectl set image deployment nginx myapp=myapp:v2 --record #更新 [root@server2 ~]# kubectl rollout undo deployment nginx --to-revision=1 #回滾 [root@server2 ~]# kubectl rollout history deployment nginx //查看歷史版本 [root@server2 ~]# curl 10.100.138.138四、資源清單
1.清單格式
清單格式
apiVersion: group/version //指明api資源屬于哪個群組和版本,同一個組可以有多個版本
$ kubectl api-versions //查詢命令
kind: //標記創建的資源類型,k8s主要支持以下資源類別
Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob
metadata: //元數據
name: //對像名稱
namespace: //對象屬于哪個命名空間
labels: //指定資源標簽,標簽是一種鍵值數據
spec: //定義目標資源的期望狀態
2. 參數信息
3 查看幫助
[root@server2 ~]# kubectl api-versions ## 查看所有api的版本信息 [root@server2 ~]# kubectl explain pod.spec.containers ## pod清單幫助 一層一層看4 刪除之前創建的
[root@server2 ~]# kubectl delete deployments.apps nginx [root@server2 ~]# kubectl delete svc nginx5 編寫創建pod 的api文件
[root@server2 ~]# vim pod.yml apiVersion: v1 kind: Pod metadata:name: nginxnamespace: default spec:containers:- name: nginximage: myapp:v1imagePullPolicy: IfNotPresent [root@server2 ~]# kubectl apply -f pod.yml [root@server2 ~]# kubectl get pod6 刪除
[root@server2 ~]# kubectl delete -f pod.yml7.編寫創建deployment api文件
[root@server2 ~]# vim deployment.yml apiVersion: apps/v1 kind: Deployment metadata:name: nginxnamespace: default spec:replicas: 3selector:matchLabels:run: nginxtemplate:metadata:labels:run: nginxspec:containers:- name: nginximage: myapp:v1imagePullPolicy: IfNotPresent [root@server2 ~]# kubectl apply -f deployment.yml [root@server2 ~]# kubectl get pod8.將運行中的pod轉換成yml格式
[root@server2 ~]# kubectl get pod nginx-b5548c7c4-4phr9 -o yaml9 優化
[root@server2 ~]# vim deployment.yml apiVersion: apps/v1 kind: Deployment metadata:name: nginxnamespace: default spec:replicas: 2selector:matchLabels:run: nginxtemplate:metadata:labels:run: nginxspec:#nodeSelector:# kubernetes.io/hostname: server4 nodeName: server3 #增加標簽選擇器#hostNetwork: true #使用主機網絡,注意端口不能沖突containers:- name: nginximage: myapp:v1imagePullPolicy: IfNotPresentresources:requests:cpu: 100m #最小限制;十分之一cpu資源,也可以寫成0.1memory: 70Milimits: #上限,超出被控制器殺死cpu: 0.5memory: 512Mi [root@server2 ~]# kubectl apply -f deployment.yml [root@server2 ~]# kubectl get pod -o wide [root@server2 ~]# kubectl describe pod全部在server3節點上
10.自主式Pod資源清單
在之前的基礎上再加一個容器進來
containers:- name: nginximage: myapp:v1imagePullPolicy: IfNotPresentresources:requests:cpu: 100m #最小限制;十分之一cpu資源,也可以寫成0.1memory: 70Milimits: #上限,超出被控制器殺死cpu: 0.5memory: 512Mi- name: busyboxplusimage: busyboxplusimagePullPolicy: IfNotPresentstdin: truetty: true [root@server2 ~]# kubectl apply -f deployment.yml [root@server2 ~]# kubectl get pod這時我們看到有兩個容器
運行的時候使用-c 指定容器
11.標簽
主要在控制器中使用,可以在節點上或pod打標簽
[root@server2 ~]# kubectl get pod --show-labels #查看標簽 [root@server2 ~]# kubectl label pod nginx-585f596658-gcd89 version=v1 ## 打標簽 [root@server2 ~]# kubectl label pod nginx-585f596658-gcd89 version=v2 --overwrite ##更改標簽 [root@server2 ~]# kubectl get pod -l version ##過濾標簽
節點標簽選擇器
在yaml文件中增加標簽選擇器
nodeSelector:disktype: ssd五、pod的生命周期
參考網站:kubernetes官網
(1)Pod 可以包含多個容器,應用運行在這些容器里面,同時 Pod 也可以有一個或多個先于應用容器啟動的 Init 容器。
(2)Init 容器與普通的容器非常像,除了如下兩點:
- 它們總是運行到完成。
- Init 容器不支持 Readiness,因為它們必須在 Pod 就緒之前運行完成,每個 Init 容器必須運行成功,下一個才能夠運行。
(3)如果 Pod 的 Init 容器失敗,Kubernetes 會不斷地重啟該 Pod,直到 Init 容器成功為止。然而,如果 Pod 對應的 restartPolicy 值為 Never,它不會重新啟動。
Init 容器能做什么?
Init 容器可以包含一些安裝過程中應用容器中不存在的實用工具或個性化代碼。
Init 容器可以安全地運行這些工具,避免這些工具導致應用鏡像的安全性降低。
應用鏡像的創建者和部署者可以各自獨立工作,而沒有必要聯合構建一個單獨的應用鏡像。
Init 容器能以不同于Pod內應用容器的文件系統視圖運行。因此,Init容器可具有訪問 Secrets 的權限,而應用容器不能夠訪問。
由于 Init 容器必須在應用容器啟動之前運行完成,因此 Init 容器提供了一種機制來阻塞或延遲應用容器的啟動,直到滿足了一組先決條件。一旦前置條件滿足,Pod內的所有的應用容器會并行啟動。
使用啟動探測器保護慢啟動容器
[root@server2 ~]# vim init.yml apiVersion: v1 kind: Pod metadata:name: myapp-podlabels:app: myapp spec:containers:- name: myapp-containerimage: myapp:v1initContainers:- name: init-myserviceimage: busyboxpluscommand: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"] [root@server2 ~]# vim service.yml --- apiVersion: v1 kind: Service metadata:name: myservice spec:ports:- protocol: TCPport: 80targetPort: 80 [root@server2 ~]# kubectl create -f init.yml [root@server2 ~]# kubectl get pod [root@server2 ~]# kubectl create -f service.yml [root@server2 ~]# kubectl get podinitContainers檢測機制檢測到myservice.default.svc.cluster.local,才會run
探針
探針 是由 kubelet 對容器執行的定期診斷:
- ExecAction:在容器內執行指定命令。如果命令退出時返回碼為 0 則認為診斷成功。
- TCPSocketAction:對指定端口上的容器的 IP 地址進行 TCP 檢查。如果端口打開,則診斷被認為是成功的。
- HTTPGetAction:對指定的端口和路徑上的容器的 IP 地址執行 HTTP Get 請求。如果響應的狀態碼大于等于200 且小于 400,則診斷被認為是成功的。
每次探測都將獲得以下三種結果之一:
- 成功:容器通過了診斷。
- 失敗:容器未通過診斷。
- 未知:診斷失敗,因此不會采取任何行動
Kubelet 可以選擇是否執行在容器上運行的三種探針執行和做出反應:
livenessProbe:指示容器是否正在運行。如果存活探測失敗,則 kubelet 會殺死容器,并且容器將受到其 重啟策略 的影響。如果容器不提供存活探針,則默認狀態為 Success。
readinessProbe:指示容器是否準備好服務請求。如果就緒探測失敗,端點控制器將從與 Pod 匹配的所有 Service 的端點中刪除該 Pod 的 IP 地址。初始延遲之前的就緒狀態默認為 Failure。如果容器不提供就緒探針,則默認狀態為 Success。
startupProbe: 指示容器中的應用是否已經啟動。如果提供了啟動探測(startup probe),則禁用所有其他探測,直到它成功為止。如果啟動探測失敗,kubelet 將殺死容器,容器服從其重啟策略進行重啟。如果容器沒有提供啟動探測,則默認狀態為成功Success。
定義存活命令
許多長時間運行的應用程序最終會過渡到斷開的狀態,除非重新啟動,否則無法恢復。 Kubernetes 提供了存活探測器來發現并補救這種情況。
[root@server2 ~]# vim live.yml apiVersion: v1 kind: Pod metadata:labels:test: livenessname: liveness-exec spec:containers:- name: livenessimage: busyboxplusargs:- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5這個容器生命的前 30 秒, /tmp/healthy 文件是存在的。 所以在這最開始的 30 秒內,執行命令 cat /tmp/healthy 會返回成功代碼。 30 秒之后,執行命令 cat /tmp/healthy 就會返回失敗代碼。
創建 Pod:
[root@server2 ~]# kubectl create -f live.yml在 30 秒內,查看 Pod 的事件:
[root@server2 ~]# kubectl describe pod liveness-exec35 秒之后,再來看 Pod 的事件:
[root@server2 ~]# kubectl describe pod liveness-exec在輸出結果的最下面,有信息顯示存活探測器失敗了,這個容器被殺死并且被重建了。
再等另外 30 秒,檢查看這個容器被重啟了:
輸出結果顯示 RESTARTS 的值增加了 1。
定義就緒 存活探測器
[root@server2 ~]# kubectl delete -f live.yml [root@server2 ~]# kubectl create -f live.yml [root@server2 ~]# kubectl get pod這里顯示沒有就緒
這時我們進入到交互頁面創建發布頁面
我們退出交互之后,再次查看,看到已經準備就緒
重啟策略
PodSpec 中有一個 restartPolicy 字段,可能的值為 Always、OnFailure 和 Never。默認為 Always。
Pod 的生命
一般Pod 不會消失,直到人為銷毀他們,這可能是一個人或控制器。
建議創建適當的控制器來創建 Pod,而不是直接自己創建 Pod。因為單獨的 Pod 在機器故障的情況下沒有辦法自動復原,而控制器卻可以。
三種可用的控制器:
使用 Job 運行預期會終止的 Pod,例如批量計算。Job 僅適用于重啟策略為 OnFailure 或 Never 的 Pod。
對預期不會終止的 Pod 使用 ReplicationController、ReplicaSet 和 Deployment ,例如 Web 服務器。 ReplicationController 僅適用于具有 restartPolicy 為 Always 的 Pod。
提供特定于機器的系統服務,使用 DaemonSet 為每臺機器運行一個 Pod 。
總結
- 上一篇: python模块与包
- 下一篇: k8s之pod管理(控制器)