Docker_logo.png

一、Docker 简介

Docker 是一个开源的平台,我们可以用 Docker 来开发、部署和运行我们的应用程序。Docker 可以帮助我们将应用程序和底层基础设施进行分离,以帮助我们更快的实现交付。通过 Docker 技术,我们可以像管理我们的应用一样管理我们的基础设施(比如操作系统、依赖的开发包等)。通过 Docker 技术,可以精简我们的整个开发和交互流程。

简单来说,Docker类似于在Windows下安装了一个虚拟机。但是Docker 其实是一个轻量级的虚拟化技术Docker 可以让开发者在构建应用时,将应用与其依赖的环境一起打包到一个可移植的容器中, 然后很方便地发布到任意操作系统中。

1.1 Docker VS 虚拟机

  • 传统 VM 需要安装操作系统才能执行应用程序,占用系统资源过多。多数情况下,用户只需要运行简单的应用程序,采用 VM 技术操作繁琐且造成资源浪费。倘若需要迁移应用服务程序,则需迁移整个 VM

  • Docker 是一种轻量级的虚拟化技术,目的和虚拟机一样,都是为了创造“隔离环境”。但是它不像 VM 采用操作系统级的资源隔离,容器采用的是进程级的系统隔离。

VM 架构图示

VM.webp

Docker 架构图示

Docker.webp

对比:

特性

Docker

虚拟机

启动速度

秒级

分钟级

镜像大小

一般为 MB

一般为 GB

运行性能

接近原生(损耗小于 2%)

损耗小于 15%

系统支持量

单机支持上千个容器

一般为几十个

隔离性

较弱的隔离

强隔离

镜像可移植性

平台无关

平台相关

安全性

1. 容器内的用户从普通用户权限提升为 root 权限,就直接具备了宿主机的 root 权限。 2. 容器中没有硬件隔离,使得容器容易受到攻击。

1. 虚拟机租户 root 权限和主机的 root 虚拟机权限是分离的。 2. 硬件隔离技术:防止虚拟机突破和宿主机交互。

优势:

  • 能够更高效的利用系统源

  • 更快速的启动时间

  • 一致的运行环境

  • 持续交付和部署

  • 更轻松的迁移

  • 更轻松的维护和扩展

1.2 容器编排技术

这里不做过多赘述,基本上类似于阿里、腾讯这种用户量比较大、需要服务器集群才必须要上容器编排,比如 k8sDocker SwarmMesos等。个人包括小型企业直接使用 Docker 足矣。

二、Docker 基本概念

2.1 Docker 镜像

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此 Docker 在设计之初,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。

docker-images.png

fenceng.png

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

2.2 Docker 容器

通过镜像运行的实例称之为容器,两者的关系就像是面向对象程序设计中的 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

Docker 利用容器来运行应用,每个容器都是相互隔离的、保证安全的平台。我们可以把容器看做是一个轻量级的Linux 运行环境。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。

前面镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,称这个为容器运行时读写而准备的存储层为容器存储层

rongqi.png

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume) 、或者 绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

2.3 Docker 仓库

Docker Repository 用于镜像的集中存储、分发的地方。有了它,镜像在构建完成后,在其他机器上就可以非常方便的下载使用这个镜像了。

一个 Docker Registry 中可以包含多个 仓库Repository);每个仓库可以包含多个 标签Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签,表示最新的一个版本。

以 Ubuntu 镜像为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest

仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。

公有仓库


公有仓库是允许用户免费上传、下载的公开镜像服务。比如官方的 Docker Hub ,也是默认的 Docker Repository,里面拥有着大量的高质量镜像。但是国内访问它可能比较慢,国内的云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为镜像加速器。国内常见有阿里云加速器、网易加速器、DaoCloud 加速器等。

私有仓库


除了公有仓库外,用户还可以在本地搭建私有仓库。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。

开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。

