一、Docker数据管理

Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层

如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW copy on write)"机制

如果将正在运行中的容器修改生成了新的数据,那么新产生的数据将会被复制到读写层,进行持久化保存,这个读写层也就是容器的工作目录,也为写时复制(COW) 机制。

COW机制节约空间,但会导致性低下,虽然关闭重启容器,数据不受影响,但会随着容器的删除,其对应的可写 层也会随之而删除,即数据也会丢失.如果容器需要持久保存数据,并不影响性能可以用数据卷技术实现

1、容器的数据管理介绍

Docker镜像是分层设计的,镜像层是只读的,通过镜像启动的容器添加了一层可读写的文件系统,用户 写入的数据都保存在这一层中。

1.Docker容器的分层

容器的数据分层目录

LowerDir: image 镜像层,即镜像本身,只读

UpperDir: 容器的上层,可读写 ,容器变化的数据存放在此处

MergedDir: 容器的文件系统,使用Union FS(联合文件系统)将lowerdir 和 upperdir 合并完成后给容器使用,最终呈现给用户的统一视图

WorkDir: 容器在宿主机的工作目录,挂载后内容会被清空,且在使用过程中其内容用户不可见

查看指定容器数据分层

[root@c7-docker-node1-71 ~]# docker inspect c8_nginx_test:v1.0
[
    {
        "Id": "sha256:2c50b1812ed42be23f776350e0bb0a98187615422c6f280d580cc7e42807f6bd",
        "RepoTags": [
            "c8_nginx_test:v1.0"
        ],
        "RepoDigests": [],
        "Parent": "sha256:bafa0116b0d35299bb47c9aa7903555f1deb8eabcf2230affe0d4c19742f6353",
        "Comment": "",
        "Created": "2024-02-17T06:29:00.306840573Z",
        "Container": "283e577f15feb32ed5c97e8aa81879423ccea51ab683107b1c34fb7d2da6da01",
        "ContainerConfig": {
            "Hostname": "283e577f15fe",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "443/tcp": {},
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/sbin/nginx\" \"-c\" \"/apps/nginx/conf/nginx.conf\"]"
            ],
            "Image": "sha256:bafa0116b0d35299bb47c9aa7903555f1deb8eabcf2230affe0d4c19742f6353",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "Lead_Author": "jiutingqiu@www.elysia.media",
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "DockerVersion": "19.03.10",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "443/tcp": {},
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/sbin/nginx",
                "-c",
                "/apps/nginx/conf/nginx.conf"
            ],
            "Image": "sha256:bafa0116b0d35299bb47c9aa7903555f1deb8eabcf2230affe0d4c19742f6353",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "Lead_Author": "jiutingqiu@www.elysia.media",
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 469687105,
        "VirtualSize": 469687105,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/data/docker/overlay2/31aa4b3325d53cc2467bd8394b4eb873667083af5c1ab8d70c7626c93004d734/diff",
                "MergedDir": "/data/docker/overlay2/bacb78ec381001a68c2bbaa19574c5353a8b14943fe8ed08924beb7314e0370f/merged",
                "UpperDir": "/data/docker/overlay2/bacb78ec381001a68c2bbaa19574c5353a8b14943fe8ed08924beb7314e0370f/diff",
                "WorkDir": "/data/docker/overlay2/bacb78ec381001a68c2bbaa19574c5353a8b14943fe8ed08924beb7314e0370f/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59",
                "sha256:d40a5e8412e46bb187fa8182cbdbfda79ecd3addc6bd4056a08e3c0ae857093b"
            ]
        },
        "Metadata": {
            "LastTagTime": "2024-02-17T14:29:00.385600828+08:00"
        }
    }
]
[root@c7-docker-node1-71 ~]# ll /data/docker/overlay2/bacb78ec381001a68c2bbaa19574c5353a8b14943fe8ed08924beb7314e0370f/
total 8
-rw-------. 1 root root  0 Feb 17 14:29 committed
drwxr-xr-x. 8 root root 74 Feb 17 14:28 diff
-rw-r--r--. 1 root root 26 Feb 17 14:28 link
-rw-r--r--. 1 root root 28 Feb 17 14:28 lower
drwx------. 2 root root  6 Feb 17 14:28 work

2.容器数据持久保存方式

如果要将写入到容器的数据永久保存,则需要将容器中的数据保存到宿主机的指定目录

Docker 提供了多种方法将宿主机的文件系统挂载到容器内,包括以下几种主要方式:

卷(Volume):
    这是 Docker 推荐的挂载方式。卷是完全由 Docker 管理的文件目录,可以在容器之间共享和重用。在创建卷时,Docker 创建了一个目录在宿主机上,然后将这个目录挂载到容器内。卷的主要优点是你可以使用 Docker CLI 或 Docker API 来备份、迁移或者恢复卷,而无需关心卷在宿主机上的具体位置。

绑定挂载(Bind Mount):
    这种方式可以将宿主机上的任意文件或目录挂载到容器内。与卷不同,绑定挂载依赖于宿主机的文件系统结构。因此,如果你在 Docker CLI 或 Docker API 中使用绑定挂载,你需要知道宿主机上的文件或目录的具体路径。另外,由于绑定挂载可以访问宿主机上的任意文件和目录,使用这种方式可能会有一定的安全风险。

tmpfs 挂载:
    tmpfs 挂载不与宿主机上的任何文件或目录相关联,而是将一个临时文件系统挂载到容器的某个目录下。这种方式的主要优点是它提供了一个高速且安全的挂载方式,因为 tmpfs 挂载通常驻留在宿主机的内存中,且在容器停止后会被自动删除。

Docker的卷(Volume)类型分为两种:

数据卷(Data Volume): 直接将宿主机目录挂载至容器的指定的目录 ,推荐使用此种方式,此方式较常用

数据卷容器(Data Volume Container): 间接使用宿主机空间,数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器,然后让其他容器通过数据卷容器读写宿主机的数据 ,此方式不常用

2、数据卷特点和使用

数据卷实际上就是宿主机上的目录或者是文件,可以被直接mount到容器当中使用

1.数据卷使用场景

数据库
日志输出
静态web页面
应用配置文件
多容器间目录或文件共享

2.数据卷的特点

数据卷是目录或者文件,并且可以在多个容器之间共同使用,实现容器之间共享和重用
对数据卷更改数据在所有容器里面会立即更新。
数据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。

3.数据卷分类

启动容器时,可以指定使用数据卷实现容器数据的持久化,数据卷有三种

指定宿主机目录或文件: 指定宿主机的具体路径和容器路径的挂载关系,此方式不会创建数据卷

匿名卷: 不指定数据名称,只指定容器内目录路径充当挂载点,docker自动指定宿主机的路径进行挂载,此方式会创建匿名数据卷,Dockerfile中VOLUME指定的卷即为此种

命名卷: 指定数据卷的名称和容器路径的挂载关系,此方式会创建命名数据卷

4.数据卷使用方法

docker run 命令的以下格式可以实现数据卷

-v, --volume=[host-src:]container-dest[:<options>]

1 绑定挂载

#指定宿主机目录或文件格式: 

-v   <宿主机绝对路径的目录或文件>:<容器目录或文件>[:ro]  #将宿主机目录挂载容器目录,两个目录都可自动创建

2 匿名卷

#匿名卷,只指定容器内路径,没有指定宿主机路径信息,宿主机自动生成/var/lib/docker/volumes/<卷ID>/_data目录,并挂载至容器指定路径

-v <容器内路径>

3 命名卷

#命名卷将固定的存放在/var/lib/docker/volumes/<卷名>/_data

-v <卷名>:<容器目录路径>

#可以通过以下命令事先创建,如可没有事先创建卷名,docker run时也会自动创建卷
docker volume create <卷名>

docker rm 的 -v 选项可以删除容器时,同时删除相关联的匿名卷

4 管理数据卷命令

docker volume COMMAND

create      #创造卷
inspect     #显示一个或多个卷的详细信息
ls          #查看所有卷
prune       #删除所有未使用的本地卷
rm          #删除一个或多个卷
[root@c7-docker-node1-71 ~]# docker volume create nginx_data
nginx_data

[root@c7-docker-node1-71 ~]# docker volume ls
DRIVER              VOLUME NAME
local               nginx_data

[root@c7-docker-node1-71 ~]# tree /data/docker/volumes/
/data/docker/volumes/
├── metadata.db
└── nginx_data
    └── _data

2 directories, 1 file

[root@c7-docker-node1-71 ~]# docker volume rm nginx_data
nginx_data
[root@c7-docker-node1-71 ~]# docker volume ls
DRIVER              VOLUME NAME

3、数据卷练习

1.在宿主机创建容器所使用的目录

[root@c7-docker-node1-71 ~]# mkdir /data/test_dir
[root@c7-docker-node1-71 ~]# echo data volume test web > /data/test_dir/index.html

2.查看容器相关目录路径

[root@d7eef0abc4c1 /]# ls /apps/nginx/html/
50x.html    index.html 

3.引用宿主机的数据卷启动容器

[root@c7-docker-node1-71 ~]# docker run -it -d -v /data/test_dir/:/apps/nginx/html/ -p 80:80 --name test c8_nginx_test:v1.0
fddcabb9a8d0658bcddb80b7fb804fdb372cc8baf82dd6adbda51c0892597731

[root@c7-docker-node1-71 ~]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                         NAMES
fddcabb9a8d0        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   5 seconds ago       Up 5 seconds        0.0.0.0:80->80/tcp, 443/tcp   test

[root@c7-docker-node1-71 ~]# curl 172.29.7.71
data volume test web

4.删除容器

[root@c7-docker-node1-71 ~]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                         NAMES
fddcabb9a8d0        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   57 seconds ago      Up 57 seconds       0.0.0.0:80->80/tcp, 443/tcp   test

[root@c7-docker-node1-71 ~]# docker rm -f test
test

[root@c7-docker-node1-71 ~]# ls /data/test_dir/
index.html

[root@c7-docker-node1-71 ~]# cat /data/test_dir/index.html 
data volume test web

4、数据卷容器

1.数据卷容器介绍

在Dockerfile中创建的是匿名数据卷,无法直接实现多个容器之间共享数据数据卷容器主要的功能是可以让数据在多个docker容器之间共享


2.使用数据卷容器

启动容器时,指定使用数据卷容器

--volumes-from <数据卷容器>

3.练习

1 创建一个数据卷容器 Server

先创建一个挂载宿主机的数据目录的容器,且可以无需启动

[root@c7-docker-node1-71 ~]# docker run -d --name volume-server -v /data/test_dir/:/apps/nginx/html/ c8_nginx_test:v1.0
478daf496d4f47d64c5ea735ef7812cec115f8c8ca2d24b7edb0a317b0f53315
[root@c7-docker-node1-71 ~]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS               NAMES
478daf496d4f        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   4 seconds ago       Up 3 seconds        80/tcp, 443/tcp     volume-server

2 启动多个数据卷容器 Client

[root@c7-docker-node1-71 ~]# docker run -d --name client1 -it --volumes-from volume-server -p 81:80 c8_nginx_test:v1.0
138212ab4efe500a67b6a63bbfe11a7b5f4004d0686a6456486efbabd0ffd85f
[root@c7-docker-node1-71 ~]# docker run -d --name client2 -it --volumes-from volume-server -p 82:80 c8_nginx_test:v1.0
d7bf20b935adde21da2b5a9c0dde3cec25031326d1430d30fdfe25df9ad291bc
[root@c7-docker-node1-71 ~]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED              STATUS              PORTS                         NAMES
d7bf20b935ad        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   2 seconds ago        Up 2 seconds        443/tcp, 0.0.0.0:82->80/tcp   client2
138212ab4efe        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   11 seconds ago       Up 11 seconds       443/tcp, 0.0.0.0:81->80/tcp   client1
478daf496d4f        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   About a minute ago   Up About a minute   80/tcp, 443/tcp               volume-server

3 测试

[root@c7-docker-node1-71 ~]# curl 172.29.7.71:81
data volume test web

[root@c7-docker-node1-71 ~]# curl 172.29.7.71:82
data volume test web


二、Docker 网络管理

1、Docker的默认的网络通信

1.Docker安装后默认的网络设置

[root@c7-docker-node1-71 ~]# ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:8b:46:ed brd ff:ff:ff:ff:ff:ff
    inet 172.29.7.71/24 brd 172.29.7.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe8b:46ed/64 scope link 
       valid_lft forever preferred_lft forever
3: virbr0:  mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:73:fc:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic:  mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:73:fc:10 brd ff:ff:ff:ff:ff:ff
5: docker0:  mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:fb:59:c1:15 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:fbff:fe59:c115/64 scope link 
       valid_lft forever preferred_lft forever

[root@c7-docker-node1-71 ~]# brctl show
bridge name bridge id       STP enabled interfaces
docker0     8000.0242fb59c115   no      
virbr0      8000.52540073fc10   yes     virbr0-nic

2.创建容器后的网络配置

veth(Virtual Ethernet)是Linux内核中的一种虚拟网络设备,通常用于连接两个网络命名空间。veth设备总是成对出现,当在一个网络命名空间中创建veth设备时,会同时创建两个端点。


3.创建第一个容器后的网络状态

[root@c7-docker-node1-71 ~]# docker run -it -d -v /data/test_dir/:/apps/nginx/html/ -p 80:80 --name test c8_nginx_test:v1.0
40dc66c89f740edf915c56e659a074fed519d897989d953a398719fd8114fea8
[root@c7-docker-node1-71 ~]# ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:8b:46:ed brd ff:ff:ff:ff:ff:ff
    inet 172.29.7.71/24 brd 172.29.7.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe8b:46ed/64 scope link 
       valid_lft forever preferred_lft forever
3: virbr0:  mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:73:fc:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic:  mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:73:fc:10 brd ff:ff:ff:ff:ff:ff
5: docker0:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:fb:59:c1:15 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:fbff:fe59:c115/64 scope link 
       valid_lft forever preferred_lft forever
47: veth96bb68c@if46:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 02:ef:66:4f:04:c2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::ef:66ff:fe4f:4c2/64 scope link 
       valid_lft forever preferred_lft forever

2、容器间的通信

1.同一个宿主机的不同容器可相互通信

[root@c7-docker-node1-71 ~]# docker run -it -d -v /data/test_dir/:/apps/nginx/html/ -p 81:80 --name test1 c8_nginx_test:v1.0
096e747289dd667530ccb6b7e2aa628ffa9882dbefb740bc89db5e6c0a7dd1d9
[root@c7-docker-node1-71 ~]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED              STATUS              PORTS                         NAMES
096e747289dd        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   8 seconds ago        Up 7 seconds        443/tcp, 0.0.0.0:81->80/tcp   test1
40dc66c89f74        c8_nginx_test:v1.0   "/sbin/nginx -c /app…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, 443/tcp   test

[root@c7-docker-node1-71 ~]# docker exec -it test bash
[root@40dc66c89f74 /]# ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
46: eth0@if47:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@40dc66c89f74 /]# ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.043 ms
^C
--- 172.17.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.043/0.071/0.100/0.029 ms
[root@40dc66c89f74 /]# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.049 ms
^C
--- 172.17.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.048/0.064/0.096/0.023 ms

3、修改默认docker0网桥的网络配置

默认docker后会自动生成一个docker0的网桥,使用的IP是172.17.0.1/16,可能和宿主机的网段发生冲突, 可以将其修改为其它网段的地址,避免冲突

[root@c7-docker-node1-71 ~]# head -n  2 /etc/docker/daemon.json 
{
"bip": "192.168.100.1/24",

[root@c7-docker-node1-71 ~]# systemctl restart docker
[root@c7-docker-node1-71 ~]# ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:8b:46:ed brd ff:ff:ff:ff:ff:ff
    inet 172.29.7.71/24 brd 172.29.7.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe8b:46ed/64 scope link 
       valid_lft forever preferred_lft forever
3: virbr0:  mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:73:fc:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic:  mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:73:fc:10 brd ff:ff:ff:ff:ff:ff
5: docker0:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:fb:59:c1:15 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:fbff:fe59:c115/64 scope link 
       valid_lft forever preferred_lft forever
47: veth96bb68c@if46:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 02:ef:66:4f:04:c2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::ef:66ff:fe4f:4c2/64 scope link 
       valid_lft forever preferred_lft forever
49: vethbbab48b@if48:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether b2:78:6d:07:c6:51 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::b078:6dff:fe07:c651/64 scope link 
       valid_lft forever preferred_lft forever

4、修改默认网络设置使用自定义网桥

新建容器默认使用docker0的网络配置,可以修改默认指向自定义的网桥网络

去掉之前在/etc/docker/daemon.json添加的bip

[root@c7-docker-node1-71 ~]# brctl addbr br0
[root@c7-docker-node1-71 ~]# ip a a 192.168.100.1/24 dev br0
[root@c7-docker-node1-71 ~]# brctl show
bridge name bridge id       STP enabled interfaces
br0     8000.000000000000   no      
docker0     8000.0242fb59c115   no      veth96bb68c
                            vethbbab48b
virbr0      8000.52540073fc10   yes     virbr0-nic

[root@c7-docker-node1-71 ~]# cat /lib/systemd/system/docker.service 
....
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -b br0
....

[root@c7-docker-node1-71 ~]# systemctl daemon-reload 
[root@c7-docker-node1-71 ~]# systemctl restart docker

5、容器名称互联

新建容器时,docker会自动分配容器名称,容器ID和IP地址,导致容器名称,容器ID和IP都不固定,那 么如何区分不同的容器,实现和确定目标容器的通信呢?解决方案是给容器起个固定的名称,容器之间 通过固定名称实现确定目标的通信

有两种固定名称:

容器名称

容器名称的别名

1.通过容器名称互联

1 容器名称介绍

即在同一个宿主机上的容器之间可以通过自定义的容器名称相互访问,比如: 一个业务前端静态页面是 使用nginx,动态页面使用的是tomcat,另外还需要负载均衡调度器,如: haproxy 对请求调度至nginx 和tomcat的容器,由于容器在启动的时候其内部IP地址是DHCP 随机分配的,而给容器起个固定的名 称,则是相对比较固定的,因此比较适用于此场景


2 容器名称实现

docker run 创建容器,可使用--link选项实现容器名称的引用,其本质就是在容器内的/etc/hosts中添加- -link后指定的容器的IP和主机名的对应关系,从而实现名称解析

--link list

docker run --name <容器名称>                    #先创建指定名称的容器
docker run --link <目标通信的容器ID或容器名称>     #再创建容器时引用上面容器的名称

3.练习

[root@c7-docker-node1-71 ~]# docker run -it --name server1  centos bash

[root@a793f4151522 /]# ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
55: eth0@if56:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.100.2/24 brd 192.168.100.255 scope global eth0
       valid_lft forever preferred_lft foreve

[root@a793f4151522 /]# 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
192.168.100.2   a793f4151522

[root@c7-docker-node1-71 ~]# docker run -it --name server2 --link server1  centos bash
[root@9e18117a1c18 /]# 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
192.168.100.2   server1 a793f4151522
192.168.100.3   9e18117a1c18

[root@9e18117a1c18 /]# ping server1
PING server1 (192.168.100.2) 56(84) bytes of data.
64 bytes from server1 (192.168.100.2): icmp_seq=1 ttl=64 time=0.133 ms
64 bytes from server1 (192.168.100.2): icmp_seq=2 ttl=64 time=0.053 ms
64 bytes from server1 (192.168.100.2): icmp_seq=3 ttl=64 time=0.051 ms
^C
--- server1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.051

2、通过自定义容器别名互联

1.容器别名介绍

自定义的容器名称可能后期会发生变化,那么一旦名称发生变化,容器内程序之间也必须要随之发生变 化,比如:程序通过固定的容器名称进行服务调用,但是容器名称发生变化之后再使用之前的名称肯定是 无法成功调用,每次都进行更改的话又比较麻烦,因此可以使用自定义别名的方式解决,即容器名称可 以随意更改,只要不更改别名即可


2.容器别名实现

docker run --name <容器名称> 
#先创建指定名称的容器

docker run --name <容器名称> --link <目标容器名称>:"<容器别名1> <容器别名2> ..." 
#给上面创建的容器起别名,来创建新容器
[root@c7-docker-node1-71 ~]# docker run -it --name server1 centos
[root@fea4780f6f0c /]# [root@c7-docker-node1-71 ~]# 
[root@c7-docker-node1-71 ~]# docker run -it --name server2 --link server1 centos
[root@917314a275c9 /]# [root@c7-docker-node1-71 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
917314a275c9        centos              "/bin/bash"         20 seconds ago      Up 19 seconds                           server2
fea4780f6f0c        centos              "/bin/bash"         53 seconds ago      Up 52 seconds                           server1

[root@c7-docker-node1-71 ~]# docker run -it --rm --name server3 --link server1:server1-alias centos 
[root@5d2b8bae0221 /]# 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
192.168.100.2   server1-alias fea4780f6f0c server1
192.168.100.4   5d2b8bae0221


6、Docker 网络连接模式

1.网络模式介绍

Docker 的网络支持5种网络模式:

none
bridge
container
host
network-name

查看默认的网络模式有三个

[root@c7-docker-node1-71 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
e0116491ef85        bridge              bridge              local
e80af8464ec1        host                host                local
5d8e1ba81e1a        none                null                local

2.网络模式指定

默认新建的容器使用Bridge模式,创建容器时,docker run 命令使用以下选项指定网络模式

docker run --network 
docker run --net=

none
bridge
host
container:<容器名或容器ID>
<自定义网络名称>

3、Bridge网络模式

1.Bridge 网络模式架构

本模式是docker的默认模式,即不指定任何模式就是bridge模式,也是使用比较多的模式,此模式创建的容器会为每一个容器分配自己的网络 IP 等信息,并将容器连接到一个虚拟网桥与外界通信

可以和外部网络之间进行通信,通过SNAT访问外网,使用DNAT可以让容器被外部主机访问,所以此模式也称为NAT模式

2.Host 模式

如果指定host模式启动的容器,那么新创建的容器不会创建自己的虚拟网卡,而是直接使用宿主机的网卡和IP地址,因此在容器里面查看到的IP信息就是宿主机的信息,访问容器的时候直接使用宿主机IP+容器端口即可,不过容器内除网络以外的其它资源,如: 文件系统、系统进程等仍然和宿主机保持隔离

此模式由于直接使用宿主机的网络无需转换,网络性能最高,但是各容器内使用的端口不能相同,适用于运行容器端口比较固定的业务

3.None 模式

在使用 none 模式后,Docker 容器不会进行任何网络配置,没有网卡、没有IP也没有路由,因此默认无法与外界通信,需要手动添加网卡配置IP等,所以极少使用

4.Container 模式

使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,而不是和宿主机共享网络,新创建的容器不会创建自己的网卡也不会配置自己的IP,而是和一个被指定的已经存在的容器共享IP和端口范围,因此这个容器的端口不能和被指定容器的端口冲突,除了网络之外的文件系统、进程信息等仍然保持相互隔离,两个容器的进程可以通过lo网卡进行通信

5.自定义网络模式

使用自定义的网段地址,网关等信息。可以使用自定义网络模式,实现不同集群应用的独立网络管理,而互不影响,而且在网一个网络内,可以直接
利用容器名相互访问,非常便利

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注