2.Pod

1. 概念

Pod 是 Kubernetes 项目里定义的最小可调度单元,是 Kubernetes 对应用程序的抽象。
Pod 组成可以是一个或者多个容器,属于同一个 Pod 的容器会共享:

  • 网络资源
  • 相同的 IP
  • 存储
  • 应用到 Pod 的自定义配置

2. Pod 的模型

根据组成 Pod 的容器数量可以将 Pod 分为两种类型:

  • 单容器模型:Pod是Kubernetes可识别的最小对象,Kubernetes管理调度Pod而不是直接管理容器,所以即使只有一个容器也需要封装到Pod里

  • 多容器模型:在这个模型中,Pod可以容纳多个紧密关联的容器以共享Pod里的资源。这些容器作为单一的,凝聚在一起的服务单元工作。比如:在Pod中有一个应用程序容器和一个日志记录容器。日志记录容器的唯一工作是从应用程序容器中提取日志。将两个容器放置同一个Pod里可消除额外的通信时间,因为它们位于同一个"主机",因此所有内容都是本地的并且它们共享所有资源,就跟在同一台物理服务器上执行这些操作一样。

Pod 本身不具备调节功能,如果 Pod 所在的节点发生故障,Pod 是不能自动调度到其他节点,需要使用控制器来完成 pod 的调度问题。Deployment就是最基础的控制器。通常我们都是在定义的控制器的配置里通过PodTemplate定义要控制的Pod,让控制器和所管控的Pod一起被创建出来。

3. Pod 的生命周期

Pod的生命周期有5个阶段:

  • Pending:pending 表示当 pod 中至少存在一个容器未创建的情况。
  • Running:容器已经创建完成,并且Pod已经被调度到了一个Node上。此时Pod内的容器正在运行,或者正在启动或重新启动。
  • Succeeded:Pod中的所有容器均已成功终止,并且不会重新启动。
  • Faild:所有容器均已终止,至少有一个容器发生了故障。失败的容器以非零状态退出。
  • Unknown:无法获得Pod的状态。

4. Pod 的 yaml 文件解析

Kubernetes 里所有的 API 对象都由四部分组成:

  • apiVersion: 当前使用的 Kubernetes 的 API 版本
  • kind:想创建的对象的种类
  • metadata:元数据,用来唯一表示当前的对象,比如 name,namespace 等
  • spec:Pod 的指定配置,例如镜像名称、容器名称、数据卷等

apiVersion,kind 和 metadata 是必填字段,适用于所有 Kubernetes 对象,而不仅仅是 pod。spec 里指定的内容(spec 也是必需字段)会因对象而异。

Pod 文件示例:

apiVersion: "api version"
kind: "Object to create"
metadata: 
  name: "Pod name"
  labels: 
    app: "label value"
spec:
  containers:
  - name: "container name"
    image: "image to use for container"

5. 示例:

5.1 单容器 Pod

apiVersion: v1 # kubernetes 的 API 版本
kind: Pod # 创建的对象为 Pod
metadata:  # 元数据
  name: first-pod # pod 的名称
  labels: 
    app: myapp
spec: # 指定的配置信息
  containers:
   - name: my-first-pod #容器名
     image: nginx # 指定的镜像

将 Pod 的清单文件部署到本地的 Kubernetes 集群中:

kubectl create -f pod-1.yaml

查看 Pod 的运行情况:

kubectl get pods

执行命令查看容器情况:

kubectl exec first-pod  -- service nginx status

在Pod里执行service nginx status指令,类似docker exec命令。

删除创建的 Pod

kubectl delete pod first-pod

5.2 多容器的 Pod

一个拥有两个容器的Pod,这些容器相互协作作为一个实体工作。其中一个容器每10秒将当前日期写入一个文件,而另一个Nginx容器则为我们展示这些日志。

apiVersion: v1
kind: Pod
metadata: 
  name: multi-container-pod
spec:
  volumes:
  - name: shared-data-logs # 为 Pod 中创建一个共享的数据卷
    emptyDir: {}
  containers:
  - name: container-writing-datas # 第一个容器的名称
    image: alpine
    command: ["/bin/sh"]
    args: ["-c", "while true; do date >> /var/log/output.txt; sleep 10; done"] # 每10秒写入当前时间
    volumeMounts:
    - name: shared-data-logs
      mountPath: /var/log
  - name: container-serving-dates # 第二个容器的名字
    image: nginx:1.7.9 # 镜像
    ports:
      - containerPort: 80 # 定义容器提供服务的端口
    volumeMounts:
    - name: shared-data-logs
      mountPath: /usr/share/nginx/html 

通过运行如下命令连接到Nginx容器里:

kubectl exec -it multi-container-pod -c container-serving-dates -- bash

在容器内运行curl'http://localhost:80/output.txt',它应该返回时间日志文件的内容给我们。

5.3 SideCar模式

可以在一个 Pod 中按照顺序启动一个或多个辅助容器,来完成一些独立于主进程(主容器)之外的工作,完成工作后这些辅助容器会依次退出,之后主容器才会启动,这种容器设计模式叫做 sidecar。

比如对于前端Web应用,如果把构建后的Js项目放到Nginx镜像的/usr/share/nginx/html目录下,Nginx和Js应用做成一个镜像运行容器,每次应用有更新或者Nginx要做升级、更新配置操作都需要重新做一个镜像,非常麻烦。

有了Pod之后,这样的问题就很容易解决了。我们可以把前端Web应用和Nginx分别做成镜像,然后把它们作为一个Pod里的两个容器"组合"在一起。这个Pod的配置文件如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: web-2
spec:
  initContainers:
  - image: kevinyan/front-app:v2
    name: front
    command: ["cp", "/www/application/*", "/app"]
    volumeMounts:
    - mountPath: /app
      name: app-volume
  containers:
  - image: nginx:1.7.9
    name: nginx
    ports:
      - containerPort: 80 # 定义容器提供服务的端口
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: app-volume
  volumes:
  - name: app-volume
    emptyDir: {}

所有spec.initContainers定义的容器,都会比spec.containers定义的用户容器先启动。并且,Init容器会按顺序逐一启动,直到它们都启动并且退出了,用户容器才会启动。所以,这个Init类型的容器启动后,执行了一句"cp /www/application/* /app",把应用包拷贝到"/app"目录下,然后退出。这个"/app"目录,挂载了一个名叫app-volume 的Volume。接下来Nginx容器,同样声明了挂载app-volume到自己的"/usr/share/nginx/html"目录下。由于这个Volume 是被Pod里的容器共享的所以等Nginx容器启动时,它的目录下就一定会存在前端项目的文件。这个文件正是上面的Init容器启动时拷贝到Volume里面的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容