目录
Docker容器的使用
Docker容器关键技术
Namespace
Cgroups
UnionFS
首先直观地了解docker如何安装使用,并快速启动mysql服务的,启动时候绑定主机上的3306端口,查找mysql容器的ip,使用mysql -h containerIP 或者127.0.0.1就可以直接访问mysql服务,暂不考虑mysql的存储卷。
# 安装docker的rpm包
yum install -y docker
# 启动docker服务
systemctl start docker
# 查看image镜像列表,现在没有pull拉取任何镜像,列表为空
docker image list
# 修改镜像源地址为国内
vi /etc/docker/daemon.json
{
"registry-mirrors" : [
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"]
}
# 拉取mysql的固定版本镜像mysql:5.7.29
docker image pull mysql:5.7.29
# 查看镜像信息
docker inspect mysql:5.7.29
# 把mysql的镜像run跑起来,--name指定容器名,-p绑定端口映射关系,这里主机和容器的3306绑定,-e环境变量,-d是后台运行
docker run mysql:5.7.29 --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin@123 -d
# 查看docker的容器进程
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
39189fab8ca8 mysql:5.7.29 "docker-entrypoint..." 44 minutes ago Up 5 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
# 查看 mysql的容器ip,知道它的ip是172.17.0.2
docker inspect 39189fab8ca8
# centos系统本地安装mysql客户端
yum install -y mysql
# 在centos中使用docker的ip或者直接主机ip+3306端口访问mysql服务,密码是上面的admin@123
mysql -h 172.17.0.2 -P 3306 -u root -p
mysql -h 127.0.0.1 -P 3306 -u root -p
# 允许mysql的远程访问
MySQL [(none)]> grant all privileges on *.* to 'root'@'%' identified by 'admin@123' with grant option;
Query OK, 0 rows affected, 1 warning (0.00 sec)
MySQL [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
Docker 利用 Linux 内核的 namespace 技术来实现容器化。Namespace 是一种隔离机制,它将系统资源封装在一个独立的命名空间中,使得在不同的命名空间中的进程看起来像在独立的操作系统实例中运行,Linux 内核代码中进程的数据结构和Namespace 的数据结构:
namespace的类型有多种:
PID Namespace:每个容器都有自己独立的进程 ID (PID) 命名空间。这意味着容器内部的进程在容器外部是不可见的,进程 ID 在容器之间是隔离的。这使得容器内的进程可以拥有自己的进程树。
Network Namespace:每个容器都有自己独立的网络命名空间。这意味着每个容器拥有自己的网络栈,包括独立的网络接口、IP 地址、路由表和防火墙规则。这使得容器之间网络隔离,可以独立地运行和与外部网络通信。
Mount Namespace:每个容器都有自己独立的文件系统视图。这意味着每个容器可以拥有自己的文件系统挂载点和文件树。容器内部对文件系统的修改不会影响到宿主机或其他容器。
UTS Namespace:每个容器都有自己独立的主机名和域名。这意味着容器可以拥有自己的主机名,并且可以在网络中被识别为一个独立的实体。
IPC Namespace:每个容器都有自己独立的进程间通信 (IPC) 命名空间。这意味着容器之间的进程无法直接进行 IPC,它们被隔离在不同的命名空间中。
Docker 使用 cgroups(Control Groups)技术来实现对容器资源的限制和管理。cgroups 是 Linux 内核中将一组进程组织在多个层次结构中,并为每个组提供资源隔离/优先级和控制的技术;
CPU 资源管理:Docker 使用 cgroups 将 CPU 资源划分为不同的组,并为每个组分配 CPU 时间片。这允许 Docker 控制容器可以使用的 CPU 资源的数量,并根据需要进行动态调整。
内存资源管理:通过 cgroups,Docker 可以为容器分配特定的内存限制。当容器超出分配的内存限制时,内核会触发 OOM(Out of Memory)机制来处理内存不足的情况。
网络带宽管理:Docker 使用 cgroups 的网络子系统来限制容器的网络带宽。这使得 Docker 可以控制容器可以使用的网络带宽,以防止某个容器占用过多的网络资源。
块设备 I/O 控制:通过 cgroups,Docker 可以对容器的块设备 I/O 进行限制和控制。这允许 Docker 控制容器对磁盘读写的速度,以避免某个容器对存储设备的过度使用。
Docker 使用 UnionFS(Union File System)技术来实现容器镜像的分层和联合挂载,它提供了灵活而高效的容器镜像管理和文件系统隔离功能,能构建、分发和运行容器镜像,同时节省存储空间,并提供了高度的可定制性和可扩展性。
分层镜像:Docker 使用分层镜像的概念来构建容器。每个镜像层都只包含对文件系统的增量修改,这样可以节省存储空间并提高镜像的构建效率。每个镜像层都可以看作是一个只读的文件系统,它们通过 UnionFS 技术联合挂载在一起,形成一个完整的容器镜像。
写时复制(Copy-on-write):当容器启动时,Docker 会为每个容器创建一个可写的容器层。这个可写层是基于镜像层的一个副本,当容器对文件系统进行修改时,UnionFS 使用写时复制技术将修改后的文件存储在可写层中,而不是原始镜像层中。这样可以避免对原始镜像层的修改,使得容器之间可以共享相同的镜像层。
联合挂载:通过 UnionFS 技术,Docker 将不同的镜像层联合挂载到容器的文件系统中,形成一个统一的文件系统视图。这使得容器可以访问并使用镜像层中的文件和目录,就像它们是在容器内部的文件一样。联合挂载还允许容器在运行时共享文件和目录,提高了容器之间的效率和资源利用率。
linux系统启动后,首先将 rootfs 设置为 readonly, 进行一系列检查, 然后将其切换为 “readwrite” 供用户使用,而docker容器启动时也是将 rootfs 以 readonly 方式加载并检查,然而接下来利用union mount 的方式 将一个 readwrite 文件系统挂载在 readonly 的 rootfs 之上, 并且允许再次将下层的 FS(file system) 设定为 readonly 并且向上叠加,这样一组 readonly 和一个 writeable 的结构构成一个 container 的运行时态, 每一个 FS 被称作一个 FS 层。