Docker-基础
Docker 是一个开源的应用容器引擎,基于 Go 语言开发。它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
核心概念
容器是轻量级的独立运行环境,镜像如同“模具”,容器则是“糕点”,共享宿主机内核,比虚拟机更高效。
- 镜像(Image):
- 容器的模板(类比:模具)
- 分层存储结构
- 包含应用代码+运行环境
- 容器(Container):
- 独立的软件运行环境
- 共享宿主机系统内核(与虚拟机本质区别)
- 轻量级、启动快(秒级)
- 仓库(Repository):
- Docker Hub:官方镜像仓库
- 镜像命名规范:
[registry]/[namespace]/[image]:[tag] - 常用镜像站解决网络问题
容器与VM区别
用容器化技术给应用程序封装独立的运行环境。 每个运行环境就是一个容器,运行容器的计算机被称为宿主机。Docker容器与虚拟机的最大区别是,Docker容器之间共用同一个系统内核, 而每个虚拟机都包含一个操作系统的完整内核, 所以Docker容器比虚拟机更轻、更小,启动速度更快。
VM
+-------------------+-------------------+-------------------+
| App 1 | App 2 | App 3 |
+-------------------+-------------------+-------------------+
| Guest OS | Guest OS | Guest OS |
+-----------------------------------------------------------+
| Hypervisor (虚拟机监视器) |
+-----------------------------------------------------------+
| Host Operating System |
+-----------------------------------------------------------+
| Hardware |
+-----------------------------------------------------------+利用 Hypervisor 虚拟化技术来模拟CPU、内存等硬件资源,这样就可以在宿主机上建立一个CentOS ,这是常说的安装一个虚拟机。每一个虚拟机都有一个独立的内核,比如 Ubuntu、CentOS 甚至是 Windows 等,在这样的虚拟机之下,每个应用都是相互独立的,VM 可以提供一个更好的隔离效果。但这样的隔离效果需要付出一定的代价,因为需要把一部分的计算资源交给虚拟化,这样就很难充分利用现有的计算资源,并且每个虚拟机都需要占用大量的磁盘空间,比如 Windows 操作系统的安装需要 10~30G 的磁盘空间,Ubuntu 也需要 5~6G,同时这样的方式启动很慢。正是因为虚拟机技术的缺点,催生出了容器技术。
容器
+-------------------+-------------------+-------------------+
| Container 1 | Container 2 | Container 3 |
| (App + Deps) | (App + Deps) | (App + Deps) |
+-----------------------------------------------------------+
| Container Runtime (如Docker) |
+-----------------------------------------------------------+
| Host Operating System |
+-----------------------------------------------------------+
| Hardware |
+-----------------------------------------------------------+是针对于进程而言的,因此无需虚拟机 ,只需要一个独立的文件系统提供其所需要文件集合即可。所有的文件隔离都是进程级别的,因此启动时间快于 VM,并且所需的磁盘空间也小于 VM。当然了,进程级别的隔离并没有想象中的那么好,隔离效果相比 VM 要差很多。
主要区别对比
| 特性 | 容器 (Docker等) | 虚拟机 (VMware, VirtualBox等) |
|---|---|---|
| 虚拟化级别 | 操作系统级虚拟化 | 硬件级虚拟化 |
| 隔离性 | 进程级别隔离(较弱) | 完全隔离(更强) |
| 启动速度 | 秒级(非常快) | 分钟级(较慢) |
| 性能 | 接近原生性能 | 有性能损耗(约5-15%) |
| 资源占用 | 非常小(共享主机内核) | 较大(每个VM需要完整OS) |
| 镜像大小 | 通常为MB级别 | 通常为GB级别 |
| 可移植性 | 高(跨平台需相同OS内核) | 高(完全独立) |
| 安全性 | 较弱(共享内核) | 强(完全隔离) |
| 部署密度 | 高(可部署更多实例) | 低(资源占用大) |
| 典型用途 | 微服务、CI/CD、云原生应用 | 传统应用、需要完全隔离的环境 |
- 虚拟化方式不同
- 虚拟机: 虚拟化硬件,每个VM运行完整的操作系统
- 容器: 虚拟化操作系统,共享主机内核
- 资源利用率
- 容器共享主机内核,无需为每个实例加载完整OS,资源利用率高
- 虚拟机需要为每个实例分配完整OS资源,开销大
- 启动时间
- 容器启动只需启动进程,非常快速
- 虚拟机需要启动完整操作系统,较慢
- 隔离性
- 虚拟机提供完全的硬件级隔离,安全性更高
- 容器是进程级隔离,共享内核,存在潜在安全风险
- 可移植性
- 容器镜像更小,更易于迁移
- 虚拟机镜像包含完整OS,体积大
Docker的隔离原理
Docker主要就是借助 Linux 内核技术Namespace来做到隔离的,Linux Namespaces机制提供一种资源隔离方案。PID,IPC,Network等系统资源不再是全局性的,而是属于某个特定的Namespace。每个namespace下的资源对于其他namespace下的资源都是透明,不可见的。因此在操作系统层面上看,就会出现多个相同pid的进程。系统中可以同时存在两个进程号为0,1,2的进程,由于属于不同的namespace,所以它们之间并不冲突。而在用户层面上只能看到属于用户自己namespace下的资源,例如使用ps命令只能列出自己namespace下的进程。这样每个namespace看上去就像一个单独的Linux系统。
namespace命令空间的隔离
| 命名空间类型 | 系统调用参数 | 隔离内容 | 备注 |
|---|---|---|---|
| UTS | CLONE_NEWUTS | 主机名和域名 (hostname 和 domainname) | 允许容器拥有独立的主机标识 |
| IPC | CLONE_NEWIPC | 进程间通信资源:信号量(Semaphore)、消息队列(Message Queue)、共享内存(Shared Memory) | 防止跨命名空间的进程通信 |
| PID | CLONE_NEWPID | 进程编号(PID),容器内进程从1开始编号 | 容器内只能看到自己的进程树 |
| Network | CLONE_NEWNET | 网络设备、网络协议栈、端口、路由表、防火墙规则等 | 容器拥有独立的网络环境(需配合虚拟网卡) |
| Mount | CLONE_NEWNS | 文件系统挂载点(Mount Points) | NS 表示"Namespace",是历史上第一个实现的命名空间 |
| User | CLONE_NEWUSER | 用户和用户组ID映射(UID/GID) | 允许容器内用户以非root身份映射到宿主机的非root用户 |
| Cgroup | CLONE_NEWCGROUP | 控制组(Cgroup)资源限制 | Linux 4.6+ 引入,隔离资源限制视图 |
| Time | CLONE_NEWTIME | 系统时钟(Boot Time和Monotonic Time) | Linux 5.6+ 引入,允许容器修改系统时间 |
资源限制(cgroup)
- 资源限制:限制任务使用的资源总额,并在超过这个 配额 时发出提示
- 优先级分配:分配CPU时间片数量及磁盘IO带宽大小、控制任务运行的优先级
- 资源统计:统计系统资源使用量,如CPU使用时长、内存用量等
- 任务控制:对任务执行挂起、恢复等操作
- 容器与镜像的关系类似于面向对象编程中的对象与类。
Docker-部署
yum安装
卸载旧版本
若您安装过docker,需要先删掉,之后再安装依赖:
sudo yum -y remove docker docker-common docker-selinux docker-engine
sudo yum -y install yum-utils device-mapper-persistent-data lvm2安装 Docker
openEuler源
# 注册openEuler
dnf config-manager --add-repo https://repo.openeuler.openatom.cn/openEuler-24.03-LTS/update/x86_64/
# 安装
dnf -y install docker docker-compose-pluginhuaweicloud源
# 下载repo文件(也可选注册repo方式)
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo
# 注册华为repo
dnf config-manager --add-repo=https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo
# 软件仓库地址替换
sudo sed -i 's+download.docker.com+mirrors.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# 替换centos识别版本号
sed -i 's+$releasever+9+' /etc/yum.repos.d/docker-ce.repo
# 安装docker-ce和依赖
dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginaliyun源
# 安装必要的一些系统工具(Cent系列需要安装)
yum install -y yum-utils
# 添加软件源信息
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 替换centos识别版本号
sed -i 's+$releasever+9+' /etc/yum.repos.d/docker-ce.repo
# 安装Docker
dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Step 4: 开启Docker服务
systemctl start docker
# 注意:
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
# 将[docker-ce-test]下方的enabled=0修改为enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
# Loading mirror speeds from cached hostfile
# Loaded plugins: branch, fastestmirror, langpacks
# docker-ce.x86_64 17.03.1.ce-1.el7.centos docker-ce-stable
# docker-ce.x86_64 17.03.1.ce-1.el7.centos @docker-ce-stable
# docker-ce.x86_64 17.03.0.ce-1.el7.centos docker-ce-stable
# Available Packages
# Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]启动
systemctl daemon-reload
systemctl enable docker --now离线部署Docker
下载离线包
wget https://download.docker.com/linux/static/stable/x86_64/docker-28.2.2.tgz
# 解压缩
tar -zxvf docker-28.2.2.tgz -C /usr/local
# 移动文件
cp /usr/local/docker/* /usr/bin/注册daemon
cat >> /etc/systemd/system/docker.service << EOF
[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
EOF赋权启动
chmod +x /etc/systemd/system/docker.service
systemctl daemon-reload
systemctl enable docker --now官方shell脚本
# 打不开情况下需要科学上网方式
curl -fsSL https://get.docker.com -o install-docker.sh
sh install-docker.sh --dry-runDocker-配置文件
vi /etc/docker/daemon.json
{
# 定义dockers工作目录
"data-root":"/data/docker",
# 存储驱动的模式
"storage-driver":"overlay2",
# 限制日志格式和大小
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
},
# 国内的镜像加速源
"registry-mirrors":[
"https://docker.m.daocloud.io",
"https://noohub.ru",
"https://huecker.io",
"https://dockerhub.timeweb.cloud"
],
# ulimits 优化
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 65535,
"Soft": 32768
},
"nproc": {
"Name": "nproc",
"Hard": 4096,
"Soft": 2048
}
},
# 指定docker的IP要区别于主机,记得加子网掩码
"bip":"172.18.0.1/16",
# 禁用 Docker 自带的 iptables 规则(Kubernetes 场景适用)
"iptables": false,
"ip-masq": false,
# 启动时候的额外的参数
"exec-opts":["native.cgroupdriver=systemd"],
# docker引擎死掉了,用docker引擎起来的容器可以继续活着
"live-restore":true,
# 设置默认容器资源限制(如文件描述符数)
"default-ulimits": { "nofile": { "Hard": 65536, "Soft": 65536 } },
# DNS
"dns": ["223.5.5.5", "114.114.114.114"],
# IPv6
"ipv6": false
}
# 创建docker工作目录
mkdir /data/docker -p
# 启动dockers
systemctl start docker