01 – Docker 简介

前言

统称来说, 容器是一种工具, 指的是可以装下其它物品的工具, 以方便人类归纳放置物品、 存储和异地运输, 具体来说比如人类使用的衣柜、 行李箱、 背包等可以成为容器, 但今天我们所说的容器是一种 IT 技术。
容器技术是虚拟化、 云计算、 大数据之后的一门新兴的并且是炙手可热的新技术, 容器技术提高了硬件资源利用率、 方便了企业的业务快速横向扩容、 实现了业务宕机自愈功能, 因此未来数年会是一个容器愈发流行的时代, 这是一个对于IT 行业来说非常有影响和价值的技术, 而对于 IT 行业的从业者来说, 熟练掌握容器技术无疑是一个很有前景的行业工作机会。
容器技术最早出现在 freebsd 叫做 jail。

docker 简介

Docker 是什么

首先 Docker 是一个在 2013年开源的应用程序并且是一个基于 go 语言编写是一个开源的 PAAS 服务(Platform as a Service, 平台即服务的缩写), go 语言是由 google 开发, docker 公司最早叫 dotCloud 后由于 Docker 开源后大受欢迎就将公司改名为 Docker Inc, 总部位于美国加州的旧金山, Docker 是基于 linux内核实现, Docker 最早采用 LXC 技术(LinuX Container 的简写, LXC 是 Linux 原生支持的容器技术, 可以提供轻量级的虚拟化, 可以说 docker 就是基于 LXC发展起来的(0.1.5 (2013-04-17), 提供 LXC 的高级封装, 发展标准的配置方法),而虚拟化技术 KVM(Kernel-based Virtual Machine) 基于模块实现, Docker 后改为自己研发并开源的 runc 技术运行容器(1.11.0 (2016-04-13)。

Docker now relies on containerd and runc to spawn containers。
Docker 相比虚拟机的交付速度更快, 资源消耗更低, Docker 采用客户端/服务端架构, 使用远程 API 来管理和创建 Docker 容器, 其可以轻松的创建一个轻量级的、 可移植的、 自给自足的容器, docker 的三大理念是 build(构建)、 ship(运输)、 run(运行), Docker 遵从 apache 2.0 协议, 并通过namespace 及 cgroup等) 来提供容器的资源隔离与安全保障等, 所以 Docke 容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机的一定性能开销) 的额外资源开销, 因此可以大幅提高资源利用率,总而言之 Docker 是一种用了新颖方式实现的轻量级虚拟机.类似于 VM 但是在原理和应用上和 VM 的差别还是很大的, 并且 docker的专业叫法是应用容器(Application Container)。

Docker 的组成
Docker 的组成https://docs.docker.com/engine/docker-overview/
Docker 主机(Host): 一个物理机或虚拟机, 用于运行 Docker 服务进程和容器。
Docker 服务端(Server): Docker 守护进程, 运行 docker 容器。
Docker 客户端(Client): 客户端使用 docker 命令或其他工具调用 docker API。
Docker 仓库(Registry): 保存镜像的仓库, 类似于 git 或 svn 这样的版本控制系
Docker 镜像(Images): 镜像可以理解为创建实例使用的模板。
Docker 容器(Container): 容器是从镜像生成对外提供服务的一个或一组服务。
官方仓库: https://hub.docker.com/

01 - Docker 简介
01 - Docker 简介

Docker 对比虚拟机

资源利用率更高: 一台物理机可以运行数百个容器, 但是一般只能运行数十个虚拟机。
开销更小: 不需要启动单独的虚拟机占用硬件资源。
启动速度更快: 可以在数秒内完成启动。

01 - Docker 简介
01 - Docker 简介

使用虚拟机是为了更好的实现服务运行环境隔离, 每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机, 但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能损耗, 我们创建虚拟机的目的是为了运行应用程序, 比如 Nginx、 PHP、 Tomcat 等 web 程序, 使用虚拟机无疑带来了一些不必要的资源开销, 但是容器技术则基于减少中间运行环节带来较大的性能提升。

01 - Docker 简介

但是, 如上图一个宿主机运行了 N 个容器, 多个容器带来的以下问题怎么解决:
1.怎么样保证每个容器都有不同的文件系统并且能互不影响?
2.一个 docker 主进程内的各个容器都是其子进程, 那么实现同一个主进程下不同类型的子进程? 各个进程间通信能相互访问(内存数据)吗?
3.每个容器怎么解决 IP 及端口分配的问题?
4.多个容器的主机名能一样吗?
5.每个容器都要不要有 root 用户? 怎么解决账户重名问题?
以上问题怎么解决?

Linux Namespace 技术

namespace 是 Linux 系统的底层概念, 在内核层实现, 即有一些不同类型的命名空间被部署在核内, 各个 docker 容器运行在同一个 docker 主进程并且共用同一个宿主机系统内核, 各 docker 容器运行在宿主机的用户空间, 每个容器都要有类似于虚拟机一样的相互隔离的运行空间, 但是容器技术是在一个进程内实现运行指定服务的运行环境, 并且还可以保护宿主机内核不受其他进程的干扰和影响, 如文件系统空间、 网络空间、 进程空间等, 目前主要通过以下技术实现容器运行空间的相互隔离:

隔离类型功能系统调用参数内核版本
MNT Namespace(mount)提供磁盘挂载点和文件系统的隔离能力CLONE_NEWNSLinux 2.4.19
IPC Namespace(Inter-Process Communication)提供进程间通信的隔离能力CLONE_NEWIPCLinux 2.6.19
UTS Namespace(UNIX Timesharing System)提供主机名隔离能力CLONE_NEWUTSLinux 2.6.19
PID Namespace(Process Identification)提供进程隔离能力CLONE_NEWPIDLinux 2.6.24
Net Namespace(network)提供网络隔离能力CLONE_NEWNETLinux 2.6.29
User Namespace(user)提供用户隔离能力CLONE_NEWUSERLinux 3.8

MNT Namespace

每个容器都要有独立的根文件系统有独立的用户空间, 以实现在容器里面启动服务并且使用容器的运行环境, 即一个宿主机是 ubuntu 的服务器, 可以在里面启动一个 centos 运行环境的容器并且在容器里面启动一个 Nginx 服务, 此 Nginx运行时使用的运行环境就是 centos 系统目录的运行环境, 但是在容器里面是不能访问宿主机的资源, 宿主机是使用了 chroot 技术把容器锁定到一个指定的运行目录里面。
例如: /var/lib/containerd/io.containerd.runtime.v1.linux/moby/容器 ID

