為什麼Kubernetes使用Pod作為最小調度單元

  • 2019 年 10 月 3 日
  • 筆記

一、Pod說明

Pod只是一個邏輯概念,一個原子調度單位,其優勢在於

  1. 可以統一調度一組容器到指定的node上
  2. 共享資源:Pod的容器可以使用localhost進行通信,使用volume進行文件共享、使用socket文件進行本地通信,減少頻繁的遠程網絡請求網絡
  3. 使容器A和容器B不依賴啟動順序(通過使用infra容器,解決docker volume-from存在的容器啟動的先後順序問題,)

二、4種容器部署方式

需求:Tomcat通過webapp下的WAR包運行應用

1. 一個tomcat鏡像+war包鏡像

將WAR包放在Tomcat鏡像的webapps目錄下,做成一個新的docker鏡像,
缺點:更新WAR包或者升級Tomcat鏡像,都要重新發佈鏡像

2. 一個tomcat鏡像+war包掛載宿主機

聲明一個hostPath類型的Volume,把宿主機的WAR包掛載到Tomcat容器當中運行起來,只有一個tomcat鏡像
缺點:要在宿主機里放一個WAR包,並且得通知宿主機更新這個包

3. 一個tomcat鏡像+一個war包鏡像,通過–volumes-from方式

通過A容器--volumes-from=B容器方式,將B容器目錄掛載
缺點:容器存在啟動先後順序,地位不對等

4. 一個tomcat鏡像+一個war包鏡像,通過pod方式

單獨給WAR包和Tomcat分別做成鏡像,然後放在一個Pod容器里組合在一起, 利用Init Container解決順序和依賴關係,
initContainers會先啟動,按順序 tomcat和initContainer的容器聲明了同樣的Volume,然後Container容器啟動後,volume就已經存在程序了,tomcat就可以直接執行
這樣只需要在tomcat或者WAR更新的時候,單獨更新相應的鏡像,yaml如下

apiVersion: v1  kind: Pod  metadata:    name: javaweb-2  spec:    initContainers:    - image: xxx/sample:v2      name: war      command: ["cp", "/sample.war", "/app"]      volumeMounts:      - mountPath: /app        name: app-volume    containers:    - image:xxx/tomcat:7.0      name: tomcat      command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]      volumeMounts:      - mountPath: /root/apache-tomcat-7.0.42-v2/webapps        name: app-volume      ports:      - containerPort: 8080        hostPort: 8001    volumes:    - name: app-volume      emptyDir: {}

三、 K8s中的Volume

K8s的volume和mountPath是bind mount的方式,功能就是把文件或目錄綁定掛載在一起,bind mount的掛載點是容器volume在宿主機上的目錄
k8s項目只要把所有Volume的定義都設計在Pod層級,一個Volume對應的宿主機目錄對於Pod來說只有一個,只要聲明掛載了這個Volume,就可以共享這個Volume對應的宿主機目錄

apiVersion: v1  kind: Pod  metadata:    name: two-containers  spec:    restartPolicy: Never    volumes:    - name: shared-data      hostPath:        path: /data    containers:    - name: nginx-container      image: nginx      volumeMounts:      - name: shared-data        mountPath: /usr/share/nginx/html    - name: debian-container      image: debian      volumeMounts:      - name: shared-data        mountPath: /pod-data      command: ["/bin/sh"]      args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]

debin-container和nginx-conntainer都聲明掛載了shared-data這個Volume,shared-data是hostPath類型,對應宿主機的/data,同時被綁定掛載進了兩個容器中,這就是為什麼nginx-container可以從它的/usr/share/nginx

四、總結

形象的說,雲計算機的操作系統是K8S,容器相當於進程,而Pod則是進程組(可以使用pstree -g查看)
Pod扮演的是傳統基礎設施的「虛擬機」的角色,容器則是虛擬機的應用程序,要完成虛擬機應用到微服務架構的遷移,核心思想是:

  1. 分析應用組成(組件、進程)
  2. 拆分成松耦合的容器(以容器鏡像方式分發)
  3. 利用Init Container解決順序和依賴關係