三、pod詳解


pod基本概念
最小部署單元
可以包含多個容器
一個pod中的容器可以共享網絡命名空間
pod是短暫的(可能做一次滾動更新,IP就可能發生變化)
 
適合放在一個pod中的應用
兩個應用之間發生文件交互
  比如有兩個應用需要共享數據,那么如果通過外部存儲共享的方式,受到網絡之類的影響,性能較差,可以用到pod中的數據卷進行數據交互
  兩個應用需要通過127.0.0.1或者socket通信(比如:nginx+php)
  兩個應用需要發生頻繁的調用
 
Pod常用命令
查看pod
  kubectl get po
    -o wide 顯示較詳細信息
    -n 指定命名空間
 
查看service
  kubectl get service
 
刪除pod命令
  kubectl delete pod {pod名稱}
 
刪除當前目錄下所有yaml文件生成的pod
  kubectl delete -f .
  kubectl delete -f {yaml文件名}:刪除該yaml文件生成的pod,不會刪除yaml文件
 如果pod反復重啟無法刪除,則刪除對應控制器
  如:kubectl get deployment 獲取對應pod的name
    kubectl delete {控制器類型} {name前綴}
 
刪除service
  kubectl delete service {service名稱}
 
查看pod創建、啟動的信息
  kubectl describe pod TYPE/NAME
  如:kubectl describe pod web-deployment-667d4bd8df-tv2c9
 
查看容器日志,觀察有沒有異常的日志
  kubectl logs TYPE/NAME
  如:kubectl logs web-deployment-667d4bd8df-tv2c9
  如果有兩個容器:
  最后指定[-c CONTAINER]
  如:kubectl logs web-deployment-667d4bd8df-tv2c9 -c web2
 
如果一個pod中有多個容器,想進入不同的容器或看不同容器的日志,使用-c指定
  kubectl exec -ti {pod名稱} -c {容器名稱} -- sh
  kubectl logs {pod名稱} -c {容器名稱}
  容器的名稱在yaml文件中查看
 
pod已經啟動,進入調試應用
  kubectl exec POD [-c CONTAINER] -- COMMAND [args...]
 
 
pod中的容器分類
Infrastructure Container:基礎容器
  維護整個Pod網絡空間
 
InitContainers:初始化容器
  先於業務容器開始執行,最先啟動的容器
 
Containers:業務容器
  並行啟動
 
Pod 的實現原理
Pod 里的所有容器,共享的是同一個 Network Namespace,並且可以聲明共享同一個 Volume,其實就是一組共享了某些資源的容器
容器的本質是進程,Pod,實際上是在扮演傳統基礎設施里“虛擬機”的角色;而容器,則是這個虛擬機里運行的用戶程序。
 
pod文件釋義
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  annotations:
    kubernetes.io/change-cause: "django.v1"  #記錄到revision中的內容,方便回滾
spec:
  # 副本數,一個副本代表啟一個容器,如果一個pod掛了,那么會在其他副本再啟一個
  replicas: 3
  selector:
    matchLabels:
      # 標簽選擇器,一般寫兩個,上面項目名,下面應用名
      project: blog
      app: django
  template:
    metadata:
      labels:
        project: blog
        app: django
    spec:
      # 打標簽,資源調度使用
      nodeSelector:
        disktype: "ssd"
      containers:
      - name: web
        image: django# 鏡像拉取策略
        imagePullPolicy: IfNotPresent
        # 資源限制
        resources:
          # 容器最大使用資源,pod內存如果超出limits,會被k8s kill掉
          # 最好都設置資源限制和請求資源值,因為沒有限制pod會超出當前node承載能力的話,會造成資源爭搶
          limits:
            # 1000m表示一核,500m表示0.5核
            cpu: 1000m
            memory: 512M
          # 請求的資源值,k8s會根據這個值調度到能容納的node
          requests:
            cpu: 900m
            memory: 500M
        # 存活健康檢查
        livenessProbe:
          exec:
            command:
              - cat
              - /tmp/healthy
          # 啟動容器后多長時間做健康檢查,單位秒
          initialDelaySeconds: 5
          # 檢查周期間隔
          periodSeconds: 5
        # 就緒健康檢查
        readinessProbe:
          exec:
            command:
              - cat
              - /tmp/healthy
        ports:
        - containerPort: 80
        # 設置容器內的變量
        env:
          - name: ABC
            value: 123
      # 重啟策略
      restartPolicy: Always
      # 如果要啟動第二個容器,下面繼續寫
      - name: web2
        image: nginx
      # 如果是私有鏡像倉庫,必須要登陸,這個為了指定登陸私有鏡像倉庫的憑據
      imagePullSecrets:
        -name: myregistrykey

 

鏡像拉取策略
IfNotPresent:鏡像在宿主機上不存在時才拉取
Always:默認值,每次創建Pod都會重新拉取一次鏡像(即使鏡像已經在宿主機上)
Never:Pod永遠不會主動拉取這個鏡像
一般都會選擇Always
 
資源限制
為了讓k8s穩定的運行,防止某一個pod占用資源過大導致連接掛掉
CPU
2 = 2000m
1 = 1000m
0.5 = 500m
0.25 = 250m
 
重啟策略(restartPolicy)
Always:當容器終止退出后,總是重啟容器,默認策略(比如nginx、mysql等需要使用)
OnFailure:當容器異常退出口(退出碼為非0),才重啟容器
Never:當容器終止退出,從不重啟容器(短期運行的應用)
 
