docker技术入门与实战 第3版学习笔记之第7章

第7章 端口映射与容器互联

在实践中,经常会碰到需要多个服务组件容器共同协作的情况,这往往需要多个容器之间能够互相访问到对方的服务。

Docker除了通过网络访问外,还提供了两个很方便的功能来满足服务访问的基本需求:一个是允许映射容器内应用的服务端口到本地宿主主机;另一个是互联机制实现多个容器间通过容器名来快速访问。

端口映射实现容器访问

在启动容器的时候,如果不指定对应参数,无法进行访问,需要通过-p进行设置参数,当使用-P的时候docker会随机映射一个49000~49000的端口

docker run -d -P training/webapp python app.py

PS C:\Users\fe> docker ps

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

PS C:\Users\fe> docker run -d -P training/webapp python app.py

Unable to find image'training/webapp:latest'locally

latest: Pulling from training/webapp

[DEPRECATION NOTICE] Docker Image Format v1, and Docker Image manifest version 2, schema 1 support will be removedinan upcoming release. Suggest the author of docker.io/training/webapp:latest to upgrade the image to the OCI Format, or Docker Image manifest v2, schema 2. More information at https://docs.docker.com/go/deprecated-image-specs/

e190868d63f8: Pull complete

909cd34c6fd7: Pull complete

0b9bfabab7c1: Pull complete

a3ed95caeb02: Pull complete

10bbbc0fc0ff: Pull complete

fca59b508e9f: Pull complete

e7ae2541b15b: Pull complete

9dd97ef58ce9: Pull complete

a4c1b0cb7af7: Pull complete

Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d

Status: Downloaded newer imagefortraining/webapp:latest

a7e6b6e0577677bf2b9efa37dc7f7b2e36e55eda98f384fd142bec46fc9d74d4

PS C:\Users\fe> docker ps

CONTAINER ID   IMAGE             COMMAND           CREATED          STATUS          PORTS                     NAMES

a7e6b6e05776   training/webapp"python app.py"44 seconds ago   Up 30 seconds   0.0.0.0:32768->5000/tcp   heuristic_bose

由此可见本机的32768被映射到了容器的5000端口,访问32768给访问容器类提供的应用,同样可以通过docker logs -f heuristic_bose 查看

如果是使用-p那么可以指定要映射的端口,在一个指定端口上只能绑定一个容器,多次使用-p可以映射多个端口

PS C:\Users\fe> docker run -d -p 3697:5000 --name test1127 training/webapp python app.py

833733604c25065f381ce9ed7ba097e70fa57f9e7d9c9a3c5ffb0505b9fb880c

PS C:\Users\fe> docker ps

CONTAINER ID   IMAGE             COMMAND           CREATED          STATUS          PORTS                     NAMES

833733604c25   training/webapp"python app.py"33 seconds ago   Up 32 seconds   0.0.0.0:3697->5000/tcp    test1127

a7e6b6e05776   training/webapp"python app.py"4 minutes ago    Up 4 minutes    0.0.0.0:32768->5000/tcp   heuristic_bose

可以使用IP:映射端口号:容器端口号格式映射到指定的地址

docker run -d -p 127.0.0.1:3697:5000 --name test1127 training/webapp python app.py

映射到指定地址的任意端口IP::容器端口

docker run -d -p 127.0.0.1::5000 --name test1127 training/webapp python app.py

可以通过udp标记来指定udp端口

docker run -d -p 127.0.0.1::5000/udp --name test1127 training/webapp python app.py

查看容器映射的端口

docker port 容器名称或ID  端口号

PS C:\Users\fe> docker ps

CONTAINER ID   IMAGE             COMMAND           CREATED          STATUS          PORTS                     NAMES

833733604c25   training/webapp"python app.py"33 seconds ago   Up 32 seconds   0.0.0.0:3697->5000/tcp    test1127

a7e6b6e05776   training/webapp"python app.py"4 minutes ago    Up 4 minutes    0.0.0.0:32768->5000/tcp   heuristic_bose

PS C:\Users\fe> docker port a7e6b6e05776

5000/tcp -> 0.0.0.0:32768

PS C:\Users\fe> docker port a7e6b6e05776 5000

0.0.0.0:32768

容器有自己的内部网络和 IP 地址,使用docker [container] inspect+容器ID 可以获取容器的具体信息。

互联机制实现便捷互访

容器的互联是一种让多个容器中的应用进行快速交互的方式,它会在源和接受容器之间创建链接关系,接受容器可以通过容器名快速访问到源容器,而不是指定的具体IP地址。

自定义容器命名

连接系统依据容器的名称来执行,因此需要自定义一个好记的名称,在重启的时候或连接其他容器的时候,自定义的名称也不会改变,使用--name可以标记自定义名称。需要注意的是容器的名称是需要是唯一的

docker run -d -P --name web training/webapp python app.py

