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 来监控服务状态即可。

yaml 复制代码
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里面启动多个容器,是我们要思考的问题。

相关推荐
zyl837212 小时前
Docker 使用手册
运维·docker·容器
Elastic 中国社区官方博客4 小时前
我们如何在 Elasticsearch Serverless 上将向量搜索吞吐量提升一倍
大数据·数据库·人工智能·elasticsearch·搜索引擎·云原生·serverless
maomao大哥闯天下5 小时前
K8s如何实现滚动更新、健康检查与探测机制
docker·容器·kubernetes
楼田莉子5 小时前
Docker学习:Docker介绍及其架构介绍
运维·后端·学习·docker·容器·架构
张忠琳7 小时前
【kubernetes v1.21】(一)Kubernetes 总览架构深度分析
云原生·架构·kubernetes
香气袭人知骤暖7 小时前
PG数据库 Docker 容器自动备份方案
数据库·docker·容器
maomao大哥闯天下8 小时前
K8s对象deployment、job、service应用详解
java·容器·kubernetes
IT策士8 小时前
第 20 篇 搭建 Kubernetes 实验环境:Minikube 与 kubectl
云原生·容器·kubernetes
JackSparrow4149 小时前
使用Ansible批量管理+更新产品环境服务器配置
运维·服务器·ci/cd·kubernetes·自动化·ansible·sre
ai产品老杨10 小时前
基于 Docker 容器化与异构计算的智能安防架构:解耦 GB28181/RTSP 协议与多芯片适配,源码交付如何助力集成商节省 95% 开发成本?
docker·容器·架构