4015 字
20 分钟
Docker 容器技术学习手册

1. Docker 简介#

1.1 出现原因#

解决开发和运维之间因运行环境不一致而产生的问题——开发完将代码和环境打包给运维,实现”一次镜像,处处运行”。

1.2 核心目标#

Build, Ship and Run Any App Anywhere — 通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的 APP 运行环境能够做到”一次镜像,处处运行”。

容器技术演进路线:光盘 > Appliance > Virtual Machine > Docker

Docker 可以存放:静态 Web 网站、用户数据库、前端、消息队列、中间件等。

1.3 容器与虚拟机比较#

传统虚拟机技术(Virtual Machine):

  • 带环境安装的一种解决方案
  • 虚拟机就是一个普通文件,不用就删
  • 基于安装在操作系统上的虚拟机管理系统,虚拟出各种硬件
  • 缺点:资源占用多、冗余步骤多、启动慢

容器虚拟化技术:

  • 弥补传统虚拟机的缺点
  • 与系统其他部分隔离开的一系列进程,从另一个镜像运行
  • 不是模拟一个完整的操作系统,而是对进程进行隔离
  • 不需要捆绑一整套操作系统

1.4 DevOps 价值#

  • 更快速的应用交付和部署
  • 更便捷的升级和扩缩容
  • 更简单的运维
  • 更高效的计算资源利用

1.5 使用企业#

新浪、美团、蘑菇街等。

1.6 相关网站#


2. Docker 安装#

2.1 基本组成#

组件说明
镜像(Image)只读的模板,可用来创建 Docker 容器
容器(Container)容器是用镜像创建的运行实例,可看作简易版的 Linux 环境
仓库(Repository)集中存放镜像,分为公开仓库和私有仓库

2.2 平台架构#

Docker 采用 C/S 模式架构,后端是松耦合架构。

Docker 入门架构图

2.3 CentOS 7 安装步骤#

参考官方文档:https://docs.docker.com/engine/install/centos

Terminal window
# 1. 确定 CentOS 版本
cat /etc/redhat-release
# 2. 卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 3. 安装 gcc 相关依赖
yum install -y gcc gcc-c++
# 4. 安装 yum-utils
yum install -y yum-utils
# 5. 设置阿里云镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 6. 安装 Docker CE
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 7. 启动 Docker
systemctl start docker
# 8. 验证安装
docker run hello-world

卸载 Docker:

Terminal window
yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

2.4 阿里云镜像加速#

地址:https://www.aliyun.com/product/acr

  1. 注册阿里云账号
  2. 获取镜像加速地址
  3. 粘贴脚本执行
  4. 重启 Docker 服务

2.5 底层原理#

Docker 利用的是宿主机的内核,不需要加载操作系统 OS 内核,因此比虚拟机有更少的抽象层,启动更快、资源占用更少。

Docker 底层原理

2.6 docker run hello-world 执行流程#

本地没有 hello-world 镜像时,Docker 从远程仓库下载镜像,在容器内运行,输出 “Hello from Docker!” 后容器自动终止。


3. Docker 常用命令#

3.1 帮助启动类命令#

Terminal window
# 启动 / 停止 / 重启 Docker
systemctl start docker
systemctl stop docker
systemctl restart docker
# 查看 Docker 状态
systemctl status docker
# 设置开机自启
systemctl enable docker
# 查看概要信息
docker info
# 查看帮助文档
docker --help
docker 具体命令 --help

3.2 镜像命令#

Terminal window
# 列出本地所有镜像
docker images
# 搜索镜像是否存在远程仓库
docker search 镜像名
# 下载镜像
docker pull 镜像名
# 查看镜像/容器/数据卷所占空间
docker system df
# 删除镜像(-f 强制删除)
docker rmi 镜像名/镜像ID
docker rmi -f 镜像名/镜像ID
# 删除所有镜像
docker rmi -f $(docker images -q)

3.3 容器命令#

Terminal window
# 新建并启动容器(交互模式)
docker run -it --name=容器名 镜像名 /bin/bash
# 新建并启动容器(后台模式/守护式容器)
docker run -d 镜像名
# 端口映射启动
docker run -d -p 外部端口:内部端口 镜像名

docker run 常用参数:

