[Container] Docker Network

1. Docker network implementation principle

Docker uses Linux bridging to virtualize a Docker container bridge (docker0) on the host. When Docker starts a container, it will assign an IP address to the container based on the network segment of the Docker bridge, called Container-IP. At the same time, the Docker bridge is each The default gateway for each container. Because containers in the same host are all connected to the same network bridge, containers can communicate directly through the container's Container-IP.

The Docker bridge is virtualized by the host and is not a real network device. It cannot be addressed by the external network, which also means that the external network cannot directly access the container through Container-IP. If the container wants to be accessible from the outside, you can map the container port to the host host (port mapping), that is, enable docker run through the -p or -P parameter when creating the container, and use [host IP] when accessing the container: [Container Port] Access the container.

docker run -d --name test1 -P nginx					#随机映射端口(从32768开始)

docker run -d --name test2 -p 43000:80 nginx		#指定映射端口

Insert image description hereInsert image description here
Insert image description hereInsert image description here

#查看容器的输出和日志信息
docker logs 容器的ID/名称在这里插入代码片

Insert image description here

2. Docker’s network mode

  • Host: The container will not virtualize its own network card, configure its own IP, etc., but use the IP and port of the host.
  • Container: The created container will not create its own network card and configure its own IP, but will share the IP and port range with a specified container.
  • None: This mode turns off the container’s network functionality.
  • Bridge: The default is this mode. This mode will allocate and set IP for each container, and connect the container to a docker0 virtual bridge, through the docker0 bridge and The iptables nat table is configured to communicate with the host.
  • Custom network

When Docker is installed, it will automatically create three networks, bridge (the created container is connected to this network by default), none, and host

docker network lsdocker network list			#查看docker网络列表在这里插入代码片

NETWORK ID     NAME      DRIVER    SCOPE
7be1b48179eb   bridge    bridge    local
8b06de5ee747   host      host      local
3610ef8d722d   none      null      local

When using docker run to create a Docker container, you can use the --net or --network option to specify the network mode of the container.

  • Host mode: Use --net=host to specify.
  • none mode: Specify using --net=none.
  • Container mode: Use --net=container:NAME_or_ID to specify.
  • Bridge mode: Use --net=bridge to specify, default setting, can be omitted.

3. Network mode explanation

1. host mode

is equivalent to the bridge mode in Vmware. It is on the same network as the host but does not have an independent IP address.
Docker uses Linux Namespaces technology to isolate resources, such as PID Namespace isolation process, Mount Namespace isolation file system, Network Namespace isolation network, etc.
A Network Namespace provides an independent network environment, including network cards, routing, iptable rules, etc., which are isolated from other Network Namespaces. A Docker container is generally assigned an independent Network Namespace. But if you use host mode when starting a container, the container will not get an independent Network Namespace, but will share a Network Namespace with the host. The container will not virtualize its own network card, configure its own IP, etc., but use the host's IP and port.

Insert image description here

2. container mode

After understanding the host mode, this mode will be easier to understand. This mode specifies that the newly created container shares a Network Namespace with an existing container, rather than sharing it with the host. The newly created container will not create its own network card and configure its own IP, but will share the IP, port range, etc. with a specified container. Similarly, apart from the network, the two containers are also isolated in other aspects such as file systems, process lists, etc. The processes of the two containers can communicate through the lo network card device.

docker run -itd --name test1 centos:7 /bin/bash #–name option can create a custom name for the container

docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ed82355f811 centos:7 “/bin/bash” 5 days ago Up 6 hours test1

docker inspect -f ‘{ {.State.Pid}}’ 3ed82355f811 #View container process number
25945

ls -l /proc/25495/ns #View the container’s process, network, file system and other namespace numbers
lrwxrwxrwx 1 root root 0 January 7 11:29 ipc - > ipc:[4026532572]
lrwxrwxrwx 1 root root 0 January 7 11:29 mnt -> mnt:[4026532569]
lrwxrwxrwx 1 root root 0 January 7 11:27 net -> net:[4026532575]
lrwxrwxrwx 1 root root 0 January 7 11:29 pid -> pid:[4026532573]
lrwxrwxrwx 1 root root 0 January 7 12:22 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 January 7 11:29 uts -> uts:[ 4026532570]

docker run -itd --name test2 --net=container:3ed82355f811 centos:7 /bin/bash
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff96bc43dd27 centos:7 “/bin/bash” 48 seconds ago Up 46 seconds test2
3ed82355f811 centos:7 “/bin/bash” 58 minutes ago Up 58 minutes test1

docker inspect -f ‘{ {.State.Pid}}’ ff96bc43dd27
27123

