Docker 与 K8S学习笔记(十八)—— Pod的使用
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: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: 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: Host Port: Command: sh -c top State: Running Started: Sat, 08 Jan 2022 05:49:45 +0000 Ready: True Restart Count: 0 Environment: 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: 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数据挂载为容器中的文件。