01 - Docker 简介

IPC Namespace

一个容器内的进程间通信, 允许一个容器内的不同进程的(内存、 缓存等)数据访问, 但是不能跨容器访问其他容器的数据。

UTS Namespace

UTS namespace(UNIX Timesharing System 包含了运行内核的名称、 版本、底层体系结构类型等信息) 用于系统标识, 其中包含了 hostname 和域名domainname , 它使得一个容器拥有属于自己 hostname 标识, 这个主机名标识独立于宿主机系统和其上的其他容器。

01 - Docker 简介

PID Namespace

Linux 系统中, 有一个 PID 为 1 的进程(init/systemd)是其他所有进程的父进程, 那么在每个容器内也要有一个父进程来管理其下属的子进程, 那么多个容器的进程通 PID namespace 进程隔离(比如
PID 编号重复、 器内的主进程生成与回收子进程等)。
例如: 下图是在一个容器内使用 top 命令看到的 PID 为 1 的进程是 nginx

01 - Docker 简介

容器内的 Nginx 主进程与工作进程:

01 - Docker 简介

那么宿主机的 PID 究竟与容器内的 PID 是什么关系?
容器 PID 追踪:

01 - Docker 简介
查看宿主机上的 PID 信息
01 - Docker 简介
查看容器中的 PID 信息

Net Namespace

每一个容器都类似于虚拟机一样有自己的网卡、 监听端口、 TCP/IP 协议栈等,Docker 使用 network namespace 启动一个 vethX 接口, 这样你的容器将拥有它自己的桥接 ip 地址, 通常是 docker0, 而 docker0 实质就是 Linux 的虚拟网桥,网桥是在 OSI 七层模型的数据链路层的网络设备, 通过 mac 地址对网络进行划分, 并且在不同网络直接传递数据。

01 - Docker 简介
查看宿主机的网卡信息
01 - Docker 简介
通过 brctl show 命令查看桥接设备
查看宿主机桥接设备
01 - Docker 简介
01 - Docker 简介
实逻辑网络图
01 - Docker 简介
宿主机 iptables 规则
01 - Docker 简介
宿主机 iptables 规则

User Namespace

各个容器内可能会出现重名的用户和用户组名称, 或重复的用户 UID 或者 GID,那么怎么隔离各个容器内的用户空间呢?

User Namespace 允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户 UID 和 GID, 只是会把用户的作用范围限制在每个容器内, 即 A 容器和 B 容器可以有相同的用户名称和 ID 的账户, 但是此用户的有效范围仅是当前容器内, 不能访问另外一个容器内的文件系统, 即相互隔离、 互补影响、 永不相见。

01 - Docker 简介

Linux control groups

在一个容器, 如果不对其做任何资源限制, 则宿主机会允许其占用无限大的内存空间, 有时候会因为代码 bug 程序会一直申请内存, 直到把宿主机内存占完,为了避免此类的问题出现, 宿主机有必要对容器进行资源分配限制, 比如 CPU、内存等, Linux Cgroups 的全称是 Linux Control Groups, 它最主要的作用, 就是限制一个进程组能够使用的资源上限, 包括 CPU、 内存、 磁盘、 网络带宽等等。 此外, 还能够对进程进行优先级设置, 以及将进程挂起和恢复等操作。
验证系统 cgroups:
Cgroups 在内核层默认已经开启, 从 centos 和 ubuntu 对比结果来看, 显然内核较新的 ubuntu 支持的功能更多。

01 - Docker 简介
Centos 7.6 cgroups
01 - Docker 简介
ubuntu cgroups

cgroups中的内存模块:

# cat /boot/config-4.15.0-54-generic | grep MEM | grep CG
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
# CONFIG_MEMCG_SWAP_ENABLED is not set
CONFIG_SLUB_MEMCG_SYSFS_ON=y

cgroups具体实现 :

blkio: 块设备 IO 限制。
cpu: 使用调度程序为 cgroup 任务提供 cpu 的访问。
cpuacct: 产生 cgroup 任务的 cpu 资源报告。
cpuset: 如果是多核心的 cpu, 这个子系统会为 cgroup 任务分配单独的 cpu 和内存。
devices: 允许或拒绝 cgroup 任务对设备的访问。
freezer: 暂停和恢复 cgroup 任务。
memory: 设置每个 cgroup 的内存限制以及产生内存资源报告。
net_cls: 标记每个网络包以供 cgroup 方便使用。
ns: 命名空间子系统。
perf_event: 增加了对每 group 的监测跟踪的能力, 可以监测属于某个特定的
group 的所有线程以及运行在特定 CPU 上的线程。

查看系统 cgroups:

[root@node1 ~]# ll /sys/fs/cgroup/
total 0
drwxr-xr-x 5 root root 0 Jun 30 18:12 blkio
lrwxrwxrwx 1 root root 11 Jun 30 18:12 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 Jun 30 18:12 cpuacct -> cpu,cpuacct
drwxr-xr-x 5 root root 0 Jun 30 18:12 cpu,cpuacct
drwxr-xr-x 3 root root 0 Jun 30 18:12 cpuset
drwxr-xr-x 5 root root 0 Jun 30 18:12 devices
drwxr-xr-x 3 root root 0 Jun 30 18:12 freezer
drwxr-xr-x 3 root root 0 Jun 30 18:12 hugetlb
drwxr-xr-x 5 root root 0 Jun 30 18:12 memory
drwxr-xr-x 3 root root 0 Jun 30 18:12 net_cls
drwxr-xr-x 3 root root 0 Jun 30 18:12 perf_event
drwxr-xr-x 5 root root 0 Jun 30 18:12 systemd

有了以上的 chroot、 namespace、 cgroups 就具备了基础的容器运行环境, 但是还需要有相应的容器创建与删除的管理工具、 以及怎么样把容器运行起来、 容器数据怎么处理、 怎么进行启动与关闭等问题需要解决, 于是容器管理技术出现了。

容器管理工具

目前主要是使用 docker, 早期有使用 lxc。

lxc

LXC: LXC 为 Linux Container 的简写。 可以提供轻量级的虚拟化, 以便隔离进程和资源, 官方网站: https://linuxcontainers.org/
Ubuntu 安装 lxc:

