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

相关推荐
互联网哪些事情4 小时前
Docker 容器化部署宝塔 Linux 面板
linux·docker·容器·宝塔云服务器
坚定信念,勇往无前4 小时前
docker安装mongodb
mongodb·docker·容器
Destiny_where4 小时前
k8s常用指令集合
linux·docker·kubernetes
叮咚侠5 小时前
将已创建的Elasticsearch 8.12.0的docker容器中的数据挂载到宿主机操作步骤
运维·elasticsearch·docker·容器·kibana
wuxingge5 小时前
docker设置代理,通过代理服务器拉取镜像
docker·容器
SZ1701102315 小时前
K8s 部署所需的配置文件
云原生·容器·kubernetes
小池先生5 小时前
docker 安装gitlab
docker·容器·gitlab
赫尔·普莱蒂科萨·帕塔5 小时前
Kurator 分布式云原生环境技术深度分析与实践指南
分布式·云原生
永亮同学5 小时前
【探索实战】从“工具堆叠”到“平台治理”:基于 Kurator 构建统一分布式云原生管理底座的实践与思考
分布式·云原生
rchmin5 小时前
云原生概念与技术详解
云原生