容器互联

使用--link参数可以让容器之间安全的进行交互

创建一个数据库容器

docker run -d --name db training/postgres

创建一个新的web容器,存在的话需要先删除,将新的容器连接到db容器

docker rm -f web

docker run -d -P --name web --link db:db training/webapp python app.py

此时,db容器和web容器建立了互联关系,--link name:alias,其中name是要连接容器的名称,alias是别名

测试时候连接连接成功

PS C:\Users\fe> dockerexec-it web ping 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.371 ms

64 bytes from db (172.17.0.2): icmp_seq=2 ttl=64 time=0.047 ms

64 bytes from db (172.17.0.2): icmp_seq=3 ttl=64 time=0.061 ms

64 bytes from db (172.17.0.2): icmp_seq=4 ttl=64 time=0.034 ms

64 bytes from db (172.17.0.2): icmp_seq=5 ttl=64 time=0.026 ms

64 bytes from db (172.17.0.2): icmp_seq=6 ttl=64 time=0.027 ms

^C

--- db ping statistics ---

6 packets transmitted, 6 received, 0% packet loss, time 5237ms

rtt min/avg/max/mdev = 0.026/0.094/0.371/0.124 ms

使用link参数建立的容器所链接的主机需要处于运行状态

所链接的容器也必须是运行状态

使用link选项链接的主机ip不需要固定,因为每次新建容器都会检查所链接容器的ip,并在/etc/hosts里生成新的alias 名称对应的ip

Docker相当于在两个互联的容器之间创建了一个虚机通道,而且不用映射它们的端口到宿主主机上。在启动d6容器的时候并没有使用-p和-P标记,从而避免了暴露数据库服务端口到外部网络上。

Docker 通过两种方式为容器公开连接信息:

更新环境变量

更新/etc/hosts 文件。

使用env命令来查看web容器的环境变量

PS C:\Users\fe> docker run --rm --name web2 --link db:db training/webapp env

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

HOSTNAME=74f0d13e6593

DB_PORT=tcp://172.17.0.2:5432

DB_PORT_5432_TCP=tcp://172.17.0.2:5432

DB_PORT_5432_TCP_ADDR=172.17.0.2

DB_PORT_5432_TCP_PORT=5432

DB_PORT_5432_TCP_PROTO=tcp

DB_NAME=/web2/db

DB_ENV_PG_VERSION=9.3

HOME=/root

其中DB_开头的环境变量是供 web 容器连接 db 容器使用,前缀采用大写的连接别名。

除了环境变量, Docker 还添加host 信息到父容器的/etc/hosts 的文件。下面是父 容器 web的hosts 文件:

PS C:\Users\fe> docker run -t -i --rm --link db:db training/webapp /bin/bash

root@87bb8e4295ab:/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.2      db e4b1d33b74a4

172.17.0.6      87bb8e4295ab

PS C:\Users\fe> docker ps

CONTAINER ID   IMAGE               COMMAND                   CREATED          STATUS          PORTS                     NAMES

a007b222bb77   wordpress"docker-entrypoint.s…"7 minutes ago    Up 7 minutes    80/tcp                    blog

99ee79c9b33f   mysql:5.6"docker-entrypoint.s…"11 minutes ago   Up 11 minutes   3306/tcp                  mysql

820326e7de1a   training/webapp"python app.py"14 minutes ago   Up 14 minutes   0.0.0.0:32771->5000/tcp   web

e4b1d33b74a4   training/postgres"su postgres -c '/us…"14 minutes ago   Up 14 minutes   5432/tcp                  db

这里有 hos 信息,第一个是 db 容器的 IP 和主机名,第二个是 web 容器, web 容器用自己的 id 作为默认主机名。

可以在 web 容器中安装 ping 命令来测试跟 db 容器的连通:

root@820326e7de1a:/opt/webapp# apt-get install -yqq inetutils-ping

(Reading database ... 18233 files and directories currently installed.)

Removing ubuntu-minimal (1.325) ...

Removing iputils-ping (3:20121221-4ubuntu1.1) ...

Selecting previously unselected package inetutils-ping.

(Reading database ... 18221 files and directories currently installed.)

Preparing to unpack .../inetutils-ping_2%3a1.9.2-1_amd64.deb ...

Unpacking inetutils-ping (2:1.9.2-1) ...

Setting up inetutils-ping (2:1.9.2-1) ...

root@820326e7de1a:/opt/webapp# ping db

PING db (172.17.0.2): 56 data bytes

64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.093 ms

64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.087 ms

64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.045 ms

64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.049 ms

^C--- db ping statistics ---

4 packets transmitted, 4 packets received, 0% packet loss

round-trip min/avg/max/stddev = 0.045/0.068/0.093/0.000 ms

在用ping的时候会将db转成对应的ip,可以使用 inspect 命令查看容器的详细信息

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容