K8S pod建立、標籤、資源限制、調度

pod介紹

pod定義與分類

  1. Pod(豆莢) 是Kubernetes集羣管理與調度的最小單元
    2.一個Pod能夠封裝一個容器或多個容器(主容器或sidecar邊車容器)
  2. 一個pod內的多個容器之間共享部分命名空間,例如:Net Namespace,UTS Namespace,IPC Namespace及存儲資源、
  3. 用戶pod默認會被調度運行在node節點之上(不運行在master節點上, 但也有例外狀況)
  4. pod內的IP不是固定的,集羣外不能直接訪問pod
    可參考: https://kubernetes.io/zh/docs/concepts/workloads/pods/

pod可分爲:

1.無控制器管理的自主式pod 沒有副本控制器控制,刪除自主式pod後不會從新建立
2.控制器管理的pod 控制器能夠控制pod的副本數,擴容與裁剪,版本更新與回滾等node

查看pod方法

pod是一種資源,能夠經過kubectl get pod來查看
kubectl get pod # pod或pods均可以, 不指定namespace,默認是名爲default的namespace
kubectl get pod -n kube-systemlinux

pod的YAML資源清單格式

先看一個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

YAML格式查找幫助方法回顧

kubectl explain namespace #查找namespace
kubectl explain pod #查找pod
kubectl explain pod.spec #查找pod.spec
kubectl explain pod.spec.containers #pod.spec.containers算法

pod建立與驗證

命令建立pod(v1.18變化)
k8s以前版本中, kubectl run命令用於建立deployment控制器 在v1.18版本中, kubectl run命令改成建立poddocker

1, 建立一個名爲pod-nginx的pod

kubectl run nginx1 --image=nginx:1.15-alpinevim

2, 驗證

kubectl get podsapi

K8S  pod建立、標籤、資源限制、調度

kubectl describe pod nginx1bash

K8S  pod建立、標籤、資源限制、調度

3.YAML建立pod

1, 準備yaml文件

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

查看pod信息

查看pod信息

kubectl get pod

K8S  pod建立、標籤、資源限制、調度

查看pod詳細信息

kubectl get pod -o wide

K8S  pod建立、標籤、資源限制、調度

描述pod詳細信息

kubectl describe pod memory-demo

K8S  pod建立、標籤、資源限制、調度

刪除pod

單個pod刪除

方法1:

kubectl delete pod memory-demo

方法2:

kubectl delete -f pod1.yml

多個pod刪除

方法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。

1.將上面的pod刪除再建立,使用下面命令查看信息

kubectl delete -f pod1.yml
kubectl apply -f pod1.yml
kubectl describe pod memory-demo

K8S  pod建立、標籤、資源限制、調度

說明: 能夠看到第二行信息仍是pulling image下載鏡像

2. 修改YAML

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      #  增 
加了這一句

3.再次刪除再建立

kubectl delete -f pod1.yml
kubectl apply -f pod1.yml
kubectl describe pod pod-stress

K8S  pod建立、標籤、資源限制、調度

說明: 第二行信息是說鏡像已經存在,直接使用了

pod的標籤

爲pod設置label,用於控制器經過label與pod關聯
語法與前面學的node標籤幾乎一致

經過命令管理標籤

1. 查看pod的標籤

kubectl get pods --show-labels

2. 打標籤,再查看

kubectl label pod memory-demo region=huanai zone=A env=test bussiness=game
kubectl get pods --show-labels

K8S  pod建立、標籤、資源限制、調度

3. 經過等值關係標籤查詢

kubectl get pods -l zone=A

K8S  pod建立、標籤、資源限制、調度

4. 經過集合關係標籤查詢

kubectl get pods -l "zone in (A,B,C)"

K8S  pod建立、標籤、資源限制、調度

5. 刪除標籤後再驗證

kubectl label pod memory-demo region- zone- env- bussiness-
kubectl get pods --show-labels

K8S  pod建立、標籤、資源限制、調度

小結:

pod的label與node的label操做方式幾乎相同 node的label用於pod調度到指定label的node節點 pod的label用於controller關聯控制的pod

經過YAML建立標籤

1.修改 yaml

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

2, 直接apply應用

kubectl apply -f pod1.yaml

3, 驗證

kubectl get pods --show-labels

K8S  pod建立、標籤、資源限制、調度

pod資源限制

參考: https://kubernetes.io/zh/docs/tasks/configure-pod-container/ass ign-memory-resource/

