前面都是快速瀏覽過各個object所扮演的角色以及object之間的關係, 接下來要針對幾個常用object深入研讀,Pod是一切的開端, 就從Pod繼續探索吧!
Pod 是K8s最小的運作單位, 是用戶可以創建或部署的最小組件, 也是K8s運作容器的基礎, 大部分的object都是為了支援或擴展Pod而存在的;它是容器的集合, 這些容器共享 Network, UTS, IPC namespace, 容器具有相同的domain, IP 和 Port, 並且可以透過IPC直接通訊。

一個Pod裡面應該只運行一個應用程序, 多個Pod可以運作在不同的主機上, 例如把無狀態的應用(application server)放在一個Pod, 有狀態的應用(database server)放在另一個Pod,application server有可能會遇到請求變多需要擴充的狀況, 拆開之後就可以依照需求獨立擴充而互不影響,這樣才符合容器輕量化的概念, 也提高資源利用率。
不過還是會有遇到需要在同一個Pod中運行多個容器的狀況, 在K8s 中有提供幾種模式可以參考
Sidecar pattern (邊車模式)
Ambassador pattern (大使模式)
Adaptor pattern (適配器模式)
一個Pod至少需要一個容器, 所以在部署Spec中字段 containers、name為必填, image字段為方便更上層的Deployment等資源可以覆蓋image, 所以image為選填;此外, 每個工作節點上都必須配置容器運行的引擎, ex: Docker;啟動容器時會先在本地查找指定的image, 不存在的image則要從指定的Registry下載到本地。
容器中的imagePullPolicy字段用於指定獲取image的策略, 其中包含:
Always: image tag 設定為 latest或image不存在時, 從指定的Registry獲取。IfNotPresent: 當本地的image找不到時才從指定的Registry下載。Never: 禁止從Registry下載, 只能使用本地的image。對於tag為latest的image, 默認imagePullPolicy為default, 其餘為IfNotPresent。
容器中的ports字段是一個列表, 由一到多個端口對象組成, 列表常用字段包含:
containerPort <integer>: 必填, 指定Pod暴露的端口。name <string>: 當前端口的名稱, 此名稱可被Service調用。protocol: 端口協議, 可為 TCP或UDP, 預設TCP。範例: 指定容器使用TCP 協定暴露 Port 80, 名稱訂為 http
apiVersion: v1
kind: Pod
metadata:
   name: pod-example
spec:
  containers:
  - name: nginx-pod
    image: nginx:latest
    imagePullPolicy: Always
    ports:
    - name: http
      containerPort: 80
      protocol: TCP
可以使用kubectl explain pod.spec.containers.ports 查看詳細說明
如果要向Pod傳遞環境變數, 可以透過兩種方式: env 和 envFrom, 這邊先看 env。
env 是一個環境變數的列表, 通常由name和value組成:
name: 環境變數的名稱, 必填
value: 環境變數的值, 默認為空範例:
apiVersion: v1
kind: Pod
metadata:
   name: pod-env-example
spec:
  containers:
  - name: nginx-pod
    image: nginx:latest
    env:
    - name: API_LISTEN_PORT
      value: ":8801"
    - name: NSQ_WORKER
      value: 200
    ...
今天看了Pod的設計模式跟spec設定, 環境變數的部分由於都是key-value的設計, 在我們的專案有應用到階層式設計的env, 此時就必須額外寫一段程式把env轉成k8s spec使用的key-value格式。