目录
本章最后一小节,讲docker使用简单的网络
一、外网访问容器
1.1 参数-P -p
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或-p 参数来指定端口映射。
-P(大写):Docker 会随机映射一个 的端口到内部容器开放的网络端口。如:
[root@vm82 ~]# docker run --name php -P -d php:rc-fpm fa02073ccd7598771ad11bb6af18e742e11928db9fa218378ffd0f818f373fc1 [root@vm82 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fa02073ccd75 php:rc-fpm "docker-php-entrypoi…" 6 seconds ago Up 4 seconds 0.0.0.0:32770->9000/tcp php
-p(小写):映射指定的网络,格式 -p [ip:]<本机端口>:[ip:]<docker端口>,也可以IPv6
-p [ip::]<本机端口>:[ip::]<docker端口>
如果不写地址就表示映射本地所有接口地址
#访问地址为 http://192.168.3.82:8000/ [root@vm82 ~]# docker run --name nginx -p 192.168.3.82:8000:80 -d nginx 4cfc901459a66467ecb3d701ada63ed9ef32102bec1c25abfaf543f9ee93153c [root@vm82 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4cfc901459a6 nginx "/docker-entrypoint.…" 8 seconds ago Up 6 seconds 192.168.3.82:8000->80/tcp nginx
1.2 映射到指定地址的任意端口
使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
docker run --rm --name web -d -p 127.0.0.1::5000 training/webapp python app.py
还可以使用 udp 标记来指定 udp 端口
docker run --rm --name web2 -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
1.3 查看映射端口配置
使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址
[root@vm82 ~]# docker port web
5000/tcp -> 0.0.0.0:32768
[root@vm82 ~]# docker port web 5000
0.0.0.0:32768
二、容器互联
2.1 说明
使用 --link 参数可以让容器之间安全的进行交互。
--link 参数的格式为 --link name:alias ,其中 name 是要链接的容器的名称, alias 是这个连接的别名。
Docker 在两个互联的容器之间创建了一个安全隧道,而且不用映射它们的端口到宿主主机上。在启动 db 容器的时候并没有使用 -p 和 -P 标记,从而避免了暴露数据库端口到外部网络上。
2.2 例子
我使用2个docker设置nginx+php,这里使用到php-fpm,需要在docker hub中下载包含有-fpm字样的
/etc/nginx/conf.d/default.conf配置文件
[root@vm82 ~]# cat /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost hualinux.com www.hualinux.com;
#charset koi8-r;
access_log /disk1/logs/nginx/hualinux.access.log main;
error_log /disk1/logs/nginx/hualinux.err.log ;
location / {
root /disk1/www/hualinux.com;
index index.php index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root /disk1/www/hualinux.com;
#fastcgi_pass 127.0.0.1:9000;
#这个是当前docker地址
fastcgi_pass 192.168.3.82:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
建立相关目录和文件
[root@vm82 ~]# mkdir -p /disk1/www/hualinux.com
[root@vm82 ~]# mkdir -p /disk1/logs/nginx
[root@vm82 ~]#
[root@vm82 ~]# cat /disk1/www/hualinux.com/index.php
<?php
ini_set('date.timezone','Asia/Shanghai');
echo "index php<br>";
echo date("H:i:s");
运行相关docker
docker run --name php7 -p 9000:9000 \
-v /disk1/www/hualinux.com:/disk1/www/hualinux.com \
-d php:7.4.7-fpm
docker run -p 8000:80 --name nginx \
-v /disk1/www/hualinux.com:/disk1/www/hualinux.com \
-v /disk1/logs/nginx:/disk1/logs/nginx:rw \
-v /etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf \
--link php7 -d nginx
操作效果如下:
[root@vm82 ~]# docker pull php:7.4.7-fpm
[root@vm82 ~]#
[root@vm82 ~]# docker run --name php7 -p 9000:9000 \
> -v /disk1/www/hualinux.com:/disk1/www/hualinux.com \
> -d php:7.4.7-fpm
83bf79c30e6f7c3b886708f6301ba889543c02f4d4e8af8b510d3ad55812688b
[root@vm82 ~]# docker run -p 8000:80 --name nginx \
> -v /disk1/www/hualinux.com:/disk1/www/hualinux.com \
> -v /disk1/logs/nginx:/disk1/logs/nginx:rw \
> -v /etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf \
> --link php7 -d nginx
5e31eead0d49ed939e4803b96e4cc77fa6968cf2046dff80d2b0c40fb6dc3496
[root@vm82 ~]#
[root@vm82 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5e31eead0d49 nginx "/docker-entrypoint.…" 7 seconds ago Up 4 seconds 0.0.0.0:8000->80/tcp nginx
83bf79c30e6f php:7.4.7-fpm "docker-php-entrypoi…" 13 seconds ago Up 9 seconds 0.0.0.0:9000->9000/tcp php7
打开浏览器输入:http://192.168.3.82:8000/index.php 如下图所示:
附录一、docker的三种网络类型
Docker 安装时会自动在 host 上创建三个网络,我们可用 docker network ls
命令查看
[root@vm82 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
86c1cd603f1d bridge bridge local
55c3bc2f4534 host host local
4e4ffc339693 none null local
1.1 none网络
故名思议,none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none
指定使用 none 网络。
我们不禁会问,这样一个封闭的网络有什么用呢?
其实还真有应用场景。封闭意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。
当然大部分容器是需要网络的,我们接着看 host 网络。
1.2host 网络
连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host
指定使用 host 网络。
root@vm82 ~]# docker run -it --network=host busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
91f30d776fb2: Pull complete
Digest: sha256:9ddee63a712cea977267342e8750ecbc60d3aab25f04ceacfa795e6fce341793
Status: Downloaded newer image for busybox:latest
/ # ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
link/ether 00:0c:29:6f:ac:60 brd ff:ff:ff:ff:ff:ff
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
link/ether 00:0c:29:6f:ac:6a brd ff:ff:ff:ff:ff:ff
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
link/ether 02:42:6f:d4:d2:85 brd ff:ff:ff:ff:ff:ff
88: veth5a09d43@if87: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0
link/ether 8a:19:59:0b:14:3c brd ff:ff:ff:ff:ff:ff
90: vethd9ca7ac@if89: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0
link/ether 62:6b:26:71:28:c9 brd ff:ff:ff:ff:ff:ff
/ #
/ # hostname
vm82
/ # exit
[root@vm82 ~]#
在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择 host 网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。
Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables
1.3 bridge网络(默认)
Docker 安装时会创建一个 命名为 docker0
的 linux bridge。如果不指定--network
,创建的容器默认都会挂到 docker0
上。