Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。由于容器的本质是一个进程,那么访问容器服务我们需要映射对应的端口。
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P
(大写) 或 -p
(小写) 参数来指定端口映射。当使用 -P
(大写) 标记时,Docker 会随机映射一个端口到内部容器开放的网络端口。
docker@default:~$ docker run -d -P nginx:latest
4bb793dd70935687006ca6c3b4734464f3e8c103190bd263e7cfad77bbe8cd86
docker@default:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bb793dd7093 nginx:latest "nginx -g 'daemon of…" 11 seconds ago Up 9 seconds 0.0.0.0:32771->80/tcp boring_hamilton
5dad393a7d4e 5dc03a089d68 "nginx -g 'daemon of…" 2 hours ago Up 2 hours 0.0.0.0:8081->80/tcp nginx_v2
docker@default:~$
从上面的操作中我们可以看到映射的随机端口是32771
。
前面我们使用-p
指定了8081
端口。
sudo docker run --name ngnix_v1 -d -p 8081:80 nginx:V1
还可以使用-p
参数绑定多个端口。
sudo docker run -d -p 5000:5000 -p 3000:80 nginx:v1
可以使用 ip:hostPort:containerPort
格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1
$ sudo docker run -d -p 127.0.0.1:5000:5000 nginx:v1
使用 ip::containerPort
绑定 localhost
的任意端口到容器的 5000
端口,本地 主机会自动分配一个端口。
$ sudo docker run -d -p 127.0.0.1::5000 nginx:v1
docker@default:~$ docker port nginx_v2
80/tcp -> 0.0.0.0:8081
容器的连接(linking
)系统是除了端口映射外,另一种跟容器中应用交互的方式。该系统会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信 息。
docker的每个容器相当于有个内网地址。比如 mymysql
容器172.17.0.2
,mynginx
容器为172.17.0.3
,那么他们的通信机制是连到了 docker0
这个bridge
,大概如下图:
--link
参数可以使容器相互连接,比如我们先创建数据库容器$ sudo docker run -d --name db training/postgres
$ sudo docker run -d -P --name web --link db:db training/webapp
--link
参数的格式为 --link name:alias
,其中 name
是要链接的容器的 名称, alias
是这个连接的别名。web
容器验证是否连接成功。docker@default:/$ docker exec -it web /bin/bash #进入web容器
root@fa80261b44e0:/opt/webapp# ping db #连接db容器测试
PING db (172.17.0.2) 56(84) bytes of data.
64 bytes from db (172.17.0.2): icmp_seq=1 ttl=64 time=0.054 ms
64 bytes from db (172.17.0.2): icmp_seq=2 ttl=64 time=0.195 ms
64 bytes from db (172.17.0.2): icmp_seq=3 ttl=64 time=0.130 ms
从上面的操作可以看出web
容器可以访问db
容器,但是反过来db
容器无法访问web
容器,web
容器能够ping通db
容器其实就是修改了web
容器的 host
文件和设置了环境变量而已。