除了官方的 Docker Registry 外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,Harbor 和 Sonatype Nexus。

三、Docker安装

3.1 Ubuntu 安装

Docker 支持以下版本的 Ubuntu 64 位操作系统:

  • Ubuntu Jammy 22.04 (LTS)

  • Ubuntu Impish 21.10

  • Ubuntu Focal 20.04 (LTS)

  • Ubuntu Bionic 18.04 (LTS)

CPU 架构要求:x86_64 (或 amd64), armhf, arm64, 和 s390x 均支持 Docker 安装。

卸载旧版本


sudo apt-get remove docker docker-engine docker.io containerd runc

3.1.1 APT 安装


  1. 更新 apt 包索引:

sudo apt-get update
  1. 由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们需要添加使用 HTTPS 传输的软件包以及 CA 证书。

sudo apt install apt-transport-https ca-certificates curl software-properties-common
  1. 添加Docker的官方GPG密钥

sudo mkdir -p /etc/apt/keyrings
# 官方源
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
​
# 国内源
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  1. 添加Docker存储库

# 官方源
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
​
# 国内源
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  1. 更新软件包列表(包括新添加的Docker存储库)

 sudo apt-get update
  1. 安装Docker Engine

 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

如何安装指定版本的 Docker ?

  1. 要想安装特定版本的 Docker, 需要先获取 repo 中可用的版本号,然后再安装

apt-cache madison docker-ce
​
docker-ce | 5:20.10.16~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.15~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.14~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.13~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
  1. 第二列中显示的即为版本号,如5:20.10.16~3-0~ubuntu-jammy.

sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io docker-compose-plugin

3.1.2 官方安装脚本安装


curl -fsSL get.docker.com -o get-docker.sh
# 通过 --mirror 选项使用国内源进行安装
sudo sh get-docker.sh --mirror Aliyun

安装测试版的 Docker, 可以从 test.docker.com 获取脚本后再执行它

 curl -fsSL https://test.docker.com -o test-docker.sh
 sudo sh test-docker.sh

3.1.3 启动 Docker


# 设置 Docker 服务开机自动启动
sudo systemctl enable docker
# 启动 Docker 服务
sudo systemctl start docker

3.1.4 建立 Docker 用户组


默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。

出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。

  1. 建立 docker 组:

sudo groupadd docker
  1. 将当前用户加入 docker 组:

sudo usermod -aG docker $USER

3.1.5 验证 Docker 是否安装成功


运行 Docker 并打印 hello-world:

sudo docker run hello-world

此命令会下载测试镜像,并基于此镜像运行容器,然后在打印 hello-world 后退出容器。若成功打印信息,表示 Docker 安装成功。

3.2 CentOS 安装

Docker 支持以下 64 位的 CentOS 版本, 且内核版本不低于 3.10:

  • CentOS 7

  • CentOS 8

  • 更高版本...

卸载旧版本


sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine

3.2.1 yum 安装


  1. 安装依赖包

sudo yum install -y yum-utils
  1. 添加 yum 软件源

# 官方源
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
​
# 国内源
sudo yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo

如果需要测试版本,执行以下命令:

sudo yum-config-manager --enable docker-ce-test
  1. 更新软件源缓存

sudo yum update
  1. 安装Docker Engine

sudo yum install docker-ce docker-ce-cli containerd.io

CentOS8 额外设置

由于 CentOS8 防火墙使用了 nftables,但 Docker 尚未支持 nftables, 我们可以使用如下设置使用 iptables

更改 /etc/firewalld/firewalld.conf

# FirewallBackend=nftables
FirewallBackend=iptables

或者执行如下命令:

firewall-cmd --permanent --zone=trusted --add-interface=docker0
​
firewall-cmd --reload

3.2.2 使用脚本安装


