一、Docker的核心概念
Docker是一款以容器虚拟化技术为基础的软件。
1、核心概念
- 镜像:类似于虚拟机镜像,可以理解为一个面向Docker引擎的只读模板,包含了文件系统。 镜像(Image)是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一条十分简单的机制来创建和更新现有的镜像。
- 容器:container类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。Container是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而容器Container之间都是相互隔离、互不可见的。 镜像自身是只读的。容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身将保持不变。
- 仓库:Repository类似于代码仓库,是Docker集中存放镜像文件的场所。 每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。 根据存储的镜像公开与否,Docker仓库可以分为公开仓库和私有仓库两种形式。
2、Docker虚拟化与普通虚拟化
虚拟化 | 区别 |
---|---|
普通虚拟化 | 在宿主机上虚拟出一套硬件后,再运行一个完整操作系统,在该系统上再运行所需应用进程,启动时间长,占用资源多 |
Docker虚拟化 | 直接运行于宿主机的内核,容器内没有自己的内核,而且也没有进行硬件虚拟,每个容器有自己的文件系统,互不干扰,启动时间块,资源占用少,可灵活分配资源 |
在实际应用场景中,虚拟化还能进行更细化的分类,比如
- 平台虚拟化:在操作系统和硬件平台间搭建虚拟化设施,使得整个操作系统都运行在虚拟后的环境中。
- 应用程序虚拟化:在操作系统和应用程序间实现虚拟化,只让应用程序运行在虚拟化环境中。
- 内存虚拟化:将不相邻的内存区,甚至硬盘空间虚拟成统一连续的内存地址。
- 桌面虚拟化:让本地桌面程序利用远程计算机资源运行,达到控制远程计算机的目的。
二、Docker 配置及安装
本文档基于centos7 环境下进行
1、安装软件
1、软件源安装
# yum install -y yum-utils device-mapper-persistent-data lvm2
# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
2、脚本安装
官方安装脚本
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
daocloud 一键安装命令
curl -sSL https://get.daocloud.io/docker | sh
3、离线安装
1、rpm安装
1、在有docker软件源的机器上下载全量依赖
# yum -y install yum-utils
# mkdir docker
# cd docker
# repotrack docker-ce
2、传输到离线环境后安装
# rpm -Uvh --force --nodeps *.rpm
参数 | 说明 |
---|---|
--force | 强制安装 |
--nodeps | 安装时不检查依赖关系 |
2、二进制安装
1、下载 Docker 二进制文件(离线安装包)
下载地址:https://download.docker.com/linux/static/stable/x86_64/
# wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.9.tgz
# tar -xzvf docker-20.10.9.tgz
docker/
docker/docker
docker/runc
docker/ctr
docker/dockerd
docker/docker-init
docker/docker-proxy
docker/containerd-shim-runc-v2
docker/containerd-shim
docker/containerd
# cp docker/* /usr/bin/
2、注册为系统服务
# vim /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
# chmod +x /usr/lib/systemd/system/docker.service
# systemctl daemon-reload
# systemctl enable docker.service
# systemctl start docker
查看docker进程日志
# journalctl -fu docker.service
# systemctl status docker
2、配置加速源
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{ "debug" : true,
"max-concurrent-downloads": 10,
"log-opts": { "max-size": "300m", "max-file": "2" },
"exec-opts": ["native.cgroupdriver=systemd"],
"max-concurrent-downloads": 10, "max-concurrent-uploads": 5,
"storage-driver": "overlay2",
"insecure-registries": ["registry.access.redhat.com","quay.io"],
"experimental" : true,
"data-root" : "/data/docker",
"live-restore": true,
"registry-mirrors": [
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://12azv802.mirror.aliyuncs.com",
"https://mirror.ccs.tencentyun.com",
"https://7ceef9d15a664728bce5f046598c7007.mirror.swr.myhuaweicloud.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
参数 | 说明 |
---|---|
registry-mirrors | 镜像源 |
max-concurrent-downloads | 上传为3个并发 |
max-concurrent-uploads | 下载为5个并发 |
log-opts | log日志设置 |
max-size | 限制单个日志文件为300M |
max-file | 最多产生2个日志文件 |
live-restore | Docker守护进程中断期间保持Docker运行 |
multiline | 配置多行识别(默认最多128行),转为单行 |
firstline | 表示单条日志的首行正则表达式 |
debug | 开启Debug模式 |
exec-opts | 额外的参数,cgroup driver设置成systemd(cgroup2默认为systemd) |
experimental | 启用实验功能 |
data-root | 工作目录(graph已在docker23.0版本正式弃用,由data-root替换) |
storage-driver | 存储驱动 |
insecure-registries | 私有仓库 |
当我们处于国内网络中,那么在访问一些境外的docker镜像网站时,可能会遇到网络传输速度较慢,尤其是在拉取镜像时,那么您可以通过配置为指定一个国内的镜像地址,来加速镜像拉取速度,例如:
镜像加速器 | 镜像加速器地址 | 专属加速器? | 其它加速? |
---|---|---|---|
https://registry.docker-cn.com | |||
DaoCloud 镜像站 | https://docker.m.daocloud.io | Docker Hub、GCR、K8S、GHCR、Quay、NVCR 等 | |
Azure 中国镜像 | https://dockerhub.azk8s.cn | 仅供内部访问 | Docker Hub、GCR、Quay |
科大镜像站 | https://docker.mirrors.ustc.edu.cn | 仅供内部访问 | Docker Hub、GCR、Quay |
阿里云 | https://<your_code>.mirror.aliyuncs.com | 需登录,系统分配 | Docker Hub |
https://reg-mirror.qiniu.com | |||
https://hub-mirror.c.163.com | |||
腾讯云 | https://mirror.ccs.tencentyun.com | 仅供内部访问 | Docker Hub |
Docker 镜像代理 | https://dockerproxy.com | Docker Hub、GCR、K8S、GHCR | |
百度云 | https://mirror.baidubce.com | Docker Hub | |
南京大学镜像站 | https://docker.nju.edu.cn | Docker Hub、GCR、GHCR、Quay、NVCR 等 | |
上海交大镜像站 | https://docker.mirrors.sjtug.sjtu.edu.cn | 已下架 | Docker Hub、GCR 等 |
中科院软件所镜像站 | https://mirror.iscas.ac.cn | Docker Hub |
参考:https://gist.github.com/y0ngb1n/7e8f16af3242c7815e7ca2f0833d3ea6
1、阿里云加速器获取方法
首先您必须先拥有一个镜像加速地址,您可以通过注册阿里云账号来获取免费的镜像加速服务。(这里假设您已经注册并登录)
可以点击“控制台”进入您的控制台首页
然后点击右上角“菜单”按钮,选择“产品与服务”->“容器镜像服务”
然后在“镜像工具”中找到“镜像加速器”,然后您会在该页面获得您的专属加速器地址,并会给出具体配置方法。
您可以将上面的内容复制,然后使用vim命令打开以下文件(如果没有则创建),并写入以下内容(注意红色字体,您的加速器地址可能在此处与本文中有所不同,请填写您从阿里云获得的真实加速器地址)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://12azv802.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2、华为云加速器获取方法
首先您必须先拥有一个镜像加速地址,您可以通过注册华为云账号来获取免费的镜像加速服务。(这里假设您已经注册并登录)
然后点击左上角“产品”按钮,选择“容器”->“容器镜像服务 SWR”
然后在“镜像中心”中找到“镜像加速器”,然后您会在该页面获得您的专属加速器地址,并会给出具体配置方法。
{
"registry-mirrors": [ "https://7ceef9d15a664728bce5f046598c7007.mirror.swr.myhuaweicloud.com" ]
}
3、使用其他镜像源
仓库地址 | 镜像地址 | 备注 |
gcr.io | gcr.nju.edu.cn | 南京大学开源镜像站,nexus3 |
gcr.tencentcloudcr.com | 仅腾讯云vpc内部访问,registry2 proxy | |
registry.k8s.io | registry-k8s-io.mirrors.sjtug.sjtu.edu.cn | 上海交通大学,registry2 proxy |
k8s.nju.edu.cn | 南京大学开源镜像站,nexus3 | |
k8s.gcr.io | gcr.nju.edu.cngoogle-containers | 南京大学开源镜像站,nexus3 |
k8s.tencentclouacr.com | 仅腾讯,云vpc内部访问,registry2 proxy | |
quay.io | quay.nju.edu.cn | 南京大学开源镜像站,nexus3 |
quay.tencentcloudcr.com | 仅腾讯云vpc内部访问,registry2 proxy | |
nvcr.io | nver.nju.edu.cn | 南京大学开源镜像站,nexus3 |
nvcr.tencentcloudcr.com | 仅腾讯云vpc内部访问,registry2 proxy | |
docker.io | mirror.ccs.tencentyun.com | 仅腾讯云vpc内部访问,registry2 proxy |
docker.nju.edu.cn | 南京大学开源镜像站,nexus3 | |
docker.mirrors.situg.situ.edu.cn | 上海交通大学,registry2 proxy | |
docker.m.daocloud.io | 国内可用,带宽低 | |
hub-mirror.c.163.com | 国内可用,更新慢 | |
******.mirror.aliyuncs.com | 国内可用,更新慢 |
4、开启路由转发功能
由于docker自身会创建一个网络,叫做bridge,跟系统的docker0是一个东西,在主机映射的端口是在系统的eth0上,这时候就需要开启IP转发,来将映射到主机IP:port的流量转发到bridge(docker0)上来。
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# sysctl -p
三、隔离与限制
1、Namespace
作用 | |
---|---|
Namespace | 实现了容器与宿主机、容器与容器之间的隔离 |
cgroup | 限制docker容器对宿主机资源的使用 |
Namespace的六项隔离 | 说明 |
---|---|
IPC | 共享内存、消息列队 |
MNT | 挂载点、文件系统 |
NET | 网络栈 |
PID | 进程编号 |
USER | 用户、组 |
UTS | 主机名、域名 |
2、Cgroup
CGroups是control groups的缩写,顾名思义就是把进程放到一个组里面统一加以控制,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO等等)的机制。CGroups为容器实现虚拟化提供了基本保证,是构建Docker等一系列虚拟化管理工具的基石。
CGroups提供了以下功能:
- 资源列表限制(Resource Limitation):CGroups可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(Out of Memory)。
优先 - 列表级分配(Prioritization):通过分配的CPU时间片数量及硬盘IO带宽大小,实际上就相当于控制了进程运行的优先级。
资 - 列表源统计(Accounting): CGroups可以统计系统的资源使用量,如CPU使用时长、内存用量等等,这个功能非常适用于计费。
进程 - 列表控制(Control):CGroups可以对进程组执行挂起、恢复等操作。
1、CGrooups V1的不足
1、多层级(hierarchy)设计导致进程的管理较为混乱
CGroups v1为了提供灵活性,允许进程可以属于多个层级的不同控制组,但实际上,这种多层级除了增加代码的复杂度和理解困难外,并没有太大用处,因为子系统只能属于一个层级。一方面,跟踪进程所有controller变得复杂;另外,各个controller之间也很难协同工作(因为controller可能属于不同的hierarchy)。所以,在实际使用中,通常是每个层级一个controller。
2、blkio子系统无法对buffer IO进行限制
CGroups v1的blkio子系统只支持sync IO和direct IO,对于buffer IO,由于内核先将数据拷贝到page cache,然后再由后台内核线程定期刷到磁盘,因此对于控制层而言所有的blockIO操作都是内核flush线程发起的,导致无法进行IO限制。
此问题在4.2版本的内核中被CGroups的维护人员以补丁修复。
3、内存子系统资源限制手段比较粗犷
CGroups v1内存控制器直接基于设定的资源使用阈值进行控制,而且比较粗犷,比如,memory子系统,根据memory.oom_control的设置,当任务使用的内存超过界限是,只有结束任务(默认动作)或者任务挂起两种动作。这种模式当有些任务的资源需求会出现峰值的时候影响比较大。
4、事件通知机制不完善
CGroups v1每次进行事件通知都是通过fork和exec一个用户层帮助程序(userland helper binary)完成的,开销相对较大。这种设计也导致在内核内部的事件传递过滤机制更加复杂。
5、控制器之间行为不一致、接口不统一
CGroups v1当新创建一个控制组的时候,有些控制器默认不会新增额外的限制,而有一些控制器则禁止任何资源的申请,需要用户手工配置。此外,不同控制器之间相同类型的控制模块命名方式、格式和单位很多都不一致,同样问题在统计和信息模块也存在,同时不同控制器的API比较混乱。
6、基于线程的控制粒度
CGroups v1允许一个进程的各个线程属于不同的控制组,这种设计表明上增加了灵活性,但这和多层级的设计类似,除了增加操作、接口和代码实现的复杂度之外,实际上并没有什么用处。此外,如果一个进程的不同线程分属于同一层级的不同控制组,那么会引入资源竞争的问题,而且多数子系统对于这种行为是没有定义的,因此如果用户真的那么用了,那结果就不可知了。
2、CGroups V2
基于v1上述一些不足,CGroups的维护人员重新设计并开发了CGroups v2,并在2016年3月合入了linux内核4.5版本, v2的主要设计思想有以下三点:
- 单一层级代替多层级
- 基于进程粒度进行控制,而不是线程
- 聚焦于简单、清晰的使用与实现,而不是“极限的”灵活性
Docker 从 Docker 20.10 开始支持 cgroup v2。在 cgroup v2 上运行 Docker 还需要满足以下条件:
- containerd:v1.4 或更高版本
- runc: v1.0.0-rc91 或更高版本
- 内核:v4.15或更高版本(推荐v5.2或更高版本)
请注意,cgroup v2 模式的行为与 cgroup v1 模式略有不同:
- 默认的 cgroup 驱动程序 (
dockerd --exec-opt native.cgroupdriver
) 在 v2 上是“systemd”,在 v1 上是“cgroupfs”。 - 默认的 cgroup 命名空间模式 (
docker run --cgroupns
) 在 v2 上是“private”,在 v1 上是“host”。 docker run
标志--oom-kill-disable
和--kernel-memory
在 v2 上被丢弃。
评论区