Docker 端口映射原理

发布时间: 更新时间: 总字数:593 阅读时间:2m 作者: IP属地: 分享 复制网址

docker 端口映射是通过宿主机的 iptables 来实现的,本文通过示例介绍端口映射的原理。

启动MySQL容器

docker 启动 mysql 容器

docker run -d -e MYSQL_ROOT_PASSWORD=password --name mysql_db -p 3306:3306 mysql

查看ip地址

$ docker inspect mysql_db|grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",

3306 端口是通过 docker-proxy 代理的

$ ps -ef|grep 3306
root        1755    1268  0 08:35 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3306 -container-ip 172.17.0.2 -container-port 3306

iptables 规则

  • 查看 iptables 中有一条 Chain DOCKER 的链
$ iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 129 packets, 38495 bytes)
 pkts bytes target     prot opt in     out     source               destination
   13   816 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 129 packets, 38495 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 634 packets, 48923 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 644 packets, 49630 bytes)
 pkts bytes target     prot opt in     out     source               destination
    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:3306

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:3306 to:172.17.0.2:3306
  • 显示 Chain DOCKERline-number,删除规则时使用
$ sudo iptables -t nat -vnL DOCKER --line-number
Chain DOCKER (2 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0
2        0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3306 to:172.17.0.2:3306

新增其他端口

sudo iptables -t nat -A  DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:8080

容器内启动 python3 -m http.server 8080,后可以通过 curl 172.17.0.2:8080 访问

查看 Chain DOCKER

$ iptables -t nat -nvL DOCKER --line-number
Chain DOCKER (2 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0
2        0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3306 to:172.17.0.2:3306
3        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.17.0.2:8080

删除端口

sudo iptables -t nat -D DOCKER <num>

说明

上面修改只是临时配置方法,也可以通过修改容器的配合文件防止重启后不生效问题,配置文件在/var/lib/docker/containers/[containerId]目录下 hostconfig.jsonconfig.v2.json

  • hostconfig.json
$ cat hostconfig.json | jq
{
  ...
  "NetworkMode": "default",
  "PortBindings": {
    "3306/tcp": [
      {
        "HostIp": "",
        "HostPort": "3306"
      }
    ]
  },
  • config.v2.json
cat config.v2.json | jq
{
  ...
  "NetworkSettings": {
    ...
    "Ports": {
      "3306/tcp": [
        {
          "HostIp": "0.0.0.0",
          "HostPort": "3306"
        }
      ]
    },
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数