docker网络配置
随着技术的进步,网络是沟通各个组件基础手段,中间件本质上是网络的高级封装。所以容器启动起来需要和外面进行交互必须开放相应的端口。
上图中是一个基础服务单元,包含一个web服务器和一个数据库,其中web服务器需要开放80端口,DB可以开放3306端口。由于我们使用docker容器,容器和宿主机的网络也是隔离的,我们在容器内部开放一个80端口,在宿主机上是是不知道的。所以需要进行宿主机和容器端口绑定。
docker提供两种方式绑定:
1、可以将容器内部端口和宿主机端口绑定,如果宿主机是多网卡,也可以指定网卡绑定
2、docker容器可以合docker容器直接绑定在一起,这样两个容器互通
说明:
1、容器和宿主机端口绑定,使容器更加像一个进程,这时容器和进程的区别就非常小
2、容器和容器互通原理上是修改了容器内部的hosts文件
3、容器是一个临时型,容器可能在任何时间被杀掉,并且启动起来,所以在运维中ip的概念就会有所模糊。虚拟机关闭和启动本身的ip地址不会变化(需要dhcp支持),但是容器中的ip地址就没法保证了 ,同一个镜像启动若干个容器,ip地址是不同的,所以web服务器依赖db,最好是搞一套域名系统。应用-主机名-ip地址强绑定在一起,这样在寻址的时候就会比较方便。这里存在一些问题,因为每个容器按照4C8G额度分配,每一个应用需要几十台或者上百台机器才能支撑下来。而且应用数量又会非常的多,这样就会造成ip地址不够用的情况。所以这一块我们不去讨论,交给专业SRE去处理。
1、nginx容器
我们需要启动一个nginx服务器用于测试网络是否正常
root@ubuntu16server:/home/yufeiliu# docker run -it nginx /bin/bash
root@4131e8452de5:/#
root@4131e8452de5:/#
root@4131e8452de5:/#
root@4131e8452de5:/#
root@4131e8452de5:/# ps -aux
bash: ps: command not found
root@4131e8452de5:/# ifconfig
bash: ifconfig: command not found
root@4131e8452de5:/# ping
bash: ping: command not found
docker容器确实非常干净,ps、ifconfig、ping这些命令都没有,所以安装一下
apt-get update && apt-get upgrade
apt-get install net-tools
apt-get install inetutils-ping
apt-get install procps
启动nginx:
root@ubuntu16server:/home/yufeiliu# docker run -d --name nginx -p 8080:80 nginx
26e9be456f349a43d8f37c5685e1e1c848857a97f9391c641e86bddffce754aa
说明:
1、这次启动参数没有带-i、-t是因为我们不需要带有shell进行交互
2、--name是给容器七个名字,毕竟容器ID是哈希值,我们记不住
3、-p是端口映射,和-v参数一样左边是宿主机,右边是容器端口
4、这里有nginx,其中左边的nginx应该是nginx:latest,可以缩写为nginx,这里没有启动进程命令
root@ubuntu16server:/home/yufeiliu# docker inspect bb5a6d2337fe
[
{
"Id": "bb5a6d2337fe4cee850e994d72cf6bcaf3156d815e366a37ad4d6769e6004275",
"Created": "2019-05-11T03:57:29.606632649Z",
"Path": "nginx",
"Args": [
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 4361,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-05-11T03:57:30.546078117Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
我们可以看到默认启动脚本是nginx -g daemon off;
5、如果我们想进入容器中看一下使用下面的方式进入
root@ubuntu16server:/home/yufeiliu# docker exec -it bb5a6d2337fe /bin/bash
root@bb5a6d2337fe:/#
docker exec相当于一个docker隔离通道,我们可以使用docker exec进入容器做一些操作,比docker attach更加灵活。
6、查看容器网络配置
"NetworkSettings": {
"Bridge": "",
"SandboxID": "0bb0d1fe6583ba18c09d8ff703280b0331582f38b14d2b269306e6fc71bdce17",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "8080"
}
]
},
"SandboxKey": "/var/run/docker/netns/0bb0d1fe6583",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "712c89b95419afd917f5ec6c174b55c0f56f5819d8fe35d6a9493e72f676e901",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "df33907e1bb77011598ae8349dc4c68064ada57386fae5142be00c4b53786189",
"EndpointID": "712c89b95419afd917f5ec6c174b55c0f56f5819d8fe35d6a9493e72f676e901",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
我们可以看到这个容器分配的ip地址是172.17.0.2、分配的mac地址是02:42:ac:11:00:02,容器中国分配的一个tcp端口80/tcp,绑定了宿主机上0.0.0.0:8080。
7、测试
2、容器和容器打通
启动两个nginx:nginx1、nginx2,nginx2依赖nginx1
启动:
docker run --name nginx1 -d -p 8080:80 nginx
docker run --name nginx2 -d -p 8081:80 --link nginx1:nginx1 nginx
说明:
1、nginx1容器对外暴露8080端口,nginx2对外暴露8081端口
2、nginx2可以访问nginx1,但是nginx1访问不了nginx2
3、测试端口连通性
root@ubuntu16server:/home/yufeiliu# curl http://127.0.0.1:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
root@ubuntu16server:/home/yufeiliu# curl http://127.0.0.1:8081
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
4、nginx2访问nginx1
root@137f72edd098:/# 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 nginx1 9708c3e88703
172.17.0.3 137f72edd098
root@137f72edd098:/# ping nginx1
PING nginx1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.096 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.194 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.194 ms
^C--- nginx1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.096/0.161/0.194/0.046 ms
root@137f72edd098:/# curl http://nginx1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
这里我们发现在nginx2容器中的hosts文件已经加上了nginx1的配置,所以两者可以像在一个网段那样正常访问
5、nginx1访问nginx2
root@ubuntu16server:/home/yufeiliu# docker exec -it nginx1 /bin/bash
root@9708c3e88703:/# 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 9708c3e88703
root@9708c3e88703:/#
root@9708c3e88703:/#
root@9708c3e88703:/# ping nginx2
bash: ping: command not found
root@9708c3e88703:/#
最后总结一下,我们可以直接将容器中的端口绑定宿主机中的端口使得像一个进程那样访问。同时容器可以link到其他容器,可以直接访问容器,这样更加直接。但是第二种存在一些缺陷,只能访问同一台宿主机,跨宿主机便没有办法了。