pod是kubernetes 的最小调度单位

同一个pod中的容器,共享同一个network namespace ,同时可以声明挂载同一个volume实现数据共享。

具体实现方式是:通过一个叫infra 的中间容器将同一个pod的容器之间网络连接起来


这个infra 容器就是我们常说的pause容器,该容器会首先被创建,并将其他容器通过join network namespace 的方式关联起来。

image.png


  • 同一个pod中2个容器它们之间的关系是:

  • 它们可以直接使用 localhost 进行通信;

  • 它们看到的网络设备跟 Infra 容器看到的完全一样;

  • 一个 Pod 只有一个 IP 地址,也就是这个 Pod 的 Network Namespace 对应的 IP 地址;

  • 其他的所有网络资源,都是一个 Pod 一份,并且被该 Pod 中的所有容器共享;

  • Pod 的生命周期只跟 Infra 容器一致,而与容器 A 和 B 无关。


案例一: 通过docker 方式部署war 包

通过docker 部署war包跟web大抵有2种方式

(1) 将war包跟tomcat 打包到一个镜像中,优点是管理方便,镜像可以到处部署;缺点是每次升级tomcat或者war包,都得重新打包镜像,比较麻烦

(2) 将tomcat 打成基础镜像,并通过hostPath 的方式,将存放在宿主机上的war包挂载到tomcat 的容器中。这种方式优点在于war包升级无需重复打包基础镜像;缺点是多台主机部署时,需要解决分布式部署的问题;

通过pod 的方式部署,可以做以下优化:

将war 包跟 tomcat 分别打包成2个镜像,共同组成一个pod,例如:

apiVersion: v1
kind: Pod
metadata:
  name: javaweb-2
spec:
  initContainers:
  - image: geektime/sample:v2
    name: war
    command: ["cp", "/sample.war", "/app"]
    volumeMounts:
    - mountPath: /app
      name: app-volume
  containers:
  - image: geektime/tomcat:7.0
    name: tomcat
    command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]
    volumeMounts:
    - mountPath: /root/apache-tomcat-7.0.42-v2/webapps
      name: app-volume
    ports:
    - containerPort: 8080
      hostPort: 8001 
  volumes:
  - name: app-volume
    emptyDir: {}

通过init container 做一些初始化操作,init container 会优先于用户定义的容器启动,它们会按照顺序逐一启动,并在所有init container 启动并退出后,才会启动用户定义的container


在上述例子中,init container 里面只有一个war包,启动时执行的操作是,将war 包拷贝到指定目录随即退出,/app 这个目标目录挂载的是宿主机上的volume,然后再用户定义容器(仅包含tomcat的镜像)中将该volume挂载进去,此时两个容器可共享该volume。

这种组合方式有个专业名词叫sidecar。


案例二: 容器日志采集

假设容器 A ,里面跑着a进程,不断的往/var/log/test.log 产生日志,如果我们要采集该日志,也可以通过sidecar 的方式部署日志采集进程。具体实现方式大致如下:

将进程a 跟 采集日志agent (例如logstash)分别打包成2个镜像,组成同一个pod;

创建一个volume ,同时挂载到两个容器中;

A 容器往volume 写入日志,而logstash 容器则负责从volume中采集日志上报给日志分析平台