docker network mode--resource allocation description

1. Docker network implementation principle

  • Docker uses Linux bridge to virtualize a Docker container bridge (docker0) on the host machine. When Docker starts a container, it will assign an IP address to the container according to the network segment of the Docker bridge, called Container-IP, and the Docker bridge is every The default gateway for each container. Because the containers in the same host are connected to the same network bridge, the containers can communicate directly through the Container-IP of the container.

simply put:

  • docker0 is a virtual gateway of a container that is automatically installed when docker is installed
  • docker0 is the gateway of the container, bound to the physical network card, responsible for NAT address translation and port mapping
  • Use ifconfig to view
[root@localhost ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:2aff:feb3:122b  prefixlen 64  scopeid 0x20<link>
        ether 02:42:2a:b3:12:2b  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2  bytes 180 (180.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

insert image description here

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

#example:

[root@localhost ~]# docker run -d --name test1 -P nginx  #大写p随机映射端口(从32768开始)
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                     NAMES
95ec3237479a   nginx     "/docker-entrypoint.…"   6 seconds ago   Up 6 seconds   0.0.0.0:49153->80/tcp, :::49153->80/tcp   test1
浏览器访问测试 192.168.113.127:49153

insert image description here

insert image description here

[root@localhost ~]# docker run -d --name test2 -p 41000:80 nginx #小写p指定映射端口
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                     NAMES
0dfa28caa72b   nginx     "/docker-entrypoint.…"   3 seconds ago   Up 2 seconds   0.0.0.0:41000->80/tcp, :::41000->80/tcp   test2
浏览器访问测试 192.168.113.127:41000

insert image description here

insert image description here

2. Docker network mode

network mode illustrate
Host The container will not virtualize its own network card, configure its own IP, etc., but use the host's IP and port
Container The created container will not create its own network card and configure its own IP, but share the IP and port range with a specified container
None This mode turns off the network function of the container
Bridge The default is this mode, which will allocate and set IP for each container, and connect the container to a docker0 virtual bridge, and communicate with the host through the docker0 bridge and iptables nat table configuration
custom network It's all up to you

1. When installing Docker, it will automatically create three networks, bridge (creating a container is connected to this network by default), none, host

#查看docker网络列表
[root@localhost ~]# docker network ls    #方法一
NETWORK ID     NAME      DRIVER    SCOPE
8634fd81aada   bridge    bridge    local
686fa85148f5   host      host      local
6b205bc8ef67   none      null      local

[root@localhost ~]# docker network list  #方法二
NETWORK ID     NAME      DRIVER    SCOPE
8634fd81aada   bridge    bridge    local
686fa85148f5   host      host      local
6b205bc8ef67   none      null      local

2. 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

network mode Specifies the network mode command
host mode Use --net=host to specify
none mode Use --net=none to specify
container mode Use --net=container:NAME_or_ID to specify
bridge mode Use --net=bridge to specify, default setting, can be omitted

3. Detailed explanation of network mode

3.1 host mode

  • The host container will not virtualize its own network card, configure its own IP, etc., but use the host's IP and port

  • If the host mode is used when starting the container, the container will not obtain an independent Network Namespace, but will share a Network Namespace with the host, and the container will not virtualize its own network card, configure its own IP, etc. but use The IP and port of the host, but other aspects of the container, such as the file system and process list, are still isolated from the host

  • The container using the host mode can directly use the IP address of the host to communicate with the outside world, and the server port inside the container can also use the port of the host without NAT. The biggest advantage of the host is that the network performance is better, but the docker host has The used port can no longer be used, and the isolation of the network is not good.

insert image description here

3.2 container mode

  • The created container will not create its own network card, set IP, etc., but share IP and port range with a specified container
  • This mode specifies that the newly created container shares a network namespace with an existing container instead of sharing with the host. The newly created container does not create its own network card and configure its own IP, but shares the IP with a specified container. Port range, etc. Similarly, in addition to the network aspects of the two containers, other things such as file systems and process lists are still isolated
  • The processes of the two containers can communicate through the lo network card device
#实例操作实验:
[root@nginx1 opt]# docker run -itd --name test1 centos:7 /bin/bash #--name选项可以给容器创建一个自定义名称

[root@nginx1 opt]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS          PORTS     NAMES
35950288a708   centos:7   "/bin/bash"   22 seconds ago   Up 21 seconds             test1

[root@nginx1 opt]# docker inspect -f '{
    
    {.State.Pid}}' 35950288a708 #查看容器进程号

[root@nginx1 opt]# ls -l /proc/28643/ns  #查看容器的进程,网络,文件系统等命名空间编号
总用量 0
lrwxrwxrwx 1 root root 0 96 19:23 ipc -> ipc:[4026532527]
lrwxrwxrwx 1 root root 0 96 19:23 mnt -> mnt:[4026532525]
lrwxrwxrwx 1 root root 0 96 19:21 net -> net:[4026532530]
lrwxrwxrwx 1 root root 0 96 19:23 pid -> pid:[4026532528]
lrwxrwxrwx 1 root root 0 96 19:23 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 96 19:23 uts -> uts:[4026532526]



[root@nginx1 opt]# docker run -itd --name test2 --net=container:35950288a708 centos:7 /bin/bash  

[root@nginx1 opt]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED              STATUS              PORTS     NAMES
29a672517519   centos:7   "/bin/bash"   About a minute ago   Up About a minute             test2

[root@nginx1 opt]# docker inspect -f '{
    
    {.State.Pid}}' 29a672517519 

