Kubernetes多容器Pod实战

前言

容器受限于“单进程模型”,往往一个容器只运行一个主进程,但是一个复杂任务又需要多个进程相互配合工作,所以推荐给每个进程都启动一个容器。这些相互配合的容器必然存在依赖关系,它们之间往往会发生频繁的基于存储卷或 Socket 的数据交换行为,因此它们其实形成了一个“容器组”的概念,它们必须成组调度到同一台机器上,否则这些数据交换处理起来会很麻烦。kubernetes 中的 Pod 其实就是容器组的概念,一个 Pod 可以包含一个或多个容器,这些容器共享存储卷和网络,可以使用 localhost 直接通信。

所以,在使用 kubernetes 部署应用时,我们应该思考这样一个问题:当面对多个容器时,我们是应该部署多个 Pod,还是在一个 Pod 里面启动多个容器?

Pod中的多容器

Pod 是 Kubernetes 的最小调度单位,一个 Pod 里面可以启动一个或多个容器,这些容器共享网络、存储卷、生命周期。

一个 Pod 中的多个容器,它们通常围绕一个核心任务紧密协作,多容器 Pod 应用场景主要有两类:

  • 主从容器模式:主容器提供核心功能,从容器提供辅助性功能,例如:日志采集上报、服务监控等
  • Sidecar 模式:边车模式,利用辅助容器来增强主容器的功能,而无需修改主容器代码。例如:辅助容器拦截进出流量,实现数据加工,请求路由等功能。

相比将多个功能打包到一个容器中,使用多容器 Pod 更符合“单一职责原则”,每个容器专注于一个任务,便于维护和扩展。同时,容器之间通过共享资源(如网络、存储)减少冗余,但彼此仍保持进程级隔离,避免直接干扰。多容器 Pod 具备灵活的扩展性,通过 Sidecar 模式,增加辅助容器来增强主容器,而无需修改主容器代码,减少侵入性。

部署多个 Pod 还是一个 Pod 启动多个容器?

这要根据业务需求、容器协作模式和运维复杂度综合决策。遵循的原则简单概括如下:

  • 单 Pod 多容器:容器之间需要高频交互(localhost 通信,共享存储卷)、且强依赖(一个容器的崩溃会影响其它容器)。举例:日志收集、服务监控、网络代理等
  • 多 Pod 单容器:容器间需要松耦合,且职责独立,甚至需要独立弹性。举例:Web服务和数据库虽然也会发生数据交换,但不适合部署在同一 Pod 里面,通信直接通过 service 即可。

多容器Pod实战

实战案例:通过 Pod 部署一个包含3个容器的应用,一个 Nginx 容器对外提供服务,运行中会产生日志;一个 log-process 容器,负责收集并处理 Nginx 才生的日志;一个 monitor 容器,负责监控 Nginx 服务状态。

这是个非常适合在一个 Pod 里面启动多个容器的例子,主容器是 Nginx,辅助容器是 log-process 和 monitor,Nginx 一旦挂了,辅助容器就没法工作也没有意义了。它们之间是强依赖的,且会发生频繁的数据交换行为,log-process 必然要共享 Nginx 的日志文件,monitor 必然要和 Nginx 建立网络连接。

如下是 Pod 对象的描述文件,spec.containers 是一个数组,配置了三个容器,分别是 nginx、log-process、monitor。因为要共享日志文件,所以声明了一个 volume,名称是 log-volume,类型是 emptyDir,只在容器运行时有效。log-volume 会被同时挂载到 Nginx 和 log-process,这样 log-process 就能读取到 Nginx 产生的日志文件了。monitor 没有额外配置啥,它直接通过 localhost 访问 Nginx 来监控服务状态即可。

apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
  labels:
    app: multi-container
spec:
  containers:
  - name: nginx
    image: docker.io/library/mynginx:1.0
    imagePullPolicy: Never
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: /var/log/nginx
      name: log-volume
  - name: log-process
    image: docker.io/library/log-process:1.0
    imagePullPolicy: Never
    volumeMounts:
    - mountPath: /app/log
      name: log-volume
    env:
    - name: LOG_FILE_PATH
      value: "/app/log/nginx_access.log"
  - name: monitor
    image: docker.io/library/monitor:1.0
    imagePullPolicy: Never
  volumes:
  - name: log-volume
    emptyDir: {}

kubectl apply -f pod.yaml部署这个 Pod,过一会发现,三个容器都已经启动成功了,且 Pod 被分配的 IP 是 10.244.1.17。

请求这个 IP,是可以成功访问到 Nginx 的。随着我们的访问,此时就已经产生访问日志了。

kubectl exec -it multi-container-pod -c log-process sh进入 log-process 容器,可以访问到 nginx_access.log,同时脚本会实时处理读取到的日志,并写入 output.log。

同理,monitor 容器会持续访问 Nginx 记录响应的状态码,来监控服务状态。

尾巴

通过 kubernetes 部署应用,我们无需关心应用会被部署到哪台机器上,但是我们要关心如何设计 Pod。面对多容器时,是部署多个 Pod,还是在一个Pod里面启动多个容器,是我们要思考的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小潘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值