Docker网络
Docker中的网络主要解决容器与容器、容器与外部网络、外部网络与容器之间的互相通信的问题。
Docker的通信方式
在默认的情况下,Docker使用网桥bridge+NAT的通信模型。
Docker在启动时默认会自动创建网桥设备Docker0,并配置地址。
当Docker启动容器时,会创建一对veth虚拟虚拟网路设备,将其中一个veth网络设备附加到网桥docker0,另一个加入容器的网络命令空间(network NameSpace),改名为eth0。这样同一个host的容器与容器之间就可以通过docker0通信了。
仅仅解决host内部的容器之间的通信是不够的,还需要解决容器与外部网络之间的通信,为此引出了NAT。
- 容器访问外部网络
为了解决容器访问外部网络,Docker创建如下MASQUERADE
-tnat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
这条规则将所有容器172.17.0.0/16发出的、目的地址为host外部网络的包IP都修改成host ip,并由host发送出去。
- 外部网络访问容器
容器提供的服务需要暴露给外部网络,docker在启动容器时,就会创建SNAT规则。
docker run -d -p 80:80 apache
就会创建一下面的SNAT规则:
iptables -t nat-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat-A Docker ! -i docker0 -tcp -m tcp --dport -j DNAT --to-destination 172.17.0.2:80
Docker网络参数
网络配置参数
Docker进程的网络配置
-b/--bridge
:指定Docker使用的网桥设备。默认情况下,Docker会创建docker0网桥设备,通过该参数可以指定docker使用已经存在的网桥设备。--bip
:指定王乔设备docker0的ip地址和掩码,使用标准的CIDR形式,--dns
配置容器的dns
容器的网络配置--net
用于指定容器使用的网络通信方式。
bridge:docker默认的方式
none:容器没有网络栈,容器无法与外部通信
container:docker会将该容器加入指定容器的network NameSpace
host:表示容器使用host的网络,没有自己独立的网络栈。
Docker数据管理
概述
Docker中的容器一旦删除,容器本身对应的rootfs文件系统就会删除,容器中的所有数据也将随之删除。有时候我们想要数据,日志或则其他需要持久化额数据,不随容器删除而删除。还有时候,我们希望在同一台host的容器之间可以共享数据。为此,Docker提供了数据卷,数据卷可以持久化数据,还可以用于容器之间共享数据。
数据卷
创建数据卷
[root@localhost ~]# docker run -it --rm -v /volume1 --name test1 ubuntu /bin/bash
root@816b0ee1b911:/# df -lh
Filesystem Size Used Avail Use% Mounted on
overlay 37G 19G 19G 51% /
tmpfs 64M 0 64M 0% /dev
tmpfs 1.1G 0 1.1G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/mapper/centos-root 37G 19G 19G 51% /volume1
tmpfs 1.1G 0 1.1G 0% /proc/asound
tmpfs 1.1G 0 1.1G 0% /proc/acpi
tmpfs 1.1G 0 1.1G 0% /proc/scsi
tmpfs 1.1G 0 1.1G 0% /sys/firmware
root@816b0ee1b911:/# ls v
var/ volume1/
root@816b0ee1b911:/# ls volume1/
root@816b0ee1b911:/# echo "hello" > /volume1/test.txt
root@816b0ee1b911:/# ls volume1/
test.txt
root@816b0ee1b911:/#
对于这种方式创建数据卷,当容器被删除后,如果没有其他容器引用该数据卷,对应的host目录也会被删除。所以不想host的目录被删除,必须一定host目录。
挂载host的目录作为数据卷
除了创建数据卷外,我们还可以挂载host的目录到容器,作为容器的数据卷。
[root@localhost /]# docker run -it --rm -v /data/vulume1:/volueme1 ubuntu /bin/bash
root@0f9510ac0f90:/# df -lh
Filesystem Size Used Avail Use% Mounted on
overlay 37G 19G 19G 51% /
tmpfs 64M 0 64M 0% /dev
tmpfs 1.1G 0 1.1G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/mapper/centos-root 37G 19G 19G 51% /volueme1
tmpfs 1.1G 0 1.1G 0% /proc/asound
tmpfs 1.1G 0 1.1G 0% /proc/acpi
tmpfs 1.1G 0 1.1G 0% /proc/scsi
tmpfs 1.1G 0 1.1G 0% /sys/firmware
root@0f9510ac0f90:/# echo "hello" > /v
var/ volueme1/
root@0f9510ac0f90:/# echo "hello" > /volueme1/hello.txt
root@0f9510ac0f90:/#
root@0f9510ac0f90:/# exit
exit
[root@localhost /]# ls /data/vulume1/
hello.txt
[root@localhost /]# cat /data/vulume1/hello.txt
hello
[root@localhost /]#
我们将host上的/data/volume1挂载容器中的volume1.通过这种方式我们在host与容器之间进行数据交换。比如,容器内的应用程序可以将日志、重要数据写到/volume1上。这样,即使容器被删除,数据仍然会保留在host上。
host目录必须是绝对路径,如果该目录不存在,docker会自动创建该目录。
在默认的情况下,容器对挂载的数据具有读写权限。我们也可以挂载只读
rw、ro。
挂载host 文件作为数据卷
[root@localhost /]# docker run -it --rm -v /etc/hosts:/etc/hosts ubuntu /bin/bash
root@2f2dd6a7a834:/# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
root@2f2dd6a7a834:/#
数据卷容器
创建和挂载数据卷容器
容器之间可以共享数据,可以创建一个数据卷容器,然后供其他容器挂载。
[root@localhost /]# docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
Unable to find image 'training/postgres:latest' locally
latest: Pulling from training/postgres
Image docker.io/training/postgres:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
a3ed95caeb02: Pull complete
6e71c809542e: Pull complete
2978d9af87ba: Pull complete
e1bca35b062f: Pull complete
500b6decf741: Pull complete
74b14ef2151f: Pull complete
7afd5ed3826e: Pull complete
3c69bb244f5e: Pull complete
d86f9ec5aedf: Pull complete
010fabf20157: Pull complete
Digest: sha256:a945dc6dcfbc8d009c3d972931608344b76c2870ce796da00a827bd50791907e
Status: Downloaded newer image for training/postgres:latest
f91c945472b8a6af306df362bf373c577ae58392f76c2edd08263867e20b444b
[root@localhost /]#
可以通过–volumes-from在其他容器挂载/dbdata数据卷
[root@localhost /]# docker run -d --volumes-from dbdata --name db1 training/postgres
1a97206a0b9cf2081a0a6ab0317923b974bf8aaf91696e062eedadc4c9aea89e
[root@localhost /]# docker run -d --volumes-from dbdata --name db2 training/postgres
e9ab2d1faab5be87988f060540a46b2f548bbe6621eb3fc829f975d0f68c5cbd
[root@localhost /]#
这个样子db1和db2也能看到dbdata所有的数据卷。
也可以同事使用多个–volumes-from参数,从多个容器挂载多个数据卷。也可以从其他已经挂载容器卷的容器挂载数据卷
[root@localhost /]# docker run -d --name db3 --volumes-from db1 training/postgres
c4ed9125ead1160a60309f6f1758962708fb02029ff29316447f6568b50cfaed
[root@localhost /]#
数据卷容器的应用
很多应用程序通常会通过系统的syslog记录日志。我们可以将应用程序和rsylog同时安装到镜像中,然后在同一个容器中同时运行应用程序和rsylog。
- 构建rsylog镜像
- 运行rsylog容器
- 在其他容器写log到日志容器
备份、恢复和迁移数据卷
备份数据卷
[root@localhost /]# docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
tar: Removing leading `/' from member names
/dbdata/
[root@localhost /]# ls
backup.tar bin boot data dev etc home lib lib64 media mnt opt proc root run sbin some srv sys tmp usr var www
[root@localhost /]#
恢复数据卷
[root@localhost /]# docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
[root@localhost /]# docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
dbdata/
[root@localhost /]#