参数说明
-i以交互模式运行
-t为容器重新分配一个伪输入终端
--name为容器指定名称
-d后台运行并返回容器 ID
-p端口映射(主机端口:容器端口)
-P随机端口映射
--privileged=true授予容器扩展权限
Terminal window
# 列出当前正在运行的容器
docker ps
# 列出所有容器(包含历史)
docker ps -a
# 退出容器
# 方式一:exit(容器停止)
# 方式二:Ctrl + P + Q(容器不停止)
# 启动 / 重启 / 停止 / 强制停止 容器
docker start 容器ID或容器名
docker restart 容器ID或容器名
docker stop 容器ID或容器名
docker kill 容器ID或容器名
# 删除已停止的容器
docker rm 容器ID或容器名
# 一次性删除多个容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm

3.4 容器管理命令#

Terminal window
# 查看容器日志
docker logs 容器ID或容器名
# 查看容器内运行的进程
docker top 容器ID或容器名
# 查看容器内部细节
docker inspect 容器ID或容器名
# 进入正在运行的容器(推荐)
docker exec -it 容器ID bash
# 重新进入容器
docker attach 容器ID

execattach 的区别:exec 进入容器后开启新的终端,attach 直接进入容器启动命令的终端。

3.5 文件拷贝与导入导出#

Terminal window
# 从容器内拷贝文件到主机
docker cp 容器ID:容器内路径 目的主机路径
docker cp c056eed39a11:/tmp/1 /root
# 导出容器为 tar 归档文件
docker export 容器ID > 文件名.tar
# 从 tar 包导入为镜像
cat redis.tar | docker import - test/redis:latest
# 保存镜像为 tar 文件
docker save -o 文件名.tar 镜像名:版本
# 从 tar 文件加载镜像
docker load -i 文件名.tar

3.6 提交容器为新镜像#

Terminal window
# 将容器提交为新的镜像
docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名:[标签名]
docker commit -m="add vim wget" -a="zzvv" ac988ab03635 test/centos:8

3.7 镜像打标签与推送#

Terminal window
# 镜像打标签
docker tag 镜像ID 指定仓库地址/仓库名:镜像版本
# 推送镜像到仓库
docker push 指定仓库地址/仓库名:镜像版本

4. Docker 镜像#

4.1 镜像概念#

  • 轻量、可执行的独立软件包
  • 只能通过镜像文件才能生成 Docker 容器实例

4.2 分层镜像#

pull 镜像的过程就是一层一层在下载。

4.3 UnionFS(联合文件系统)#

  • 分层、轻量且高性能的文件系统
  • 支持对文件系统的修改作为一次提交来一层层叠加
  • 可将不同目录挂载到同一虚拟文件系统下
  • 镜像可以通过分层来进行继承
  • 是 Docker 镜像的基础
  • 特性:一次同时加载多个文件系统,各层文件系统叠加起来,外部看是一个文件系统

4.4 镜像加载原理#

  • Docker 镜像由一层一层的文件系统组成
  • 最底层是引导文件系统 bootfs(boot file system),包含 bootloader 和 kernel
  • boot 加载完整内核后存在于内存中,内存使用权从 bootfs 转交给内核,然后卸载 bootfs

4.5 分层结构的好处#

最大好处是共享资源,方便复制迁移。

Docker 镜像层都是只读的,容器层是可写的。


5. 本地镜像发布到阿里云#

5.1 操作流程#

  1. 登录阿里云开发者平台:https://cr.console.aliyun.com/
  2. 进入控制台 > 容器镜像服务
  3. 创建命名空间和仓库名称
  4. 进入管理界面获取脚本
  5. 将本地镜像推送到阿里云
Terminal window
# 登录阿里云容器镜像服务
docker login --username=用户名 registry.cn-hangzhou.aliyuncs.com
# 为镜像打标签
docker tag 镜像ID registry.cn-hangzhou.aliyuncs.com/命名空间/仓库名:版本
# 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/命名空间/仓库名:版本

6. 本地镜像发布到私有仓库#

6.1 搭建 Docker Registry 私有仓库#

Terminal window
# 1. 拉取 registry 镜像
docker pull registry
# 2. 运行私有库(使用容器卷映射)
docker run -d -p 5000:5000 -v /root/registry:/tmp/registry --privileged=true registry
# 3. 为镜像打标签(指向私有仓库地址)
docker tag redis:latest 8.130.164.248:5000/redis:latest
# 4. 修改 Docker 配置,增加加速节点和仓库节点
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://c5fd77pt.mirror.aliyuncs.com"],
"insecure-registries": ["172.24.252.156:5000"]
}
Terminal window
# 5. 重启 Docker
systemctl restart docker
# 6. 推送镜像到私有仓库
docker push 8.130.164.248:5000/redis:latest
# 7. 验证仓库中的镜像
curl -XGET http://8.130.164.248:5000/v2/_catalog
# 8. 从私有仓库拉取镜像
docker pull 8.130.164.248:5000/redis:latest

