假设有一个Nginx应用程序,启用了“http_stub_status_module”模块,以提供关于Nginx运行状态的统计信息。同时,获取这些统计信息的访问路径被配置为“/nginx_status”,内容如下:
为了能够定期将“/nginx_status”路径提供的统计信息存储到数据库中,开发了一个“指标采集程序”来完成这项任务,如图3-1所示。
这两个应用程序之间存在“密切协作关系”,因此它们被定义在同一个Pod中,如图3-2所示。
图3-1 Nginx指标采集流程
图3-2 Pod中定义的多个容器
在这种环境下,我们会想到一个问题:指标采集程序是否可以访问“http://127.0.0.1/nginx_status”?
你的答案可能是否定的,因为这两个容器的网络命名空间是隔离的。
不过,这在Pod中是可以的。这是因为Kubernetes将这两个容器共享了网络命名空间,使其在一个网络协议栈中。具体来说,当创建一个Pod时,Kubernetes首先会创建一个“Pause容器”,这是一个特殊的容器,在创建后即刻进入“暂停”状态,仅用于创建一个容器环境。接着,我们定义的容器会被创建并加入“Pause容器”的网络命名空间中,如图3-3所示。
图3-3 Pod中容器之间的共享网络
这样,Pod中所有的容器都处于同一个网络命名空间中,应用程序就像被部署在同一台主机上,可以通过本地回环地址(127.0.0.1)访问彼此。
接下来,运行一个Pod来验证这个结论。创建一个名为“pod-network.yaml”的文件,内容如下:
创建Pod资源:
[root@k8s-master ~]# kubectl apply -f pod-network.yaml
查看Pod对象:
在上述结果中,第二列“READY”值为“2/2”,其中左侧的2表示目前正在运行的容器数量,右侧的2表示定义的容器数量,当两个数值相等时则表示Pod内所有容器均正常运行。这里仅显示我们定义的两个容器,而不会显示“Pause容器”,这是因为它是由Kubernetes内部管理的,对用户不可见。不过,可以在Pod所在节点上看到它,查看Pod所在节点:
该Pod被分配到“k8s-node2”节点上。进入该节点中并执行docker命令查看容器:
最后一个则是“Pause容器”,它由“registry.aliyuncs.com/google_containers/pause:3.9”镜像创建。
进入“web”容器中,执行curl命令测试访问,你将看到统计信息:
[root@k8s-master ~]# kubectl exec -it pod-network -c web -- bash root@pod-network:/# curl http://127.0.0.1/nginx_status Active connections: 1 server accepts handled requests 3 3 3 Reading: 0 Writing: 1 Waiting: 0
同样,在“collect”容器中也可以访问“http://127.0.0.1/nginx_status”:
[root@k8s-master ~]# kubectl exec -it pod-network -c collect -- bash root@pod-network:/# curl http://127.0.0.1/nginx_status Active connections: 1 server accepts handled requests 3 3 3 Reading: 0 Writing: 1 Waiting: 0
这说明“web”和“collect”容器在同一个网络协议栈中共享“Pause容器”的网络。