- Pod(豆莢) 是Kubernetes集羣管理與調度的最小單元
2.一個Pod能夠封裝一個容器或多個容器(主容器或sidecar邊車容器)- 一個pod內的多個容器之間共享部分命名空間,例如:Net Namespace,UTS Namespace,IPC Namespace及存儲資源、
- 用戶pod默認會被調度運行在node節點之上(不運行在master節點上, 但也有例外狀況)
- pod內的IP不是固定的,集羣外不能直接訪問pod
可參考: https://kubernetes.io/zh/docs/concepts/workloads/pods/
1.無控制器管理的自主式pod 沒有副本控制器控制,刪除自主式pod後不會從新建立
2.控制器管理的pod 控制器能夠控制pod的副本數,擴容與裁剪,版本更新與回滾等node
pod是一種資源,能夠經過kubectl get pod來查看
kubectl get pod # pod或pods均可以, 不指定namespace,默認是名爲default的namespace
kubectl get pod -n kube-systemlinux
先看一個yaml格式的pod定義文件解釋nginx
# yaml格式的pod定義文件完整內容: apiVersion: v1 #必選,api版本號,例如v1 kind: Pod #必選,Pod metadata: #必選,元數據 name: string #必選,Pod名稱 namespace: string #Pod所屬的命名空間,默認在default的 namespace labels: # 自定義標籤 name: string #自定義標籤名字 annotations: #自定義註釋列表 name: string spec: #必選,Pod中容器的詳細定義(指望) containers: #必選,Pod中容器列表 - name: string #必選,容器名稱 image: string #必選,容器的鏡像名稱 imagePullPolicy: [Always | Never | IfNotPresent] #獲取 鏡像的策略 Alawys表示下載鏡像 IfnotPresent表示優先使用本地鏡像, 不然下載鏡像,Nerver表示僅使用本地鏡像 command: [string] #容器的啓動命令列表,如不指定,使用打包 時使用的啓動命令 args: [string] #容器的啓動命令參數列表 workingDir: string #容器的工做目錄 volumeMounts: #掛載到容器內部的存儲卷配置 - name: string #引用pod定義的共享存儲卷的名稱,需用 volumes[]部分定義的的卷名 mountPath: string #存儲卷在容器內mount的絕對路徑,應少 於512字符 readOnly: boolean #是否爲只讀模式 ports: #須要暴露的端口庫號列表 - name: string #端口號名稱 containerPort: int #容器須要監聽的端口號 hostPort: int #容器所在主機須要監聽的端口號,默認與 Container相同 protocol: string #端口協議,支持TCP和UDP,默認TCP env: #容器運行前需設置的環境變量列表 - name: string #環境變量名稱 value: string #環境變量的值 resources: #資源限制和請求的設置 limits: #資源限制的設置 cpu: string #Cpu的限制,單位爲core數,將用於docker run --cpu-shares參數 memory: string #內存限制,單位能夠爲Mib/Gib,將用 於docker run --memory參數 requests: #資源請求的設置 cpu: string #Cpu請求,容器啓動的初始可用數量 memory: string #內存清求,容器啓動的初始可用數量 livenessProbe: #對Pod內個容器健康檢查的設置,當探測無響 應幾回後將自動重啓該容器,檢查方法有exec、httpGet和tcpSocket,對 一個容器只需設置其中一種方法便可 exec: #對Pod容器內檢查方式設置爲exec方式 command: [string] #exec方式須要制定的命令或腳本 httpGet: #對Pod內個容器健康檢查方法設置爲HttpGet, 須要制定Path、port path: string port: number host: string scheme: string HttpHeaders: - name: string value: string tcpSocket: #對Pod內個容器健康檢查方式設置爲tcpSocket 方式 port: number initialDelaySeconds: 0 #容器啓動完成後首次探測的時間, 單位爲秒 timeoutSeconds: 0 #對容器健康檢查探測等待響應的超時時 間,單位秒,默認1秒 periodSeconds: 0 #對容器監控檢查的按期探測時間設置,單 位秒,默認10秒一次 successThreshold: 0 failureThreshold: 0 securityContext: privileged:false restartPolicy: [Always | Never | OnFailure] # Pod的重啓 策略,Always表示一旦無論以何種方式終止運行,kubelet都將重啓, OnFailure表示只有Pod以非0退出碼退出才重啓,Nerver表示再也不重啓該 Pod nodeSelector: obeject # 設置NodeSelector表示將該Pod調度 到包含這個label的node上,以key:value的格式指定 imagePullSecrets: #Pull鏡像時使用的secret名稱,以key: secretkey格式指定 - name: string hostNetwork:false #是否使用主機網絡模式,默認爲false, 若是設置爲true,表示使用宿主機網絡 volumes: #在該pod上定義共享存儲卷列表 - name: string #共享存儲卷名稱 (volumes類型有不少種) emptyDir: {} #類型爲emtyDir的存儲卷,與Pod同生命週期 的一個臨時目錄。爲空值 hostPath: string #類型爲hostPath的存儲卷,表示掛載 Pod所在宿主機的目錄 path: string #Pod所在宿主機的目錄,將被用於同期中 mount的目錄 secret: #類型爲secret的存儲卷,掛載集羣與定義的 secret對象到容器內部 scretname: string items: - key: string path: string configMap: #類型爲configMap的存儲卷,掛載預約義的 configMap對象到容器內部 name: string items: - key: string path: string
kubectl explain namespace #查找namespace
kubectl explain pod #查找pod
kubectl explain pod.spec #查找pod.spec
kubectl explain pod.spec.containers #pod.spec.containers算法
命令建立pod(v1.18變化)
k8s以前版本中, kubectl run命令用於建立deployment控制器 在v1.18版本中, kubectl run命令改成建立poddocker
kubectl run nginx1 --image=nginx:1.15-alpinevim
kubectl get podsapi
kubectl describe pod nginx1bash
vim pod1.yml網絡
apiVersion: v1 kind: Pod metadata: name: memory-demo spec: containers: - name: memory-demo-ctr image: polinux/stress command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
解釋以下: app
apiVersion: v1 # api版本 kind: Pod # 資源類型爲Pod metadata: name: memory-demo # 自定義pod的名稱 spec: containers: # 定義pod裏包含的容器 - name: memory-demo-ctr # 自定義pod中的容器名 image: polinux/stress # 啓動容器的鏡像名 command: ["stress"] # 自定義啓動容器時要執行的命令 (相似dockerfile裏的CMD) args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"] # 自定義啓動容器執行命令的參數 # polinux/stress這個鏡像用於壓力測試,在啓動容器時傳命令與參數就是 至關於分配容器運行時須要的壓力
2, 經過yaml文件建立pod
kubectl apply -f pod1.yml
kubectl get pod
kubectl get pod -o wide
kubectl describe pod memory-demo
方法1:
kubectl delete pod memory-demo
方法2:
kubectl delete -f pod1.yml
方法1: 後接多個pod名
kubectl delete pod pod名1 pod名2 pod名3
方法2: 經過awk截取要刪除的pod名稱,而後管道給xargs
kubectl get pods |awk 'NR>1 {print $1}' |xargs kubectl delete pod
方法3: 若是要刪除的pod都在同一個非default的命名空間,則可直接刪除 命名空間
kubectl delete ns xxxx
由imagePullPolicy參數控制
Always : 無論本地有沒有鏡像,都要從倉庫中下載鏡像
Never : 歷來不從倉庫下載鏡像, 只用本地鏡像,本地沒有就算了
IfNotPresent: 若是本地存在就直接使用, 不存在才從倉庫下載
默認的策略是:
當鏡像標籤版本是latest,默認策略就是Always
若是指定特定版本默認拉取策略就是IfNotPresent。
kubectl delete -f pod1.yml
kubectl apply -f pod1.yml
kubectl describe pod memory-demo
說明: 能夠看到第二行信息仍是pulling image下載鏡像
vim pod1.yml
apiVersion: v1 kind: Pod metadata: name: memory-demo spec: containers: - name: memory-demo-ctr image: polinux/stress command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"] imagePullPolicy: IfNotPresent # 增 加了這一句
kubectl delete -f pod1.yml
kubectl apply -f pod1.yml
kubectl describe pod pod-stress
說明: 第二行信息是說鏡像已經存在,直接使用了
爲pod設置label,用於控制器經過label與pod關聯
語法與前面學的node標籤幾乎一致
kubectl get pods --show-labels
kubectl label pod memory-demo region=huanai zone=A env=test bussiness=game
kubectl get pods --show-labels
kubectl get pods -l zone=A
kubectl get pods -l "zone in (A,B,C)"
kubectl label pod memory-demo region- zone- env- bussiness-
kubectl get pods --show-labels
pod的label與node的label操做方式幾乎相同 node的label用於pod調度到指定label的node節點 pod的label用於controller關聯控制的pod
vim pod1.yml
apiVersion: v1 kind: Pod metadata: name: memory-demo namespace: default labels: env: dev app: nginx # 直接在原來的yaml里加上多個標籤 spec: spec: containers: - name: memory-demo-ctr image: polinux/stress command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"] imagePullPolicy: IfNotPresent
kubectl apply -f pod1.yaml
kubectl get pods --show-labels
參考: https://kubernetes.io/zh/docs/tasks/configure-pod-container/ass ign-memory-resource/
vim pod2.yml
apiVersion: v1 kind: Namespace metadata: name: ns1 --- apiVersion: v1 kind: Pod metadata: name: pod2 namespace: ns1 spec: containers: - name: memory-demo-ctr image: polinux/stress imagePullPolicy: IfNotPresent resources: limits: memory: "200Mi" requests: memory: "100Mi" command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
vim pod3.yml
apiVersion: v1 kind: Namespace metadata: name: ns1 --- apiVersion: v1 kind: Pod metadata: name: pod3 namespace: ns1 spec: containers: - name: memory-demo-ctr image: polinux/stress imagePullPolicy: IfNotPresent resources: limits: memory: "200Mi" requests: memory: "100Mi" command: ["stress"] args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
kubectl apply -f pod2.yml
kubectl apply -f pod3.yml
kubectl describe pod pod3 -n ns1
查看會發現pod-stress3這個pod狀態變爲OOMKilled,由於它是內存不足所 以顯示Container被殺死
一旦pod中的容器掛了,容器會有重啓策略,以下
Always:表示容器掛了老是重啓,這是默認策略
OnFailures:表容器狀態爲錯誤時才重啓,也就是容器正常終止時才重
啓
Never:表示容器掛了不予重啓
對於Always這種策略,容器只要掛了,就會當即重啓,這樣是很耗費 資源的。因此Always重啓策略是這麼作的:第一次容器掛了當即重 啓,若是再掛了就要延時10s重啓,第三次掛了就等20s重啓...... 依次 類推
測試完後刪除kubectl delete ns ns1
vim pod4.yml
kind: Pod metadata: name: pod4 namespace: ns1 spec: containers: - name: c1 image: polinux/stress imagePullPolicy: IfNotPresent resources: limits: memory: "200Mi" requests: memory: "100Mi" command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"] - name: c2 image: polinux/stress imagePullPolicy: IfNotPresent resources: limits: memory: "200Mi" requests: memory: "100Mi" command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
kubectl apply -f pod4.yml
kubectl get pods -o wide -n ns1
能夠看到有2個容器,運行在192.168.5.11(node2)節點
4,在node2上驗證,確實產生了2個容器
docker ps -a |grep stress
命令幫助
kubectl exec -h
不用交互直接執行命令
格式爲: kubectl exec pod名 -c 容器名 -- 命令
-c 容器名爲可選項,若是是1個pod中1個容器,則不用指定;
若是是1個pod中多個容器,不指定默認爲第1個。
kubectl exec pod4 -c c2 -n ns1 -- touch /111
kubectl exec pod4 -c c2 -n ns1-- ls /111
不指定容器名,則默認爲pod裏的第1個容器
kubectl exec pod4 -n ns1 -- touch /222
kubectl exec pod4 -c c1 -n ns1 -- ls /222
和docker exec幾乎同樣
kubectl exec -it pod4 -c c1 -- /bin/bash
vim pod-nginx.yaml
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: c1 image: nginx:1.15-alpine - name: c2 image: nginx:1.15-alpine
kubectl apply -f pod-nginx.yaml
kubectl get pods |grep nginx
kubectl describe pod nginx
有一個啓不來,由於一個容器中兩個pod是共用網絡的,因此不能兩個都佔用 80端口
經過查找192.168.5.11(node2)上面的容器,而後docker logs查 看,獲得以下的報錯,說明是端口被佔用
kubectl describe pod nginx #查看
[root@node2 ~]# docker ps -a
docker logs -f -t --tail 100 e188eded7a01 #查看容器日誌
kubernetes會經過算法將pod調度到node節點上運行
pod調度流程
咱們爲了實現容器主機資源平衡使用, 可使用約束把pod調度到指定的 node節點
nodeName 用於將pod調度到指定的node名稱上
nodeSelector 用於將pod調度到匹配Label的node上
vim pod-nodename.yml
apiVersion: v1 kind: Pod metadata: name: pod-nodename spec: nodeName: 192.168.5.10 containers: - name: nginx image: nginx:1.15-alpine
kubectl apply -f pod-nodename.yml
kubectl describe pod pod-nodename |tail -6
倒數第3行沒有使用scheduler,而是直接給node1了,說明nodeName約束生效
kubectl label nodes 192.168.5.11 bussiness=game
vim pod-nodeselector.yml
apiVersion: v1 kind: Pod metadata: name: pod-nodeselect spec: nodeSelector: bussiness: game containers: - name: nginx image: nginx:1.15-alpine
kubectl apply -f pod-nodeselector.yml
kubectl describe pod pod-nodeselect |tail -6
仍然通過了scheduler,但確實分配到了node2(192.168.5.11)上有興趣能夠再刪除後再建立,重複幾回驗證