Docker 整理笔记(二)
Networking:
docker 创建在本地创建了一个网卡设备docker0,默认地址是 172.17.0.1,是网卡也可以理解为软交换机。
[ZW@docker ~]# ifconfig | grep -C5 docker0
docker0: flags=4099 mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:53ff:fef6:4154 prefixlen 64 scopeid 0x20
ether 02:42:53:f6:41:54 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
docker 网络机制:
[ZW@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
84b330d92923 bridge bridge local
f70243acdd4c host host local
ed7f69c4a866 none null local
docker启动一个虚拟机会在本地虚出一块网络设备,一半插在虚拟机,一半插在docker0,来完成通信。ifconfig可以看到虚拟网卡,ip link show 可以看到另外一半网卡(也就是虚拟机中看到的eth0):
[ZW@docker ~]# docker container start web && ifconfig | grep veth
web
vethfa4b6f6: flags=4163 mtu 1500
kvm外部访问虚拟机的方法只能nat转发或者桥接(我瞎说的),而docker可以通过和真机或者其他虚拟机共享网络空间的方式来进行也就是A虚拟机有 mount user pid ,B也有独立的mount user pid ,AB 或者 AB真机 共享 network UTS ipc。(也就是联盟式网络、开放式网络(open container))
所以docker可以有这几种网络:
1.none:不需要通信的孤岛网络
2.bridge:桥接式net网络(docker 默认网络方式)
3.joinded:联盟网络A机B机
4.open container:宿主机共享网络A、B真机、(联盟网络的延伸)
设定docker 网络 :
在run一个容器时我们可以指定网络方式:
[ZW@docker ~]# docker container run --help | grep network
--network string Connect a container to a
network (default "default")
可以查看网络bridge,host , none的网络信息
[ZW@docker ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "dacbc276f6b07d734709317892d66abb045f88f0ff38fbbb5f8c78773ce36549",
"Created": "2018-10-28T11:05:07.769121664+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16", #子网
"Gateway": "172.17.0.1" #网关
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
扩展IP命令:
centos中可以手动去操作网络名称空间“ip”命令:
[root@localhost ~]# rpm -qf /sbin/ip
iproute-3.10.0-74.el7.x86_64
[root@localhost ~]# ip netns help
Usage: ip netns list
ip netns add NAME #添加网络名称空间
ip netns set NAME NETNSID
ip [-all] netns delete [NAME]
ip netns identify [PID]
ip netns pids NAME
ip [-all] netns exec [NAME] cmd ... #在网络空间里执行命令
ip netns monitor
ip netns list-id
可以手动添加网络名称空间:
[root@localhost ~]# ip netns add r1
[root@localhost ~]# ip netns add r2
[root@localhost ~]# ip netns list
r2
r1
还可以在创建的名称空间里执行命令:可以看到默认只有一个Lo本地网卡
[root@localhost ~]# ip netns exec r1 ifconfig -a
lo: flags=8 mtu 65536
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ip link 命令可以创建网卡对,放到名称空间内。
[root@localhost ~]# ip link help
Usage: ip link add [link DEV] [ name ] NAME
...
手动创建一对网卡:
[root@localhost ~]# ip link add name eth1.1 type veth peer name veth1.2
#name制定网卡名 type 制定网卡类型为虚拟网卡 peer制定网卡对另外一半叫什么
[root@localhost ~]# ip link
5: [email protected]: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether ce:ac:2e:6d:73:43 brd ff:ff:ff:ff:ff:ff
6: [email protected]: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether ee:47:86:a6:b9:1b brd ff:ff:ff:ff:ff:ff
可以ip set手动吧一半网卡放到名称空间里面:
[root@localhost ~]# ip link set dev veth1.2 netns r1
[root@localhost ~]# ip link
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:02:de:1c brd ff:ff:ff:ff:ff:ff
3: virbr0: mtu 1500 qdisc noqueue state DOWN mode DEFAULT qlen 1000
link/ether 52:54:00:0b:9b:e5 brd ff:ff:ff:ff:ff:ff
4: virbr0-nic: mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT qlen 1000
link/ether 52:54:00:0b:9b:e5 brd ff:ff:ff:ff:ff:ff
6: eth1.1@if5: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether ee:47:86:a6:b9:1b brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@localhost ~]# ip netns exec r1 ifconfig -a
lo: flags=8 mtu 65536
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth1.2: flags=4098 mtu 1500
ether ce:ac:2e:6d:73:43 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
还可以用ip link 命令 改名:
[root@localhost ~]# ip netns exec r1 ip link set dev veth1.2 name eth0
[root@localhost ~]# ip netns exec r1 ifconfig -a
eth0: flags=4098 mtu 1500
ether ce:ac:2e:6d:73:43 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=8 mtu 65536
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
现在两边都有网卡了 可以给个地址激活:
[root@localhost ~]# ifconfig eth1.1 192.168.0.1/24 up
[root@localhost ~]# ip netns exec r1 ifconfig eth0 192.168.0.3/24
[root@localhost ~]# ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.076 ms
同理也可以把宿主机的网卡挪到r2中让r1 r2通信,通过网络名称空间、网卡的组合,模拟网络环境。
四种网络:
none: 只有lo,不和外界通信
bridged: 一半在容器,一半在docker0桥上,桥接.(默认)
joined: A容器和B容器联盟式,
open container: 直接共享真机网络空间
启动容器时可以指定网络--network 指定主机名-h --dns指定dns:
[root@docker ~]# docker run --name t1 -it --network bridged - -dns 8.8.8.8 --rm busybox:latest
可以注入hosts文件内–add-host
[root@docker ~]# docker run --name t1 -it -h t1 --add-host www.baidu.com:1.1.1.1 busybox:latest
容器内地址是内网,网络是不可达的,我们需要把它暴露出来:
-P:做了dnat转换相当于
[root@docker ~]# docker run --name t1 -it -p 80 --rm nginx:1.14-alpine
[root@docker ~]# docker port t1
80/tcp -> 0.0.0.0:32769
[root@docker ~]# iptables -t nat -vnL | grep dpt
0 0 MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:80
1 60 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:32768 to:172.17.0.2:80
可以看到把容器地址映射到了真机的32768端口.
-p也可以直接指定映射到真机的哪个ip的哪个端口:
docker run --name t1 -it -p 192.168.64.100:5555:80 --rm nginx:1.14-alpine
[root@docker ~]# docker port t1
80/tcp -> 192.168.64.100:5555
Joined container联盟容器;
两个容器有独立的PID,USER.MOUNT共享NETWORK,IPC,UTS
启动时–network 指定网络类型:
A容器中:
docker run --name b1 -it --rm busybox:latest
B容器中;
docker run --name b2 --network container:b1 -it --rm busybox:latest
去容器中ifconfig然后会发现两个容器会公用网络空间.
共享主机(直接暴露端口);
docker run --name b2 --network host -it --rm busybox:latest
修改docker0;
自定义docker0桥的网络属性信息:/etc/docker/daemon.json文件
{
"bip": "192.168.1.5/24",
"fixed-cidr": "10.20.0.0/16",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "10.20.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
dockerd守护进程的C/S,其默认仅监听Unix SOcket格式的地址,/var/run/docker.sock;如果使用TCP套接字,
vim /etc/docker/daemon.json:
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
手动创建网络桥;
ip link set dev docker network create -d bridge --subnet 172.26.0.0/16 --gateway 172.26.0.1 mybr0