目录:
案例
存在于硬件层和操作系统层间的虚拟化技术。 虚拟机通过“伪造”一个硬件抽象接口,将一个操作系统以及操作系统层以上的层嫁接到硬件上,实现和真实物理机几乎一样的功能。比如我们在一台 Windows 系统的电脑上使用 Android 虚拟机,就能够用这台电脑打开 Android 系统上的应用。
存在于操作系统层和函数库层之间的虚拟化技术。 容器通过“伪造”操作系统的接口,将函数库层以上的功能置于操作系统上。以 Docker 为例,其就是一个基于 Linux 操作系统的 Namespace 和 Cgroup 功能实现的隔离容器,可以模拟操作系统的功能。简单来说,如果虚拟机是把整个操作系统封装隔离,从而实现跨平台应用的话,那么容器则是把一个个应用单独封装隔离,从而实现跨平台应用。所以容器体积比虚拟机小很多,理论上占用资源更少。容器化就是应用程序级别的虚拟化技术。容器提供了将应用程序的代码、运行时、系统工具、系统库和配置打包到一个实例中的标准方法。容器共享一个内核(操作系统),它安装在硬件上。
存在于函数库层和应用程序之间的虚拟化技术。 Java 虚拟机同样具有跨平台特性,所谓跨平台特性实际上也就是虚拟化的功劳。我们知道 Java 语言是调用操作系统函数库的, JVM 就是在应用层与函数库层之间建立一个抽象层,对下通过不同的版本适应不同的操作系统函数库,对上提供统一的运行环境交给程序和开发者,使开发者能够调用不同操作系统的函数库。
主机虚拟化的原理是通过在物理服务器上安装一个虚拟化层来实现。这个虚拟化层可以在物理服务器和客户操作系统之间建立虚拟机,使得它们可以独立运行。从软件框架的角度上,根据虚拟化层是直接位于硬件之上还是在一个宿主操作系统之上,将虚拟化划分为 Type1 和 Type2.Type1 类的 Hypervisor(Hypervisor 是一种系统软件,它充当计算机硬件和虚拟机之间的中介,负责有效地分配和利用由各个虚拟机使用的硬件资源,这些虚拟机在物理主机上单独工作,因此, Hypervisor 也称为虚拟机管理器。 )直接运行在硬件之上,没有宿主机操作系统, Hypervisor 直接控制硬件资源和客户机。典型框架为 Xen、 VmwareESX。
Type2 类的 Hypervisor 运行在一个宿主机操作系统之上(Vmware Workstation)或者系统里面,Hypervisor 作为宿主机操作系统中的一个应用程序,客户机就是在宿主机操作系统上的一个进程。
容器虚拟化,有别于主机虚拟化,是操作系统层的虚拟化。通过 namespace 进行各程序的隔离,加上 cgroups 进行资源的控制,以此来进行虚拟化。
什么是 Namespace(命名空间)namespace 是 Linux 内核用来隔离内核资源的方式。通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前namespace 里的进程,对其他 namespace 中的进程没有影响。Linux 提供了多个 API 用来操作 namespace,它们是 clone()、 setns() 和 unshare() 函数,为了确定隔离的到底是哪项 namespace,在使用这些 API 时,通常需要指定一些调用参数: CLONE_NEWIPC、 CLONE_NEWNET、 CLONE_NEWNS、CLONE_NEWPID、 CLONE_NEWUSER、 CLONE_NEWUTS 和CLONE_NEWCGROUP。如果要同时隔离多个 namespace,可以使用 | (按位或)组合这些参数。
举个例子
三年一班的小明和三年二班的小明,虽说他们名字是一样的,但是所在班级不一样,那么,在全年级排行榜上面,即使出现两个名字一样的小明,也会通过各自的学号来区分。对于学校来说,每个班级就相当于是一个命名空间,这个空间的名称是班级号。班级号用于描述逻辑上的学生分组信息,至于什么学生分配到 1 班,什么学生分配到2 班,那就由学校层面来统一调度。
NameSpace 隔离实战
实战目的
dd 命令详解
Linux dd 命令用于读取、转换并输出数据。dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。
语法
dd OPTION
参数
案例
# 生成 1 个镜像文件
dd if=/dev/zero of=fdimage.img bs=8k count=10240
#将 testfile 文件中的所有英文字母转换为大写,然后转成为 testfile_1 文件
dd if=testfile_2 of=testfile_1 conv=ucase
mkfs 命令详解
用于在设备上创建 Linux 文件系统,俗称格式化,比如我们使用 U 盘的时候可以格式化。
语法
mkfs [-V] [-t fstype] [fs-options] filesys [blocks]
参数
-t fstype:指定要建立何种文件系统;如 ext3, ext4
filesys :指定要创建的文件系统对应的设备文件名;
blocks:指定文件系统的磁盘块数。
-V : 详细显示模式
fs-options:传递给具体的文件系统的参数
实例
#将 sda6 分区格式化为 ext4 格式
mkfs -t ext4 /dev/sda6
#格式化镜像文件为 ext4
mkfs -t ext4 ./fdimage.img
mount 命令详解
mount 常见用法
mount [-l]
mount [-t vfstype] [-o options] device dir
常见参数
案例
#将 /dev/hda1 挂在 /mnt 之下。
mount /dev/hda1 /mnt
#将镜像挂载到/mnt/testext4 下面,需要确保挂载点也就是目录存在
mkdir -p /mnt/testext4
mount ./fdimage.img /mnt/testext4
unshare 命令详解
unshare 主要能力是使用与父程序不共享的名称空间运行程序。
语法
unshare [options] program [arguments]
常用参数
#hostname 隔离
root@139-159-150-152:~# unshare -u /bin/bash
root@139-159-150-152:~# hostname test1
root@139-159-150-152:~# hostname
test1
root@139-159-150-152:~# exit
exit
root@139-159-150-152:~# hostname
139-159-150-152
root@139-159-150-152:
实战操作一(PID 隔离)
1.在主机上执行 ps -ef,可以看到进程列表如下,其中启动进程 PID 1 为 init 进程
2.我们打开另外一个 shell ,执行下面命令创建一个 bash 进程,并且新建一个 PID Namespace:
unshare --fork --pid --mount-proc /bin/bash
exit
实战操作二(Mount 隔离)
1. 打开第一个 shell 窗口 A,执行命令, df -h ,查看主机默认命名空间的磁盘挂载情况
2. 打开一个新的 shell 窗口B,执行 Mount 隔离命令
# --mount 表示我们要隔离 Mount 命名空间了
# --fork 表示新建进程
unshare --mount --fork /bin/bash
mkdir -p /data/tmpmount
3. 在窗口 B 中添加新的磁盘挂载
dd if=/dev/zero of=fdimage.img bs=8k count=10240
mkfs -t ext4 ./fdimage.img
mount ./fdimage.img /data/tmpmount
4. 在窗口 B 挂载的磁盘中添加文件
echo "Hello world!" > /data/tmpmount/hello.txt
5. 查看窗口 B 中的磁盘挂载信息
6. 查看窗口 A 中的磁盘挂载信息
7. 查看窗口 B 中的文件信息
8. 查看窗口 A 中的文件信息,可以看到窗口 B 中新建的文件和磁盘挂载在主机的窗口中并没有,说明我们实现了文件系统隔离。
9. 窗口 B 执行 exit,退出
exit
1. 什么是 cgroups
cgroups(Control Groups) 是 linux 内核提供的一种机制, 这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。 简单说, cgroups 可以限制、记录任务组所使用的物理资源。本质上来说, cgroups 是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。
2.为什么使用 cgroups
其可以做到对 cpu,内存等资源实现精细化的控制,目前越来越火的轻量级容器Docker 及 k8s 中的 pod 就使用了 cgroups 提供的资源限制能力来完成 cpu,内存等部分的资源控制。比如在一个既部署了前端 web 服务,也部署了后端计算模块的八核服务器上,可以使用 cgroups 限制 web server 仅可以使用其中的六个核,把剩下的两个核留给后端计算模块。
3.cgroups 的用途
Resource limitation: 限制资源使用,例:内存使用上限/cpu 的使用限制Prioritization: 优先级控制,例: CPU 利用/磁盘 IO 吞吐Accounting: 一些审计或一些统计Control: 挂起进程/恢复执行进程
4. cgroups 可以控制的子系统
CGroups 资源控制实战
实战目的
基础知识
pidstat
概述
语法
pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ]
参数
Ubuntu 安装
#卸载
apt remove sysstat -y
#安装
apt install sysstat -y
CentOS 安装
#卸载
yum remove sysstat -y
#安装
yum install sysstat -y
stress
概述
stress 是 Linux 的一个压力测试工具,可以对 CPU、 Memory、 IO、磁盘进行压力测试。
语法
stress [OPTION [ARG]]
参数
安装
Ubuntu:
#卸载
apt remove stress -y
#安装
apt install stress -y
CentOS:
#卸载
yum remove stress -y
#安装
yum install stress -y
实操一、 cgroups 信息查看
cgroups 版本查看
如果看到 cgroup2,表示支持 cgroup v2
cgroups 子系统查看
cgroups 挂载信息查看
可以看到默认存储位置为 /sys/fs/cgroup
查看一个进程上的 cgroup 限制
1. 以当前 shell 进程为例,查看进程的 cgroup
2. 比如 cpu 在 user.slice,我们可以找到这个目录,里面有对 init 进程的详细限制信息
实操二、使用 cgroups 对内存进行控制
1. 创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录/sys/fs/cgroup/memory,我们创建目录 test_memory
2. 可以看到内存限制文件已经自动在 test_memory 中创建完成了, cgroups 文件系统会在创建文件目录的时候自动创建相应的配置文件
3. 配置 cgroup 的策略为最大使用 20M 内存
4. 启动 1 个消耗内存的进程,每个进程占用 50M 内存
5. 打开一个新的 shell 窗口 B 窗口,使用 pidstat 查看状态,红色为进程 id
6. 打开一个新的 shell C 窗口,将进程 id 移动到我们的 cgroup 策略
7. 可以看到进程无法申请到足够内存退出
可以看到进程消失了
实操三、使用 cgroups 对 cpu 进行控制
1. 创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录/sys/fs/cgroup/cpu,我们创建目录 test_cpu,可以看到系统会自动为我们创建 cgroup的 cpu 策略
2. 打开新的 shell 窗口 B 窗口,使用 stress 模拟一个任务, cpu 使用率为 100
3. 可以看到 cpu 的使用率为 100%
4. 打开新的 shell 窗口 C 窗口,我们设置 cproup 的 cpu 使用率为 30%, cpu 使用率
的计算公式 cfs_quota_us/cfs_period_us
所以我们将 cfs_quota_us 的值设置为 30000 ,从理论上讲就可以限制 test_cpu 控制的进程的 cpu 利用率最多是 30% 。
5. 我们可以看到进程的 PID 为 62577,我们将该进程放到 tasks 文件进行控制
6. B 窗口中可以看到我们监控的 cpu 的使用率由 100%降低为 30%
至此我们成功的模拟了对内存和 cpu 的使用控制,而 docker 本质也是调用这些的 API来完成对资源的管理,只不过 docker 的易用性和镜像的设计更加人性化,所以 docker才能风靡全球, docker 课程完后我们会看下 docker 如何对资源控制对比这种控制可以说简单不止一倍。
LXC(LinuX Containers) Linux 容器,一种操作系统层虚拟化技术,为 Linux 内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享 API 来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得 Linux 用户可以容易的创建和管理系统或应用容器。LXC 是最早一批真正把完整的容器技术用一组简易使用的工具和模板来极大的简化了
容器技术使用的一个方案LXC 虽然极大的简化了容器技术的使用,但比起直接通过内核调用来使用容器技术,其复杂程度其实并没有多大降低,因为我们必须要学会 LXC 的一组命令工具,且由于内核的创建都是通过命令来实现的,通过批量命令实现数据迁移并不容易。其隔离性也没有虚拟机那么强大。后来就出现了 docker,所以从一定程度上来说, docker 就是 LXC 的增强版。
LXC 容器操作实战
实战目的
通过 lxc 来完成容器的创建,体会容器,并了解 docker 并不是容器的唯一实现。自docker 0.9 版本起, docker 除了继续支持 LXC 外,还开始引入自家的 libcontainer,试图打造更通用的底层容器虚拟化库。如今的 docker 基本上都已经是使用libcontainer 而非 LXC 了。
基础知识
LXC 的常用命令如下:
lxc-checkconfig
lxc-create
lxc-start
lxc-ls
lxc-info
lxc-attach
lxc-stop
lxc-destory
安装 LXC
Ubuntu 安装
安装前执行检查看下是否需要卸载,如果需要卸载,执行下面的命令完成卸载,不需要直接到第 2 步
# 一、检查是否安装。清理资源
systemctl status lxc
lxc-stop -n xxx # lxc-ls -f 遍历所有容器,停止运行的容器
lxc-destroy -n xxx # 删除对应的容器
# 二、 卸载软件
apt-get purge --auto-remove lxc lxc-templates
# 三、 检查服务已经没有该服务了
systemctl status lxc
没有安装的话,执行下面的命令完成安装
#一、安装
#lxc 主程序包
#lxc-templates lxc 的配置模板
#bridge-utils 网桥管理工具
apt install lxc lxc-templates bridge-utils -y
#二、检查服务是否正常运行
systemctl status lxc
CentOS 安装
# 一、检查是否安装。清理资源
systemctl status lxc #检查是否安装
lxc-stop -n xxx # lxc-ls -f 遍历所有容器,停止对应的容器
lxc-destroy -n xxx #删除对应的容器
# 二、 卸载软件
yum remove lxc lxc-templates lxc-libs lxc-extra libvirt
debootstrap
# 三、检查,提示服务不存在
systemctl status lxc
CentOS 安装 LXC,如果已经安装,可以检查下是否需要卸载,如果需要卸载执行Centos 卸载 LXC
# 一、 配置源
yum -y install epel-release #这个软件包里包含 epel yum 源和
GPG 的配置
# 二、 安装程序
# lxc 主程序包
# lxc-templates lxc 的配置模板
# bridge-utils 网桥管理工具 lxc-libs lxc 所需的库文件
# libcgroup cgroup 安装包
# libvirt 管理 Linux 的虚拟化功能所需的服务器端守护程序。 需要针对特定驱
动程序的管理程序。
# debootstrap debootstrap 是 Debian 引导程序,它允许您将 Debian 基本系统
(例如 Debian 或 Ubuntu)安装到当前正在运行的系统的目录中。
yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup
libvirt lxc-extra debootstrap
#三、启动和检查
#如果未运行输入以下命令完成启动
systemctl start lxc #启动 lxc 服务
systemctl start libvirtd #启动虚拟机监控服务
systemctl status lxc
systemctl status libvirtd
LXC 容器操作实战
3. 查看 lxc 提供的容器模板
4. 创建一个 lxc 虚拟主机,这个命令就会下载安装指定环境下的软件包,创建新容器。整个过程需要时间较长,与容器的类型有关。
5. 下载安装完所有软件包后, LXC 容器镜像就创建完成了,你可以看到默认的登录界面。容器被放到 /var/lib/lxc/<容器名> 这个目录下,容器的根文件系统放在/var/lib/lxc/<容器名>/rootfs 目录下。创建过程中下载的软件包保存在 /var/cache/lxc 目录下面,当你想另外建一个一样的容器时,可以省去很多下载时间。
6. 查看创建的容器信息。
7. 启动容器,我们可以看到容器状态为运行中
8. 查看容器的详细信息
9. 容器 ip 为 10.0.3.248, 我们通过 ssh 进入容器,查看 ip 地址,磁盘挂载信息,目录信息和宿主机都不一样
10. 在容器外面执行命令
11. 停止容器
12. 删除容器
root@139-159-150-152:/var/run/docker/netns# lxc-destroy -n
lxchost1
root@139-159-150-152:/var/run/docker/netns# lxc-ls -f
root@139-159-150-152:/var/run/docker/netns#
Docker 本质
Docker 本质其实是 LXC 之类的增强版,它本身不是容器,而是容器的易用工具。容器是 linux 内核中的技术, Docker 只是把这种技术在使用上简易普及了。 Docker 在早期的版本其核心就是 LXC 的二次封装发行版。Docker 作为容器技术的一个实现,或者说让容器技术普及开来的最成功的实现。Docker 是基于 Go 语言实现的一个开源项目,它的主要目标是“Build, Ship and Run Any APP, Anywhere”,即通过对组件的封装、分发、部署、运行等生命周期的管理,使得用户的应用及其运行环境能够做到“一次封装,到处运行”。早期 Docker 利用 LXC 做容器管理引擎,但是在创建容器时,不再使用模板去安装生成,而是通过镜像技术(把一个操作系统用户空间所需要使用到的组件事先编排好,并整体打包成一个文件, image 文件),镜像文件集中放在一个仓库中。当需要创建容器时, Docker 调用 LXC 的工具 lxc-create,但不再通过 lxc 的模板去安装,而是连接到镜像服务器上下载匹配的镜像文件,而后基于镜像启动容器。所以, Docker 极大的
简化了容器的使用难度。以后我们创建启动容器,只需要一个命令, docker-run,docker-stop 就可以启动停止一个容器了。
Docker 的引擎迭代
Docker 早期是基于 LXC 容器管理引擎实现,当后来成熟之后, Docker 自建了一个容器引擎叫 libcontainer,后来 CNCF 的介入, Docker 又研发了一个工业化标准的容器引擎 runC,目前所使用的新版 Docker,所使用的容器引擎就是 RunC。
Docker 和虚拟机的区别
Docker 为什么比虚拟机资源利用率高,启动快
docker 有比虚拟机更少的抽象层。 docker 不需要 Hypervisor 实现硬件资源虚拟化,运行在 docker 容器上的程序直接使用的是实际物理机的硬件资源。因此在 cpu、内存利用率上 docker 将会在效率上有明显的优势。 docker 利用的是宿主机的内核,而不需要Guest OS,节省了 Guest OS 占用的资源。docker 不需要 Guest OS,创建一个容器时,不需要和虚拟机一样重新加载一个操作系统内核。从而避免引寻、加载操作系统内核返回时耗时耗资源的过程,当新建一个虚拟机时,虚拟机软件需要加载 Guest OS,返回新建过程是分钟级别的。而新建一个docker 容器只需要几秒钟。
Docker 和 JVM 虚拟化的区别?
Docker 发展过程中衍生了以下版本,目前我们学习和使用提到的版本是 docker-ce。lxc:上文中提到, lxc 是最早的 linux 容器技术,早期版本的 docker 直接使用 lxc 来实现容器的底层功能。虽然使用者相对较少,但 lxc 项目仍在持续开发演进中。libcontainer: docker 从 0.9 版本开始自行开发了 libcontainer 模块来作为 lxc 的替代品实现容器底层特性,并在 1.10 版本彻底去除了 lxc。在 1.11 版本拆分出 runc 后,libcontainer 也随之成为了 runc 的核心功能模块, runc 后续变成了容器标准。moby: moby 是 docker 公司发起的开源项目,其中最主要的部分就是同名组件 moby,事实上这个 moby 就是 dockerd 目前使用的开源项目名称, docker 项目中的 engine
(dockerd)仓库现在就是从 moby 仓库 fork 而来的,使用 containerd 作为运行时标准。 https://mobyproject.org/docker-ce: docker 的开源版本, CE 指 Community Edition。 docker-ce 中的组件来自于 moby、 containerd 等其他项目。 https://www.docker.com/pricing/docker-ee: docker 的收费版本, EE 指 Enterprise Edition。其基础组件来源和docker-ce 是一样的,但附加了一些其他的组件和功能。https://www.docker.com/pricing/
官方架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。Docker 容器通过 Docker 镜像来创建。
生活案例
上面概念比较难以理解,我们列举个生活中的案例,以一家人去旅游入住酒店为例。我们一家人和朋友一块旅游去酒店,我们就是 Docker Client 到酒店办理入住,办理退房,缴费需要酒店前台提供各种服务,酒店前台就是我们的Docker Daemon, Docker 的核心服务端酒店是建在美丽的海边,酒店的宅基地和大楼就是我们实际的物理服务器或者虚拟服务器,也就是 Docker Host酒店就 1000 多个房间,每个房间里面不一样,有标间、大床房、家庭房等,这就是Docker 镜像仓库酒店的标准的房间豪华大床房和双人标间,这个就是 Docker 镜像,我们客户是没有办法修改的。我们办理完入住了一个豪华大床房,然后把行李,个人物品带到了一个具体的房间号,比如 9527,那么这个房间我们可以使用了,朋友也开了一间豪华大床房,虽然豪华大床房一样,当时我们携带的物品,我们的洗漱时间,睡觉时间都不一样,这个就是容器 Docker Container。容器的销毁,也就是我们一周后旅游结束了,搬出了酒店,酒店把我们的房间恢复了镜像原来的样子。
新时代软件诉求
我们来考虑 2 个问题, Docker 为什么要设计镜像,然后又搭建个 Docker Hub,搞个镜像仓库呢?我们来看下现在的时代发生了什么数据量疯狂增长:随着物联网、边缘计算等智能终端设备不断普及,受到来自物联网设备信号、元数据、娱乐相关数据、云计算和边缘计算的数据增长的驱动,全球数据量呈现加速增长。根据 IDC 分布的《数据时代 2025》预测,全球数据量将从 2018 年的 33ZB 增至 2025年的 175ZB,增长超过 5 倍;中国平均增速快于全球 3%,预计到 2025 年将增至48.6ZB,占全球数据圈的比例由 23.4%提升至 27.8%。其中,中国企业级数据量将从2015 年占中国数据量的 49%增长到 2025 年的 69%。
处理能力快速增加:
腾讯云全球服务器数量 100w+,数据量 EB+; 2020 年阿里云:在全国已建成 5 大超级数据中心,阿里云在全球 22 个地域部署了上百个数据中心,服务器的总规模数已经接近 200 万台。
某省疾控中心疫苗预约系统、全员核酸检测系统、健康码系统共 300 余台服务器,并为核酸检测系统快速扩容计算和存储资源。
软件需求爆发式增长:
软件发布频繁
研发模式从瀑布开发演变为敏捷开发,原来 3 个月上一次新功能,现在两周一次,而开发过程中我们也经常遇到需要修改需求,然后变更再发布的情况。软件上线有问题需要快速回滚,对软件有着极强的版本管理和回滚诉求。
软件需要共享
软件的研发人员、研发公司在设计、研发好一款软件的时候,如何方便的共享给他人,而又能快速的使用起来。
环境搭建复杂,技术种类繁多每个项目组使用的语言不一样,需要不同的环境,每个都得搞一套。每次都要从 yum开始一个个完成部署安装,每次都有各种奇怪的问题,运维成本很高。
Docker 解决方案
云时代需要我们针对这些诉求有一套针对的解决方案。我们要处理海量的数据,如何处理呢?
购买大量的服务器,并研发对应软件开发的需求需要频繁的变更上线,如何才能将修改的代码快速的分发到几百或者几千台服务器呢?如何共享软件呢?搞一个中心仓库,让各个服务器去下载软件包,安装,所以 CentOS 搞了 yum 仓库,docker 设计了镜像仓库, docker hub 是公共的托管仓库。软件设计好以后,怎么快速安装启动,有问题回滚呢?将 docker 需要的所有信息设计一套软件格式,把所有的依赖搞进去,并打上版本标签,这样不会换一个服务器各种问题,所以 Docker 设计了镜像。不同的开发环境怎么搭建呢,一会 java,一会 c++?docker 设计了镜像来应对,镜像里面存放了需要运行的环境,就像我们的 iPhone 内置 ios,我们的华为 mate 50 内置鸿蒙一样,一条命令就可以完成某个环境的搭建。
CentOS 安装
安装 Docker
1. 确认操作系统
[root@centos1 ~]# cat /etc/*release*
CentOS Linux release 7.9.2009 (Core)
Derived from Red Hat Enterprise Linux 7.9 (Source)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
CentOS Linux release 7.9.2009 (Core)
CentOS Linux release 7.9.2009 (Core)
cpe:/o:centos:centos:7
2. 确认 CPU 架构
[root@centos1 ~]# uname -a
Linux centos1 3.10.0-1160.71.1.el7.x86_64 #1 SMP Tue Jun 28
15:37:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
3. 卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
4. 卸载历史版本
#删除机器上的包
sudo yum remove docker-ce docker-ce-cli containerd.io dockerbuildx-plugin docker-compose-plugin docker-ce-rootless-extras
#执行卸载
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
5. 配置仓库
[root@centos1 ~]# ll /etc/yum.repos.d/
total 40
-rw-r--r--. 1 root root 1664 Nov 23 2020 CentOS-Base.repo
-rw-r--r--. 1 root root 1309 Nov 23 2020 CentOS-CR.repo
-rw-r--r--. 1 root root 649 Nov 23 2020 CentOS-Debuginfo.repo
-rw-r--r--. 1 root root 314 Nov 23 2020 CentOS-fasttrack.repo
-rw-r--r--. 1 root root 630 Nov 23 2020 CentOS-Media.repo
-rw-r--r--. 1 root root 1331 Nov 23 2020 CentOS-Sources.repo
-rw-r--r--. 1 root root 8515 Nov 23 2020 CentOS-Vault.repo
-rw-r--r--. 1 root root 616 Nov 23 2020 CentOS-x86_64-
kernel.repo
[root@centos1 ~]# sudo yum install -y yum-utils
[root@centos1 ~]# sudo yum-config-manager --add-repo
https://download.docker.com/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror
adding repo from: https://download.docker.com/linux/centos/dockerce.repo
grabbing file https://download.docker.com/linux/centos/dockerce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
[root@centos1 ~]# ll /etc/yum.repos.d/
total 44
-rw-r--r--. 1 root root 1664 Nov 23 2020 CentOS-Base.repo
-rw-r--r--. 1 root root 1309 Nov 23 2020 CentOS-CR.repo
-rw-r--r--. 1 root root 649 Nov 23 2020 CentOS-Debuginfo.repo
-rw-r--r--. 1 root root 314 Nov 23 2020 CentOS-fasttrack.repo
-rw-r--r--. 1 root root 630 Nov 23 2020 CentOS-Media.repo
-rw-r--r--. 1 root root 1331 Nov 23 2020 CentOS-Sources.repo
-rw-r--r--. 1 root root 8515 Nov 23 2020 CentOS-Vault.repo
-rw-r--r--. 1 root root 616 Nov 23 2020 CentOS-x86_64-
kernel.repo
-rw-r--r--. 1 root root 1919 Apr 5 07:45 docker-ce.repo
# 配置使用国内源
[root@centos1 yum.repos.d]# sed -i
's@//download.docker.com@//mirrors.ustc.edu.cn/docker-ce@g'
/etc/yum.repos.d/docker-ce.repo
6. 安装最新版本
sudo yum install -y docker-ce docker-ce-cli containerd.io dockerbuildx-plugin docker-compose-plugin
7. 启动 docker
#配置加载
sudo systemctl daemon-reload
#启动服务
sudo systemctl start docker
#开启启动
sudo systemctl enable docker
#查看服务状态
sudo systemctl status docker
8. 检查安装结果查看版本
[root@centos1 ~]# docker version
Client: Docker Engine - Community
Version: 23.0.3
API version: 1.42
Go version: go1.19.7
Git commit: 3e7cbfd
Built: Tue Apr 4 22:04:18 2023
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 23.0.3
API version: 1.42 (minimum version 1.12)
Go version: go1.19.7
Git commit: 59118bf
Built: Tue Apr 4 22:02:01 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.20
GitCommit: 2806fc1057397dbaeefbea0e4e17bddfbd388f38
runc:
Version: 1.1.5
GitCommit: v1.1.5-0-gf19387a
docker-init:
Version: 0.19.0
GitCommit: de40ad0
9. 更详细查看 docker 信息
[root@centos1 ~]# docker info
Client:
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.10.4
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.17.2
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 23.0.3
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local
logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 2806fc1057397dbaeefbea0e4e17bddfbd388f38
runc version: v1.1.5-0-gf19387a
init version: de40ad0
Security Options:
seccomp
Profile: builtin
Kernel Version: 3.10.0-1160.71.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.795GiB
Name: centos1
ID: 0b3c79d5-957d-4d04-a856-ac15a2a09db2
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
10. 执行 hello-world 可以看到 Hello from Docker,表面 docker 服务正常
[root@centos1 ~]# sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest:
sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e
889e9
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/
Docker 镜像源修改
对于使用 systemd 的系统(Ubuntu 16.04+、 Debian 8+、 CentOS 7), 在配置文件
/etc/docker/daemon.json 中加入:
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}
重新启动 docker:
sudo systemctl restart docker
Docker 目录修改
Docker 默认的安装目录为/var/lib/docker,这里面会存放很多很多镜像,所以我们在安
装的时候需要考虑这个目录的空间,有三种解决方案。
#假定我们磁盘的大的目录为 /data
mkdir -p /data/var/lib/docker
# 编辑配置文件
vi /etc/docker/daemon.json
# 输入下面的 json
{
"data-root": "/data/var/lib/docker"
}
# 加载配置
sudo systemctl daemon-reload
# 重启 docker
sudo systemctl restart docker
#查看 docker 状态
sudo systemctl status docker
配置文件信息/etc/docker/daemon.json
修改前在/var/lib/docker 下
修改后在/data/var/lib/docker 下