1.準備2個不一樣限制方式的建立pod

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"]

K8S  pod建立、標籤、資源限制、調度

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被殺死

K8S  pod建立、標籤、資源限制、調度

說明:

一旦pod中的容器掛了,容器會有重啓策略,以下
Always:表示容器掛了老是重啓,這是默認策略
OnFailures:表容器狀態爲錯誤時才重啓,也就是容器正常終止時才重

Never:表示容器掛了不予重啓
對於Always這種策略,容器只要掛了,就會當即重啓,這樣是很耗費 資源的。因此Always重啓策略是這麼作的:第一次容器掛了當即重 啓,若是再掛了就要延時10s重啓,第三次掛了就等20s重啓...... 依次 類推
測試完後刪除

kubectl delete ns ns1

pod包含多個容器

1.準備yml文件

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"]

2.應用yml文件建立pod

kubectl apply -f pod4.yml

3. 查看pod在哪一個節點

kubectl get pods -o wide -n ns1

K8S  pod建立、標籤、資源限制、調度

能夠看到有2個容器,運行在192.168.5.11(node2)節點

4,在node2上驗證,確實產生了2個容器

docker ps -a |grep stress

K8S  pod建立、標籤、資源限制、調度

對pod裏的容器進行操做

命令幫助
kubectl exec -h

K8S  pod建立、標籤、資源限制、調度

不用交互直接執行命令
格式爲: 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

K8S  pod建立、標籤、資源限制、調度

不指定容器名,則默認爲pod裏的第1個容器

kubectl exec pod4 -n ns1 -- touch /222

K8S  pod建立、標籤、資源限制、調度

kubectl exec pod4 -c c1 -n ns1 -- ls /222

K8S  pod建立、標籤、資源限制、調度

和容器交互操做

和docker exec幾乎同樣

kubectl exec -it pod4 -c c1 -- /bin/bash

K8S  pod建立、標籤、資源限制、調度

驗證pod中多個容器網絡共享

1, 編寫YAML

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

2. 應用YAML

kubectl apply -f pod-nginx.yaml

3.查看pod信息與狀態

kubectl get pods |grep nginx
K8S  pod建立、標籤、資源限制、調度

kubectl describe pod nginx

有一個啓不來,由於一個容器中兩個pod是共用網絡的,因此不能兩個都佔用 80端口

K8S  pod建立、標籤、資源限制、調度

經過查找192.168.5.11(node2)上面的容器,而後docker logs查 看,獲得以下的報錯,說明是端口被佔用
kubectl describe pod nginx #查看

K8S  pod建立、標籤、資源限制、調度

[root@node2 ~]# docker ps -a

K8S  pod建立、標籤、資源限制、調度

docker logs -f -t --tail 100 e188eded7a01 #查看容器日誌

K8S  pod建立、標籤、資源限制、調度

4、pod調度

kubernetes會經過算法將pod調度到node節點上運行
pod調度流程

K8S  pod建立、標籤、資源限制、調度

調度約束方法

咱們爲了實現容器主機資源平衡使用, 可使用約束把pod調度到指定的 node節點
nodeName 用於將pod調度到指定的node名稱上
nodeSelector 用於將pod調度到匹配Label的node上

案例1: nodeName

1. 編寫YAML文件

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

2.應用YAML文件建立pod

kubectl apply -f pod-nodename.yml

3. 驗證

kubectl describe pod pod-nodename |tail -6

倒數第3行沒有使用scheduler,而是直接給node1了,說明nodeName約束生效

K8S  pod建立、標籤、資源限制、調度

案例2: nodeSelector

1.爲192.168.5.11(node2)打標籤

kubectl label nodes 192.168.5.11 bussiness=game

2. 編寫YAML文件

vim pod-nodeselector.yml

apiVersion: v1
kind: Pod
metadata:
   name: pod-nodeselect
spec:
  nodeSelector:
    bussiness: game
  containers:
  - name: nginx
    image: nginx:1.15-alpine

3.應用YAML文件建立pod

kubectl apply -f pod-nodeselector.yml

4.驗證

kubectl describe pod pod-nodeselect |tail -6

K8S  pod建立、標籤、資源限制、調度

仍然通過了scheduler,但確實分配到了node2(192.168.5.11)上有興趣能夠再刪除後再建立,重複幾回驗證

相關文章
相關標籤/搜索