Docker基本管理

本文详细介绍了Docker的基本概念,包括Docker的隔离技术、核心概念(镜像、容器和仓库)以及容器的优缺点。此外,还详细阐述了Docker的安装过程,镜像的创建与操作,如搜索、获取、删除和标签管理。接着讨论了容器的创建、启动、管理,包括如何进入容器、复制文件、导出和导入容器。此外,文章还深入探讨了Docker的网络配置,包括网络模式、自定义网络设置以及资源控制,如CPU和内存的限制。最后,介绍了如何清理Docker占用的磁盘空间。

一、Docker概述

1. Docker是什么

Docker是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源。
Docker是在Linux容器里运行的开源工具,是一种轻量级的“虚拟机”。
Docker的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自给自足的容器。
目前Docker只能支持64位系统。

2. Docker的设计宗旨

Docker的Logo设计为蓝色鲸鱼,拖着许多集装箱。
鲸鱼可看作为宿主机,集装箱可理解为相互隔离的容器,每个集装箱中都包含自己的应用程序。

在这里插入图片描述

Docker的设计宗旨:Build,Ship and Run Any APP,Anywhere
即通过对应用组件的封装、发布、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,导出运行”的目的。这里的组件,既可以是一个应用,也可以是一套服务,甚至是一个完整的操作系统。

3. 容器的优点

容器化越来越受欢迎,因为容器是:
● 灵活:即使是最复杂的应用也可以集装箱化
● 轻量级:容器利用并共享主机内核
● 可互换:可以即时部署更新和升级
● 便携式:可以再本地构建,部署到云,并在任何地方运行
● 可扩展:可以增加并自动分发容器副本
● 可堆叠:可以垂直和即时堆叠服务

4. Docker容器和虚拟机的区别

容器是在Linux上本机运行,并与其他容器共享主机的内核,它运行的是一个独立的进程,不占用其他任何可执行文件的内存,非常轻量。
虚拟机运行的是一个完整的操作系统,通过虚拟机管理程序对主机资源进行虚拟访问,相比之下需要的资源更多。

特性Docker容器openstack虚拟机
部署难度非常简单组件多,部署复杂
启动速度秒级分钟级
执行性能和物理系统几乎一致vm会占用一些资源
镜像体积镜像MB级别虚拟机镜像GB级别
管理效率管理简单组件相互依赖,管理复杂
可管理性单进程完整的系统管理
网络连接比较弱借助neutron可以灵活组件各类网络管理
计算能力损耗几乎无损耗50%左右
性能接近原生弱于
系统支持量(单机)上千个几十个
隔离性资源隔离/限制完全隔离

5. 容器的三种重要技术(namespace/cgroup)

docker本质就是宿主机的一个进程,docker是通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500G并不是实际占用物理磁盘500G)。

6. namespace的六项隔离

namespace系统调用参数隔离内容
UTSCLONE_NEWUTS主机名与域名
IPCCLONE_NEWWIPC信号量、消息队列和共享内存
PIDCLONE_NEWPID进程编号
NETWORKCLONE_NEWNET网络设备、网络栈、端口等
MOUNTCLONE_NEWNS挂载点(文件系统)
USERCLONE_NEWUSER用户和用户组(3.8以后的内核才支持)

7. Docker核心的三个概念

7.1 镜像

Docker的镜像是创建容器的基础,类似虚拟机的快照,可以理解为一个面向Docker容器引擎的只读模板。
通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量和配置文件。
Docker镜像也是一个压缩包,只是这个压缩包不只是可执行文件,环境部署脚本,它还包含了完整的操作系统。因为大部分的镜像都是基于某个操作系统来构建,所以很轻松的就可以构建本地和远程一样的环境,这也是Docker镜像的精髓。

7.2 容器

Docker的容器是从镜像创建的运行实例,它可以被启动、停止和删除。所创建的每一个容器都是相互隔离、互不可见,以保证平台的安全性。
可以把容器看做是一个简易版的Linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行在其他的应用程序。

7.3 仓库

Docker仓库是用来集中保存镜像的地方,当创建了自己的镜像之后,可以使用push命令将它上传到公有仓库(Public)或者私有仓库(Private)。当下次要在另外一台机器上使用这个镜像时,只需从仓库获取。
Docker的镜像、容器、日志等内容全部都默认存储在/var/lib/docker目录下。

二、安装Docker

1. 服务器环境

[root@localhost ~]# hostnamectl set-hostname docker
[root@localhost ~]# su
[root@docker ~]# systemctl disable --now firewalld
[root@docker ~]# setenforce 0
setenforce: SELinux is disabled

2. 安装依赖包