7. Docker 容器数据卷#

7.1 概念#

卷(Volume)是目录或文件,设计目的是数据的持久化,完全独立于容器的生存周期。Docker 容器删除时不会删除其挂载的数据卷。

7.2 特点#

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接实时生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它

7.3 创建数据卷#

Terminal window
# 创建映射(-v 物理机路径:容器内路径)
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名

添加 --privileged=true 参数,否则挂载会遇到 cannot open directory: Permission denied 错误。

7.4 读写规则#

Terminal window
# 默认读写模式
docker run -it --privileged=true -v /宿主机目录:/容器内目录 镜像名
# 只读模式(容器内只读不写)
docker run -it --privileged=true -v /宿主机目录:/容器内目录:ro 镜像名

7.5 卷的继承和共享#

Terminal window
# 容器2 继承容器1 的卷规则
docker run -it --privileged=true --volumes-from 父容器 镜像名

8. Docker 常规安装简介#

8.1 通用步骤#

  1. 搜索镜像:docker search 镜像名
  2. 拉取镜像:docker pull 镜像名
  3. 查看镜像:docker images
  4. 启动镜像:docker run
  5. 停止容器:docker stop
  6. 移除容器:docker rm

8.2 常见应用安装#

Tomcat:

Terminal window
docker search tomcat
docker pull tomcat
docker run -d -p 8080:8080 --name mytomcat tomcat

MySQL:

Terminal window
docker search mysql
docker pull mysql:5.7
docker run -d -p 3306:3306 \
--name mymysql \
-e MYSQL_ROOT_PASSWORD=root \
-v /root/mysql/data:/var/lib/mysql \
mysql:5.7

Redis:

Terminal window
docker search redis
docker pull redis
docker run -d -p 6379:6379 \
--name myredis \
redis

Nginx:

Terminal window
docker search nginx
docker pull nginx
docker run -d -p 80:80 \
--name mynginx \
-v /root/nginx/html:/usr/share/nginx/html \
nginx

9. Dockerfile 解析#

9.1 概念#

Dockerfile 是构建 Docker 镜像的文本文件,由构建镜像所需的指令和参数构成的脚本。

9.2 构建三部曲#

  1. 编写 Dockerfile 文件
  2. 构建 镜像:docker build
  3. 运行 容器:docker run

9.3 基础知识#

  1. 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
  2. 指令按照从上到下顺序执行
  3. # 表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交

9.4 构建流程#

  1. 从基础镜像运行一个容器
  2. 执行一条指令并对容器做出修改
  3. 执行类似 docker commit 的操作提交一个新的镜像层
  4. Docker 再基于刚提交的镜像运行一个新容器
  5. 执行 Dockerfile 中的下一条指令,直到所有指令执行完成

9.5 常用保留字指令#

指令说明
FROM基础镜像,指定存在的镜像作为模板
MAINTAINER镜像维护者的姓名和邮箱地址
RUN容器构建时需要运行的命令(docker build 时执行)
EXPOSE当前容器对外暴露的端口
WORKDIR指定创建容器后终端默认登录的工作目录
USER指定镜像以什么用户执行,默认 root
ENV在构建镜像过程中设置环境变量
ADD将宿主机目录下的文件拷贝进镜像,且会自动处理 URL 和解压 tar 压缩包
COPY将构建上下文目录中的文件/目录复制到镜像内的目标路径
VOLUME容器数据卷,用于数据保存和持久化
CMD指定容器启动后要执行的命令(docker run 时执行),可被覆盖
ENTRYPOINT指定容器启动时要运行的命令,不会被覆盖

9.6 CMD 与 RUN 的区别#

  • RUN:在 docker build 构建镜像时执行
  • CMD:在 docker run 启动容器时执行

Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 会被 docker run 之后的参数替换。

9.7 ENTRYPOINT 与 CMD 的配合#

ENTRYPOINT 不会被 docker run 后面的命令覆盖。当 ENTRYPOINT 和 CMD 一起使用时,CMD 不再是直接运行命令,而是作为参数传递给 ENTRYPOINT:

ENTRYPOINT ["executable"]
CMD ["param1", "param2"]
# 最终执行:executable param1 param2

优点:执行 docker run 时可以指定 ENTRYPOINT 运行所需的参数。

9.8 Dockerfile 实战案例#

