Kubernetes pod 是部署在同一主机的一组容器。 如果你定义的 pod 里只有一个容器那么可以说此 pod 就是此容器。 既然要部署在一起,那么这组容器是要干点什么事情的。 他们在一起是要共享些什么,并且要一起生一起死。
Kubernetes pod 内的容器共享 Network Namespaces, Volumes and Resources limits。
想要理解共享的含义,让我们先来看一下用 Docker 怎么实现这样的共享。
Docker Containers Shared Network Namespace
Docker 为容器提供了四种网络模式 bridge, none, container 和 host 。其中 container 模式就是提供容器间共享网络命名空间(Network Namespace)的模式。
还记得我们上一篇 Kubernetes - Running First App on Kubernetes 在 build docker image 章节里创建了一个 Node.js 服务的 Docker 镜像,这里用它来做演示作为其中一个容器。用下面命令创建一个运行 Node.js server process 的容器
$ docker run --rm -d --name=node-server -p 80:80 tiven/kube-tiven
看到这里暴露的端口号是 80
不是 8080
另外一个容器使用 nginx 作为 Node.js server 的前置反向代理服务器。首先创建一个 nginx 的配置文件内容如下
default.conf
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
此配置内容简单,监听在 80
端口,把所有请求代理到本机 8080
端口。再新建一个 Docker 镜像构建文件
Dockerfile
FROM nginx
ADD default.conf /etc/nginx/conf.d/default.conf
此配置文件含义是基于 nginx 默认最新镜像,使用我们建的配置文件替换掉原来默认带的配置文件。运行构建镜像,然后创建容器
$ docker build -t kube-nginx .
$ docker run --rm -d --name=nginx-web --network=container:node-server kube-nginx
可以看到 --network=container:node-server
参数说明此容器运行在基于现有容器 node-server
的网络上。
如下调用你运行 Docker 容器的主机的 80
端口,可以访问 Node.js server 进程
$ curl <host-ip>:80
You've hit 26316a133da7
查看两个容器详情,可以看到我们确实访问了 26316a133da7
这个容器上的进程
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52aea5a754da kube-nginx "nginx -g 'daemon of…" 49 seconds ago Up 10 seconds nginx-web
26316a133da7 tiven/kube-tiven "node app.js" 18 hours ago Up 18 hours 0.0.0.0:80->80/tcp node-server
基于现有容器网络的 Docker 容器网络模式架构如下图所示,可以更好地理解 Docker 容器共用网络的整个交互过程
Pods using pause
上面的容器共享网络模式有一些瑕疵,一些共享的属性(如端口号)放在哪个容器初始化都不合适。所以 Kubernetes Pod 使用了一个单独的容器作为 Pod 内其他容器的基础设施容器,如下
$ docker run --rm -d --name=pause -p 80:80 k8s.gcr.io/pause
k8s.gcr.io/pause
是 Kubernetes 的一个镜像,它基本为空,只作为共享基础设施用。我们把暴露的端口号设置在此容器上,然后运行其他的容器,如下
$ docker run --rm -d --name=node-server --network=container:pause tiven/kube-tiven
$ docker run --rm -d --name=nginx-web --network=container:pause kube-nginx
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9e013c5f982c kube-nginx "nginx -g 'daemon of…" 2 minutes ago Up 19 seconds nginx-web
3a5db34a2373 tiven/kube-tiven "node app.js" 2 minutes ago Up 53 seconds node-server
b788ed17093d k8s.gcr.io/pause "/pause" 3 minutes ago Up About a minute 0.0.0.0:80->80/tcp pause
$ curl <host-ip>
You've hit b788ed17093d
看到返回的结果是显示访问的 b788ed17093d
主机名,说明 hostname
也是共享的。
Kubernetes pod 的容器共享网络架构如下图所示
除了 network Kubernetes pod 内容器还共享另外两种设施进程命名空间(pid)和进程间通信(ipc),重新运行容器如下
$ docker run --rm -d --name=pause -p 80:80 k8s.gcr.io/pause
$ docker run --rm -d --name=node-server --network=container:pause --pid=container:pause --ipc=container:pause tiven/kube-tiven
$ docker run --rm -d --name=nginx-web --network=container:pause --pid=container:pause --ipc=container:pause kube-nginx
$ docker exec -it node-server bash
root@00d5a8ed906a:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 265272 444 ? Ssl 05:25 0:00 /pause
root 9 0.9 2.8 872872 28600 ? Ssl 05:25 0:00 node app.js
root 20 0.4 0.4 32472 4948 ? Ss 05:25 0:00 nginx: master p
systemd+ 25 0.0 0.2 32952 2500 ? S 05:25 0:00 nginx: worker p
root 26 1.0 0.2 20244 3012 pts/0 Ss 05:26 0:00 bash
root 31 0.0 0.2 17500 2060 pts/0 R+ 05:26 0:00 ps aux
查看 node-server
容器内的进程可以看到三个容器的所有进程。
Comments