# 测试版
# curl -fsSL test.docker.com -o get-docker.sh
​
# 正式版
$ curl -fsSL get.docker.com -o get-docker.sh
​
# 通过 --mirror 选项使用指定源进行安装
$ sudo sh get-docker.sh --mirror Aliyun
# sudo sh get-docker.sh --mirror AzureChinaCloud

3.2.3 启动 Docker

sudo systemctl enable docker
sudo systemctl start docker

3.2.4 建立 Docker 用户组


默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。

出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。

  1. 建立 docker 组:

sudo groupadd docker
  1. 将当前用户加入 docker 组:

sudo usermod -aG docker $USER

3.2.5 验证 Docker 是否安装成功


运行 Docker 并打印 hello-world:

sudo docker run --rm hello-world

若输出以下信息,代表安装成功

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Status: Downloaded newer image for hello-world:latest
​
Hello from Docker!
This message shows that your installation appears to be working correctly.
​
To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
​
To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash
​
Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/
​
For more examples and ideas, visit:
 https://docs.docker.com/get-started/

3.2.6 遇到的问题


如果在 CentOS 使用 Docker 看到下面的这些警告信息:

WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

请添加内核配置参数以启用这些功能。

sudo tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

然后重新加载 sysctl.conf 即可

sudo sysctl -p

四、Docker 使用

4.1 Docker 镜像


4.1.1 搜索镜像

docker search [option] keyword

比如搜索仓库中 mysql 相关的镜像,可以输入如下命令:

docker search mysql

search_mysql.jpg

返回字段说明:

  • NAME : 镜像名称;

  • DESCRIPTION : 镜像描述信息;

  • STARS : 用户标星数;

  • OFFICIAL: 是否为官方提供,[OK]表示为官方提供;

search命令参数:

  • --help: 帮助内容,可以查看search 命令支持的参数;

  • -f, --filter filter: 过滤输出的内容;

  • --limit int:指定搜索内容展示个数;

  • --no-index: 不截断输出内容;

  • --no-trunc:不截断输出内容;

4.1.2 拉取&下载镜像

docker pull [IMAGE_NAME]:[TAG]

参数说明:

  • IMAGE_NAME: 表示想要下载的镜像名称;

  • TAG: 镜像的标签, 通常是镜像的版本号, 如果不指定,则下载 latest 标签

比如下载一个 Mysql 5.7 镜像,可以通过下面命令来下载:

docker pull mysql:5.7

5c5b69c7f64a730443946e6b469bd14f.dockermysql

当有 Downloaded 字符串输出的时候,说明下载成功了!!

pull 命令参数

  • --help: 帮助内容,可以查看pull 命令支持的参数;

  • -a, --all-tags=true|false: 是否获取仓库中所有镜像,默认为否;

  • --disable-content-trust: 跳过镜像内容的校验,默认为 true;

4.1.3 查看镜像信息

1、运行images命令会列出本地镜像列表

docker images
或
docker image ls

images-info.jpg

红色标注的字段说明:

  • REPOSITORY: 来自于哪个仓库;

  • TAG: 镜像的标签信息,比如 5.7、latest 表示镜像不同的版本;

  • IMAGE ID: 镜像的 ID, 如果您看到两个 ID 完全相同,那么实际上,它们指向的是同一个镜像,只是标签名称不同罢了;

  • CREATED: 镜像创建于什么时间;

  • SIZE: 镜像的大小,优秀的镜像一般体积都比较小

2、运行inspect命令可以获取镜像的更多详细信息

docker inspect mysql:5.7

docker inspect 返回的是 JSON 格式的信息,如果您想获取其中指定的一项内容,可以通过 -f 来指定,如获取镜像大小:

docker inspect -f {{".Size"}} mysql:5.7

3、运行history命令可以查看镜像历史

docker history mysql:5.7

可以列出各个层(layer)的创建信息

输出信息中,为了美观,超出的都省略了,如果想要看具体信息,可以添加 --no-trunc 参数,命令如下:

docker history --no-trunc mysql:5.7

4.1.4 导入导出镜像

可以将自己本地的镜像分享给别人,可以将镜像导出成 tar 包,别人直接导入这个 tar 包,即可将镜像引入到本地镜像库。

导出镜像

通过 docker save 命令可以导出 Docker 镜像。

docker save -o mysql.tar mysql:5.7

执行成功后,即可在当前目录看到打包好的 tar 包了

导入镜像

可以通过 docker load 命令导入镜像:

docker load -i mysql.tar
或者
docker load < mysql.tar

4.1.5 删除镜像

1、通过标签删除镜像

docker rmi [image]
或者
docker image rm [image]

支持的参数如下:

  • -f, -force: 强制删除镜像,即便有容器引用该镜像;

  • -no-prune: 不要删除未带标签的父镜像;

Note: 当有多个同名镜像存在时,想要删除指定镜像需带上 TAG。

2、通过 ID 删除镜像

假如镜像 ID 为:ee7cbd482336

docker rmi ee7cbd482336

3、清理镜像

在使用 Docker 一段时间后,系统一般都会残存一些临时的、没有被使用的镜像文件,可以通过以下命令进行清理:

docker image prune

它支持的子命令有:

  • -a, --all: 删除所有没有用的镜像,而不仅仅是临时文件;

  • -f, --force:强制删除镜像文件,无需弹出提示确认;

另外,执行完 docker image prune 命令后,还会告诉我们释放了多少存储空间!

4.2 Docker 容器


4.2.1 启动容器

docker run IMAGE:TAG

参数说明:

  • IMAGE: 镜像名称;

  • TAG: 标签,镜像版本号;

run命令参数说明:

  • -t: 让 Docker 分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上;

  • -i: 让容器的标准输入保持打开;

以 daemon 守护态方式运行容器

运行容器时添加 -d 参数可以让容器以后台的方式运行,例如启动一个 Ubuntu 后台容器,并每隔一秒打印 Hello world,命令如下:

docker run -d ubuntu:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"

执行成功后,会返回一个容器 ID。

后台运行的容器可以通过 docker logs 命令来查看日志:

docker container logs [container ID or NAMES]

启动终止状态的容器

执行如下命令,可以将已经终止 (exited)运行的容器重启。

docker container start [container ID or NAMES]

4.2.2 查看容器

  • docker ps : 查看正在运行中的容器;

  • docker ps -a : 查看所有容器,包括运行中的、已经停止运行的容器。

  • docker ps -l : 查看最新创建的容器,注意,只列出最后创建的容器。

  • docker ps -n=2: -n=2 指定列出最新创建的 2 个容器。

4.2.3 进入容器

1、 exit 命令

docker exec -it [container ID or NAMES] 

要想退出容器,只需键入 exit 命令回车即可,但是 exit 后容器不会停止

2、 attach 命令

docker attach [container ID or NAMES] 

这种方式在执行 exit 命令退出容器时,会导致容器停止运行。

4.2.4 停止容器

1、 stop 命令

docker container stop [container ID or NAMES]
# 简写模式(可省略关键字 container )
docker stop [container ID or NAMES]

2、 kill 强制命令

docker container kill [container ID or NAMES]
# 简写模式(可省略关键字 container )
docker kill [container ID or NAMES]

3、 查看已经停止运行的容器

执行如下命令,可以看到那些已经停止运行的容器:

docker container ls -a

想要重启已经停止运行的容器,命令如下:

docker container start [container ID or NAMES]

另外,docker container restart 命令会将一个已经运行中的容器重新启动。

4.2.5 重启容器

# 不管容器是否启动,直接重启
docker restart [container ID or NAMES]

参数:

-t : 设置关闭容器的限制时间,若超时未能关闭,则使用 kill 命令强制关闭,默认值为 10s,这个时间用于容器保存自己的状态。例如:

# 限时 5s 关闭 redis 容器,然后重启
docker restart -t=5 redis

4.2.6 导出&导入容器

1、导出容器

使用 docker export 命令可以导出容器,比如想导出下面的 Redis 容器:

docker export 9e8d11aeef0c > redis.tar

导出的 tar 包快照存于当前目录下。

2、导入容器

使用 docker import 命令可以将快照导入为镜像,例如:

cat redis.tar | docker import - test/redis:v1.0

除了通过快照的方式导入容器,还可以通过指定 URL 或者某个目录来导入,例如:

docker import http://example.com/exampleimage.tgz example/imagerepo

4.2.7 删除容器

docker container rm [container ID or NAMES]
# 简写模式(可省略关键字 container )
docker rm [container ID or NAMES]

添加 -f 参数可强制删除一个正在运行的容器:

使用docker container prune可以删除掉所有已经停止运行的容器

五、数据管理

5.1 数据卷


5.1.1 特性

  • 数据卷可以在容器之间共享和重用;

  • 对数据卷的修改会立刻生效;

  • 更新数据卷不会影响镜像;

  • 数据卷默认一直存在,即使容器被删除;

5.1.2 volume使用

volume : Docker 管理宿主机文件系统的一部分,默认位于 /var/lib/docker/volumes 目录下, 也是最常用的方式。

  • 创建数据卷

docker volume create test-vol
  • 查看所有的数据卷

docker volume ls
  • 查看数据卷信息

# 查看数据卷名为 test-vol 的信息
docker volume inspect test-vol
  • 运行容器时挂载数据卷

数据卷 test-vol创建成功后,我们运行一个 Nginx 容器,并尝试挂载该数据卷,挂载命令支持两种:

(1)-v

docker run -d -it --name=test-nginx -p 8011:80 -v test-vol:/usr/share/nginx/html nginx:1.13.12

参数说明:

  • -d : 后台运行容器;

  • --name=test-nginx : 指定容器名为 test-nginx;

  • -p 8011:80 : 将容器的 80 端口挂载到宿主机的 8011 端口;

  • -v test-vol:/usr/share/nginx/html : 将 test-vol 数据卷挂载到容器中的 /usr/share/nginx/html 目录上;

(2)--mount

docker run -d -it --name=test-nginx -p 8011:80 --mount source=test-vol,target=/usr/share/nginx/html nginx:1.13.12

参数说明:

  • --mount source=test-vol,target=/usr/share/nginx/html : 将 test-vol 数据卷挂载到容器中的 /usr/share/nginx/html 目录上;

-v--mount 有什么区别?

都是挂载命令,使用 -v 挂载时,如果宿主机上没有指定文件不会报错,会自动创建指定文件;当使用 --mount时,如果宿主机中没有这个文件会报错找不到指定文件,不会自动创建指定文件。

删除数据卷

由于数据卷的生命期独立于容器,想要删除数据卷,就需要我们手动来操作, 执行命令如下:

docker volume rm test-vol

5.1.3 bind mount使用

通过 bind mount 模式可以挂载到宿主机的任意位置,示例如下:

docker run -d -it --name=test-nginx -p 8011:80 -v /docker/nginx1:/usr/share/nginx/html nginx:1.13.12

参数说明:

  • -v /docker/nginx1:/usr/share/nginx/html : 将宿主机中的 /docker/nginx1 目录挂载到容器中的 /usr/share/nginx/html 目录;

与 volume 不同,bind mount 这种方式会隐藏目录中的内容(非空情况下)

5.2 数据卷容器


5.2.1 创建数据卷容器

运行一个器,并创建一个名为 dbdata 的数据卷:

docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

容器运行成功后,会发现该数据卷容器处于停止运行状态,这是因为数据卷容器并不需要处于运行状态,只需用于提供数据卷挂载即可。

5.2.2 挂载数据卷

--volumes-from 命令支持从另一个容器挂载容器中已创建好的数据卷。

比如:

docker run -d --volumes-from dbdata --name db1 training/postgres
docker run -d --volumes-from dbdata --name db2 training/postgres
docker ps
CONTAINER ID       IMAGE                COMMAND                CREATED             STATUS              PORTS               NAMES
7348cb189292       training/postgres    "/docker-entrypoint.   11 seconds ago      Up 10 seconds       5432/tcp            db2
a262c79688e8       training/postgres    "/docker-entrypoint.   33 seconds ago      Up 32 seconds       5432/tcp            db1

还可以使用多个 --volumes-from 参数来从多个容器挂载多个数据卷。 也可以从其他已经挂载了数据卷的容器来挂载数据卷。

如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除。如果想要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 docker rm -v 命令来指定同时删除关联的容器。

5.3 使用数据卷容器备份、恢复、迁移数据卷


5.3.1 备份

首先使用 --volumes-from 命令创建一个加载 dbdata 的容器卷容器,并将宿主机当前目录挂载到容器的 /backup 目录,命令如下:

sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

容器启动后,使用了 tar 命令来将 dbdata 数据卷备份为容器中 /backup/backup.tar 文件,因为挂载了的关系,宿主机的当前目录下也会生成 backup.tar 备份文件。

5.3.2 恢复/迁移

如果要恢复数据到一个容器,首先创建一个带有空数据卷的容器 dbdata2

sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后创建另一个容器,挂载 dbdata2 容器卷中的数据卷,并使用 untar 解压备份文件到挂载的容器卷中。

sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf
/backup/backup.tar

为了查看/验证恢复的数据,可以再启动一个容器挂载同样的容器卷来查看:

sudo docker run --volumes-from dbdata2 busybox /bin/ls /dbdata

常用命令

基本命令


命令

说明

docker info

检查当前容器的安装情况(包括镜像数、容器书、多少个物理机节点)

docker version

查看当前安装的 Docker 的版本信息

容器生命周期相关命令


命令

说明

docker run -d -p x:x --name xxx 镜像id

以后台方式运行容器

docker create --name xxx nginx:latest

创建一个新的容器,但是不启动

docker start/stop/restart

启动\停止\重启一个容器

docker kill 容器id

终止一个运行中的容器,kill 不管是否同意,直接强制终止

docker rm -vf 容器id

删除一个或者多个容器

docker exec -it id bash

进入到容器内部

docker attach

进入到容器内部

容器操作相关命令


说明

命令

docker ps -a | grep xxxx

显示某一个组件 XXX 的容器列表

docker inspect id

获取容器或者镜像的元数据

docker top id

查看容器中运行的进程信息

docker stats id

实时显示容器资源的使用统计

docker events

从服务器获取实时事件

docker logs id

查看容器内的标准日志输出

docker port id

列出指定容器的端口映射

docker cp ./t.txt id:/root/

将宿主机当前目录下的 t.txt 复制到 id 容器中的 root 目录下

docker diff id

列出该容器自创建以来,容器内部文件的变化

docker commit -m "comment" -a "authon" 容器id repository:tag

将指定容器打包成一个本地镜像

docker update --memory=16G

修改容器运行中的配置,即时生效无需配置

本地镜像管理相关命令


命令

说明

docker images

列出本地宿主机上的所有镜像

docker history id

查看指定镜像的分层结构以及创建历史

docker image inspect id

查看镜像的元数据信息

docker rmi id

根据镜像 id 删除镜像

docker tag image-name:tag

给指定镜像增加 tag

docekr build -t tag .

通过当前目目录下的 Dockerfile 来构建一个标签为 tag 的镜像

docker export -o xxx.tar id

将镜像打包成文件

docker import xxx.tar name

从归档文件中创建镜像

docker save -o xxx.tat id

将指定镜像保存为归档文件

docker load --input xxx.tar

用于将 docker save 生成的归档文件还原成镜像

镜像仓库相关命令


命令

说明

docker loging -u xxx -p xxx

登录一个 docker 镜像仓库,如果未指定镜像仓库地址,则默认为Docker Hub镜像仓库

docker logout

退出登录的镜像仓库

docker pull nginx

从默认的 Docker hub 上拉取 nginx 镜像

docker push image_name

将本地镜像上传到镜像仓库(注意需要先登录)

docker search xxx

从默认的 Docker Hub 中搜索指定的镜像

参数命令


以下汇总 docker run 命令支持的相关参数:

容器运行相关参数

参数

说明

-a,--attach=[]

是否绑定到标准输入、输出、和错误.

-d,--detach=true|false

是否在后台运行,默认为 false

--detach-keys=""

从attach模式退出的快捷键,默认是 Ctrl+P

--entrypoint=""

镜像存在入口命令时覆盖新的命令.

-expost=[]

暴露出来的镜像端口

--group-add=[]

运行容器的用户组

-i

保持标准输入打开

--ipc=""

容器 IP 命名空间

--isolation="default"

容器使用的隔离机制

--log-driver=""

指定容器的日志驱动类型

--log-opy=[]

传递给日志驱动的选项

--net="bridge"

指定容器的网络模式

--net-alias=[]

容器在网络中的别名

--volume=[=[HOST-DIR]:]CONTAINER-DIR:[:OPTIONS]]

挂载宿主机上的数据卷到容器内

--volume-driver=""

挂载数据卷的驱动类型.

--volumes-from=[]

其他容器挂载数据卷

容器环境配置相关参数

参数

说明

--add-host=[]

在容器内添加一个宿主机名到 IP 地址的映射关系,修改 HOST 文件

--device=[]

映射物理机上的设备到容器

--dns-search=[]

指定容器 DNS 搜索域

--dns-opt=[]

自定义的 DNS 选项

--dns=[]

自定义的 DNS 服务器

-e,-env=[]

指定容器内的环境变量

-env-file=[]

从文件中读取环境变量到容器内

-h,--hostname=""

指定容器中的主机名

--ip=""

指定容器内 ip4 的地址

--ip6=""

指定容器内 ip6 的地址

--link=[id]

连接到其他容器,不需要其他容器暴露端口

--name==""

指定容器的别名

CPU 相关参数


参数

说明

--cpu-shares=0

允许容器使用 CPU 资源的相对权重,默认一个容器能用满一个 CPU,用于设置多个容器竞争 CPU 时,各个容器相对能分配到 CPU 时间占比

--cpu-period=0

限制容器在 CFS 调度下 CPU 占用的时间片,用于绝对设置容器能使用的 CPU 时间

--cpu-quota=0

限制容器在 CFS 调度器下的 CPU 配额,用于绝对设置容器能使用 CPU 的时间

--cpuset-cpus=""

限制容器能使用那些 cpu 核数

--cpuset-mems=""

NUMA 架构下使用那些核心内存

内存资源相关参数

参数

说明

--kernel-memory=""

限制容器使用内核的内存大小

-m,--memory=""

限制容器内应用使用内存的大小

--memory-reservation=""

当系统中内存过小时,容器会被强制限制内存到给定值默认情况下等于内存限制值

--memory-swap="LIMIT"

限制容器使用内存和交换分区的大小

--oom-kill-disable=true

内存耗尽时是否终止容器

--oom-score-adj=""

调整容器的内存耗尽参数

--memory-swappiness="0-100"

调整容器的内存交换分区参数

容器磁盘 IO 控制相关参数

参数

说明

--device-read-bps

限制此设备上的读速率

--device-read-iops

通过每秒读 IO 次数限制指定设备的读速率

--device-write-bps

限制此设备的写速率

--device-write-iops

通过每秒写 IO 次数限制指定设备的写速率

--blkio-weight

容器默认磁盘 IO 的加权值

--blkio-weight-device

针对特定设备的 IO 加权控制