健康檢查(Probe)
  Probe有兩種類型
    存活檢查(livenessProbe)
      如果檢查失敗,將殺死容器,根據Pod的重啟策略來操作
    就緒檢查(readinessProbe)
      如果檢查失敗,k8s會把Pod從service endpoints中剔除
  在生產環境中一般兩個檢查會一起配置,兩個檢查除了名稱不一樣以外,其他都是一樣的
 
Probe支持一下三種檢查方法(一般通過查進程,端口來判斷)
httpGet
  發送HTTP請求,返回200-400范圍狀態碼為存活
# 健康檢查
livenessProbe:
  httpGet:
    path: /index.html
    port: 80
  # 啟動容器后多長時間做健康檢查,單位秒
  initialDelaySeconds: 5
  # 檢查周期間隔
  periodSeconds: 5
exec
  執行Shell命令返回狀態碼是0為成功
tcpSocket
  發起TCP Socket建立成功
 
pod提供數據卷和infra container解決共享存儲和網絡
共享存儲
比如有A、B兩個容器,都需要讀寫同一個存儲設備,那么一般會用到共享存儲,但共享存儲設備可能不在同一個空間內,會消耗過多的網絡資源等,這時可以將兩個容器部署在同一個Pod內,使用本地的磁盤來做數據交換,比如利用k8s提供的數據卷,A、B兩個容器都讀寫同一個目錄文件完成數據交換
 
共享網絡
k8s在創建一個pod的時候,會默認創建一個負責網絡的容器(infra container),該容器會有自己的網絡命名空間,這時候把容器A、B加入到這個容器中,就打通了A、B兩個容器的網絡
 
nodeName
用於將Pod調度到指定的Node上,因為不經過調度器(scheduler ),所以針對污點之類的,nodeName還是可以分配到已設置污點的node上
apiVersion: v1
kind: Pod
metadata:
  name: pod-example
  labels:
    app: nginx
spec:
  # 指定分配到k8s-node2節點
  nodeName: k8s-node2
  containers:
  - name: nginx
    image: nginx:1.15
影響pod調度的因素
1、根據request的值查找有足夠資源的node來調度此node
2、nodeSelector:用於將pod調度到匹配Label的node上
  給node打標簽
    kubectl label nodes {node名稱} key=value
    如:kubectl label nodes k8s-node1 disktype=ssd
  查看node的標簽
    kubectl get node --show-labels
  刪除node標簽(最后橫杠,別忘記)
    kubectl label nodes k8s-node2 {標簽鍵名}-
    如:kubectl label nodes k8s-node1 disktype-
apiVersion: v1
kind: Pod
metadata:
    name: pod-example
spec:
    # 調度到標簽為ssd的node上
    nodeSelector:
        disktype: "ssd"
containers:
 - name: nginx
  image: nginx:1.15

 

3、nodeAffinity:類似於nodeSelector,可以根據節點上的標簽來約束Pod可以調度到哪些節點
  相比nodeSelector:
    匹配有更多的邏輯組合,不只是字符串的完全相等
    調度分為軟策略和硬策略,而不是硬性要求
      硬: 必須滿足,否則啟動不成功
      軟:嘗試滿足,不保證
  操作符:In、Notln、Exists、DoesNotExist、Gt、Lt
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
     nodeAffinity:
       #硬性要求,如果沒有滿足標簽的node,那么無法啟動
       requiredDuringSchedulingIgnoredDuringExecution:
         nodeSelectorTerms:
         - matchExpressions:
          # gpu是鍵
          - key: gpu
          # 意思是哪個node節點含有這個鍵值,就會調度到哪個node
            operator: In
            values:
            # 這是值
            - nvidia-tesla
        #軟性要求
        preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
             matchExpressions:
             - key: group
             operator: In
             values:
             - ai
containers:
- name: web
image: nginx

 

4、污點(Taint)
  避免pod調度到特定的node上
    應用場景:
      專用節點
      配備了特殊硬件的節點
      基於污點的驅逐
    設置污點:
      kubtctl taint node {node名稱} key=value:effect
      如:kubtctl taint node k8s-node1 gpu=yes:NoSchedule
      其中[effect]可取值為:
        NoSchedule: 一定不能被調度
        PreferNoSchedule:盡量不要調度
        NoExecute: 不僅不會調度,還會驅逐node上已有的pod,被驅逐的oid自 動分配至別的node
    刪除污點:
      kubtctl taint node {node名稱} key:[effect]-
    查看污點:
      kubectl describe node | grep -i taint
 
污點容忍(Tolerations)
apiVersion: v1
kind: Pod
metadata:
  name: pod-taints
spec:
  containers:
  - name: pod-taints
     image: busybox:latest
   # 可以容忍污點等於no的污點類型,並且污點類型為NoSchedule
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "no"
    effect: "NoSchedule"
當node設置了污點以后,配置相同的污點容忍就可以分配到該node上

給Pod設置環境變量:
1、自定義變量
2、來自Pod字段,pod本身會攜帶一些屬性值,比如pod名稱,分配到哪個節點等,可以從pod中引用這個變量,在容器中使用,比如容器有個程序想知道pod運行在哪個節點上,可以用這個實現
3、來自secret、configmap
具體可查看以下鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM