Docker 基础知识
容器网络基础

容器网络基础

容器网络是一种特殊的网络环境,它允许你在多个容器之间创建一个虚拟的网络。这个网络可以让你在不同的容器之间共享数据、通信和资源。

Docker bridge网络

Docker 提供了一个名为 bridge 的默认网络。这个网络是容器网络的基础,它提供了一种简单的方式来连接容器之间。

bridge 网络的特点

  • bridge 网络是一个虚拟的网络,它运行在 Docker 主机上。
  • 它可以将多个容器连接到一起,形成一个单一的网络环境。
  • bridge 网络仅能在Docker 主机上可用,局域网内的其他主机默认是不能直接连接到本Docker的主机下的bridge网络。

命令说明

用法:

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

查看网络

docker network ls

创建网络

docker network create my-net

Docker网络实验

环境准备

创建一个默认的网络容器

docker run -d --name ubuntu-default-network my-ubuntu-sshd-image:v1.0 /usr/sbin/sshd -D

创建两个指定网络为my-net容器

docker run -d --network my-net --name ubuntu-my-net1 my-ubuntu-sshd-image:v1.0 /usr/sbin/sshd -D
docker run -d --network my-net --name ubuntu-my-net2 my-ubuntu-sshd-image:v1.0 /usr/sbin/sshd -D

查看docker进程:

docker ps

结果如下:

CONTAINER ID   IMAGE                       COMMAND                 STATUS          PORTS     NAMES
8769116e88b5   my-ubuntu-sshd-image:v1.0   "/usr/sbin/sshd -D"     Up 11 seconds   22/tcp    ubuntu-my-net2
e3f38be57b79   my-ubuntu-sshd-image:v1.0   "/usr/sbin/sshd -D"     Up 16 seconds   22/tcp    ubuntu-my-net1
a10e4bb9a82f   my-ubuntu-sshd-image:v1.0   "/usr/sbin/sshd -D"     Up 17 minutes   22/tcp    ubuntu-default-network

查看容器ip

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}} {{.Name}}' ubuntu-default-network ubuntu-my-net1 ubuntu-my-net2

结果如下:

172.17.0.2  /ubuntu-default-network
172.18.0.2  /ubuntu-my-net1
172.18.0.3  /ubuntu-my-net2

验证主机网络

在Docker主机下,ping这两个网络:

ping -c 4 172.17.0.2

结果如下:

PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.192 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.090 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.093 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.091 ms

--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3075ms
rtt min/avg/max/mdev = 0.090/0.116/0.192/0.043 ms

网络通信正常。

ping -c 4 172.18.0.2

网络通信正常。

验证容器间网络

  • ubuntu-my-net1 到 ubuntu-my-net2
docker exec -t ubuntu-my-net1 ping -c4 172.18.0.3

正常:

PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.128 ms
64 bytes from 172.18.0.3: icmp_seq=2 ttl=64 time=0.129 ms
64 bytes from 172.18.0.3: icmp_seq=3 ttl=64 time=0.127 ms
64 bytes from 172.18.0.3: icmp_seq=4 ttl=64 time=0.128 ms

--- 172.18.0.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3076ms
rtt min/avg/max/mdev = 0.127/0.128/0.129/0.000 ms
  • ubuntu-my-net2 到 ubuntu-my-net1
docker exec -t ubuntu-my-net2 ping -c4 172.18.0.2

正常:

PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.175 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.119 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.123 ms
64 bytes from 172.18.0.2: icmp_seq=4 ttl=64 time=0.153 ms

--- 172.18.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3054ms
rtt min/avg/max/mdev = 0.119/0.142/0.175/0.022 ms
  • ubuntu-my-net1 到 ubuntu-default-network
docker exec -t ubuntu-my-net1 ping -c4 172.17.0.2

网络不通:

PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.

--- 172.17.0.2 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3071ms
  • ubuntu-default-network 到 ubuntu-my-net1 结查也一样,可以自行验证。

验证同局域网网络下的其它主机和容器网络的通信

  • 情况一 进入另外一台练习机ping容器网络,执行:
ping -c4 172.17.0.2

结果不通:

PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
From 172.17.0.1 icmp_seq=1 Destination Host Unreachable
From 172.17.0.1 icmp_seq=2 Destination Host Unreachable
From 172.17.0.1 icmp_seq=3 Destination Host Unreachable
From 172.17.0.1 icmp_seq=4 Destination Host Unreachable

--- 172.17.0.2 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3050ms
pipe 3
  • 情况二 容器内连接局域网内其它主机:
docker exec -t ubuntu-my-net1 ping -c4 10.32.1.51

网络正常:

PING 10.32.1.51 (10.32.1.51) 56(84) bytes of data.
64 bytes from 10.32.1.51: icmp_seq=1 ttl=63 time=0.675 ms
64 bytes from 10.32.1.51: icmp_seq=2 ttl=63 time=0.616 ms
64 bytes from 10.32.1.51: icmp_seq=3 ttl=63 time=0.720 ms
64 bytes from 10.32.1.51: icmp_seq=4 ttl=63 time=2.20 ms

--- 10.32.1.51 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3068ms

总结

Docker 为容器提供了一种bridge网络,每个network有一个独立的网段,每个容器会被分配到一个容器ip, 具备以下特点:

  • Docker主机可以连通所有网段的bridge网络
  • 相同网段network内部是互通的
  • 不同网段network容器网络是隔离的
  • 容器网络可以连通局域网内其它IP
  • 网内其它IP无法直达容器网络

如何容器给同局域网内的其它主机提供服务?

用法:

docker run --help | grep publish
  -p, --publish list                   Publish a container's port(s) to the host

例子:

docker run -d --network my-net -p 1022:22 --name ubuntu-sshd-net1 my-ubuntu-sshd-image:v1.0 /usr/sbin/sshd -D

选项解释:

  • -p 1022:22:这个选项将主机上的端口 1022 映射到容器内的端口 22。这对外部访问 SSH(端口 22)非常有用。

通过-p参数将容器的服务端口暴露在主机上是最常见的方法,在网络下的其它主机就可以直接使用Docker主机ip和1022端口来连接到容器ubuntu-sshd-net1中。

验证:

  • 查看容器PORTS:
# docker ps
CONTAINER ID   IMAGE                          PORTS                                   NAMES
343e8b029382   my-ubuntu-sshd-image:v1.0      0.0.0.0:1022->22/tcp, :::1022->22/tcp   ubuntu-sshd-net1

确认1022会转发到容器ubuntu-sshd-net1的22端口。

  • 确认容器ip
docker exec -ti ubuntu-sshd-net1 ip a

容器IP为172.18.0.4

  • 使用其他主机进行连接测试
ssh -p1022 root@docker主机ip

结果:

ssh -p1022 root@10.32.x.xx
The authenticity of host '[10.32.x.xx]:1022 ([10.32.x.xx]:1022)' can't be established.
ECDSA key fingerprint is SHA256:fUKVKz44MGBnbqD59SEbRzuc1Mi0V2K8Rt5gwpHdFjk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[10.32.x.xx]:1022' (ECDSA) to the list of known hosts.
root@10.32.x.xx's password: 
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.4.0-1115-kvm x86_64)

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

root@343e8b029382:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
25: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.4/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

确定ssh已经连上172.18.0.4容器。

资源清理

危险命令,慎用!

删除所有容器:

docker container ls -aq | xargs docker container rm -f