[root@nginx1 opt]# ls -l /proc/28960/ns  #查看可以发现两个容器的 net namespace 编号相同
总用量 0
lrwxrwxrwx 1 root root 0 96 19:30 ipc -> ipc:[4026532622]
lrwxrwxrwx 1 root root 0 96 19:30 mnt -> mnt:[4026532620]
lrwxrwxrwx 1 root root 0 96 19:30 net -> net:[4026532530]
lrwxrwxrwx 1 root root 0 96 19:30 pid -> pid:[4026532623]
lrwxrwxrwx 1 root root 0 96 19:30 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 96 19:30 uts -> uts:[4026532621]

insert image description here

3.3 none mode

  • In none mode, the Docker container has its own Network Namespace, but does not perform any network configuration for the Docker container. That is to say, this Docker container has no 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, and a closed network can well guarantee the security of the container

insert image description here

3.4 Bridge mode

  • The bridge mode is the default network mode of docker, if you don’t write the –net parameter, it is the bridge mode

Equivalent to the nat mode in Vmware, the container uses an independent network Namespace and connects to the docker0 virtual network card. Configure communication with the host through the docker0 bridge and the iptables nat table. This mode will allocate Network Namespace, set IP, etc. for each container, and connect a Docker container on a host to a virtual network bridge

(1) When the Docker process starts, a virtual network bridge named docker0 will be created on the host, and the Docker container started on this host will be connected to this virtual bridge. The working mode of the virtual bridge is similar to that of 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 NIC 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 another device. Therefore, veth devices are often used to connect two network devices

(3) Docker puts one end of the veth pair device in the newly created container, and names it eth0 (the network card of the container), and puts the other end in the host, named with a similar name like veth*, and adds this network device into the docker0 bridge. Can be viewed through the brctl show command

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

insert image description here

3.5 Custom Network

#直接使用bridge,无法支持指定IP运行docker
docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:7 /bin/bash

#1.创建自定义网络
#可以先自定义网络,再使用指定IP运行docker
[root@nginx1 opt]# docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork

#docker1为执行ifconfig -a命令时,显示的网卡名,如果不使用--opt参数指定此名称,那你在使用ifconfig-a命令查看网络信总时,看到的是类似br-110eb56a0b22这样的名字,这显然不怎么好记
#mynetwork为执行docker network list命令时,显示的oridgek网络模式名称