root@s1:~# apt install lxc lxd
Reading package lists... Done
Building dependency tree
Reading state information... Done
lxd is already the newest version (3.0.3-0ubuntu1~18.04.1).
lxc is already the newest version (3.0.3-0ubuntu1~18.04.1).
root@s1:~# lxc-checkconfig #检查内核对 lcx 的支持状况, 必须全部为 lcx
root@s1:~# lxc-create -t 模板名称 -n lcx-test
root@s1:~# lxc-create -t download --name alpine12 -- --dist alpine
--release 3.9 --arch amd64
Setting up the GPG keyring
Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs
---
You just created an Alpinelinux 3.9 x86_64 (20190630_13:00) container.
root@s1:~# lxc-start alpine12 #启动 lxc 容器
root@s1:~# lxc-attach alpine12 #进入 lxc 容器
~ # ifconfig
eth0 Link encap:Ethernet HWaddr 00:16:3E:DF:54:94
inet addr:10.0.3.115 Bcast:10.0.3.255 Mask:255.255.255.0
inet6 addr: fe80::216:3eff:fedf:5494/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18 errors:0 dropped:0 overruns:0 frame:0
TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2102 (2.0 KiB) TX bytes:1796 (1.7 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
~ # uname -a
Linux alpine12 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC
2018 x86_64 Linux
~ # cat /etc/issue
Welcome to Alpine Linux 3.9
Kernel \r on an \m (\l)
命令备注:
-t 模板: -t 选项后面跟的是模板, 模式可以认为是一个原型, 用来说明我们需要一个什么样的容器(比如容器里面需不需要有 vim, apache 等软件). 模板实际上就是一个脚本文件(位/usr/share/lxc/templates目录), 我们这里指定download模板(lxc-create 会调用 lxc-download 脚本, 该脚本位于刚说的模板目录中)是说明我们目前没有自己模板, 需要下载官方的模板
--name 容器名称: 为创建的容器命名
-- : --用来说明后面的参数是传递给 download 脚本的, 告诉脚本需要下载什么
样的模板
--dist 操作系统名称: 指定操作系统
--release 操作系统: 指定操作系统, 可以是各种 Linux 的变种
--arch 架构: 指定架构, 是 x86 还是 arm, 是 32 位还是 64 位

lxc 启动容器依赖于模板, 清华模板源:
https://mirrors.tuna.tsinghua.edu.cn/help/lxc-images/, 但是做模板相对较难,需要手动一步步创构建文件系统、 准备基础目录及可执行程序等, 而且在大规模使用容器的场景很难横向扩展, 另外后期代码升级也需要重新从头构建模板, 基于以上种种原因便有了 docker。

docker

Docker 启动一个容器也需要一个外部模板但是较多镜像, docke 的镜像可以保存在一个公共的地方共享使用, 只要把镜像下载下来就可以使用, 最主要的是可以在镜像基础之上做自定义配置并且可以再把其提交为一个镜像, 一个镜像可以被启动为多个容器。
Docker 的镜像是分层的, 镜像底层为库文件且只读层即不能写入也不能删除数据, 从镜像加载启动为一个容器后会生成一个可写层, 其写入的数据会复制到容器目录, 但是容器内的数据在删除容器后也会被随之删除。

01 - Docker 简介

pouch:

  • https://www.infoq.cn/article/alibaba-pouch
  • https://github.com/alibaba/pouch

Docker 的优势

快速部署: 短时间内可以部署成百上千个应用, 更快速交付到线上。
高效虚拟化: 不需要额外的 hypervisor 支持, 直接基于 linux 实现应用虚拟化,相比虚拟机大幅提高性能和效率。
节省开支: 提高服务器利用率, 降低 IT 支出。
简化配置: 将运行环境打包保存至容器, 使用时直接启动即可。
快速迁移和扩展: 可夸平台运行在物理机、 虚拟机、 公有云等环境, 良好的兼容性可以方便将应用从 A 宿主机迁移到 B 宿主机, 甚至是 A 平台迁移到 B 平台。

Docker 的缺点

隔离性: 各应用之间的隔离不如虚拟机彻底。

docker(容器)的核心技术

容器规范

容器技术除了的 docker 之外, 还有 coreOS 的 rkt, 还有阿里的 Pouch, 为了保证容器生态的标准性和健康可持续发展, 包括 Linux 基金会、 Docker、 微软、红帽谷歌和、 IBM、 等公司在 2015 年 6 月共同成立了一个叫 open container(OCI) 的组织, 其目的就是制定开放的标准的容器规范, 目前 OCI 一共发布了两个规范, 分别是 runtime spec 和 image format spec, 有了这两个规范, 不同的容器公司开发的容器只要兼容这两个规范, 就可以保证容器的可移植性和相互可操作性。

容器 runtime(runtime spec):
runtime 是真正运行容器的地方, 因此为了运行不同的容器 runtime 需要和操作系统内核紧密合作相互在支持, 以便为容器提供相应的运行环境。
目前主流的三种 runtime:

  • Lxc: linux 上早期的 runtime, Docker 早期就是采用 lxc 作为 runtime。
  • runc: 目前 Docker 默认的 runtime, runc 遵守 OCI 规范, 因此可以兼容 lxc。
  • rkt: 是 CoreOS 开发的容器 runtime, 也符合 OCI 规范, 所以使用 rktruntime也可运行 Docker 容器。

runtime 主 要 定 义 了 以 下 规 范 , 并 以 json 格 式 保 存 在/run/docker/runtime-runc/moby/容器 ID/state.json 文件, 此文件会根据容器的状态实时更新内容:

版本信息: 存放 OCI 标准的具体版本号。
容器 ID: 通常是一个哈希值, 可以在所有 state.json 文件中提取出容器 ID 对容器进行批量操作(关闭、 删除等), 此文件在容器关闭后会被删除, 容器启动后会自动生成。

PID: 在容器中运行的首个进程在宿主机上的进程号, 即将宿主机的那个进程设置为容器的守护进程。
容器文件目录: 存放容器 rootfs 及相应配置的目录, 外部程序只需读取 state.json 就可以定位到宿主机上的容器文件目录。

容器创建: 创建包括文件系统、 namespaces、 cgroups、 用户权限在内的各项内容。
容器进程的启动: 运行容器启动进程, 该文件在/run/containerd/io.containerd.runtime.v1.linux/moby/容器 ID/config.json。

容器生命周期: 容器进程可以被外部程序关停, runtime 规范定义了对容器操作信号的捕获, 并做相应资源回收的处理, 避免僵尸进程的出现。

容器镜像(image format spec)
OCI 容器镜像主要包含以下内容:

文件系统:定义以 layer 保存的文件系统,在镜像里面是 layer.tar,每个 layer 保存了和上层之间变化的部分,image format spec 定义了 layer 应该保存哪些文件,怎么表示增加、 修改和删除的文件等操作。
manifest 文件: 描述有哪些 layer, tag 标签及 config 文件名称。
config 文件: 是一个以 hash 命名的 json 文件, 保存了镜像平台, 容器运行时容器运行时需要的一些信息, 比如环境变量、 工作目录、 命令参数等。
index 文件: 可选的文件,指向不同平台的 manifest 文件,这个文件能保证一个镜像可以跨平台使用, 每个平台拥有不同的 manifest 文件使用 index 作为索引。

父镜像: 大多数层的元信息结构都包含一个 parent 字段, 指向该镜像的父镜像。
参数:

ID: 镜像 ID, 每一层都有 ID
tag 标签: 标签用于将用户指定的、 具有描述性的名称对应到镜像 ID
仓库: Repository 镜像仓库
os: 定义类型
architecture : 定义 CPU 架构
author: 作者信息
create: 镜像创建日期

容器管理工具

管理工具连接 runtime 与用户, 对用户提供图形或命令方式操作, 然后管理工具将用户操作传递给 runtime 执行。
lxc 是 lxd 的管理工具。
Runc 的管理工具是 docker engine, docker engine 包含后台 deamon 和 cli两部分, 大家经常提到的 Docker 就是指的 docker engine。
Rkt 的管理工具是 rkt cli。

容器定义工具

容器定义工具允许用户定义容器的属性和内容, 以方便容器能够被保存、 共享和重建。
Docker image: 是 docker 容器的模板, runtime 依据 docker image 创建容器。
Dockerfile: 包含 N 个命令的文本文件, 通过 dockerfile 创建出 docker image。
ACI(App container image): 与 docker image 类似, 是 CoreOS 开发的 rkt 容器的镜像格式。

Registry

统一保存镜像而且是多个不同镜像版本的地方, 叫做镜像仓库。
Image registry: docker 官方提供的私有仓库部署工具。
Docker hub: docker 官方的公共仓库, 已经保存了大量的常用镜像, 可以方便大家直接使用。
Harbor: vmware 提供的自带 web 界面自带认证功能的镜像仓库, 目前有很多公司使用。

172.18.200.101/project/centos:7.2.1511
172.18.200.101/project/centos: latest
172.18.200.101/project/java-7.0.59:v1
172.18.200.101/project/java-7.0.59:v2

编排工具

当多个容器在多个主机运行的时候, 单独管理容器是相当复杂而且很容易出错, 而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的, 也无法实现动态伸缩的功能, 因此需要有一种工具可以实现统一管理、动态伸缩、 故障自愈、 批量执行等功能, 这就是容器编排引擎。
容器编排通常包括容器管理、 调度、 集群定义和服务发现等功能。
Docker swarm: docker 开发的容器编排引擎。
Kubernetes: google 领导开发的容器编排引擎, 内部项目为 Borg, 且其同时支持 docker 和 CoreOS。
Mesos+Marathon: 通用的集群组员调度平台, mesos(资源分配)与 marathon(容器编排平台)一起提供容器编排引擎功能。

01 - Docker 简介

docker(容器)的依赖技术

容器网络

docker 自带的网络 docker network 仅支持管理单机上的容器网络, 当多主机运行的时候需要使用第三方开源网络, 例如 calico、 flannel 等。

服务发现

容器的动态扩容特性决定了容器 IP 也会随之变化, 因此需要有一种机制可以自动识别并将用户请求动态转发到新创建的容器上, kubernetes 自带服务发现功能, 需要结合 kube-dns 服务解析内部域名。

容器监控

可以通过原生命令 docker ps/top/stats 查看容器运行状态, 另外也可以使heapster/ Prometheus 等第三方监控工具监控容器的运行状态。

数据管理

容器的动态迁移会导致其在不同的 Host 之间迁移, 因此如何保证与容器相关的数据也能随之迁移或随时访问, 可以使用逻辑卷/存储挂载等方式解决。

日志收集

docker 原生的日志查看工具 docker logs, 但是容器内部的日志需要通过 ELK等专门的日志收集分析和展示工具进行处理。

Docker 安装及基础命令介绍

官方网址: https://www.docker.com/
系统版本选择:
Docker 目前已经支持多种操作系统的安装运行, 比如 Ubuntu、 CentOS、Redhat、 Debian、 Fedora, 甚至是还支持了 Mac 和 Windows, 在 linux 系统上需要内核版本在 3.10 或以上, docker 版本号之前一直是 0.X 版本或 1.X 版本,但是从 2017 年 3 月 1 号开始改为每个季度发布一次稳版, 其版本号规则也统一变更为 YY.MM, 例如 17.09 表示是 2017 年 9 月份发布的, 本次演示的操作系统使用 Centos 7.5 为例。
Docker 版本选择:
Docker 之前没有区分版本, 但是 2017 年初推出(将 docker 更名为)新的项目 Moby, github 地址: https://github.com/moby/moby, Moby 项目属于 Docker项目的全新上游, Docker 将是一个隶属于的 Moby 的子产品, 而且之后的版本之后开始区分为 CE 版本(社区版本) 和 EE(企业收费版) , CE 社区版本和EE 企业版本都是每个季度发布一个新版本, 但是 EE 版本提供后期安全维护 1年, 而 CE 版本是 4 个月, 本次演示的 Docker 版本为 18.03, 以下为官方原文:
https://blog.docker.com/2017/03/docker-enterprise-edition/

Docker CE and EE are released quarterly, and CE also has a monthly “Edge” option. Each Docker EE release is supported and maintained for one year and receives security and critical bugfixes during that period. We are also improving Docker CE maintainability by maintaining each quarterly CE release for 4 months. That gets Docker CE users a new 1-month window to update from one version to the next.

01 - Docker 简介

与 kubernetes 结合使用的时候, 要安装经过 kubernetes 官方测试通过的 docker版本, 避免出现不兼容等未知的及不可预估的问题发生, kubernetes 测试过的docker 版本可以在 github 查询, 具体如下:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.
md#external-dependencies

01 - Docker 简介

下载 rpm 包安装

官方 rpm 包下载地址:
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
二进制下载地址:
https://download.docker.com/
https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/
阿里镜像下载地址:
https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/

01 - Docker 简介

通过修改 yum 源安装

[root@docker-server1 ~]# rm -rf /etc/yum.repos.d/*
[root@docker-server1 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo
http://mirrors.aliyun.com/repo/Centos-7.repo
[root@docker-server1 ~]# wget -O /etc/yum.repos.d/epel.repo
http://mirrors.aliyun.com/repo/epel-7.repo
[root@docker-server1 ~]# wget -O /etc/yum.repos.d/docker-ce.repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@docker-server1 ~]# yum install docker-ce

01 - Docker 简介

ubuntu 安装 docker、 启动并验证服务

root@docker-server1:~#apt-get install
docker-ce=5:18.09.9~3-0~ubuntu-bionic
docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic
root@docker-server1:~# systemctl start docker
root@docker-server1:~# systemctl enable docker
验证docker服务启动:

01 - Docker 简介

验证 docker 版本

01 - Docker 简介

验证 docker0 网卡

在 docker 安装启动后, 默认会生成一个名称为 docker0 的网卡并且默认 IP 地址为 172.17.0.1 的网卡。

01 - Docker 简介

验证 docker 信息

root@docker-server1:~# docker info
Containers: 2 #当前主机运行的容器总数
Running: 1 #有几个容器是正在运行的
Paused: 0 #有几个容器是暂停的
Stopped: 1 #有几个容器是停止的
Images: 3 #当前服务器的镜像数
Server Version: 18.09.9 #服务端版本
Storage Driver: overlay2 #正在使用的存储引擎
Backing Filesystem: xfs #后端文件系统, 即服务器的磁盘文件系统
Supports d_type: true #是否支持 d_type
Native Overlay Diff: true #是否支持差异数据存储
Logging Driver: json-file #日志类型
Cgroup Driver: cgroupfs #Cgroups 类型
Plugins: #插件
Volume: local #卷
Network: bridge host macvlan null overlay # overlay 夸主机通信
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk
syslog #日志类型
Swarm: inactive #是否支持 swarm
Runtimes: runc #已安装的容器运行时
Default Runtime: runc #默认使用的容器运行时
Init Binary: docker-init #初始化容器的守护进程, 即 pid 为 1 的进程
containerd version: 894b81a4b802e4eb2a91d1ce216b8817763c29fb #版本
runc version: 425e105d5a03fabd737a126ad93d62a9eeede87f # runc 版本
init version: fec3683 #init 版本
Security Options: #安全选项
Apparmor #安全模块, https://docs.docker.com/engine/security/apparmor/
seccomp #审计(操作), https://docs.docker.com/engine/security/seccomp/
Profile: default #默认的配置文件
Kernel Version: 4.15.0-55-generic #宿主机内核版本
Operating System: Ubuntu 18.04.3 LTS #宿主机操作系统
OSType: linux #宿主机操作系统类型
Architecture: x86_64 #宿主机架构
CPUs: 1 #宿主机 CPU 数量
Total Memory: 1.924GiB #宿主机总内存
Name: docker-server1.magedu.net #宿主机 hostname
ID:
ZFPD:UIA5:SR6E:Y6SS:52QL:5MPT:VDY3:ATVI:QMVG:HAFF:MN74:2HPD #
宿主机 ID
Docker Root Dir: /var/lib/docker #宿主机数据保存目录
Debug Mode (client): false #client 端是否开启 debug
Debug Mode (server): false #server 端是否开启 debug
Registry: https://index.docker.io/v1/ #镜像仓库
Labels: #其他标签
Experimental: false #是否测试版
Insecure Registries: #非安全的镜像仓库
127.0.0.0/8
Live Restore Enabled: false #是否开启活动重启(重启 docker-daemon 不关闭容器)
Product License: Community Engine #产品许可信息
WARNING: No swap limit support #系统警告信息(没有开启 swap 资源限制)
root@docker-server1:~#

解决不支持 swap 限制警告

root@docker-server1:~# vim /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0
cgroup_enable=memory swapaccount=1"
# update-grub
# reboot

docker 存储引擎

目前 docker 的默认存储引擎为 overlay2, 不同的存储引擎需要相应的系统支持,如需要磁盘分区的时候传递 d-type 文件分层功能, 即需要传递内核参数开启格式化磁盘的时候的指定功能。

历史更新信息:
https://github.com/moby/moby/blob/master/CHANGELOG.md
官方文档关于存储引擎的选择文档:
https://docs.docker.com/storage/storagedriver/select-storage-driver/
存储驱动类型:

AUFS(AnotherUnionFS) 是一种 Union FS, 是文件级的存储驱动。 所谓 UnionFS 就是把不同物理位置的目录合并 mount 到同一个目录中。 简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。 这种文件系统可以一层一层地叠加修改文件。 无论底下有多少层都是只读的, 只有最上层的文件系统是可写的。 当需要修改一个文件时, AUFS 创建该文件的一个副本, 使用 CoW 将文件从只读层复制到可写层进行修改, 结果也保存在可写层。 在 Docker 中, 底下的只读层就是 image, 可写层就是 Container, 是 Docker 18.06 及更早版本的首选存储驱动程序, 在内核 3.13 上运行 Ubuntu 14.04 时不支持 overlay2。

Overlay: 一种 Union FS 文件系统, Linux 内核 3.18 后支持。
overlay2: Overlay 的升级版, 到目前为止, 所有 Linux 发行版推荐使用的存储类型。
devicemapper: 是 CentOS 和 RHEL 的推荐存储驱动程序, 因为之前的内核版本不支持 overlay2, 但是当前较新版本的 CentOS 和 RHEL 现在已经支持overlay2, 因此推荐使用 overlay2。
ZFS(Sun-2005)/btrfs(Oracle-2007): 目前没有广泛使用。
vfs: 用于测试环境, 适用于无法使用 copy-on-write 文件系统的情况。 此存储驱动程序的性能很差, 通常不建议用于生产。

Docker 官方推荐首选存储引擎为 overlay2, devicemapper 存在使用空间方面的一些限制, 虽然可以通过后期配置解决, 但是官方依然推荐使用 overlay2, 以下是网上查到的部分资料:
https://www.cnblogs.com/youruncloud/p/5736718.html

01 - Docker 简介

如果 docker 数据目录是一块单独的磁盘分区而且是 xfs 格式的, 那么需要在格式化的时候加上参数-n ftype=1, 否则后期在启动容器的时候会报错不支持 d-type。

01 - Docker 简介
01 - Docker 简介
Centos 7.2 报错界面
01 - Docker 简介
Centos 7.3 修复此问题

docker 服务进程

通过查看 docker 进程, 了解 docker 的运行及工作方式。

查看宿主机进程树

Docker 版本:
Server: Docker Engine - Community
Engine:
Version: 18.09.7
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: 2d0083d
Built: Thu Jun 27 17:26:28 2019
OS/Arch: linux/amd64
Experimental: false
01 - Docker 简介

18.06 及之前的 docker 版本, 进程关系:

01 - Docker 简介
01 - Docker 简介

查看 containerd 进程关系:
有四个进程:

  • dockerd: 被 client 直接访问, 其父进程为宿主机的 systemd 守护进程。
  • docker-proxy: 实现容器通信, 其父进程为 dockerd
  • containerd: 被 dockerd 进程调用以实现与 runc 交互。
  • containerd-shim: 真正运行容器的载体, 其父进程为 containerd。
01 - Docker 简介

containerd-shim 命令使用

[root@node1 ~]# containerd-shim -h
Usage of containerd-shim:
-address string
    grpc address back to main containerd
-containerd-binary containerd publish
    path to containerd binary (used for containerd publish) (default "cont
-criu string
    path to criu binary
-debug
    enable debug output in logs
-namespace string
    namespace that owns the shim
-runtime-root string
    root directory for the runtime (default "/run/containerd/runc")
-socket string
    abstract socket path to serve
-systemd-cgroup
    set runtime to use systemd-cgroup
-workdir string
    path used to storge large temporary data

容器的创建与管理过程

通信流程:
1.dockerd 通过 grpc 和 containerd 模块通信(runc)交换, dockerd 和 containerd通信的 socket 文件: /run/containerd/containerd.sock。
2. containerd 在 dockerd 启动时被启动, 然后 containerd 启动 grpc 请求监听,containerd 处理 grpc 请求, 根据请求做相应动作。
/usr/bin/dockerd -H fd:// –containerd=/run/containerd/containerd.sock
3. 若是创建容器, containerd 拉起一个 container-shim 容器进程 , 并进行相应
的创建操作。
4. container-shim 被拉起后, start/exec/create 拉起 runC 进程, 通过 exit、 control文件和 containerd 通信, 通过父子进程关系和 SIGCHLD(信号)监控容器中进程状态。
5. 在整个容器生命周期中, containerd 通过 epoll 监控容器文件, 监控容器事件。

01 - Docker 简介

grpc 简介:
gRPC 是 Google 开发的一款高性能、 开源和通用的 RPC 框架, 支持众多语言客户端。
https://www.grpc.io/

01 - Docker 简介

docker 镜像加速配置

国内下载国外的镜像有时候会很慢, 因此可以更改 docker 配置文件添加一个加速器, 可以通过加速器达到加速下载镜像的目的。

获取加速地址

浏览器打开 http://cr.console.aliyun.com, 注册或登录阿里云账号, 点击左侧的镜像加速器, 将会得到一个专属的加速地址, 而且下面有使用配置说明:

01 - Docker 简介

生成配置文件

[root@docker-server1 ~]# mkdir -p /etc/docker
[root@docker-server1 ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
> {
> "registry-mirrors": ["https://9916w1ow.mirror.aliyuncs.com"]
> }
> EOF
{
"registry-mirrors": ["https://9916w1ow.mirror.aliyuncs.com"]
} [
root@docker-server1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://9916w1ow.mirror.aliyuncs.com"]
}

重启 docker 服务

[root@docker-server1 ~]# systemctl daemon-reload
[root@docker-server1 ~]# sudo systemctl restart docker

Docker 镜像管理

Docker 镜像含有启动容器所需要的文件系统及所需要的内容, 因此镜像主要用于创建并启动 docker 容器。
Docker 镜像含里面是一层层文件系统,叫做 Union File System(Union FS 联合文件系统) , 2004 年由纽约州立大学石溪分校开发, 联合文件系统可以将多个目录挂载到一起从而形成一整个虚拟文件系统, 该虚拟文件系统的目录结构就像普通 linux 的目录结构一样, docker 通过这些文件再加上宿主机的内核提供了一个 linux 的虚拟环境,每一层文件系统我们叫做一层 layer, 联合文件系统可以对每一层文件系统设置三种权限, 只读(readonly) 、 读写(readwrite) 和写出(whiteout-able) , 但是 docker 镜像中每一层文件系统都是只读的,构建镜像的时候,从一个最基本的操作系统开始,每个构建的操作都相当于做一层的修改,增加了一层文件系统,一层层往上叠加,上层的修改会覆盖底层该位置的可见性,这也很容易理解, 就像上层把底层遮住了一样,当使用镜像的时候, 我们只会看到一个完全的整体, 不知道里面有几层也不需要知道里面有几层, 结构如下:

01 - Docker 简介
# pwd
/usr/local/src
#mkdir a b system
#touch a/a.txt b/b.txt
#mount -t aufs -o dirs=./a:./b none ./system/
#tree system/
system/
├── a.txt
└── b.txt
0 directories, 2 file

一个典型的 Linux 文件系统由 bootfs 和 rootfs 两部分组成, bootfs(boot file system) 主要包含 bootloader 和 kernel, bootloader 主要用于引导加载 kernel,当 kernel 被加载到内存中后 bootfs 会被 umount 掉, rootfs (root file system)包含的就是典型 Linux 系统中的/dev, /proc, /bin, /etc 等标准目录和文件,下图就是 docker image 中最基础的两层结构, 不同的 linux 发行版(如ubuntu 和 CentOS ) 在 rootfs 这一层会有所区别。
但是对于 docker 镜像通常都比较小, 官方提供的 centos 基础镜像在 200MB 左右, 一些其他版本的镜像甚至只有几 MB, docker 镜像直接调用宿主机的内核,镜像中只提供 rootfs, 也就是只需要包括最基本的命令、 工具和程序库就可以了, 比如alpine 镜像, 在 5M 左右。
下图就是有两个不同的镜像在一个宿主机内核上实现不同的 rootfs。

01 - Docker 简介

容器、 镜像父镜像:

01 - Docker 简介

docker 命令是最常使用的 docker 客户端命令, 其后面可以加不同的参数以实现相应的功能, 常用的命令如下:

搜索镜像

在官方的 docker 仓库中搜索指定名称的 docker 镜像, 也会有很多镜像。
[root@docker-server1 ~]# docker search centos:7.2.1511 #带指定版本号
[root@docker-server1 ~]# docker search centos #不带版本号默认 latest

01 - Docker 简介

下载镜像

从 docker 仓库将镜像下载到本地, 命令格式如下:

# docker pull 仓库服务器:端口/项目名称/镜像名称:tag(版本)号
[root@docker-server1 ~]# docker pull alpine
[root@docker-server1 ~]# docker pull nginx
[root@docker-server1 ~]# docker pull hello-world
[root@docker-server1 ~]# docker pull centos
01 - Docker 简介

查看本地镜像

#下载完成的镜像比下载的大, 因为下载完成后会解压

[root@docker-server1 ~]# docker images
01 - Docker 简介

REPOSITORY #镜像所属的仓库名称

TAG#镜像版本号(标识符) , 默认为 latest
IMAGE ID#镜像唯一 ID 标示
CREATED#镜像创建时间
VIRTUAL SIZE#镜像的大小

镜像导出

可以将镜像从本地导出问为一个压缩文件, 然后复制到其他服务器进行导入使用。

#导出方法 1:
[root@docker-server1 ~]# docker save centos -o /opt/centos.tar.gz
[root@docker-server1 ~]# ll /opt/centos.tar.gz
-rw------- 1 root root 205225472 Nov 1 03:52 /opt/centos.tar.gz
#导出方法 2:
[root@docker-server1 ~]# docker save centos > /opt/centos-1.tar.gz
[root@docker-server1 ~]# ll /opt/centos-1.tar.gz
-rw-r--r-- 1 root root 205225472 Nov 1 03:52 /opt/centos-1.tar.gz
#查看镜像内容:
[root@docker-server1 ~]# cd /opt/
[root@docker-server1 opt]# tar xvf centos.tar.gz
[root@docker-server1 opt]# cat manifest.json #包含了镜像的相关配置, 配置文件、 分层
[{"Config":"196e0ce0c9fbb31da595b893dd39bc9fd4aa78a474bbdc21459a3ebe855b7768.json","RepoTags":["docker.io/centos:latest"],"Layers":["892eb
b5d1299cbf459f67aa070f29fdc6d83f4025c58c090e9a69bd4f7af436b/layer.tar"]}]

#分层为了方便文件的共用, 即相同的文件可以共用:
[{“Config”:” 配 置 文 件 .json”,”RepoTags”:[“docker.io/nginx:latest”],”Layers”:[“分层 1/layer.tar”,”分层 2 /layer.tar”,”分层 3 /layer.tar”]}]

镜像导入

将镜像导入到 docker

[root@docker-server1 ~]# scp /opt/centos.tar.gz 192.168.10.206:/opt/
[root@docker-server2 ~]# docker load < /opt/centos.tar.gz
01 - Docker 简介

删除镜像

[root@docker-server1 opt]# docker rmi centos
01 - Docker 简介

#获取运行参数帮助

[root@linux-docker opt]# docker daemon –help

总结: 企业使用镜像及常见操作:搜索、 下载、 导出、 导入、 删除

命令总结

  • # docker load -i centos-latest.tar.xz #导入本地镜像
  • # docker save > /opt/centos.tar #centos #导出镜像
  • # docker rmi 镜像 ID/镜像名称 #删除指定 ID 的镜像, 通过镜像启动容器的
  • 时候镜像不能被删除, 除非将容器全部关闭
  • # docker rm 容器 ID/容器名称 #删除容器
  • # docker rm 容器 ID/容器名-f #强制删除正在运行的容器

容器操作基础命令

命令格式:
# docker run [选项] [镜像名] [shell 命令] [参数]
# docker run [参数选项] [镜像名称, 必须在所有选项的后面] [/bin/echo ‘hello wold’] #单次执行, 没有自定义容器名称
# docker run centos /bin/echo ‘hello wold’ #启动的容器在执行完 shel 命令就退出了

从镜像启动一个容器

会直接进入到容器, 并随机生成容器 ID 和名称
[root@docker-server1 ~]# docker run -it docker.io/centos bash
[root@11445b3a84d3 /]#
#退出容器不注销
ctrl+p+q

显示正在运行的容器

[root@linux-docker ~]# docker ps

01 - Docker 简介

显示所有容器

包括当前正在运行以及已经关闭的所有容器:
[root@linux-docker ~]# docker ps -a

删除运行中的容器

即使容正在运行当中, 也会被强制删除掉
[root@docker-server1 ~]# docker rm -f 11445b3a84d3

01 - Docker 简介

随机映射端口

[root@docker-server1 ~]# docker pull nginx #下载 nginx 镜像
[root@docker-server1 ~]# docker run -P docker.io/nginx #前台启动并随机映

射本地端口到容器的 80
#前台启动的会话窗口无法进行其他操作, 除非退出, 但是退出后容器也会退出。

01 - Docker 简介

#随机端口映射, 其实是默认从 32768 开始

01 - Docker 简介

#访问端口

01 - Docker 简介

指定端口映射

方式 1: 本地端口 81 映射到容器 80 端口:
# docker run -p 81:80 –name nginx-test-port1 nginx
方式 2: 本地 IP:本地端口:容器端口
# docker run -p 192.168.10.205:82:80 –name nginx-test-port2
docker.io/nginx
方式 3: 本地 IP:本地随机端口:容器端口
# docker run -p 192.168.10.205::80 –name nginx-test-port3
docker.io/nginx
方式 4: 本机 ip:本地端口:容器端口/协议, 默认为 tcp 协议
# docker run -p 192.168.10.205:83:80/udp –name nginx-test-port4
docker.io/nginx
方式 5: 一次性映射多个端口+协议:
# docker run -p 86:80/tcp -p 443:443/tcp -p 53:53/udp –name
nginx-test-port5 docker.io/nginx

01 - Docker 简介
#查看 Nginx 容器访问日志:
[root@docker-server1 ~]# docker logs nginx-test-port3 #一次查看
[root@docker-server1 ~]# docker logs -f nginx-test-port3 #持续查看

查看容器已经映射的端口

[root@docker-server1 ~]# docker port nginx-test-port5
01 - Docker 简介

自定义容器名称

[root@docker-server1 ~]# docker run -it --name nginx-test nginx
01 - Docker 简介

后台启动容器

[root@docker-server1 ~]# docker run -d -P --name nginx-test1 docker.io/nginx 9aaad776850bc06f516a770d42698e3b8f4ccce30d4b142f102ed3cb34399b31
01 - Docker 简介

创建并进入容器

[root@docker-server1 ~]# docker run -t -i --name test-centos2docker.io/centos /bin/bash
[root@a8fb69e71c73 /]# #创建容器后直接进入, 执行 exit 退出后容器关闭
01 - Docker 简介
[root@docker-server1 ~]# docker run -d --name centos-test1docker.io/centos2cbbec43ba939476d798a5e1c454dd62d4d893ee12a09b587556ba6395353152

单次运行

容器退出后自动删除:

[root@linux-docker opt]# docker run -it --rm --name nginx-delete-testdocker.io/nginx

传递运行命令

容器需要有一个前台运行的进程才能保持容器的运行, 通过传递运行参数是一种方式, 另外也可以在构建镜像的时候指定容器启动时运行的前台命令。

[root@docker-server1 ~]# docker run -d centos /usr/bin/tail -f '/etc/hosts
01 - Docker 简介

容器的启动和关闭

[root@docker-server1 ~]# docker stop f821d0cd5a99
[root@docker-server1 ~]# docker start f821d0cd5a99

进入到正在运行的容器

使用 attach 命令

#使用方式为 docker attach 容器名, attach 类似于 vnc, 操作会在各个容器界面显示, 所有使用此方式进入容器的操作都是同步显示的且 exit 后容器将被关闭, 且使用 exit 退出后容器关闭, 不推荐使用, 需要进入到有 shell 环境的容器,比如 centos 为例:

[root@s1 ~]# docker run -it centos bash
[root@63fbc2d5a3ec /]#
[root@s1 ~]# docker attach 63fbc2d5a3ec
[root@63fbc2d5a3ec /]#

在另外一个窗口启动测试页面是否同步

01 - Docker 简介

使用 exec 命令:

执行单次命令与进入容器, 不是很推荐此方式, 虽然 exit 退出容器还在运行。

01 - Docker 简介

使用 nsenter 命令:

推荐使用此方式, nsenter 命令需要通过 PID 进入到容器内部, 不过可以使用 docker inspect 获取到容器的 PID:

[root@docker-server1 ~]# yum install util-linux #安装 nsenter 命令
[root@docker-server1 ~]# docker inspect -f "{{.NetworkSettings.IPAddress}}" 91fc190cb538
172.17.0.2
[root@docker-server1 ~]# docker inspect -f "{{.State.Pid}}" mydocker #获取到某个 docker 容器的 PID, 可以通过 PID 进入到容器内
[root@docker-server1 ~]# docker inspect -f "{{.State.Pid}}" centos-test35892
[root@docker-server1 ~]# nsenter -t 5892 -m -u -i -n -p
[root@66f511bb15af /]# ls

脚本方式:

将 nsenter 命令写入到脚本进行调用, 如下:

[root@docker-server1 ~]# cat docker-in.sh
#!/bin/bash
docker_in(){
  NAME_ID=$1
  PID=$(docker inspect -f "{{.State.Pid}}" ${NAME_ID})
  nsenter -t ${PID} -m -u -i -n -p
}
docker_in $1
#测试脚本是否可以正常进入到容器且退出后仍然正常运行:
[root@docker-server1 ~]# chmod a+x docker-in.sh
[root@docker-server1 ~]# ./docker-in.sh centos-test3
[root@66f511bb15af /]# pwd
/
[root@66f511bb15af /]# exit
logout
[root@docker-server1 ~]# ./docker-in.sh centos-test3
[root@66f511bb15af /]# exit
Logout
01 - Docker 简介

查看容器内部的 hosts 文件

[root@docker-server1 ~]# docker run -i -t --name test-centos3
docker.io/centos /bin/bash
[root@056bb4928b64 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4 056bb4928b64 #默认会将实例的 ID 添加到自己的 hosts 文件

#ping 容器 ID:

01 - Docker 简介

批量关闭正在运行的容器

[root@docker-server1 ~]# docker stop $(docker ps -a -q) #正常关闭所有运行中的容器
01 - Docker 简介

批量强制关闭正在运行的容器

[root@docker-server1 ~]# docker kill $(docker ps -a -q) #强制关闭所有运行中的容器
01 - Docker 简介

批量删除已退出容器

[root@docker-server1 ~]# docker rm -f `docker ps -aq -f status=exited`
01 - Docker 简介

批量删除所有容器

[root@docker-server1 ~]# docker rm -f $(docker ps -a -q)
01 - Docker 简介

指定容器 DNS

Dns 服务, 默认采用宿主机的 dns 地址
一是将 dns 地址配置在宿主机
二是将参数配置在 docker 启动脚本里面 –dns=1.1.1.1

其他命令

# docker update 容器 --cpus 2 #更新容器配置信息
# docker events #获取 dockerd 的实时事件
2020-05-12T08:26:37.116277036+08:00 container create
ba55fe25733c123e7bf9ab5a8bcb78ddb83d864e2f012a2f0098c9bb9e4a66f2
(image=busybox, name=nifty_elgamal)
2020-05-12T08:26:37.118436296+08:00 container attach
ba55fe25733c123e7bf9ab5a8bcb78ddb83d864e2f012a2f0098c9bb9e4a66f2
(image=busybox, name=nifty_elgamal)
root@docker-node1:~# docker stop f8ae0c8dcaf8
f8ae0c8dcaf8
root@docker-node1:~# docker wait f8ae0c8dcaf8 #显示容器的退出状态码
137
# docker diff f8ae0c8dcaf8 #检查容器更改过的文件或目录
[root@docker-server1 ~]# docker run -it --rm --dns 223.6.6.6 centos bash
[root@afeb628bf074 /]# cat /etc/resolv.conf
nameserver 223.6.6.6






本文版权归个人技术分享站点所有,发布者:chaoqiang,转转请注明出处:https://www.zhengchaoqiang.com/2004.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
chaoqiangchaoqiang
上一篇 2022-06-12 12:43
下一篇 2022-07-06 09:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

近期个人博客正在迁移中,原博客请移步此处,抱歉!