我口袋只剩玫瑰一片此行又山高路远
Docker
什么是Docker?
- 容器:Docker 容器(Container) 是从镜像创建的运行时实例。它是一个轻量级、独立的环境,可以在多个环境中一致运行,并且彼此隔离。
- 镜像:容器的模板,包含运行应用程序所需的所有文件、依赖和配置。
- Dockerfile:用于定义如何构建 Docker 镜像的脚本。
- Docker Hub:Docker 镜像的公共仓库,可以下载和分享镜像。
Docker架构
-
Docker Client(客户端) :用户交互入口。
-
Docker Daemon(守护进程) :负责处理 Docker 容器、镜像、网络等操作的后台服务。
-
Docker Image(镜像) :创建容器的模板。
-
Docker Container(容器) :镜像的运行实例。
-
Docker 注册表:存储和分发镜像的地方。
-
Docker 网络:容器间的通信。
-
Docker 存储:持久化容器数据。
-
Docker Swarm:容器编排和集群管理工具。
Docker的运行流程
-
用户使用 Docker Client 与 Docker Daemon 建立通信,并发送请求给后者;
-
Docker Daemon 作为 Docker 架构的主体部分,首先提供 Docker Server 的功能,使其可以接收 Docker Client 的请求;
-
Docker Engine 执行 Docker 内部的一系列工作,每一项工作都是以一个 Job 的形式存在;
-
Job 的运行过程中,当需要容器镜像时,则从 Docker Registry 中下载镜像,并通过镜像管理驱动 Graph Driver 将下载镜像以 Graph 的形式存储;
-
当需要为 Docker 创建网络环境时,通过网络管理驱动 Network driver 创建并配置 Docker 容器网络环境;
-
当需要限制 Docker 容器运行资源,或执行用户指令等操作时,则通过 Exec driver 来完成。
容器的隔离是如何实现的?
Docker 通过多种技术实现了容器的隔离,确保容器在共享宿主机资源的同时,互相之间和宿主机之间没有干扰。通过 命名空间、控制组、文件系统隔离、网络隔离、安全机制等技术,Docker 能够提供强大的容器隔离性,使得容器化应用在执行时更加安全、独立和高效。
安装
下载地址:Docker: Accelerated Container Application Development
设置镜像源(Settings \ Docker Engine):
{
"registry-mirrors": [
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
],
"insecure-registries": [],
"debug": true,
"experimental": false
}
快速开始
Docker Hello World
在 cmd 打开并输入:
docker run hello-world
Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world e6590344b1a5: Pull complete Digest: sha256:d715f14f9eca81473d9112df50457893aa4d099adeb4729f679006bf5ea12407 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:
- The Docker client contacted the Docker daemon.
- The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64)
- The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
- 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: hub.docker.com/
For more examples and ideas, visit: docs.docker.com/get-started…
Docker使用
全局命令
显示 Docker 系统的详细信息
docker info
显示 Docker 客户端和守护进程的版本信息
docker version
显示容器的实时资源使用情况
docker stats
清理不再使用的资源
删除停止的容器、未使用的网络和悬挂的镜像
docker system prune [OPTIONS]
强制清理
docker system prune -f包括卷在内的完全清理
docker system prune -a --volumes
容器使用
启动容器
docker run
docker run -itd --name tencentos-test tencentos/tencentos_server24
列出正在运行的容器
docker ps
如果需要列出已停止的容器,请执行
docker ps -a
获取容器的详细信息
docker inspect 容器名称
停止容器
docker stop
杀死一个Docker容器
docker kill <container_id>
启动已停止的容器
docker start
重启容器
docker restart
删除容器
docker rm
查看容器日志
docker logs 容器名称
在运行的容器中执行命令
docker exec -it 容器名称/容器ID bash
docker exec -it tencentos-test bash退出终端
exit
导出容器(快照)
docker export 容器ID > 快照名称
docker export ac62a76297eb > D:\Docker\Snapshot\tencentos.tar
导入容器快照
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
注:
docker import仅保留文件系统,丢失历史记录和元数据(如标签和环境变量)。
从本地tar文件导入
cat D:\Docker\Snapshot\tencentos.tar | docker import - my_image:latest
或
docker import D:\Docker\Snapshot\tencentos.tar my_image:latest
从 URL 直接导入
docker import http://example.com/my_container.tar my_image:latest
添加镜像元数据
cat my_container.tar | docker import --change "ENV LANG=en_US.UTF-8" - my_image:latest
镜像使用
列出镜像列表(查看本地镜像)
docker images
查看镜像详细信息
docker inspect <镜像ID或名称>
拉取镜像
docker pull <镜像名>:<标签>
官方镜像
docker image pull 镜像名称
# 或简写为
docker pull 镜像名称
docker pull ubuntu docker pull ubuntu:16.04
个人镜像
docker pull 仓库名称/镜像名称
docker pull xunmi/django
第三方仓库镜像
docker pull 第三方仓库地址/仓库名称/镜像名称
docker pull hub.c.163.com/library/mysql:latest
推送镜像
将镜像推送到远程仓库
docker push <仓库名>/<镜像名>:<标签>
查找镜像
docker search 镜像名称
docker search centosNAME: 镜像仓库源的名称
DESCRIPTION: 镜像的描述
OFFICIAL: 是否 docker 官方发布
STARS: 类似 Github 里面的 star
删除镜像
docker rmi <镜像ID或名称>
强制删除镜像
docker rmi -f <镜像ID或名称>
删除未被使用的镜像
docker image prune
删除所有未使用的镜像
docker image prune -a
构建镜像
构建镜像的原则
- 尽量保持镜像精简
- 避免在容器中使用 root 用户
- 合并相关指令、减少层数
- 尽量缓存中间层
- 明确指定版本,避免使用
latest标签 - 尽量减少容器暴露的端口
- 清理缓存和临时文件
- 正确使用
ENTRYPOINT和CMD指令来指定容器的启动命令 - 保持
Dockerfile可读性 - 避免暴露敏感信息
从现有镜像创建
- 你在容器里安装了新软件,想要保存这次修改。
- 你修改了配置文件,希望创建新的镜像,以后直接使用这个配置。
- 你想基于现有容器创建一个新的基础镜像,而不使用
Dockerfile重新构建。
docker commit [选项] <容器ID或名称> <新镜像名>:<标签>
指定作者信息
docker commit -a "Your Name <your.email@example.com>" my_container my_custom_ubuntu:latest指定提交信息
docker commit -m "Added vim and updated packages" my_container my_custom_ubuntu:latest多个选项
docker commit -a "Your Name" -m "Installed vim and curl" my_container my_custom_ubuntu:v1
使用Docker File 创建
docker build [选项] <上下文目录>
docker build -t my_image:latest -f /path/to/Dockerfile .
| 选项 | 描述 |
|---|---|
-t | 给构建的镜像打标签,格式为 name:tag,例如 my_image:latest |
-f | 指定 Dockerfile 的路径,默认是当前目录下的 Dockerfile |
--no-cache | 禁用缓存,不使用之前构建的缓存层,强制从头开始构建 |
--build-arg | 设置构建时的参数,传递给 Dockerfile 中的 ARG 指令 |
--pull | 始终尝试拉取最新的基础镜像 |
--quiet | 安静模式,只输出构建镜像的 ID |
--rm | 构建完成后删除临时容器,默认为 true |
--target | 构建指定的阶段,适用于多阶段构建(见下面示例) |
Dockerfile 和 docker commit
- 通过
Dockerfile创建镜像:适用于需要复现、版本控制的镜像构建,推荐用于生产环境中的镜像管理。 - 通过
docker commit创建镜像:适用于快速保存容器的当前状态,适合实验性或临时操作,但不适用于长时间管理和维护。
镜像归档(导出镜像)
将一个或多个 Docker 镜像导出为 tar 归档文件,方便备份、传输或导入到另一台机器。
docker save -o <文件名>.tar <镜像名>:<标签>
或
docker save <镜像名:标签> > <输出文件>
保存单个镜像
docker save -o my_image.tar my_image:latest保存多个镜像
docker save -o my_images.tar my_image1:latest my_image2:v1保存压缩镜像
docker save my_image:latest | gzip > my_image.tar.gz
恢复镜像
docker load 用于从 docker save 生成的 tar 归档文件加载 Docker 镜像,通常用于镜像备份恢复或迁移到其他机器。
docker load -i <文件名>.tar
或
cat <镜像文件> | docker load
从 tar 文件加载镜像
docker load -i my_image.tar从加载 gzip 压缩的镜像
gunzip -c my_image.tar.gz | docker load
查看镜像历史
docker history <镜像名>:<标签>
标记镜像
docker tag <镜像ID或名称> <新名称>:<新标签>
Docker File
一个 Dockerfile 由多条指令(Instruction) 组成,每条指令都会在构建镜像时执行。
# 1. 指定基础镜像(FROM)
FROM ubuntu:latest
# 2. 维护者信息(可选)
LABEL maintainer="your.email@example.com"
# 3. 运行命令(RUN)
RUN apt-get update && apt-get install -y curl vim
# 4. 复制文件到镜像中(COPY)
COPY my_script.sh /usr/local/bin/my_script.sh
# 5. 设置工作目录(WORKDIR)
WORKDIR /usr/local/bin
# 6. 指定容器启动时执行的命令(CMD)
CMD ["bash"]
CMD 和 ENTRYPOINT 的区别
CMD命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)ENTRYPOINT的 Exec 格式用于设置容器启动时要执行的命令及其参数,同时可通过CMD命令或者命令行参数提供额外的参数ENTRYPOINT中的参数始终会被使用,这是与CMD命令不同的一点
多阶段构建(Multi-Stage Build)
想减少最终镜像的大小,可以使用多阶段构建,最终镜像不会包含 Go 编译器,减少体积。
# 第一阶段:构建应用
FROM golang:alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
# 第二阶段:创建更小的最终镜像
FROM alpine
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]
Docker网络
Docker中的网络模式
bridge:默认模式,容器通过虚拟网桥连接到宿主机的网络。host:容器共享宿主机的网络。none:容器没有网络连接。container:容器与另一个容器共享网络。overlay:跨多个 Docker 主机的虚拟网络,通常用于 Docker Swarm 集群中,支持在集群中的容器之间进行通信。
常用命令
指定容器的网络模式
docker run --network <网络模式> 要运行的镜像的名称或 ID
- --network bridge
- --network host
- --network none
- --network container:
- --network
列出所有网络
docker network ls
查看网络详情
docker network inspect <network_name>
创建自定义网络
docker network create [OPTIONS] NETWORK_NAME
--driver:指定网络驱动程序(即网络类型)
--subnet:指定子网范围,通常与自定义网络一起使用,定义网络的 IP 范围。
--gateway:为网络指定一个网关地址,通常与
--subnet配合使用。--ip-range:为容器分配 IP 地址的范围。此选项指定一个子集的 IP 地址范围,而不是整个子网。
--internal:创建一个内部网络,容器无法访问外部网络(即不允许容器访问互联网)。
--attachable:允许在 Docker Swarm 集群模式下,容器能够附加到
overlay网络上。
删除网络
docker network rm <network_name>
端口映射
docker run -p <host_port>:<container_port> <image_name>
映射端口
docker run -p 8080:80 my_image映射多个端口
docker run -p 8080:80 -p 443:443 my_image自动选择宿主机端口(如果不指定宿主机端口,Docker 会自动选择一个端口进行映射)
docker run -p 80 my_image映射到特定的 IP 地址
docker run -p 127.0.0.1:8080:80 my_image使用
-P自动暴露端口docker run -P my_image
host_port:宿主机上暴露的端口。container_port:容器内应用程序监听的端口。image_name:用于创建容器的镜像。
查看端口映射
docker ps
或
docker inspect <container_id> | grep "PortBindings"
Docker协调与集群管理
Docker Compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。
docker-compose.yml
docker-compose.yml 文件采用 YAML 格式,通常包含以下几个主要部分:
version:定义 Compose 文件的版本。services:定义应用中的所有服务,每个服务代表一个容器实例。networks:定义服务间通信的网络。volumes:定义数据卷,用于容器间共享数据或持久化数据。configs和secrets(可选):用于存储配置信息和敏感数据。
多个 Compose 文件
docker-compose.override.yml
在 docker-compose 中,docker-compose.override.yml 是一个可选的文件,主要用于覆盖或扩展 docker-compose.yml 的默认配置,通常用于开发环境或本地调试。
docker-compose up -d # 自动加载 override 文件
合并原则
- 后面的文件覆盖前面的配置
- 相同的
services、volumes等会合并 environment、ports、volumes这样的数组不会自动合并,需要手动确保完整性
常用配置选项
-
build:- 如果需要从 Dockerfile 构建镜像,可以使用
build指令。
web: build: ./web - 如果需要从 Dockerfile 构建镜像,可以使用
-
environment:- 设置容器的环境变量。
db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: rootpassword -
volumes:- 挂载宿主机目录到容器中。
web: image: nginx:latest volumes: - ./html:/usr/share/nginx/html -
ports:- 映射容器的端口到宿主机端口。
web: image: nginx:latest ports: - "8080:80" -
depends_on:- 定义服务间的启动顺序。
depends_on用于确保服务按顺序启动,例如确保数据库先启动。
web: image: my_web_app depends_on: - db - 定义服务间的启动顺序。
-
restart:- 配置容器的重启策略。
web: image: nginx:latest restart: always可选值:
no:不重启。always:总是重启容器。unless-stopped:除非容器被显式停止,否则总是重启。on-failure:仅在容器非零退出时重启。
-
networks:- 配置容器使用自定义网络,使它们能够相互通信。
networks: my_network: driver: bridge -
extra_hosts:- 向容器添加主机名到 IP 地址的映射。
web: image: nginx:latest extra_hosts: - "example.com:192.168.1.100"
常用命令
启动所有服务
docker-compose up
加上
-d选项可以让服务在后台运行docker-compose up -ddocker-compose.yml 默认使用 YAML 格式,但也可以使用 JSON 格式编写 docker-compose.json。
docker-compose -f docker-compose.json up -d还可以使用多个 Compose 文件
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
启动指定服务的容器并运行命令
docker-compose run
启动已经存在的服务
docker-compose start
停止服务
docker-compose down
查看服务日志
docker-compose logs
查看正在运行的容器
docker-compose ps
停止服务但不删除容器
docker-compose stop
停止服务后,删除容器、网络和卷
docker-compose down --volumes
Docker Swarm
Docker Swarm是一个容器编排工具,它允许我们在不同的主机上管理多个容器。通过Swarm,我们可以将多个Docker主机变成一个单一的主机,以便于监控和管理。
Kubernetes
其他
Docker Volumes
Docker Volumes(数据卷) 是 Docker 提供的一种数据持久化机制,用于在容器和宿主机之间共享数据,同时避免数据因容器销毁而丢失。
Docker Volumes 的类型
-
Volumes(数据卷) (推荐)
- 由 Docker 管理,默认存储在
/var/lib/docker/volumes/目录。 - 容器可以挂载到 Volumes 上,数据不会随容器删除而丢失。
- 由 Docker 管理,默认存储在
-
Bind Mounts(绑定挂载)
- 允许将宿主机的任意目录或文件挂载到容器中,而不仅限于
/var/lib/docker/volumes/。 - 宿主机上的文件权限和安全性直接影响容器。
- 允许将宿主机的任意目录或文件挂载到容器中,而不仅限于
-
tmpfs Mounts(内存挂载)
- 将数据存储在内存中,不会写入磁盘,适用于高性能、临时数据存储的场景。
相关操作
创建 Volume
docker volume create <volume_name>
查看所有 Volumes
docker volume ls
查看 Volume 详细信息
docker volume inspect <volume_name>
使用 Volume 运行容器
docker run -d --name my_container -v <volume_name>:/app busybox
docker run:创建并运行一个新的容器。
-d:以后台模式运行容器(detached mode)。
--name my_container:给容器指定名称my_container(否则会自动分配一个随机名称)。
-v <volume_name>:/app:
-v选项用于挂载 Docker Volume。<volume_name>是 Docker Volume 的名称。/app是容器内的挂载路径,表示 容器中的/app目录将映射到宿主机上的<volume_name>数据卷。
busybox:使用busybox这个轻量级 Linux 镜像。
删除 Volume
docker volume rm <volume_name>
删除所有未使用的 Volumes
docker volume prune
安装CentOS
镜像拉取
因Centos 已被官方停止支持,故不建议继续使用,可以尝试使用 TencentOS Server 2.4 代替
docker pull tencentos/tencentos_server24