Docker6 映射

Docker允许映射容器内应用的服务端口到本地的宿主主机,还能实现多个容器之间通过容器名来快速访问。

端口映射

从外部访问容器

当容器中运行一些网络应用,要让外部访问这些应用的时候,我们可以通过参数 -P 或者 -p来指定端口。使用大P参数时,Docker会随机映射一个49000-49900的端口到容器内部的端口。

1
2
3
4
5
6
root@rexyan:/# docker run -d  -P training/webapp python app.py
d03564d51bdeb439e3c9f140575ab53cd665e47c35efd567a8c20aefc14c2e6d
root@rexyan:/# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d03564d51bde training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:32770->5000/tcp clever_austin
root@rexyan:/#

可以看见将本机的32770端口映射到了容器内的5000端口。我们可以浏览器访问本机IP+32770端口就能看见内容了

可以使用docker logs来查看访问的信息

1
2
3
4
5
root@rexyan:/# docker logs d03564d51bde
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
10.10.10.1 - - [06/Apr/2018 05:41:40] "GET / HTTP/1.1" 200 -
10.10.10.1 - - [06/Apr/2018 05:41:41] "GET /favicon.ico HTTP/1.1" 404 -

除了使用-P随机生成一个本机端口与容器的应用进行端口映射外,我们还可以使用-p来指定端口

1
2
root@rexyan:/# docker run -d -p 16666:5000 training/webapp python app.py
30e63bcaf4a3df3708eacd0fb114ce66ce2fb1ee2b103409e1286313e98dda03

将本机16666端口与容器5000进行映射。

映射所有接口地址

使用-p默认会绑定本地所有接口上的所有地址,多次使用-p参数,可以绑定多个端口

1
root@rexyan:/# docker run -d -p 11111:5000 -p 11112:5000 training/webapp python app.py

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

1
root@rexyan:/# docker run -d -p 10.10.10.133:10203:5000 training/webapp python app.py

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

1
root@rexyan:/# docker run -d -p 10.10.10.133::5000 training/webapp python app.py

这里会默认分配一个端口出来,相当于-P

1
2
3
root@rexyan:/# docker ps 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b25a3d9236 training/webapp "python app.py" 2 seconds ago Up 1 second 10.10.10.133:32769->5000/tcp elegant_clarke

查看端口映射配置

1
2
root@rexyan:/# docker port a1b25a3d9236
5000/tcp -> 10.10.10.133:32769

还可以使用docker inspect + id/名称来查看

1
docker inspect a1b25a3d9236

容器互联

容器互联是一种让多个容器中应用进行快速交互的方式,它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器。

自定义容器名称

创建容器的时候系统会自动创建名称,但是我们可以使用–name来指定自己的容器名称,这里注意容器名称是不能重复的。

1
2
3
4
5
root@rexyan:/# docker run -d -p 12000:5000 --name web  training/webapp python app.py 
f59bdcfceb9c8913fa77eb90bba2ae54342fde166934097a6ff6279aaab89f28
root@rexyan:/# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f59bdcfceb9c training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:12000->5000/tcp web

在创建docker的时候,如果使用-rm 参数,这代表容器终止后会被删除。-rm 参数不能和-d一起使用。

容器互联

新建一个容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@rexyan:/# docker run -d --name db training/postgres
Unable to find image 'training/postgres:latest' locally
latest: Pulling from training/postgres
a3ed95caeb02: Pull complete
6e71c809542e: Pull complete
2978d9af87ba: Pull complete
e1bca35b062f: Pull complete
500b6decf741: Pull complete
74b14ef2151f: Pull complete
7afd5ed3826e: Pull complete
3c69bb244f5e: Pull complete
d86f9ec5aedf: Pull complete
010fabf20157: Pull complete
Digest: sha256:a945dc6dcfbc8d009c3d972931608344b76c2870ce796da00a827bd50791907e
Status: Downloaded newer image for training/postgres:latest
d8d7bec173c29963f34d840547760c0a9629fc71950f2c5592fe7b8c3d8c014b

新建一个web容器,与刚刚新建的db容器进行互联,格式为–link name:alias name是与之连接的容器名称,alias是这个连接的别名。这样做的好处是我们无需使用-p或者-P暴露出容器db的地址,增加了安全性。

1
root@rexyan:/# docker run  -d -P --name web --link db:db training/webapp python app.py

可以从两个方面看出这两个容器是否互联,我们可以进入到创建好的web容器中

1
root@rexyan:/# docker exec -it b295295fdd14 /bin/bash

查看hosts 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@b295295fdd14:/opt/webapp# cat /etc/hosts 
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 db d8d7bec173c2
172.17.0.2 b295295fdd14
root@b295295fdd14:/opt/webapp# ping db
PING db (172.17.0.3) 56(84) bytes of data.
64 bytes from db (172.17.0.3): icmp_seq=1 ttl=64 time=0.239 ms
64 bytes from db (172.17.0.3): icmp_seq=2 ttl=64 time=0.132 ms
64 bytes from db (172.17.0.3): icmp_seq=3 ttl=64 time=0.131 ms

我们看见了172.17.0.2对应是是自己的容器id,172.17.0.3对应带了名称为db的容器,容器id为d8d7bec173c2。我们可以在当前web容器中ping db容器,直接使用ping db 可以ping通,说明两个的网络是互通的。

第二种方式是使用env来查看web容器的环境变量,创建一个临时的web4容器,并关联db,查看env

1
2
3
4
5
6
7
8
9
10
11
12
root@rexyan:/# docker run --rm --name web4 --link db:db training/webapp env 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=fc701885a079
DB_PORT=tcp://172.17.0.3:5432
DB_PORT_5432_TCP=tcp://172.17.0.3:5432
DB_PORT_5432_TCP_ADDR=172.17.0.3
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_PROTO=tcp
DB_NAME=/web4/db
DB_ENV_PG_VERSION=9.3
HOME=/root
root@rexyan:/#

上面的内容中DB_开头的环境变量是提供web4容器与db容器连接使用的。

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run -d -P training/webapp python app.py     # 创建一个容器,并且关联一个本地随机端口
docker logs d03564d51bde # 查看id为d03564d51bde容器的log信息
docker run -d -p 16666:5000 training/webapp python app.py # 创建容器,指定本地端口16666和容器5000端口进行网络互联
docker run -d -p 11111:5000 -p 11112:5000 training/webapp python app.py # 创建容器,指定两个本地两个端口与容器进行网络互联
docker run -d -p 10.10.10.133:10203:5000 training/webapp python app.py # 创建容器,指定ip和端口与容器进行网络互联
docker run -d -p 10.10.10.133::5000 training/webapp python app.py # 创建容器,指定ip与容器进行网络互联,端口会随机分配一个,和-P一样
docker port a1b25a3d9236 # 查看容器id为a1b25a3d9236的端口信息
docker inspect a1b25a3d9236 # 查看容器id为a1b25a3d9236的详细信息
docker run -d -p 12000:5000 --name web training/webapp python app.py # 创建一个name为web的容器,并将本地12000端口和容器5000进行关联
docker run -d --name db training/postgres # 创建一个name为db的容器
docker run -d -P --name web --link db:db training/webapp python app.py # 创建一个name为web的容器,并使用--link实现与db容器的互联
docker exec -it b295295fdd14 /bin/bash # 连接id为b295295fdd14的容器
docker run --rm --name web4 --link db:db training/webapp env # 创建一个临时web4容器,利用env查看容器的环境变量,可看见关联的容器db的一些地址信息