#查看是否创建成功
[root@nginx1 opt]# ifconfig
docker1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:52:ab:85:af  txqueuelen 0  (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

#再次创建就不会出错了
[root@nginx1 opt]# docker run -itd --name test5 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash

ps: overlay overlay network

​ ip/mac vlan virtual MAC address

3. Resource Control

1. CPU resource control

  • cgroups is a very powerful linux kernel tool. It can not only limit resources isolated by namespace, but also set weights for resources, calculate usage, control process start and stop, and so on. So cgroups (Control groups) realize the quota and measurement of resources

  • Cgroups have four major functions:

Function illustrate
resource constraints Ability to limit the total amount of resources used by tasks
priority assignment Through the number of allocated cpu time slices and the size of disk IO bandwidth, it is actually equivalent to controlling the task running priority
Resource statistics You can count the resource usage of the system, such as cpu time, memory usage, etc.
mission control cgroup can perform operations such as suspend and resume on tasks

1.1 Set the upper limit of CPU usage

  • Linux uses CFS (Completely Fair Scheduler) to schedule the CPU usage of each process. The default scheduling period of CFS is 100ms

  • We can set the scheduling cycle of each container process and how much CPU time each container can use during this cycle

  • Use --cpu-period to set the scheduling period, use --cpu-quota to set the CPU time that the container can use in each period. Both can be used together

The effective range of the CFS period is 1ms~1s, and the corresponding value range of --cpu-period is 1000~100000
and the CPU quota of the container must not be less than 1ms, that is, the value of --cpu-quota must be >= 1000

#1.查看CPU使用率
[root@nginx1 opt]# docker run -itd --name test3 centos:7 /bin/bash

[root@nginx1 opt]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS          PORTS     NAMES
7211583c640c   centos:7   "/bin/bash"   45 seconds ago   Up 44 seconds             test3

[root@nginx1 opt]# cd/sys/fs/cgroup/cpu/docker/7211583c640c37beb5079f67f6e3657e3628ba8b8dde388ea69697532b155fe4/

[root@nginx1 7211583c640c37beb5079f67f6e3657e3628ba8b8dde388ea69697532b155fe4]# cat cpu.cfs_quota_us 
-1
[root@nginx1 7211583c640c37beb5079f67f6e3657e3628ba8b8dde388ea69697532b155fe4]# cat cpu.cfs_period_us 
100000

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

#2.进行CPU压力测试
[root@nginx1 docker]# docker exec -it 7211583c640c /bin/bash
[root@7211583c640c opt]# vim cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
[root@7211583c640c opt]# sh cpu.sh 

#可再开启个终端查看
[root@nginx1 opt]# top   #可以看到这个脚本占了很多的cpu资源


#3.设置CPU使用率
#设置50%的比例分配CPU使用时间上限
#可以重新创建一个容器并设置限额
docker run -itd --name test2 --cpu-quota 50000 centos:7 /bin/bash
[root@nginx1 ~]# echo 50000 > /sys/fs/cgroup/cpu/docker/7211583c640c37beb5079f67f6e3657e3628ba8b8dde388ea69697532b155fe4/cpu.cfs_quota_us 

#进入容器在执行下脚本
[root@nginx1 docker]# docker exec -it 7211583c640c /bin/bash
[root@7211583c640c opt]# sh cpu.sh 

#可再开启个终端查看
[root@nginx1 ~]# top  #可以看到cpu占用率接近50%,cgroups对cpu的控制起了效果

1.2 Set the CPU resource usage ratio (only valid when multiple containers are set)

Docker specifies the CPU share through –cpu-shares, the default value is 1024, and the value is a multiple of 1024

#创建两个容器为 q1 和 q2,若只有这两个容器,设置容器的权重,使得q1和q2的CPU资源占比为1/3和2/3
[root@nginx1 ~]# docker run -itd --name q1 --cpu-shares 512 centos:7
[root@nginx1 ~]# docker run -itd --name q2 --cpu-shares 1024 centos:7

#分别进入容器,进行压力测试
[root@nginx1 ~]# docker exec -it q2 /bin/bash
[root@nginx1 ~]# docker exec -it q1 /bin/bash

#进入容器分别安装
[root@e631251e8a35 /]# yum install -y epel-release
[root@e631251e8a35 /]# yum install stress -y
[root@e631251e8a35 /]# stress -c 4

#查看容器运行状态(动态更新),因为我是4个CPU所以cpu值会这么大,正常的就是去掉前面百位数
[root@nginx1 /]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O     PIDS
af8bafc64df1   q2        242.36%   198.4MiB / 4.669GiB   4.15%     35.4MB / 574kB   0B / 25.3MB   7
e631251e8a35   q1        156.18%   198.5MiB / 4.669GiB   4.15%     35.4MB / 358kB   0B / 24.9MB   7

insert image description here

1.3 Set the container to bind the specified CPU

#先分配虚拟机4个CPU核数
[root@nginx1 /]# docker run -itd --name q3 --cpuset-cpus 1,3 centos:7 /bin/bash

#进入容器,进行压力测试
[root@nginx1 /]# docker exec -it q3 bash
[root@53a585a0396c /]# yum install -y epel-release
[root@53a585a0396c /]# yum install -y stress
[root@53a585a0396c /]# stress -c 4

#退出容器,执行 top 命令再按 1 查看CPU使用情况
[root@nginx1 /]# top

insert image description here

2. Restrictions on memory usage

[root@nginx1 /]# docker run -itd --name q4 -m 512m centos:7 /bin/bash
[root@nginx1 /]# docker stats

insert image description here

3. Limit the available swap size

强调一下 --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 容器就可以使用多少)
 
#例:首先你的宿主机要有swap
#--vm 1:启动1个内存工作线程
#--vm-bytes 200M:每个线程分配200M内存
#如果让工作线程分配的内存超过 1g,分配的内存超过了限额,stress线程会报错,容器退出
docker run -itd -m 300m --memory-swap=1g centos:7 --vm 1 --vm-byres 200 

'注意!一旦容器Cgroup使用的内存超过了限制的容量,Linux内核就会尝试收回这些内存'
'如果仍旧无法控制内存使用在这个设置的范围之内,就会杀死该进程!

4. Restrictions on disk IO quota control (blkio)

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

--device-write-bps : 限制某个设备上的写速度bps(数据量),单位可以是kb、mb(M)或者gb

例:docker run -itd --name test5 --device-write-bps /dev/sda:1mb centos:7 /bin/bash

-----------------------------------------------------------------------
bps 是byte per second,每秒读写的数据量
iops是io per second,每秒IO的次数
可通过以下参数控制容器的bps 和iops:
-–device-read-bps ,限制读菜个设备的bps
-–device-write-bps,限制写某个设备的bps
-–device-read-iops,限制读某个设备的iops(次数)
-–device-write-iops,限制写入某个设备的iops(次数)
------------------------------------------------------------------------

#创建容器,并限制写速度
docker run -it --name test5 --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/liwenbin19920922/article/details/126903541