Pod 是一組緊密關聯的容器集合,它們共享IPC、Network和UTS namespace,是 Kubernetes 排程的基本單元。Pod 的設計理念是支援多個容器在一個 Pod 中共享網路和檔案系統,可以通過程式間通訊和檔案共享這種簡單高效的方式組合完成服務。
一、Pod的定義
這裡還是以我們之前做的webapp為例定義一個Pod,這是一個最簡單的Pod定義
apiVersion: v1 kind: Pod metadata: name: webapp labels: app: webapp spec: containers: - name: webapp image: 172.16.194.135:5000/webapp:latest ports: - containerPort: 5000
關於Pod的定義比較重要的就是kind、spec.containers,kind就是定義資源型別、在spec.containers中主要定義容器所使用的映象,這裡可以定義多個容器。
二、Pod的基本使用
在使用Pod前我們需要注意,在Kubernetes中對於長時間執行的容器的要求是:其主程式需要一直在前臺執行。如果主程式執行在後臺,則Kubernetes會認為Pod執行結束,將會銷燬Pod。以webapp映象為例,它的Dockerfile如下:
FROM java:8 WORKDIR /opt/soft/ EXPOSE 4567 COPY webapp-1.0-SNAPSHOT.jar /opt/soft/webapp.jar ENTRYPOINT ["java", "-jar", "/opt/soft/webapp.jar"]
接下來,我們嘗試一下Pod中多容器的場景,我們的Pod包含兩個容器:webapp和busybox,Pod定義如下:
apiVersion: v1 kind: Pod metadata: name: webapp labels: app: webapp spec: containers: - name: webapp image: 172.16.194.135:5000/webapp:1.0 ports: - containerPort: 5000 - name: busybox image: busybox command: ["sh", "-c", "top"]
注意:busybox容器中我們定義了啟動命令top,這樣做就是為了確保busybox容器始終在前臺執行top命令,避免容器直接被銷燬。
我們建立Pod,並通過describe可以清楚看到這兩個容器的建立過程:
$ sudo kubectl create -f webapp_pod.yaml pod/webapp created $ sudo kubectl describe pod webapp Name: webapp Namespace: default Priority: 0 Node: ayato/172.16.194.135 Start Time: Sat, 08 Jan 2022 05:49:38 +0000 Labels: app=webapp Annotations: <none> Status: Running IP: 172.17.0.6 IPs: IP: 172.17.0.6 Containers: webapp: Container ID: docker://9c68ef7019126b65e2feba5d4d69e55997a9e573ce585b0bbb6a7cfe2fe20b31 Image: 172.16.194.135:5000/webapp:1.0 Image ID: docker-pullable://172.16.194.135:5000/webapp@sha256:df3a447a013ada0642dec67bb31976f42f1a0699a68873d0452f514fa24e5c77 Port: 5000/TCP Host Port: 0/TCP State: Running Started: Sat, 08 Jan 2022 05:49:40 +0000 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-pcr2h (ro) busybox: Container ID: docker://0dfd00b5fa8e419bfe0b4a43595c83cb1d4986980914865ae3371e1724c7f568 Image: busybox Image ID: docker-pullable://busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678 Port: <none> Host Port: <none> Command: sh -c top State: Running Started: Sat, 08 Jan 2022 05:49:45 +0000 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-pcr2h (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-pcr2h: Type: Secret (a volume populated by a Secret) SecretName: default-token-pcr2h Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m50s default-scheduler Successfully assigned default/webapp to ayato Normal Pulled 3m49s kubelet Container image "172.16.194.135:5000/webapp:1.0" already present on machine Normal Created 3m48s kubelet Created container webapp Normal Started 3m48s kubelet Started container webapp Normal Pulling 3m48s kubelet Pulling image "busybox" Normal Pulled 3m44s kubelet Successfully pulled image "busybox" in 4.516692787s Normal Created 3m44s kubelet Created container busybox Normal Started 3m43s kubelet Started container busybox
我們之前說過同一個Pod中的容器共享網路,也就是說我們在busybox容器中可以通過localhost訪問webapp的介面,我們嘗試一下:
$ sudo kubectl exec -it webapp -c busybox /bin/sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # wget http://localhost:4567/api/hello Connecting to localhost:4567 (127.0.0.1:4567) saving to 'hello' hello 100% |******************************************************************************************| 15 0:00:00 ETA 'hello' saved / # cat hello Hello my friend/ #
三、Pod容器共享Volume
同一個Pod中的容器能夠共享Pod級別的Volume,Volume可以被定義為各種型別,多個容器分別進行掛載操作。我們還是以webapp和busybox為例,webapp向volume中寫log,busybox通過tail命令讀log,Pod定義如下:
apiVersion: v1 kind: Pod metadata: name: webapp labels: app: webapp spec: containers: - name: webapp image: 172.16.194.135:5000/webapp:1.0 ports: - containerPort: 5000 volumeMounts: - name: webapp-logs mountPath: /tmp - name: busybox image: busybox command: ["sh", "-c", "tail -f /logs/log.out"] volumeMounts: - name: webapp-logs mountPath: /logs volumes: - name: webapp-logs emptyDir: {}
我們通過Pod定義中可以看到:我們設定了一個Volume,名稱為webapp-logs,type為emptyDir。容器webapp將Volume掛載到/tmp目錄,因為webapp配置了logback並會向/tmp中寫日誌。容器busybox將Volume掛載到/logs目錄,並通過tail命令持續讀日誌。我們啟動Pod,並使用kubectl logs命令從busybox中讀取tail的輸出:
$ sudo kubectl create -f webapp_pod.yaml pod/webapp created $ sudo kubectl logs webapp -c busybox 06:30:27.810 [INFO ] [main] [org.demo.webapp.todolist.TodoListApplication] Starting TodoListApplication v1.0-SNAPSHOT using Java 1.8.0_111 on webapp with PID 1 (/opt/soft/webapp.jar started by root in /opt/soft) 06:30:27.821 [INFO ] [main] [org.demo.webapp.todolist.TodoListApplication] No active profile set, falling back to default profiles: default 06:30:30.060 [INFO ] [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer] Tomcat initialized with port(s): 4567 (http) 06:30:30.079 [INFO ] [main] [org.apache.coyote.http11.Http11NioProtocol] Initializing ProtocolHandler ["http-nio-4567"] 06:30:30.088 [INFO ] [main] [org.apache.catalina.core.StandardService] Starting service [Tomcat] 06:30:30.089 [INFO ] [main] [org.apache.catalina.core.StandardEngine] Starting Servlet engine: [Apache Tomcat/9.0.41] 06:30:30.359 [INFO ] [main] [org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]] Initializing Spring embedded WebApplicationContext 06:30:30.359 [INFO ] [main] [org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext] Root WebApplicationContext: initialization completed in 2407 ms 06:30:30.913 [INFO ] [main] [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] Initializing ExecutorService 'applicationTaskExecutor' 06:30:32.634 [WARN ] [main] [org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration$DefaultTemplateResolverConfiguration] Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration) 06:30:32.956 [INFO ] [main] [org.apache.coyote.http11.Http11NioProtocol] Starting ProtocolHandler ["http-nio-4567"] 06:30:33.096 [INFO ] [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer] Tomcat started on port(s): 4567 (http) with context path '' 06:30:33.131 [INFO ] [main] [org.demo.webapp.todolist.TodoListApplication] Started TodoListApplication in 6.387 seconds (JVM running for 7.205)
關於Volume的型別,有如下幾種:
1)emptyDir:emptyDir是在Pod分配到Node時建立的,它的初始內容為空,並且無須指定host上對應的目錄檔案,它是由Kubernetes自動分配的目錄,當Pod銷燬後,emptyDir中的資料也會被刪除。一般可用作臨時空間,存放應用程式臨時資料。
2)hostPath:將宿主機中的檔案或目錄掛載到Pod中。通常用於應用永久資料的儲存。
3)iscsi:將iSCSI儲存裝置上的目錄掛載到Pod中。
4)nfs:將NFS上的目錄掛載到Pod中。
5)glusterfs:將GlusterFS網路檔案系統的目錄掛載到Pod中。
6)rbd:將Ceph塊裝置共享儲存掛載到Pod中。
7)gitRepo:通過掛載一個空目錄,並從Git中克隆一個git倉庫供Pod使用。
8)configmap:將配置資料掛載為容器中的檔案。
9)secret:將Secret資料掛載為容器中的檔案。