ls -l /proc/27123/ns #Check it and you can see that the net namespace numbers of the two containers are the same
lrwxrwxrwx 1 root root 0 January 7 12:27 ipc -> ipc:[4026532692]
lrwxrwxrwx 1 root root 0 January 7 12:27 mnt -> mnt:[4026532690]
lrwxrwxrwx 1 root root 0 January 7 12:27 net -> net:[4026532575]
lrwxrwxrwx 1 root root 0 January 7 12:27 pid -> pid:[4026532693]
lrwxrwxrwx 1 root root 0 January 7 12:27 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 January 7 12:27 uts -> uts:[4026532691]

Insert image description here
Insert image description here

3. none mode

Using none mode, the Docker container has its own Network Namespace, but no network configuration is performed for the Docker container. In other words, this Docker container does not have network card, IP, routing and other information. In this network mode, the container only has the lo loopback network and no other network cards. This type of network cannot be connected to the Internet. A closed network can ensure the security of the container.

Insert image description here

4. bridge mode

Bridge mode is docker's default network mode. Without the –net parameter, it is bridge mode.

Equivalent to the nat mode in Vmware, the container uses an independent network Namespace and is connected to the docker0 virtual network card. Communicate with the host through the docker0 bridge and iptables nat table configuration. This mode assigns Network Namespace, sets IP, etc. to each container, and connects a Docker container on the host to a virtual bridge.

(1) When the Docker process starts, a virtual bridge named docker0 will be created on the host, and the Docker container started on this host will connect to this virtual bridge. A virtual bridge works similarly to a physical switch, so that all containers on the host are connected to a Layer 2 network through the switch.

(2) Assign an IP from the docker0 subnet to the container, and set the IP address of docker0 as the default gateway of the container. Create a pair of virtual network card veth pair devices on the host. Veth devices always appear in pairs. They form a data channel. Data entering from one device will come out from the other device. Therefore, veth devices are often used to connect two network devices.

