外部访问容器
有时候,容器要运行一些网络应用,需要外部能访问到这些应用,就需要使用-p/P 参数指定一个主机端口,映射到容器端口中。其中使用P系统会分配一个随机的端口到内部容器开放的网络端口。
就拿仓库服务镜像来做例子:
$ sudo docker run -d -P registry
b89fc89e061dee24ac532af1890cd26e6e016545e0978b01d3d4eadca67119aa
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b89fc89e061d registry:latest "docker-registry" 5 seconds ago Up 4 seconds 0.0.0.0:32768->5000/tcp focused_brown
$ curl 192.168.4.100:32768/v1/search
{"num_results": 0, "query": "", "results": []}[root@registry liugang]#
$ sudo docker logs b89fc89e061d
[2015-08-18 00:11:41 +0000] [1] [INFO] Starting gunicorn 19.1.1
[2015-08-18 00:11:41 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
我们可以看到,当我们加上-P时,docker会任意指定一个一个端口指定到容器的开放端口5000上。从容器到运行日志也是可以看出,在容器的5000端口会有一个监听。当我们通过外网的,也就是宿主机的IP 和端口就可以访问到该容器内提供的服务,这里是仓库服务。
-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有
ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort。
映射所有接口地址
我们用到的是 hostPort:containerPort,也就是将制定端口映射到主机地址的任意地址的指定端口:
$ sudo docker run -d -p 80:5000 registry
a7abe89606427e3cb90698a6d302e8
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7abe8960642 registry:latest "docker-registry" 4 seconds ago Up 3 seconds 0.0.0.0:80->5000/tcp ecstatic_wright
2abb0f04066999adff36b13be2e380c3de
我们将主机80端口映射到容器,这样我们直接用主机地址就可以访问到容器了。
映射到指定地址的指定端口
可以使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1
$ sudo docker run -d -p 127.0.0.1:5000:5000 registry
9f11390c1e9d048f7d82ff6bfb7e65f5531865343a5a2e6b660c0634e90eda26
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f11390c1e9d registry:latest "docker-registry" 6 seconds ago Up 5 seconds 127.0.0.1:5000->5000/tcp romantic_carson
映射到指定地址的任意端口
使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
$ sudo sudo docker run -d -p 127.0.0.1::5000 registry
d8cd77ecc45f434ab9edc0a7e83514ef7cb019fabc9bdbc0b522bb916b309789
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d8cd77ecc45f registry:latest "docker-registry" 4 seconds ago Up 3 seconds 127.0.0.1:32768->5000/tcp grave_carson
从上面看出,此时docker默认的传输协议是tcp方式,我们也可以改为其他方式标记:
$ sudo docker run --name=test_port -d -p 127.0.0.1:5000:5000/udp registry
使用 docker port 查看端口信息
$ docker port test_port
5000/udp -> 127.0.0.1:5000
注意:
容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)
-p 标记可以多次使用来绑定多个端口