自定义镜像 MyCentosJava-8,使 CentOS 7 具备 vim + ifconfig + JDK8:

FROM centos:7
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim net-tools glibc.i686
RUN mkdir -p /usr/local/java
ADD jdk-8u144-linux-x64.tar.gz /usr/local/java/
ENV JAVA_HOME /usr/local/java/jdk1.8.0_144
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MYPATH
CMD echo "success--------ok"
CMD /bin/bash

构建镜像:

Terminal window
docker build -t centos-new:7 .

10. Docker 微服务实战#

10.1 构建微服务项目#

通过 IDEA 新建普通微服务模块:

  1. 建 Module:docker_boot
  2. 改 POM
  3. 写 YML
  4. 主启动类
  5. 业务类

10.2 Dockerfile 发布微服务#

  1. IDEA 打包微服务 jar 包
  2. 编写 Dockerfile
  3. 构建镜像:docker build -t 镜像名 .
  4. 运行容器:docker run -d -p 端口:端口 镜像名
  5. 访问测试

11. Docker 网络#

11.1 网络情况#

  • 未启动 Docker 时:ens33lovirbr0
  • 启动 Docker 后:会产生名为 docker0 的虚拟网桥

11.2 常用命令#

Terminal window
# 查看网络
docker network ls
# 查看网络源数据
docker network inspect 网络名字
# 删除网络
docker network rm 网络名字
# 创建网络
docker network create 网络名字

11.3 网络模式#

模式参数说明
bridge--network bridge默认模式,为每个容器分配 IP 并连接至 docker0 虚拟网桥
host--network host容器不虚拟自己的网卡,使用宿主机的 IP 和端口
none--network none容器有独立的 Network namespace,但没有进行任何网络设置
container--network container:容器名新容器和指定容器共享 IP、端口范围等

11.4 自定义网络#

容器 IP 变动时可以通过服务名直接网络通信,不受 IP 变化影响。


12. Docker Compose 容器编排#

官方文档:https://docs.docker.com/compose/

12.1 概念#

Docker Compose 负责实现对 Docker 容器集群的快速编排,可以管理多个 Docker 容器组成的一个应用。需要定义一个 YAML 配置文件,配置好容器之间的调度问题就能直接管理多个容器。

12.2 核心概念#

概念说明
服务(Service)一个个应用的容器实例
工程(Project)由一组关联的应用容器组成的一个完整业务单元
配置文件docker-compose.yaml

12.3 三步骤#

  1. 编写 Dockerfile — 定义各个微服务应用并构建出对应的镜像文件
  2. 编写 docker-compose.yaml — 定义完整业务单元,安排好整体应用中各个容器服务
  3. 执行 docker-compose up — 启动并运行整个应用程序,完成一键部署上线

12.4 常用命令#

命令说明
docker-compose up创建并启动所有容器
docker-compose up -d后台创建并启动所有容器
docker-compose down停止并删除容器、网络、卷、镜像
docker-compose ps列出项目中所有容器
docker-compose logs查看容器日志
docker-compose build构建或重新构建服务
docker-compose start启动已存在的容器
docker-compose stop停止运行中的容器
docker-compose restart重启容器

12.5 Compose 编排微服务#

改造微服务工程 docker_boot

  1. SQL 建表建库
  2. 改 POM
  3. 写 YML
  4. 主启动类
  5. 业务类
  6. mvn package 打成 jar 包上传到 Linux

不使用 Compose 的方式:

  • 单独启动 MySQL 容器实例
  • 单独启动 Redis 容器实例
  • 单独启动微服务工程
  • 需要手动管理启动顺序

使用 Compose 的方式:

  • 通过 docker-compose.yaml 一键定义和管理所有容器
  • 自动处理依赖和启动顺序

13. 可视化工具与容器监控#

13.1 Portainer — 轻量级可视化工具#

Portainer 是 Docker 的轻量级可视化管理工具,提供 Web 界面管理 Docker 容器、镜像、网络、数据卷等。

13.2 CAdvisor + InfluxDB + Grafana — 容器监控方案#

  • CAdvisor:容器资源监控工具,收集容器的 CPU、内存、网络等数据
  • InfluxDB:时序数据库,存储 CAdvisor 收集的监控数据
  • Grafana:数据可视化平台,展示 InfluxDB 中的监控数据
Docker 容器技术学习手册
https://blog.xeu.asia/posts/docker-guide/
作者
Xeu
发布于
2024-05-28
许可协议
CC BY-NC-SA 4.0