Docker 概述 Docker 是一个开源的应用容器引擎,Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
应用场景
微服务架构:每个服务独立容器化,便于管理和扩展。
CI/CD 流水线:与 Jenkins/GitLab CI 集成,实现自动化构建和测试。
开发环境标准化:新成员一键启动全套依赖服务
云原生基础:Kubernetes 等编排工具基于 Docker 管理容器集群。
容器基本架构
传统应用部署的痛点
环境不一致:应用在开发环境运行正常,但在测试或生产环境出现问题
依赖管理复杂:不同应用需要不同版本的运行时、库文件等
资源利用率低:传统虚拟机需要完整的操作系统,占用大量资源
部署复杂:需要手动配置环境、安装依赖,容易出错
容器化技术的解决方案
环境标准化:将应用及其依赖打包在一起,确保在任何环境中都能一致运行
轻量级:容器共享宿主机的操作系统内核,比虚拟机更轻量
快速部署:容器可以在几秒内启动,大大提高了部署效率
可移植性:一次构建,到处运行
核心概念 镜像 (Image) 定义:镜像是一个只读的模板,包含了运行应用所需的所有内容:代码、运行时、库文件、环境变量和配置文件。
分层存储:镜像由多个层组成,每一层代表一次修改
只读性:镜像本身是只读的,不能直接修改
可复用:同一个镜像可以创建多个容器
版本管理:通过标签(tag)进行版本管理
容器 容器是镜像的运行实例,是一个轻量级、可移植的执行环境,基于镜像创建,与其他容器隔离,共享主机操作系统内核,启动快(毫秒级)、资源占用低;虚拟机有独立内核,启动慢(分钟级)、资源开销大。 特点:
隔离性:每个容器都有自己的文件系统、网络和进程空间
临时性:容器可以被创建、启动、停止、删除
可写层:容器在镜像基础上添加了一个可写层
进程级:容器内通常运行一个主进程
仓库 (Repository) 仓库是存储和分发镜像的地方,可以包含一个镜像的多个版本。
分类:
公共仓库:如 Docker Hub,任何人都可以使用
私有仓库:企业内部搭建,用于存储私有镜像
官方仓库:由软件官方维护的镜像仓库。
Dockerfile 文本文件,描述如何自动构建镜像(例如指定基础镜像、安装软件、复制文件等)。
Docker 架构 Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。 Docker 容器通过 Docker 镜像来创建。
工作流程
构建镜像:使用 Dockerfile 创建镜像。
推送镜像到注册表:将镜像上传到 Docker Hub 或私有注册表中。
拉取镜像:通过 docker pull 从注册表中拉取镜像。
运行容器:使用镜像创建并启动容器。
管理容器:使用 Docker 客户端命令管理正在运行的容器(例如查看日志、停止容器、查看资源使用情况等)。
网络与存储:容器之间通过 Docker 网络连接,数据通过 Docker 卷或绑定挂载进行持久化。
Docker 客戶端 Docker 客户端是用户与 Docker 守护进程交互的命令行界面(CLI)。它是用户与 Docker 系统的主要交互方式,用户通过 Docker CLI 发出命令,这些命令被发送到 Docker 守护进程,由守护进程执行相应的操作。
Docker 守护进程(Docker Daemon) Docker 守护进程(通常是 dockerd)是 Docker 架构的核心,负责管理容器生命周期、构建镜像、分发镜像等任务。守护进程通常以后台进程的方式运行,等待来自 Docker 客户端的 API 请求。
Docker 引擎 API Docker 引擎 API 是 Docker 提供的 RESTful 接口,允许外部客户端与 Docker 守护进程进行通信。通过这个 API,用户可以执行各种操作,如启动容器、构建镜像、查看容器状态等。
Docker 容器 容器是 Docker 的执行环境,它是轻量级、独立且可执行的软件包。容器是从 Docker 镜像启动的,包含了运行某个应用程序所需的一切——从操作系统库到应用程序代码。容器在运行时与其他容器和宿主机共享操作系统内核,但容器之间的文件系统和进程是隔离的。
Docker 镜像 Docker 镜像是容器的只读模板。每个镜像都包含了应用程序运行所需的操作系统、运行时、库、环境变量和应用代码等。镜像是静态的,用户可以根据镜像启动容器。
Docker 仓库 Docker 仓库是用来存储 Docker 镜像的地方,最常用的公共仓库是 Docker Hub。
Docker Compose Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过 Compose,用户可以使用一个 docker-compose.yml 配置文件定义多个容器(服务),并可以通过一个命令启动这些容器。Docker Compose 主要用于开发、测试和部署多容器的应用。
Docker Swarm Docker Swarm 是 Docker 提供的集群管理和调度工具。它允许将多个 Docker 主机(节点)组织成一个集群,并通过 Swarm 集群管理工具来调度和管理容器。Swarm 可以实现容器的负载均衡、高可用性和自动扩展等功能。
Docker 网络 Docker 网络允许容器之间相互通信,并与外部世界进行连接。
Docker 卷 Docker 卷是一种数据持久化机制,允许数据在容器之间共享,并且独立于容器的生命周期。与容器文件系统不同,卷的内容不会随着容器的销毁而丢失,适用于数据库等需要持久存储的应用。
使用 Docker 安裝 Ubuntu 安裝 方式 1
1 2 3 4 5 6 7 8 # 下载并执行Docker官方安装脚本 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh # 启动Docker服务 sudo systemctl start docker sudo systemctl enable docker
方式 2
卸载旧版本sudo apt-get remove docker docker-engine docker.io containerd runc
更新索引包
1 sudo apt-get remove docker docker-engine docker.io containerd runc
安装 apt 依赖包
1 2 3 4 5 6 $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common
添加 Docker 的官方 GPG 密钥:
1 curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
设置稳定版仓库
1 2 3 4 5 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/ \ $ (. /etc/os-release && echo "$VERSION_CODENAME " ) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update
docker 常用命令 镜像获取与查看 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 搜索镜像(Docker Hub) docker search [关键词] # 拉取镜像 docker pull [镜像名]:[标签] # 示例:拉取Ubuntu 20.04镜像 docker pull ubuntu:20.04 # 查看本地镜像列表 docker images # 或 docker image ls # 查看镜像详情 docker inspect [镜像名]:[标签] # 查看镜像构建历史 docker history [镜像名]:[标签]
镜像操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 为镜像打标签 docker tag [原镜像名:标签] [新镜像名:新标签] # 示例:标记镜像用于推送至私有仓库 docker tag myapp:v1 registry.example.com/myapp:v1 # 推送镜像到仓库 docker push [镜像名:标签] # 删除镜像 docker rmi [镜像名:标签] # 或 docker image rm [镜像名:标签] # 强制删除镜像(即使有容器依赖) docker rmi -f [镜像名:标签]
镜像导入导出 1 2 3 4 5 6 7 8 9 10 11 12 13 # 导出镜像 docker save -o [文件名.tar] [镜像名:标签] # 示例 docker save -o ubuntu_20_04.tar ubuntu:20.04 # 导入镜像 docker load -i [文件名.tar] # 清理悬空镜像(无标签镜像) docker image prune # 清理所有未使用镜像 docker image prune -a
容器创建与启动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 创建容器(不启动) docker create -it [镜像名:标签] # 创建并启动容器 docker run [选项] [镜像名:标签] [命令] # 常用选项: # -d: 后台运行 # -it: 交互式终端 # -p 宿主机端口:容器端口: 端口映射 # --name 容器名: 指定名称 # -v 卷名:容器路径: 挂载数据卷 # --rm : 容器退出后自动删除 # 示例:启动一个Nginx容器 docker run -d -p 80:80 --name mynginx nginx:1.23
容器状态管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # 查看运行中的容器 docker ps # 查看所有容器(包括停止的) docker ps -a # 启动容器 docker start [容器ID/名称] # 停止容器 docker stop [容器ID/名称] # 重启容器 docker restart [容器ID/名称] # 强制终止容器 docker kill [容器ID/名称] # 暂停容器 docker pause [容器ID/名称] # 恢复容器 docker unpause [容器ID/名称]
容器交互与信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 进入运行中的容器 docker exec -it [容器ID/名称] /bin/bash # 查看容器日志 docker logs [容器ID/名称] # 实时查看日志 docker logs -f [容器ID/名称] # 查看最后100行日志 docker logs --tail 100 [容器ID/名称] # 查看容器内进程 docker top [容器ID/名称] # 查看容器资源使用情况 docker stats [容器ID/名称] # 查看容器详细信息 docker inspect [容器ID/名称] # 查看容器端口映射 docker port [容器ID/名称]
容器文件操作 1 2 3 4 5 # 从容器复制文件到本地 docker cp [容器ID/名称]:[容器内路径] [本地路径] # 从本地复制文件到容器 docker cp [本地路径] [容器ID/名称]:[容器内路径]
容器删除与清理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 删除容器 docker rm [容器ID/名称] # 强制删除运行中的容器 docker rm -f [容器ID/名称] # 删除所有已停止的容器 docker container prune # 批量操作示例 # 停止所有运行中的容器 docker stop $(docker ps -q) # 删除所有容器 docker rm -f $(docker ps -aq)
容器与镜像转换 1 2 3 4 5 6 7 8 # 从容器创建镜像 docker commit [容器ID/名称] [新镜像名:标签] # 导出容器快照 docker export -o [文件名.tar] [容器ID/名称] # 从快照导入镜像 docker import [文件名.tar] [镜像名:标签]
网络命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # 查看网络列表 docker network ls # 创建自定义网络 docker network create --driver bridge [网络名] # 示例 docker network create my-network # 查看网络详情 docker network inspect [网络名] # 将容器连接到网络 docker network connect [网络名] [容器名] # 将容器从网络断开 docker network disconnect [网络名] [容器名] # 删除网络 docker network rm [网络名] # 清理未使用的网络 docker network prune
容器互联示例 1 2 3 4 5 6 # 创建两个容器并连接到同一网络 docker run -d --name app1 --network my-network myapp:v1 docker run -d --name app2 --network my-network myapp:v1 # 此时app1可以通过容器名ping通app2 docker exec app1 ping app2
数据卷命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # 创建数据卷 docker volume create [卷名] # 示例 docker volume create mysql-data # 查看数据卷列表 docker volume ls # 查看数据卷详情 docker volume inspect [卷名] # 删除数据卷 docker volume rm [卷名] # 清理未使用的数据卷 docker volume prune # 运行容器时挂载数据卷 docker run -d -v [卷名]:[容器内路径] --name [容器名] [镜像名] # 示例:MySQL数据持久化 docker run -d -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:8.0 docker run -d -v [主机目录]:[容器内路径] --name [容器名] [镜像名] # 示例 docker run -d -v /home/user/app:/app --name myapp myapp:v1
配置 DNS DNS(Domain Name System,域名系统)是互联网的一项核心基础服务,它的主要作用是将人类容易记忆的域名(如www.baidu.com)转换为计算机能够识别的 IP 地址(如 180.101.50.242),从而实现网络设备之间的通信。 DNS 就像一个 “网络通讯录”,负责在 “域名” 和 “IP 地址” 之间建立映射,让用户无需记住复杂的 IP,只需输入域名就能访问网站。
宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS
1 2 3 { "dns" : [ "114.114.114.114" , "8.8.8.8" ] }
启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8
如果只想在指定的容器设置 DNS,则可以使用以下命令:
1 docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
Docker 仓库管理 仓库(Repository)是集中存放镜像的地方
注册 docker 账号
登录 docker login
登出 docker logout
查询镜像 docker search
拉取镜像 docker pull
推送镜像 docker push
Dockerfile Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
构建过程
新建 dockerfile 文件
添加配置文本
构建镜像docker build -t 镜像名称:镜像标签 .
指令介绍 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # 基础镜像 FROM node:16-alpine # 设置工作目录 WORKDIR /app # 复制依赖文件 COPY package*.json ./ # 安装依赖 RUN npm install --production # 复制应用代码 COPY . . # 暴露端口 EXPOSE 3000 # 启动命令 CMD ["node", "app.js"]
Docker Compose Compose 是用于定义和运行多容器 Docker 应用程序的工具。 通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务
使用步骤
使用 Dockerfile 定义应用程序的环境
使用 docker-compose.yml 定义构成应用程序的服务,
执行 docker-compose up 命令来启动并运行整个应用程序。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 version: "3" services: frontend: image: nginx:1.23 ports: - "80:80" volumes: - ./frontend:/usr/share/nginx/html depends_on: - backend backend: image: mynodeapp:v1 ports: - "3000:3000" depends_on: - db environment: - DB_HOST=db - DB_USER=root - DB_PASS=123456 db: image: mysql:8.0 volumes: - mysql-data:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=123456 - MYSQL_DATABASE=mydb volumes: mysql-data:
启动应用:docker-compose up -d