docker学习实战
前言
梳理一些关于docker相关的知识
基础概念相关
一、核心概念与原理
- Docker与虚拟机的区别
- 隔离级别:Docker是进程级隔离,共享宿主机内核;虚拟机是硬件级隔离,需运行完整操作系统
- 资源消耗:Docker启动秒级、资源占用低(MB级);虚拟机启动分钟级、资源消耗高(GB级)
- 性能:Docker接近原生性能,虚拟机存在额外虚拟化开销
- Docker安全性
- 依赖Linux内核安全特性(命名空间、cgroups、AppArmor/SELinux)实现隔离
- 镜像签名机制保障镜像来源可信
- 生产环境验证表明隔离性弱于虚拟机但安全性仍较高
二、容器与镜像管理
容器生命周期
状态:运行(Running)、暂停(Paused)、重启(Restarting)、退出(Exited)
常用命令:1
2
3docker start/stop/restart <容器ID> # 启停容器
docker rm $(docker ps -aq) # 清理停止的容器
docker logs <容器ID> # 查看日志数据持久化
- 使用卷(Volume)实现数据持久化:
docker run -v /宿主机路径:/容器路径
- 容器退出后数据保留,需手动删除容器才会清除
镜像管理
- 镜像构建原则
- 精简层级,避免冗余依赖
- 使用.dockerignore过滤无关文件
- 指定明确版本号(如
FROM ubuntu:20.04
)
- Dockerfile指令
- 高频指令:
FROM
、RUN
、COPY
、ADD
、EXPOSE
、CMD
- COPY vs ADD:
- COPY直接复制文件
- ADD支持自动解压压缩包和远程URL下载
三、高级特性与工具
- Docker Compose
- 用途:通过YAML文件定义多容器应用
- 启动命令:
docker-compose up -d
- Docker Swarm
- 集群管理工具,支持服务弹性伸缩
- 节点类型:Manager(管理集群)、Worker(运行容器)
- 网络模式
- bridge:默认桥接网络
- host:共享宿主机网络栈
- overlay:跨主机容器通信
四、生产环境实践
- 资源控制
- 通过
--cpus
限制CPU,--memory
限制内存 - 使用cgroups实现资源隔离
- 监控方案
- 基础命令:
docker stats
实时监控资源使用 - 日志收集:
docker logs
结合ELK等工具
- 环境迁移
- 步骤:停止Docker服务→复制/var/lib/docker目录→调整新宿主机配置
五、进阶问题
- 容器化应用类型
- 优先无状态应用(如Web服务),有状态应用需配合持久化存储
- 非Linux系统运行原理
- Mac/Windows通过Linux虚拟机运行容器(如Hyper-V、VirtualBox)
- CI/CD集成
- 镜像作为标准化交付物,实现开发/测试/生产环境一致性
Docker安装(centos7)
1. 卸载旧版本
首先如果系统中已经存在旧的Docker,则先卸载
1 | yum remove docker \ |
2. 配置Docker的yum库
1 | sudo yum install -y yum-utils device-mapper-persistent-data lvm2 |
如果安装失败,使用阿里云更新yum源(通常应该不会,安装好centos第一件事,通常得换源的 :) )
- 换源:
1
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
- 清除yum:
1
yum clean all
- 更新缓存
1
yum makecache
3. 配置Docker的yum源
1 | sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo |
4. 更新yum,建立缓存
1 | sudo yum makecache |
5. 安装Docker
1 | yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin |
6. 启动和校验
1 | 启动Docker |
7. 配置镜像加速
1 |
|
Docker基础
docker官方网站:https://docs.docker.com/
常用命令
命令 | 说明 |
---|---|
docker pull | 拉取镜像 |
docker push | 推送镜像到DockerRegistry |
docker images | 查看本地镜像 |
docker rmi | 删除本地镜像 |
docker run | 创建并运行容器(不能重复创建) |
docker stop | 停止指定容器 |
docker start | 启动指定容器 |
docker restart | 重新启动容器 |
docker rm | 删除指定容器 |
docker ps | 查看容器 |
docker logs | 查看容器运行日志 |
docker exec | 进入容器 |
docker save | 保存镜像到本地压缩文件 |
docker load | 加载本地压缩文件到镜像 |
docker inspect | 查看容器详细信息 |
总结开来,可以用下图所示:
默认情况下,每次重启虚拟机我们都需要手动启动Docker和Docker中的容器。通过命令可以实现开机自启:
1 | Docker开机自启 |
一则常用演示(nginx)
1 | 第1步,去DockerHub查看nginx镜像仓库及相关信息 |
Docker其它知识
Docker安装
centos7 安装
1 | 如果安装旧版本,可以先卸载 |
运行结果
1 | [kemi@localhost ~]$ sudo docker run hello-world |
关于chroot
chroot是在Unix和Linux系统的一个操作,针对正在运行的软件进程和它的子进程,改变它外显的根目录。
一个运行在这个环境下,经由chroot设置根目录的程序,它不能够对这个指定根目录之外的文件进行访问动作,不能读取,也不能更改它的内容。
一个示例:
1 | 在rootfs下创建了一些目录和放置了一些二进制文件 |
此时通过一个chroot命令,启动一个sh进程,并且把这个rootfs作为sh进程的根目录
1 | chroot /home/kemi/rootfs /bin/sh |
此时还不能称之为一个完整的容器,因为网路等信息还没有隔离:需要通过linux的namespace、Cgroup、联合文件系统来具体实现,具体的职责大致是:
- namespace:主机名、网络、pid等资源的隔离
- Cgroup: 对进程或者进程组作资源的限制
- 联合文件系统:用于镜像构建和容器运行环境
关于namespace
Namespace对内核资源进行隔离,使得容器中的进程都可以在单独的命名空间中运行,并且只可以访问当前容器命名空间的资源。
Namespace可以隔离进程ID、主机名、用户ID、文件名、网络访问和进程间通信等相关资源
其中docker用到下面5中namespace:
- pid namespace: 隔离进程ID
- net namespace: 隔离网络接口
- mnt namespace: 文件系统挂载点隔离
- ipc namespace: 信号量,消息队列和共享内存的隔离
- uts namespace: 主机名和域名的隔离
关于cgroup
cgroup是一种linux内核功能,可以限制和隔离进程的资源使用情况(如CPU、内存、磁盘I/O、网络等)
关于联合文件系统
又叫UnionFS,是一种通过创建文件层进程操作的文件系统
docker利用改技术,为容器提供构建层,使得容器可以实现写时复制以及镜像的分层和存储
常用的联合文件系统有AUFS、Overlay和Devicemapper等
实现原理及关键技术
核心概念
docker核心围绕:镜像、容器、仓库来构建的
镜像
通俗的讲,镜像是一个只读的文件和文件夹组合,是Docker容器启动的先决条件。
镜像是一个只读的文件和文件夹组合,包含了容器运行时所需要的所有基础文件和配置信息,是容器启动的基础。
镜像不包括任何动态数据。
通常情况下,可以通过下面两种方式创建镜像:
- 基于centos镜像制作自己的业务镜像
- 安装nginx服务
- 部署应用程序
- 做一些自定义配置
- 从功能镜像仓库拉取别人制作好的镜像
- 常用的软件或者系统,例如nginx、ubuntu、centos、mysql等,可以到Docker Hub搜索并下载。
镜像构建
直接看图,有下面几种:
1 | Docker镜像的拉取使用docker pull命令 |
构建方法:
- 使用docker commit命令从运行中的容器提交为镜像
- 使用docker build命令从Dockerfile构建镜像:主要的构建方式
Dockerfile文件
- Dockerfile的每一行命令都会生成一个对立的镜像层,并且拥有唯一的ID
- Dockerfile的命令是完全透明的,通过查看Dockerfile的内容,可以知道镜像是如何创建的
- Dockerfile是纯文本的,方便跟随代码一起存放在代码仓库并管理
相关指令简介:
| Dockerfile指令 | 指令说明 |
| ————- |:————-:|
| FROM | Dockerfile除了注释第一行必须是FROM,FROM后面跟镜像名称,代码我们要基于哪个基础镜像构建我们的容器 |
| RUN | RUN后面跟一个具体的命令,类似于Linux命令行执行命令 |
| ADD | 拷贝本机文件或者远程文件到镜像内 |
| COPY | 拷贝本机文件的到镜像内 |
| USER | 指定容器启动用户 |
| ENTRYPOINT | 容器的启动命令 |
| CMD | CMD为ENTRYPOINT指令提供默认参数,也可以单独使用CMD指定容器启动参数 |
| ENV | 指定容器运行时的环境变量,格式为key=value |
| ARG | 定义外部变量,构建镜像时可以使用build-arg
| EXPOSE | 指定容器监听的端口,格式为[port]/tcp或者[port]/udp |
| WORKDIR | 为Dockerfile中跟在其后的所有RUN、CMD、ENTRYPOINT、COPY和ADD命令设置工作目录 |
示例:
1 | FROM centos:7 |
实现原理
Docker镜像是由一系列镜像层(layer)组成的,每一层代表了镜像构建过程中的一次提交。
一个示例:
容器
通俗的讲,容器是镜像的运行实体,而镜像是静态的只读文件,容器带有运行时,即容器运行着真正的应用进程。
容器有初建、运行、停止、暂停和删除五种状态
在容器内部,无法看到主机上的进程、环境变量、网络等信息
容器的生命周期
- created: 初建状态
- running: 运行状态
- stopped: 停止状态
- paused: 暂停状态
- deleted: 删除状态
仓库
类似于代码仓库,Docker的镜像仓库用来存储和分发Docker镜像,其中可以分为公共镜像仓库和私有镜像仓库。
Docker架构
经典的C/S架构模式,客户端负责发送指令,服务的负责接收和处理指令。
Docker客户端是一种泛称:
- Docker命令是Docker用户与Docker服务端交互的主要方式
- 使用直接请求Rest API方式与Docker服务端交互
- 使用各种语言的SDK与Docker服务端交互
Docker服务端是Docker所有后台服务的统称:其中dockerd负责响应和处理来自Docker客户端的请求,然后将客户端的请求转化为Docker的具体操作。
容器编排相关
综合应用(环境搭建)
搭建Postgresql
1. 拉取镜像
1 | docker pull postgres |
2. 创建本地卷
Docker 会自动在 /var/lib/docker/volume/ 路径下为主机上的卷创建一个目录。该卷可以在容器之间共享和重用, 且默认会一直存在。
1 | docker volume list # 列出 Docker 卷 |
3. 构建镜像容器
1 | docker run -it \ |
其中,上述命令分别的含义是:
| 名称 | 解释 |
|:————-:|:————-:|
| –name |自定义容器名称 |
| –restart always | 设置容器在 docker 重启时自动启动容器 |
| -e POSTGRES_PASSWORD | Postgresql 数据库密码 |
| -e ALLOW_IP_RANGE=0.0.0.0/0 | 表示允许所有 IP 访问 |
| -e TZ=’Asia/Shanghai’ | 设置时区 |
| -v [path] : [path] | 本地目录映射 (本地目录 : 容器内路径) |
| -p 55435:5432 | 端口映射 (主机端口 : 容器端口) |
| d postgres | 镜像名称 |
4. 进入容器
1 | docker exec -it postgres bash |
输入用户名/密码执行完后,再根据提示输入
1 | psql -U postgres -W |
输入密码,登录成功
6. 创建新用户
根据第五步,先切换到 Linux 用户 postgres,并执行如下 psql。
PS:根据你实际的需要,按需修改即可,都是传统的语句。
1 | create user nimbusk with password 'nimbusk123'; # 创建数据库新用户 |
7. 客户端链接验证
这个没啥,找个你常用的链接验证即可