Docker端口映射与容器互联
在实践中,经常需要多个服务组件容器共同协作的情况,这往往需要多个容器之间能够互相访问到对方的服务。Docker除了通过网络访问外,还提供了两个很方便的功能来满足服务访问的基本需求:一个是允许映射容器内应用的服务端口到本地宿主机;另一个是互联机制实现多个容器间通过容器名来快速访问。
1:从外部访问容器应用
在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络进行访问容器内的应用和服务的。当容器中运行一些网络应用,要让外部访问这些应用,可以通过-P或-p参数来指定端口映射。
当使用-P(大写)标记时,Docker会随机映射一个端口至容器内部开放的网络端口。
[root@virtual_host ~]# docker run -d --name nginx -P registry.kubernetes.com/library/nginx:alpine
4788c55ab2e5ec1d912f18346a74ea9eb0ab48442f92b063605f205a84976567
[root@virtual_host ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4788c55ab2e5 registry.kubernetes.com/library/nginx:alpine "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx
使用-p(小写)则可以指定要映射的端口,并且在一个指定端口上只可以绑定一个容器。支持的格式有 IP:HostPort:ContainerPort | IP: : ContainerPort | HostPort: ContainerPort
(1)映射所有接口地址
#使用hostPort:containerPort格式,将本地的80端口映射到容器的80端口,可以执行以下命令:
[root@virtual_host ~]# docker run -d --name nginx -p 80:80 registry.kubernetes.com/library/nginx:alpine
2435b2ec6f0f3691e7ada21e8ffffd3112c6c9bac6ec034bdb902c74e579cf6b
#此时默认会绑定本地所有接口上的所有地址。多次使用-p标记可以绑定多个端口。例如:
[root@virtual_host ~]# docker run -d --name nginx -p 80:80 -p 81:81 registry.kubernetes.com/library/nginx:alpine
043be62ed17a4bb1cc63ce51c6e6f7c5b535abb9de48b50f52502efcf8e02897
[root@virtual_host ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
043be62ed17a registry.kubernetes.com/library/nginx:alpine "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:80-81->80-81/tcp, :::80-81->80-81/tcp nginx
(2)映射到指定地址的指定端口
#可以使用ip:hostPort:containerPort格式指定映射一个特定的地址,例如localhost的地址127.0.0.1
[root@virtual_host ~]# docker run -d --name nginx -p 127.0.0.1:80:80 registry.kubernetes.com/library/nginx:alpine
1fb75f5ad53bc38112d71382098fc7f5113e26e0c22928e540af6f9a5ccf7b8f
[root@virtual_host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1fb75f5ad53b registry.kubernetes.com/library/nginx:alpine "/docker-entrypoint.…" 2 seconds ago Up 1 second 127.0.0.1:80->80/tcp nginx
[root@virtual_host ~]# ss -lnt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:111 *:*
LISTEN 0 128 127.0.0.1:80 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 128 [::]:22 [::]:*
[root@virtual_host ~]# curl 10.0.0.12
curl: (7) Failed connect to 10.0.0.12:80; Connection refused
[root@virtual_host ~]# curl 127.0.0.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
(3)映射到指定地址的任意端口
#使用ip::containerPort绑定localhost的任意端口到容器的80端口,本地主机会任意分配一个端口
[root@virtual_host ~]# docker run -d --name nginx -p 127.0.0.1::80 registry.kubernetes.com/library/nginx:alpine
1d7d38adc367f8c38b22603e10ef6ffca9c895bd7d4fb1d0514ea39764ec9219
[root@virtual_host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d7d38adc367 registry.kubernetes.com/library/nginx:alpine "/docker-entrypoint.…" 1 second ago Up 1 second 127.0.0.1:49153->80/tcp nginx
[root@virtual_host ~]# curl -I 127.0.0.1:49153
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Tue, 28 Dec 2021 13:26:07 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 25 Jan 2022 15:26:06 GMT
Connection: keep-alive
ETag: "61f0168e-267"
Accept-Ranges: bytes
(4)查看端口映射情况、
[root@virtual_host ~]# docker port nginx
80/tcp -> 127.0.0.1:49153
测试:
启动一个nginx容器,将宿主机80端口映射到容器的80端口
进入容器,开启nginx服务,写入一个测试语句到默认的index文件中,并测试访问
[root@virtual_host ~]# docker run -d --name nginx -p 80:80 registry.kubernetes.com/library/nginx:alpine
01e64e78d6d0dabbec5c43025c812ae1d0f3e8ab44a9f8d525849f1d31f8f103
[root@virtual_host ~]# docker port nginx
80/tcp -> 0.0.0.0:80
80/tcp -> :::80
[root@virtual_host ~]# docker exec -it nginx /bin/sh
/ # echo "<a href="https://www.cnblogs.com/devopsdu"><h1>DevOpsdu</h1></a>" >/usr/share/nginx/html/index.html
/ # exit
[root@virtual_host ~]# curl 127.0.0.1
<a href=https://www.cnblogs.com/devopsdu><h1>DevOpsdu</h1></a>
2:容器的互联
容器的互联是一种让多个容器中的应用进行快速交互的方式,它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体的IP地址。
(1)自定义容器名称
连接系统依据容器的名称来执行。因此需要自定义一个好记的容器名。使用–name标记可以为容器自定义命名:
[root@virtual_host ~]# docker run -d --name nginx-1 -p 80:80 registry.kubernetes.com/library/nginx:alpine
a6704a4d628894b7cd27e5ae30915c4b780da757e46269cc98aa69c699b2eb90
(2)容器互联
使用–link 参数可以让容器直接安全的交互
[root@virtual_host ~]# docker exec -it nginx-2 /bin/sh
/ # 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.2 nginx-2 a6704a4d6288 nginx-1
172.17.0.3 c4632c377527
/ # ping nginx-1
PING nginx-1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.185 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.179 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.085 ms
64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.061 ms
用户可以连接多个容器到db容器上。