外部访问容器

有时候,容器要运行一些网络应用,需要外部能访问到这些应用,就需要使用-p/P 参数指定一个主机端口,映射到容器端口中。其中使用P系统会分配一个随机的端口到内部容器开放的网络端口。

就拿仓库服务镜像来做例子:

  1. $ sudo docker run -d -P registry
  2. b89fc89e061dee24ac532af1890cd26e6e016545e0978b01d3d4eadca67119aa
  3. $ sudo docker ps
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. b89fc89e061d registry:latest "docker-registry" 5 seconds ago Up 4 seconds 0.0.0.0:32768->5000/tcp focused_brown
  6. $ curl 192.168.4.100:32768/v1/search
  7. {"num_results": 0, "query": "", "results": []}[root@registry liugang]#
  8. $ sudo docker logs b89fc89e061d
  9. [2015-08-18 00:11:41 +0000] [1] [INFO] Starting gunicorn 19.1.1
  10. [2015-08-18 00:11:41 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)

我们可以看到,当我们加上-P时,docker会任意指定一个一个端口指定到容器的开放端口5000上。从容器到运行日志也是可以看出,在容器的5000端口会有一个监听。当我们通过外网的,也就是宿主机的IP 和端口就可以访问到该容器内提供的服务,这里是仓库服务。

-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有

  1. ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort

映射所有接口地址

我们用到的是 hostPort:containerPort,也就是将制定端口映射到主机地址的任意地址的指定端口:

  1. $ sudo docker run -d -p 80:5000 registry
  2. a7abe89606427e3cb90698a6d302e8
  3. $ sudo docker ps
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. a7abe8960642 registry:latest "docker-registry" 4 seconds ago Up 3 seconds 0.0.0.0:80->5000/tcp ecstatic_wright
  6. 2abb0f04066999adff36b13be2e380c3de

我们将主机80端口映射到容器,这样我们直接用主机地址就可以访问到容器了。

映射到指定地址的指定端口

可以使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1

  1. $ sudo docker run -d -p 127.0.0.1:5000:5000 registry
  2. 9f11390c1e9d048f7d82ff6bfb7e65f5531865343a5a2e6b660c0634e90eda26
  3. $ sudo docker ps
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. 9f11390c1e9d registry:latest "docker-registry" 6 seconds ago Up 5 seconds 127.0.0.1:5000->5000/tcp romantic_carson

映射到指定地址的任意端口

使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。

  1. $ sudo sudo docker run -d -p 127.0.0.1::5000 registry
  2. d8cd77ecc45f434ab9edc0a7e83514ef7cb019fabc9bdbc0b522bb916b309789
  3. $ sudo docker ps
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. d8cd77ecc45f registry:latest "docker-registry" 4 seconds ago Up 3 seconds 127.0.0.1:32768->5000/tcp grave_carson

从上面看出,此时docker默认的传输协议是tcp方式,我们也可以改为其他方式标记:

  1. $ sudo docker run --name=test_port -d -p 127.0.0.1:5000:5000/udp registry

使用 docker port 查看端口信息

  1. $ docker port test_port
  2. 5000/udp -> 127.0.0.1:5000

注意:

容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)

-p 标记可以多次使用来绑定多个端口