查看/usr/bin下与docker有关的二进制执行文件:
-rwxr-xr-x. 1 1000 1000 34519704 7月 18 2019 containerd
-rwxr-xr-x. 1 1000 1000 6038112 7月 18 2019 containerd-shim
-rwxr-xr-x. 1 1000 1000 65632394 7月 18 2019 docker
-rwxr-xr-x. 1 1000 1000 71650528 7月 18 2019 dockerd
-rwxr-xr-x. 1 1000 1000 764144 7月 18 2019 docker-init
-rwxr-xr-x. 1 1000 1000 2851084 7月 18 2019 docker-proxy
-rwxr-xr-x. 1 1000 1000 19491032 7月 18 2019 ctr
-rwxr-xr-x. 1 1000 1000 8514432 7月 18 2019 runc
这些组件根据工作职责可以分为以下三大类。
- Docker 相关的组件:docker、dockerd、docker-init 和 docker-proxy
- containerd 相关的组件:containerd、containerd-shim 和 ctr
- 容器运行时相关的组件:runc
先看docker-proxy。docker-proxy 主要是用来做端口映射的。当我们使用docker run命令启动容器时,如果使用了 -p 参数,docker-proxy 组件就会把容器内相应的端口映射到主机上来,底层是依赖于iptables
实现的。
使用以下命令启动一个 nginx 容器并把容器的 80 端口映射到主机的 8080 端口
[root@k8s-master bin]# docker run --name=nginx -d -p 8080:80 nginx
查看一下启动的容器 IP:
[root@k8s-master bin]# docker inspect --format '{{ .NetworkSettings.IPAddress }}' nginx
172.17.0.2
ps 命令查看一下主机上是否有 docker-proxy 进程
[root@k8s-master bin]# ps aux |grep docker-proxy
root 48045 0.0 0.1 103292 4144 ? Sl 15:19 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.2 -container-port 80
root 82391 0.0 0.0 112824 980 pts/0 S+ 15:45 0:00 grep --color=auto docker-proxy
查看一下主机上 iptables nat 表的规则
[root@k8s-master bin]# iptables -L -nv -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
16 1557 cali-PREROUTING all -- * * 0.0.0.0/0 0.0.0.0/0 /* cali:6gwbT8clXdHdC1b1 */
24 2087 KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
2 113 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 3 packets, 180 bytes)
pkts bytes target prot opt in out source destination
16367 986K cali-OUTPUT all -- * * 0.0.0.0/0 0.0.0.0/0 /* cali:tVnHkvAo15HuiPy0 */
16409 989K KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
1890 113K DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 3 packets, 180 bytes)
pkts bytes target prot opt in out source destination
16371 986K cali-POSTROUTING all -- * * 0.0.0.0/0 0.0.0.0/0 /* cali:O3lYWMrLQYEMJtB5 */
16769 1010K KUBE-POSTROUTING all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
0 0 MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:80
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
通过最后一行规则我们可以得知,通过DNAT服务(目标地址转换)当我们访问主机的 8080 端口时,iptables 会把流量转发到 172.17.0.2 的 80 端口