(3) Docker places one end of the veth pair device in the newly created container and names it eth0 (the container's network card), and the other end in the host, names it with a similar name like veth*, and adds this network device to the docker0 bridge. You can view it through the brctl show command.

(4) When using docker run -p, docker actually makes DNAT rules in iptables to implement the port forwarding function. You can use iptables -t nat -vnL to view.

Insert image description here

5. Custom network

# Directly using bridge mode does not support running docker on a specified IP. For example, an error will be reported when executing the following command
docker run -itd --name test3 --network bridge -- ip 172.17.0.10 centos:7 /bin/bash

//Create a custom network
#You can customize the network first, and then use the specified IP to run docker
docker network create --subnet=172.18 .0.0/16 --opt "com.docker.network.bridge.name" = "docker1" mynetwork

#docker1 is the network card name displayed when executing the ifconfig -a command. If you do not use the --opt parameter to specify this name, then when you use the ifconfig -a command to view network information, you will see something similar to br -110eb56a0b22 A name like this is obviously not easy to remember.
#mynetwork is the bridge network mode name displayed when executing the docker network list command.

docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash

Insert image description here

4. Resource Control

Docker uses Cgroup to control the resource quota used by containers,including three major aspects: CPU, memory, and disk, basically covering common resources Quota and usage controls.
Cgroup is the abbreviation of ControlGroups. It is a mechanism provided by the Linux kernel that can limit, record, and isolate the physical resources (such as CPU, memory, disk IO, etc.) used by the process group. It is Many projects such as LXC and docker are used to implement process resource control. Cgroup itself is the infrastructure that provides functions and interfaces for grouping management of processes. Specific resource management such as I/O or memory allocation control is implemented through this function.

1. CPU resource control

(1) Set the upper limit of CPU usage
Linux uses CFS (Completely Fair Scheduler) to schedule the use of the CPU by each process. The default scheduling period of CFS is 100ms.
We can set the scheduling cycle of each container process, and the maximum amount of CPU time each container can use during this cycle.

Use --cpu-period to set the scheduling period, and use --cpu-quota to set the CPU time that the container can use in each cycle. Both can be used together.
The valid range of CFS period is 1ms~1s, and the corresponding value range of --cpu-period is 1000~1000000.
The container's CPU quota must be no less than 1ms, that is, the value of --cpu-quota must be >= 1000.

docker run -itd --name test5 centos:7 /bin/bash

docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED      STATUS       PORTS     NAMES
3ed82355f811   centos:7   "/bin/bash"   5 days ago   Up 6 hours             test5

cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
cat cpu.cfs_quota_us 
-1

cat cpu.cfs_period_us 
100000
---------------------------------------------------------------------------------------------------------
#cpu.cfs_period_us:cpu分配的周期(微秒,所以文件名中用 us 表示),默认为100000。
#cpu.cfs_quota_us:表示该cgroups限制占用的时间(微秒),默认为-1,表示不限制。 如果设为50000,表示占用50000/100000=50%的CPU。
---------------------------------------------------------------------------------------------------------

#进行CPU压力测试
docker exec -it 3ed82355f811 /bin/bash
vim /cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done

chmod +x /cpu.sh
./cpu.sh

top					#可以看到这个脚本占了很多的cpu资源

#设置50%的比例分配CPU使用时间上限
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash	#可以重新创建一个容器并设置限额
或者
cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
echo 50000 > cpu.cfs_quota_us
docker exec -it 3ed82355f811 /bin/bash
./cpu.sh

top					#可以看到cpu占用率接近50%,cgroups对cpu的控制起了效果

#在多核情况下,如果允许容器进程完全占用两个 CPU, 则可以将 cpu-period 设置为 100000( 即 0.1 秒), cpu-quota设置为 200000(0.2 秒)。


Insert image description here
Insert image description here
Insert image description here
Insert image description hereInsert image description here

(2)设置CPU资源占用比(设置多个容器时才有效)
Docker 通过 --cpu-shares 指定 CPU 份额,默认值为1024,值为1024的倍数。
#创建两个容器为 c1 和 c2,若只有这两个容器,设置容器的权重,使得c1和c2的CPU资源占比为1/3和2/3。
docker run -itd --name c1 --cpu-shares 512 centos:7	
docker run -itd --name c2 --cpu-shares 1024 centos:7

#分别进入容器,进行压力测试
yum install -y epel-release
yum install -y stress
stress -c 4				#产生四个进程,每个进程都反复不停的计算随机数的平方根

#查看容器运行状态(动态更新)
docker stats
CONTAINER ID   NAME             CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O         PIDS
c3ee18e65852   c2               66.50%    5.5MiB / 976.3MiB     0.56%     20.4MB / 265kB   115MB / 14.2MB    4
bb02d3b345d8   c1               32.68%    2.625MiB / 976.3MiB   0.27%     20.4MB / 325kB   191MB / 12.7MB    4

可以看到在 CPU 进行时间片分配的时候,容器 c2 比容器 c1 多一倍的机会获得 CPU 的时间片。
但分配的结果取决于当时主机和其他容器的运行状态, 实际上也无法保证容器 c1 一定能获得 CPU 时间片。比如容器 c1 的进程一直是空闲的,那么容器 c2 是可以获取比容器 c1 更多的 CPU 时间片的。极端情况下,例如主机上只运行了一个容器,即使它的 CPU 份额只有 50,它也可以独占整个主机的 CPU 资源。

Cgroups 只在容器分配的资源紧缺时,即在需要对容器使用的资源进行限制时,才会生效。因此,无法单纯根据某个容器的 CPU 份额来确定有多少 CPU 资源分配给它,资源分配结果取决于同时运行的其他容器的 CPU 分配和容器中进程运行情况。

Insert image description here


(3)设置容器绑定指定的CPU
#先分配虚拟机4个CPU核数
docker run -itd --name test7 --cpuset-cpus 1,3 centos:7 /bin/bash

#进入容器,进行压力测试
yum install -y epel-release
yum install stress -y
stress -c 4

#退出容器,执行 top 命令再按 1 查看CPU使用情况。

Insert image description here
Insert image description here

2 Limitations on memory usage

//-m(--memory=) 选项用于限制容器可以使用的最大内存
docker run -itd --name test8 -m 512m centos:7 /bin/bash

docker stats

//限制可用的 swap 大小, --memory-swap
强调一下,--memory-swap 是必须要与 --memory 一起使用的。

正常情况下,--memory-swap 的值包含容器可用内存和可用 swap。
所以 -m 300m --memory-swap=1g 的含义为:容器可以使用 300M 的物理内存,并且可以使用 700M(1G - 300)的 swap。

如果 --memory-swap 设置为 0 或者 不设置,则容器可以使用的 swap 大小为 -m 值的两倍。
如果 --memory-swap 的值和 -m 值相同,则容器不能使用 swap。
如果 --memory-swap 值为 -1,它表示容器程序使用的内存受限,而可以使用的 swap 空间使用不受限制(宿主机有多少 swap 容器就可以使用多少)。

3. Limitations on disk IO quota control (blkio)

--device-read-bps:限制某个设备上的读速度bps(数据量),单位可以是kb、mb(M)或者gb。
例:docker run -itd --name test9 --device-read-bps /dev/sda:1M  centos:7 /bin/bash

--device-write-bps : 限制某个设备上的写速度bps(数据量),单位可以是kb、mb(M)或者gb。
例:docker run -itd --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash

--device-read-iops :限制读某个设备的iops(次数)
 
--device-write-iops :限制写入某个设备的iops(次数)

#创建容器,并限制写速度
docker run -it --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash

#通过dd来验证写速度
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct				#添加oflag参数以规避掉文件系统cache
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.0025 s, 1.0 MB/s

#清理docker占用的磁盘空间
docker system prune -a			#可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络

Guess you like

Origin blog.csdn.net/2302_76410765/article/details/131828675