[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@docker ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum-utils:提供了yum-config-manager工具
device mappper:是Linux内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构。
device mapper存储驱动程序需要device-mapper-persistent-data和lvm2。

3. 设置阿里云镜像源

[root@docker ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
已加载插件:fastestmirror, langpacks
adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo

4. 安装Docker-CE并设置为开机自动启动

[root@docker ~]# yum install -y docker-ce docker-ce-cli containerd.io
[root@docker ~]# systemctl enable --now docker.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

安装好的Docker系统有两个程序,Docker服务端和Docker客户端。其中Docker服务端是一个服务进程,负责管理所有容器。Docker客户端则扮演着Docker服务端的远程控制器,可以用来控制Docker的服务端进程。大部分情况下Docker服务端和客户端运行在一台机器上。

三、Docker镜像创建与操作

1. 搜索镜像

格式:docker search 关键字

[root@docker ~]# docker search nginx
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                             Official build of Nginx.                        15592     [OK]       
jwilder/nginx-proxy               Automated Nginx reverse proxy for docker con…   2071                 [OK]
······

2. 获取镜像

格式:docker pull 仓库名称[:标签]
如果下载镜像时不指定标签,则默认会下载仓库中最新版本的镜像,即选择标签为latest标签。

[root@docker ~]# docker pull nginx:latest
latest: Pulling from library/nginx
07aded7c29c6: Pull complete 
bbe0b7acc89c: Pull complete 
44ac32b0bba8: Pull complete 
91d6e3e593db: Pull complete 
8700267f2376: Pull complete 
4ce73aa6e9b0: Pull complete 
Digest: sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

3. 镜像加速下载

浏览器访问http://cr.console.aliyun.com/cn-hangzhou/instances/mirrors获取镜像加速器配置

在这里插入图片描述

[root@docker ~]# sudo mkdir -p /etc/docker
[root@docker ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
> {
>   "registry-mirrors": ["https://3c7tpzyf.mirror.aliyuncs.com"]
> }
> EOF
{
  "registry-mirrors": ["https://3c7tpzyf.mirror.aliyuncs.com"]
}
[root@docker ~]# sudo systemctl daemon-reload
[root@docker ~]# sudo systemctl restart docker

4. 查看镜像信息

镜像下载后存放在/var/lib/docker

[root@docker ~]# cd /var/lib/docker
[root@docker docker]# ls
buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes

5. 查看下载的镜像文件信息

[root@docker docker]# cat /var/lib/docker/image/overlay2/repositories.json 
{"Repositories":{"nginx":{"nginx:latest":"sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b","nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506":"sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b"}}}[root@docker docker]# 

6. 查看下载到本地的所有镜像

[root@docker docker]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    f8f4ffc8092c   9 days ago   133MB

REPOSITORY:镜像属于的仓库
TAG:镜像的标签信息,标记同一个仓库中的不同镜像
IMAGE ID:镜像的唯一ID号,唯一标识一个镜像
CREATED:镜像创建的时间
SIZE:镜像大小

7. 根据镜像的唯一标识ID号,获取镜像详细信息

[root@docker docker]# docker inspect f8f4ffc8092c
......
 {

        "Id": "sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b",

        "RepoTags": [

            "nginx:latest"

        ],
......

8. 为本地的镜像添加新的标签

格式:docker tag 名称[:标签] 新名称[:标签]

[root@docker docker]# docker tag nginx:latest nginx:test
[root@docker docker]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    f8f4ffc8092c   9 days ago   133MB
nginx        test      f8f4ffc8092c   9 days ago   133MB

9. 删除镜像

格式1:docker rmi 仓库名称:标签
当一个镜像有多个标签时,只是删除其中指定的标签

[root@docker docker]# docker rmi nginx:latest
Untagged: nginx:latest
[root@docker docker]# docker images 
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        test      f8f4ffc8092c   9 days ago   133MB

格式2:docker rmi 镜像ID号
会彻底删除该镜像

[root@docker docker]# docker rmi f8f4ffc8092c
Untagged: nginx:test
Untagged: nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
......

若该镜像的标签数大于1,需要使用-f强制删除

[root@docker docker]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    f8f4ffc8092c   9 days ago   133MB
nginx        test      f8f4ffc8092c   9 days ago   133MB
[root@docker docker]# docker rmi f8f4ffc8092c
Error response from daemon: conflict: unable to delete f8f4ffc8092c (must be forced) - image is referenced in multiple repositories
[root@docker docker]# docker rmi f8f4ffc8092c -f
Untagged: nginx:latest
Untagged: nginx:test
Untagged: nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
......

注意:如果该镜像已经被容器使用,正确的做法是先删除依赖该镜像的所有容器,再去删除镜像。

10. 存入镜像:将镜像保存称为本地文件

格式:docker save -o 存储文件名 存储的镜像

[root@docker docker]# docker save -o nginx.tar nginx:latest
[root@docker docker]# ls -lh
总用量 132M
······
drwxr-x--- 3 root root   19 108 11:21 network
······

11. 载入镜像:将镜像文件导入到镜像库中

格式:
docker load < 镜像文件

[root@docker docker]# docker rmi nginx:latest 
Untagged: nginx:latest
Untagged: nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
Deleted: sha256:c9958d4f33715556566095ccc716e49175a1fded2fa759dbd747750a89453490
Deleted: sha256:c47815d475f74f82afb68ef7347b036957e7e1a1b0d71c300bdb4f5975163d6a
Deleted: sha256:3b06b30cf952c2f24b6eabdff61b633aa03e1367f1ace996260fc3e236991eec
Deleted: sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364
[root@docker docker]# docker load < nginx.tar 
476baebdfbf7: Loading layer [==================================================>]  72.53MB/72.53MB
525950111558: Loading layer [==================================================>]  64.97MB/64.97MB
0772cb25d5ca: Loading layer [==================================================>]  3.072kB/3.072kB
6e109f6c2f99: Loading layer [==================================================>]  4.096kB/4.096kB
88891187bdd7: Loading layer [==================================================>]  3.584kB/3.584kB
65e1ea1dc98c: Loading layer [==================================================>]  7.168kB/7.168kB
Loaded image: nginx:latest

或者
docker load -i 镜像文件

[root@docker docker]# docker rmi nginx:latest 
Untagged: nginx:latest
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
Deleted: sha256:c9958d4f33715556566095ccc716e49175a1fded2fa759dbd747750a89453490
Deleted: sha256:c47815d475f74f82afb68ef7347b036957e7e1a1b0d71c300bdb4f5975163d6a
Deleted: sha256:3b06b30cf952c2f24b6eabdff61b633aa03e1367f1ace996260fc3e236991eec
Deleted: sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364
[root@docker docker]# docker load -i nginx.tar 
476baebdfbf7: Loading layer [==================================================>]  72.53MB/72.53MB
525950111558: Loading layer [==================================================>]  64.97MB/64.97MB
0772cb25d5ca: Loading layer [==================================================>]  3.072kB/3.072kB
6e109f6c2f99: Loading layer [==================================================>]  4.096kB/4.096kB
88891187bdd7: Loading layer [==================================================>]  3.584kB/3.584kB
65e1ea1dc98c: Loading layer [==================================================>]  7.168kB/7.168kB
Loaded image: nginx:latest

12. 上传镜像

默认上传到docker hub官方公共仓库,需要注册使用公共仓库的账户。http://hub.docker.com
可以使用docker login命令来输入用户名、密码和邮箱来完成注册和登录。
在上传镜像之前,还需要先对本地镜像添加新的标签,然后再使用docker push命令进行上传。

[root@docker docker]# docker tag nginx:latest ding1201/nginx:test
[root@docker docker]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ding1201
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@docker docker]# docker push ding1201/nginx
Using default tag: latest
The push refers to repository [docker.io/ding1201/nginx]
tag does not exist: ding1201/nginx:latest
#上传失败,上传需要镜像名称:标签,无标签默认为latest
[root@docker docker]# docker push ding1201/nginx:test
The push refers to repository [docker.io/ding1201/nginx]
65e1ea1dc98c: Mounted from library/nginx 
88891187bdd7: Mounted from library/nginx 
6e109f6c2f99: Mounted from library/nginx 
0772cb25d5ca: Mounted from library/nginx 
525950111558: Mounted from library/nginx 
476baebdfbf7: Mounted from library/nginx 
test: digest: sha256:39065444eb1acb2cfdea6373ca620c921e702b0f447641af5d0e0ea1e48e5e04 size: 1570
[root@docker docker]# docker search ding1201
NAME             DESCRIPTION   STARS     OFFICIAL   AUTOMATED
ding1201/nginx                 0           
##上传成功

四、Docker容器操作

1. 容器创建

容器创建就是将镜像加载到容器的过程。
新创建的容器默认处于停止状态,不允许任何程序,需要在其中发起一个进程来启动容器。

格式:docker create [选项] 镜像
常用选项:
-i:让容器的输入保持打开
-t:让Docker分配一个伪终端

[root@localhost ~]# docker create -it centos:7 bash
2ad313983c40bb0b2bbd10a8174dd7924b2556b7287b1d85b7e4d543c32d64b7

2. 查看容器的运行状态

[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED          STATUS    PORTS     NAMES
2ad313983c40   centos:7   "bash"    33 seconds ago   Created             priceless_johnson

-a选项可以显示所有的容器
CONTAINER ID:容器ID号
IMAGE:加载的镜像
COMMAND:运行的程序
CREATED:创建时间
STATUS:当前状态
PORTS:端口映射
NAMES:名称(未定义将随机创建)

3. 启动容器

格式:docker start 容器ID/名称

[root@docker docker]# docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS    PORTS     NAMES
5a5c3c2e785f   ding1201/nginx:test   "/docker-entrypoint.…"   56 seconds ago   Created             strange_hofstadter
[root@docker docker]# docker start 5a5c3c2e785f
5a5c3c2e785f
[root@docker docker]# docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS     NAMES
5a5c3c2e785f   ding1201/nginx:test   "/docker-entrypoint.…"   7 minutes ago   Up 5 seconds   80/tcp    strange_hofstadter

4. 创建并启动容器

可以直接执行docker run命令,等同于先执行docker create命令,再执行docker start命令。
注意:容器是一个与其中运行的shell命令共存亡的终端,命令运行容器运行,命令结束容器退出。

[root@docker docker]# docker run centos:7 bash -c ls /
anaconda-post.log
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@docker docker]# docker ps -a
CONTAINER ID   IMAGE      COMMAND          CREATED          STATUS                      PORTS     NAMES
3fb76edd101c   centos:7   "bash -c ls /"   10 seconds ago   Exited (0) 10 seconds ago             naughty_ganguly
##命令执行后,容器直接退出

4.1 docker运行条件

docker容器默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker容器中pid=1的进程挂了,那么docker容器便会只会退出,也就是说docker容器中必须有一个前台进程,否则认为容器已经挂掉。
可以对docker容器执行一条死循环命令,防止容易的自动退出。

[root@docker docker]# docker run centos:7 bash -c "while true;do echo hello;done"
##此时终端将不停显示hello,ctrl+c无法退出,需再另一台终端stop该容器
[root@docker ~]# docker ps -a 
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS     NAMES
41d204a8820d   centos:7   "bash -c 'while true…"   31 seconds ago   Up 30 seconds             elastic_brown
[root@docker ~]# docker stop 41d204a8820d
41d204a8820d
[root@docker ~]# docker ps -a 
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS                       PORTS     NAMES
41d204a8820d   centos:7   "bash -c 'while true…"   5 minutes ago   Exited (137) 4 minutes ago             elastic_brown

为避免占用终端无法退出的情况可以使用 -d 选项,docker容器以守护形式在后台运行。
容器所运行的程序不能结束。

4.2 创建容器并持续运行

[root@docker ~]# docker run -itd --name test centos:7 bash
a7db7eff73bfd9af9147b76b6b686e8be5098bcc7588c02f379c4d682fd9b052
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED        STATUS        PORTS     NAMES
a7db7eff73bf   centos:7   "bash"    1 second ago   Up 1 second             test

4.3 docker在后台的标准运行过程

当利用docker run来创建容器时,Docker在后台的标准运行过程是:

(1)检查本地是否存在指定的镜像。当镜像不存在时,会从公有仓库下载;
(2)利用镜像创建并启动一个容器;
(3)分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;
(4)从宿主主机配置的网桥接口中桥接一个虚拟机接口到容器中;
(5)分配一个地址池中的IP地址给容器;
(6)执行用户指定的应用程序,执行完毕后容器被终止运行。

5. 终止容器运行

格式:docker stop 容器的ID/名称

[root@docker ~]# docker stop test
test
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS                       PORTS     NAMES
a7db7eff73bf   centos:7   "bash"    4 minutes ago   Exited (137) 2 seconds ago             test

6. 容器的进入

需要进入容器进行命令操作时,可以使用docker exec命令进行运行着的容器。
格式:docker exec -it 容器ID/名称 /bin/bash
-i:让容器的输入保持打开
-t:让那个Docker分配一个伪终端

[root@docker ~]# docker start test
test
[root@docker ~]# docker exec -it test bash
[root@a7db7eff73bf /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@a7db7eff73bf /]# exit
exit
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS              PORTS     NAMES
a7db7eff73bf   centos:7   "bash"    8 minutes ago   Up About a minute             test

也可在run创建容器时,使用-it选项进入容器,但是退出容器时,容器也将停止运行。

[root@docker ~]# docker run -it --name test1 centos:7 bash
[root@3d9cd43c52f2 /]# exit
exit
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED          STATUS                     PORTS     NAMES
3d9cd43c52f2   centos:7   "bash"    8 seconds ago    Exited (0) 2 seconds ago             test1
a7db7eff73bf   centos:7   "bash"    11 minutes ago   Up 5 minutes                         test

7. 复制

7.1 主机复制到容器中

[root@docker ~]# docker cp test.txt test:/opt
[root@docker ~]# docker exec -it test bash
[root@a7db7eff73bf /]# cd /opt
[root@a7db7eff73bf opt]# ls
test.txt
[root@a7db7eff73bf opt]# cat test.txt 
test

7.2 从容器复制到主机

[root@docker ~]# docker cp test:/opt/test.txt 111.txt  
[root@docker ~]# cat 111.txt
test

8. 容器的导出与导入

用户可以将任何一个Docker容器从一台机器迁移到另一台机器。在迁移过程中,可以使用“docker export”命令将已经创建好的容器导出为文件,无论这个容器是处于运行状态还是停止状态均可导出。可将导出文件传输到其他机器,通过相应的导入命令实现容器的迁移。

8.1 导出

格式:docker export 容器ID/名称 文件名

[root@docker ~]# docker ps -a 
CONTAINER ID   IMAGE      COMMAND   CREATED          STATUS                      PORTS     NAMES
3d9cd43c52f2   centos:7   "bash"    17 minutes ago   Exited (0) 17 minutes ago             test1
a7db7eff73bf   centos:7   "bash"    29 minutes ago   Up 22 minutes                         test
[root@docker ~]# docker export test > /opt/centos.tar
[root@docker ~]# cd /opt
[root@docker opt]# ls 
apr-1.6.2.tar.gz  apr-util-1.6.0.tar.gz  centos.tar  containerd  rh

8.2 导入

格式:cat 文件名 | docker import - 镜像名称:标签

[root@docker opt]# docker stop test
test
[root@docker opt]# docker rm test
test
[root@docker opt]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED          STATUS                      PORTS     NAMES
3d9cd43c52f2   centos:7   "bash"    21 minutes ago   Exited (0) 21 minutes ago             test1
[root@docker opt]# cat centos.tar | docker import - centos7:test
sha256:e180fc5d26ee4f4c13fabb682871bec45790711a4b1a9ac33dd88c9674cfcfc2
[root@docker opt]# docker images
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
centos7          test      e180fc5d26ee   8 seconds ago   204MB
ding1201/nginx   test      f8f4ffc8092c   10 days ago     133MB
nginx            latest    f8f4ffc8092c   10 days ago     133MB
centos           7         eeb6ee3f44bd   3 weeks ago     204MB

9. 删除容器

格式:docker rm [-f] 容器ID/名称

[root@docker opt]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED          STATUS                      PORTS     NAMES
3d9cd43c52f2   centos:7   "bash"    34 minutes ago   Exited (0) 34 minutes ago             test1
[root@docker opt]# docker rm test1
test1
[root@docker opt]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

容器在运行状态下,需要先stop停止容器才可以将其删除,或使用-f选项

[root@docker opt]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED          STATUS          PORTS     NAMES
7a80d181e011   centos:7   "bash"    23 seconds ago   Up 23 seconds             test2
d5a47ba9ab3a   centos:7   "bash"    27 seconds ago   Up 26 seconds             test1
[root@docker opt]# docker rm test1
Error response from daemon: You cannot remove a running container d5a47ba9ab3adf0e0524820d03d942961a6d38d1b5effa973b7569dd29b04241. Stop the container before attempting removal or force remove
[root@docker opt]# docker rm test1 -f
test1
[root@docker opt]# docker stop test2
test2
[root@docker opt]# docker rm test2
test2

10. 批量操作容器

批量停止容器

docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash

docker ps -a | awk 'NR>=2{print $1}' | xargs docker stop

批量删除容器
方法一:

docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash

docker ps -a | awk 'NR>=2{print $1}' | xargs docker rm -f

方法二:

docker rm $(docker ps -a -q)

批量删除镜像

docker images | awk 'NR>=2{print "docker rmi -f "$3}' | bash

五、Docker网络

1. Docker网络实现原理

Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网络的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

2. Docker网桥

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时通过-p或-P参数来启用,访问容器的时候就通过 [宿主机IP]:[容器端口]访问容器

[root@docker ~]# docker run -d --name test1 -P nginx
514ae4b4bec05707b66a7dab89a1f0c49e5ef2266ae15d5f72b45e38495c4e25
[root@docker ~]# docker run -d --name test2 -p 43000:80 nginx
##使用固定的43000端口
36e92b38ea300478fbd4b699ea6dcaf1c91213ce53aeab92311d18d011e49df5
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                     NAMES
36e92b38ea30   nginx     "/docker-entrypoint.…"   9 seconds ago    Up 9 seconds    0.0.0.0:43000->80/tcp, :::43000->80/tcp   test2
514ae4b4bec0   nginx     "/docker-entrypoint.…"   16 seconds ago   Up 16 seconds   0.0.0.0:49153->80/tcp, :::49153->80/tcp   test1

验证

[root@docker ~]# curl http://192.168.100.6:43000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@docker ~]# curl http://192.168.100.6:49153
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

3. Docker的网络模式

网络模式说明
Host容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
Container创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。
None该模式关闭了容器的网络功能。
Bridge默认为该模式,此模式会为每一个容器分配、设置IP等,并将容器连接到一个Docker0虚拟网桥,通过docker0网桥以及iptables nat表配置与宿主机通信。
自定义网络自定义网络后,可指定容器IP

4. 查看容器网络

安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、none、host。

[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
358c6341c661   bridge    bridge    local
8efcfd849c5a   host      host      local
21745308f633   none      null      local
[root@docker ~]# docker network list
NETWORK ID     NAME      DRIVER    SCOPE
358c6341c661   bridge    bridge    local
8efcfd849c5a   host      host      local
21745308f633   none      null      local

5. 创建网络

使用docker run创建Docker容器时,可以用–net或–network选项指定容器的网络模式
● host模式:使用–net=host指定
● none模式:使用–net=none指定
● container模式:使用–net=container:NAME_or_ID指定
● bridge模式:使用–net=bridge指定,默认设置,可省略

6. 网络模式详解

6.1 host模式

在这里插入图片描述

相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。

[root@docker ~]# docker run -itd --name test1 --net=host centos:7 bash
151137e9ce767273f776e56bada9baba23fec48ddfe8a30c89216341d4bbf1ab
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS         PORTS     NAMES
151137e9ce76   centos:7   "bash"    3 seconds ago   Up 2 seconds             test1
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test1
##查看容器进程号
5117
[root@docker ~]# ls -l /proc/5117/ns
##查看容器的进程、网络、文件系统等命名空间编号
总用量 0
lrwxrwxrwx 1 root root 0 1011 16:04 ipc -> ipc:[4026532576]
lrwxrwxrwx 1 root root 0 1011 16:04 mnt -> mnt:[4026532574]
lrwxrwxrwx 1 root root 0 1011 16:04 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 1011 16:04 pid -> pid:[4026532577]
lrwxrwxrwx 1 root root 0 1011 16:04 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1011 16:04 uts -> uts:[4026532575]
[root@docker ~]# docker run -itd --name test2 --net=host centos:7 bash
6f519f4fc026f67766b08ff1d098a6fd6ab7440359795a64350e2d1b2c61f05c
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test2
5209
[root@docker ~]# ls -l /proc/5209/ns
总用量 0
lrwxrwxrwx 1 root root 0 1011 16:05 ipc -> ipc:[4026532580]
lrwxrwxrwx 1 root root 0 1011 16:05 mnt -> mnt:[4026532578]
lrwxrwxrwx 1 root root 0 1011 16:05 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 1011 16:05 pid -> pid:[4026532581]
lrwxrwxrwx 1 root root 0 1011 16:05 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1011 16:05 uts -> uts:[4026532579]
##net与user的命名空间相同,host模式与系统共享IP

6.2 container模式

在这里插入图片描述

在理解了host模式后,这个模式也就好理解了。这个模式指定新常见的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信

[root@docker ~]# docker run -itd --name test1 centos:7 bash
16cfef748ce1e1653e19925b6c38b28f70ebadb85a4ff5c8913befe1d1b6a7e9
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test1
5428
[root@docker ~]# ls -l /proc/5428/ns
总用量 0
lrwxrwxrwx 1 root root 0 1011 16:18 ipc -> ipc:[4026532578]
lrwxrwxrwx 1 root root 0 1011 16:18 mnt -> mnt:[4026532576]
lrwxrwxrwx 1 root root 0 1011 16:13 net -> net:[4026532581]
lrwxrwxrwx 1 root root 0 1011 16:18 pid -> pid:[4026532579]
lrwxrwxrwx 1 root root 0 1011 16:18 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1011 16:18 uts -> uts:[4026532577]
[root@docker ~]# docker run -itd --name test2 --net=container:test1 centos:7 bash
477032acba96fa0f4adb590a6846792fa99615e2eb9744e250cf14a9d7092a53
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test2
5597
[root@docker ~]# ls -l /proc/5597/ns
总用量 0
lrwxrwxrwx 1 root root 0 1011 16:20 ipc -> ipc:[4026532699]
lrwxrwxrwx 1 root root 0 1011 16:20 mnt -> mnt:[4026532697]
lrwxrwxrwx 1 root root 0 1011 16:20 net -> net:[4026532581]
lrwxrwxrwx 1 root root 0 1011 16:20 pid -> pid:[4026532700]
lrwxrwxrwx 1 root root 0 1011 16:20 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1011 16:20 uts -> uts:[4026532698]
##net与user的命名空间相同,container模式之间共享IP

6.3 none模式

在这里插入图片描述

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

6.4 bridge模式

在这里插入图片描述

bridge模式是docker的默认网络模式,不用–net参数,就是bridge模式。
相当于Vmware中的nat模式,容器使用独立Network Namespace,并连接到docker0虚拟网卡。通过docker0网桥以及iptables nat表配置与宿主机通信,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
(1)当docker进程启动时,会在主机上创建一个名为Docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
(2)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
(3)Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以veth*这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
(4)使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

[root@docker ~]# docker run -itd --name test1 -P centos:7 bash
92f615aecf1e9e22956446536db4bcfa91d2ce94dd9e3e9253c40a5e1d2b0fde
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED          STATUS          PORTS     NAMES
92f615aecf1e   centos:7   "bash"    15 seconds ago   Up 14 seconds             test1
[root@docker ~]# iptables -t nat -vnL
······
Chain POSTROUTING (policy ACCEPT 531 packets, 39905 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
······

6.5 自定义网络

6.5.1 使用bridge指定IP

直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错

[root@docker ~]# docker run -itd --name test1 --network=bridge --ip 172.17.0.8 centos:7 bash
0e1c5c2a0ed99d3e857dbf9a42046c670235d4eac4a5aa2690e4d7ce703cca5e
docker: Error response from daemon: user specified IP address is supported on user defined networks only.
##IP错误,无法使用
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED              STATUS    PORTS     NAMES
0e1c5c2a0ed9   centos:7   "bash"    About a minute ago   Created             test1
[root@docker ~]# docker start test1
Error response from daemon: user specified IP address is supported on user defined networks only
Error: failed to start containers: test1
##IP错误,无法启动
6.5.2 创建自定义网络

可以先自定义网络,再使用指定IP运行docker

[root@docker ~]# docker network create --subnet=172.111.0.0/16 --opt "com.docker.network.bridge.name"="docker" mynetwork
716c662b9ad34a62ecab84510ae5d1d1ed760b455bf26a0f2b2bb48874e41eba
[root@docker ~]# ifconfig
docker: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.111.0.1  netmask 255.255.0.0  broadcast 172.111.255.255
        ether 02:42:0d:82:b4:9d  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
······

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

验证:

[root@docker ~]# docker run -itd --name test1 --net mynetwork --ip 172.111.0.11 centos:7 bash
d4fb4caa7742252627858dc9fbc2df47c900040fdf4e7aa145d8c7e1849c2d5a
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS         PORTS     NAMES
d4fb4caa7742   centos:7   "bash"    3 seconds ago   Up 2 seconds             test1
[root@docker ~]# docker exec -it test1 bash
[root@d4fb4caa7742 /]# ifconfig
bash: ifconfig: command not found
[root@d4fb4caa7742 /]# yum install -y net-tools
[root@d4fb4caa7742 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.111.0.11  netmask 255.255.0.0  broadcast 172.111.255.255
        ether 02:42:ac:6f:00:0b  txqueuelen 0  (Ethernet)
        RX packets 4806  bytes 18886571 (18.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3302  bytes 182103 (177.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1  (Local Loopback)
        RX packets 83  bytes 7777 (7.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 83  bytes 7777 (7.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

六、资源控制

1. CPU资源控制

1.1 cgroups

cgroups(Control groups),是一个非常强大的linux内核工具,他不仅可以限制被namespace隔离起来的资源,还可以为资源设置权重、计算使用量、操控进程启停等等。所以cgroups实现了对资源的配额和度量。

1.2 cgroups的四大功能

● 资源限制:可以对任务使用的资源总额进行限制
● 优先级分配:通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制了任务运行优先级
● 资源统计:可以统计系统的资源使用量,如cpu时长,内存用量等
● 任务控制:cgroup可以对任务执行挂起、恢复等操作

1.3 CPU资源控制的三种方式

设置CPU使用率上限
设置CPU资源占用比(设置多个容器时才生效)
设置容器绑定指定的CPU

1.4 设置CPU使用率上限

1.4.1 使用率配置

Linux通过CFS(Completely Fair Schedular,完全公平调度器)来调度各个进程对CPU的使用。CFS默认的调度周期是100ms。我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少CPU时间。
使用–cpu-period即可设置调度周期,使用–cpu-quota即可设置在每个周期内容器能使用的CPU时间。两者可以配合使用。
CFS周期的有效范围1ms1s,对应的–cpu-period的数值范围是1000-1000000。
而容器的CPU配额必须不小于1ms,即–cpu-quota的值必须>=1000。

[root@docker ~]# docker run -itd --name test1 centos:7 bash
a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS         PORTS     NAMES
a9c1ed9d865b   centos:7   "bash"    7 seconds ago   Up 5 seconds             test1
[root@docker ~]# cd /sys/fs/cgroup/cpu/docker/a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a/
##路径为/sys/fs/cgroup/cpu/docker/容器ID开头的文件名
[root@docker a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a]# ls
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks
[root@docker a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a]# cat cpu.cfs_quota_us 
-1
[root@docker a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a]# cat cpu.cfs_period_us 
100000

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

1.4.2 压力测试
[root@docker ~]# docker exec -it test1 bash
[root@a9c1ed9d865b /]# vim /cpu.sh
bash: vim: command not found
[root@a9c1ed9d865b /]# vi cpu.sh

#!/bin/bash
i=0
while true
do   
  let i++
done

[root@a9c1ed9d865b /]# chmod +x cpu.sh 
[root@a9c1ed9d865b /]# ./cpu.sh 

另开终端查看cpu负载

[root@docker ~]# top

top - 19:59:59 up  6:17,  2 users,  load average: 0.94, 0.43, 0.20
Tasks: 213 total,   2 running, 210 sleeping,   1 stopped,   0 zombie
%Cpu(s): 46.2 us,  3.5 sy,  0.0 ni, 50.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4030168 total,  2481744 free,   625300 used,   923124 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used.  3058428 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                                                        
  9732 root      20   0   11688   1096    916 R 100.0  0.0   2:44.05 cpu.sh         
                                                                                                                                            
##来自cpu.sh的命令占用了近50%CPU资源 

1.5 设置CPU资源占用比(设置多个容器时才生效)

1.5.1 资源占比设置

Docker通过–cpu-shares指定CPU份额,默认值为1024,值为1024的倍数。
创建两个容器为test1和tests2,若只有这两个容器,设置容器的权重,使得test1和test2的CPU资源占比为1/3和2/3。

[root@docker ~]# docker run -itd --name test1 --cpu-shares 1024 centos:7
b4b37e6d33a914756296f165c6cc7317fd48324b4b2a05482bc49ad2f3a5ed06
[root@docker ~]# docker run -itd --name test2 --cpu-shares 2048 centos:7
900ebea2c5ed9fd6adc3fe2b7a823b041f904312e67b9cbd4b9023ae64e38149
#若出现WARNING: IPv4 forwarding is disabled. Networking will not work.
#如下开启宿主机的IP转发功能即可
[root@docker ~]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf 
[root@docker ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@docker ~]# systemctl restart network
[root@docker ~]# systemctl restart docker
1.5.2 压力测试(设置宿主机为4核)

test1容器

[root@docker ~]# docker exec -it test1 bash
[root@b4b37e6d33a9 /]# yum install -y epel-release && yum install -y stress
[root@b4b37e6d33a9 /]# stress -c 4
stress: info: [93] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd

test2容器

[root@docker ~]# docker exec -it test2 bash
[root@900ebea2c5ed /]# yum install -y epel-release && yum install -y stress
[root@900ebea2c5ed /]# stress -c 4
stress: info: [110] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd

宿主机查看负载

[root@docker ~]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O     PIDS
29900b8c61c3   test1     132.90%   2.586MiB / 3.843GiB   0.07%     2.42kB / 0B   4.88MB / 0B   7
c062b6088afb   test2     265.13%   1008KiB / 3.843GiB    0.03%     648B / 0B     1.18MB / 0B   7
##由于宿主机开了4核,因此cpu负载为400%

1.6 设置容器绑定指定的CPU

1.6.1 指定CPU设置
[root@docker ~]# docker run -itd --name test1 --cpuset-cpus 0,3 centos:7 bash
##指定本容器使用 03号cpu
a8efc1d070d82266478473be987d98d1a0689c5a44dbbf6f75e6fde70769a346
1.6.2 压力测试

进入容器压测

[root@docker ~]# docker exec -it test1 bash
[root@a8efc1d070d8 /]# yum install -y epel-release && yum install -y stress
[root@a8efc1d070d8 /]# stress -c 4
stress: info: [166] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd

宿主机查看负载

[root@docker ~]# top
top - 17:07:25 up 15 min,  2 users,  load average: 0.17, 1.41, 1.61
Tasks: 232 total,   6 running, 226 sleeping,   0 stopped,   0 zombie
%Cpu0  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.3 us,  0.0 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4030168 total,  2522948 free,   564680 used,   942540 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used.  3134820 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                   
  2989 root      20   0    7312     96      0 R  49.8  0.0   0:02.78 stress                                                                    
  2990 root      20   0    7312     96      0 R  49.8  0.0   0:02.78 stress                                                                    
  2991 root      20   0    7312     96      0 R  49.8  0.0   0:02.79 stress                                                                    
  2992 root      20   0    7312     96      0 R  49.8  0.0   0:02.78 stress     
······ 
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O         PIDS
a8efc1d070d8   test1     201.01%   168.7MiB / 3.843GiB   4.29%     27.7MB / 490kB   52.8MB / 25.2MB   7

2. 对内存使用的限制

2.1 物理内存

-m(–memory=)选项用于限制容器可以使用的最大内存

[root@docker ~]# docker run -itd --name test1 -m 1g centos:7 bash
add63bbc42c166dc0c7336c36c352760162193f338e4a1b78973ab553ebc7b29
[root@docker ~]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O   PIDS
add63bbc42c1   test1     0.00%     392KiB / 1GiB       0.04%     578B / 0B   0B / 0B     1
##MEM LIMIT为物理内存大小

2.2 交换空间内存

–memory-swap可限制swap分区的内存大小,但必须与-m命令一起使用。
正常情况下,–memory-swap的值包含容器可用内存和可用swap。
所以-m 300m --memory-swap=1g的含义为:容器可以使用300M的物理内存,并且可以使用700M(1G-300M)的swap。
如果–memory-swap设置为0或者不设置,则容器可以使用的swap大小为-m值的两倍。
如果–memory-swap的值和-m相同,则容器不能使用swap。
如果–memory-swap的值为-1,它表示容器程序使用的内存受限,而可以使用的swap空间使用不受限制(宿主机有多少swap容器就可以使用多少)。

[root@docker ~]# docker run -itd --name test1 -m 300m --memory-swap=1G centos:7 bash
cd4169e1c9a9cba52b5cff580fb60d3694b09d9f5ac843bee339aadc63c6d7a5
##给与容器300M物理内存以及700M交换空间

3. 对磁盘IO配额控制(blkio)的限制

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

3.1 创建容器并限制写速度

[root@docker ~]# docker run -it --name test --device-write-bps /dev/sda:1mb centos:7 bash
[root@d638b2689beb /]# dd if=/dev/zero of=write_test bs=1M count=10 oflag=direct
##添加oflag参数以规避掉文件系统cash
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.003 s, 1.0 MB/s

3.2 创建容器并限制写次数

[root@docker ~]# docker run -itd --name test --device-write-iops /dev/sda:10 centos:7 bash
480096c14d1a13953a03573097826b2c151f63a8942998316a67ba45403e6177
[root@docker ~]# docker inspect test
······
            "BlkioDeviceWriteIOps": [
                {
                    "Path": "/dev/sda",
                    "Rate": 10
                }
            ],
······

3.3 清理docker占用的磁盘空间

docker system prune -a
清除停止的容器以及未被使用的镜像

[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    87a94228f133   9 hours ago   133MB
centos       7         eeb6ee3f44bd   3 weeks ago   204MB
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS                       PORTS     NAMES
8c754e5c5f4f   centos:7   "bash"    6 minutes ago   Up 6 minutes                           test1
480096c14d1a   centos:7   "bash"    7 minutes ago   Exited (137) 5 seconds ago             test
[root@docker ~]# docker system prune -a
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all images without at least one container associated to them
  - all build cache

Are you sure you want to continue? [y/N] y
Deleted Containers:
480096c14d1a13953a03573097826b2c151f63a8942998316a67ba45403e6177

Deleted Images:
untagged: nginx:latest
untagged: nginx@sha256:b0c17557e2a3a17bcf18498222824312832f69dbf78edab10f08334900bd7fda
deleted: sha256:87a94228f133e2da99cb16d653cd1373c5b4e8689956386c1c12b60a20421a02
deleted: sha256:55b6972054b24c53054322a52748324df5797eefbb6dc374e41522a91d532dd5
deleted: sha256:6b88aa6f4485486bfc779cccfbe4a7a47a502a7cff2cd70be89c59dcd0db12a8
deleted: sha256:472c64059965c7b6b1b534ba07374c1d034b17c99acb3cf4534fe78abed41101
deleted: sha256:788a5cf1e4599312b5923694f53e556ba0e2eb4a6bbb51958e0ec2b510345a49
deleted: sha256:410f31f9ae37c62af85e8f9575c5f4d75542be1739ac1ca5982cf461be0b13bc
deleted: sha256:e81bff2725dbc0bf2003db10272fef362e882eb96353055778a66cda430cf81b

Total reclaimed space: 133.3MB
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
centos       7         eeb6ee3f44bd   3 weeks ago   204MB
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS         PORTS     NAMES
8c754e5c5f4f   centos:7   "bash"    6 minutes ago   Up 6 minutes             test1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值