Docker,这个字眼大家不陌生吧,不过作为网络工程师可能平时接触不到,如果在看文章的是运维人员,那么70%以上的运维人员都会跟Docker打交道。即使网工用不到,作为非常火爆热门的技术,也希望大家能坚持看50%的文章,熏陶一下技术。
Docker由Solomon Hykes于2013年推出,最初是一个开源项目,旨在简化开发人员在开发、测试和生产环境中部署应用程序的过程。Docker通过容器技术提供了一种轻量级的虚拟化解决方案,使应用程序可以在任何环境中一致地运行。随着Docker的普及,DevOps和云计算领域的工作方式发生了深刻变化,Docker已成为现代软件开发和部署的重要工具。
在现代软件开发中,快速迭代和持续交付变得至关重要。Docker的出现使得开发人员可以轻松创建、共享和运行应用程序,从而提高了开发效率,降低了环境不一致性带来的问题。此外,Docker的隔离特性增强了系统的安全性和稳定性,使其在微服务架构和云原生应用中得到了广泛应用。
目录:
容器技术
容器与虚拟机的区别
容器化的优点
Docker的基本概念
镜像 (Image)
容器 (Container)
仓库 (Repository)
Docker引擎 (Docker Engine)
Docker架构
Docker客户端与服务端
Docker的组件
安装Docker
Docker镜像
Docker镜像的基础操作
构建Docker镜像
优化Docker镜像
管理镜像
Docker容器
Docker容器的基本操作
容器的生命周期管理
容器网络
容器日志与调试
Docker Compose
Docker Compose的基本概念
Docker Compose文件格式
Docker Compose的基本操作
Docker Compose的高级功能
Docker Swarm
Docker Swarm的基本概念
设置和管理Docker Swarm集群
创建和管理Swarm服务
写在最后
Docker的基础概念
Docker的基本操作
数据管理与网络
Docker Compose
Docker Swarm
如果已经有Docker基础的朋友,可以直接滑到最后总结部分进行查漏补缺!
容器技术
容器与虚拟机的区别
虚拟机 (VM)
VM包含完整的操作系统,并在虚拟化层之上运行多个操作系统实例。
VM需要更多的系统资源(CPU、内存、存储)来管理这些操作系统实例。
容器 (Container)
容器共享主机操作系统的内核,具有独立的文件系统、进程和网络空间。
容器更轻量级,启动速度快,占用资源少。
特性 | 虚拟机 | 容器 |
---|---|---|
启动时间 | 几分钟 | 几秒 |
资源开销 | 高(包含操作系统内核) | 低(共享主机操作系统内核) |
性能 | 中等 | 高(更接近主机性能) |
隔离级别 | 强(完全隔离) | 较弱(共享内核) |
适用场景 | 多种操作系统和更高安全隔离需求 | 快速部署、微服务、开发测试等 |
容器化的优点
快速启动:容器可以在几秒钟内启动,提高了开发和部署效率。
轻量级:容器共享主机操作系统内核,占用更少的系统资源。
一致性:确保应用程序在开发、测试和生产环境中的行为一致,减少“环境问题”。
便捷性:容器化应用可以打包成独立的单元,便于分发、复制和管理。
可移植性:容器化应用可以在任何支持Docker的平台上运行,无需修改代码。
Docker的基本概念
镜像 (Image)
Docker镜像是一个轻量级、独立、可执行的软件包,包含了运行某个应用程序所需的全部内容,包括代码、运行时、库、环境变量和配置文件。镜像是只读的,当容器启动时,Docker会在镜像的顶部添加一个可写层。
容器 (Container)
容器是镜像的一个运行实例,它包括了镜像中的所有内容以及一个可写层。容器是独立的、可移植的单元,可以在任何支持Docker的平台上运行。
仓库 (Repository)
Docker仓库是存储和分发镜像的地方。Docker Hub是官方的公共仓库,用户也可以搭建私有仓库来存储自己的镜像。仓库中可以包含多个镜像,每个镜像可以有不同的标签(Tag)。
Docker引擎 (Docker Engine)
Docker引擎是一个轻量级的运行时和工具集,用于创建和管理容器。它包括以下组件:
Docker守护进程 (Docker Daemon):负责管理容器的生命周期。
Docker CLI (命令行界面):用于与Docker守护进程交互的命令行工具。
Docker Registries (镜像仓库):存储和分发Docker镜像。
Docker架构
Docker客户端与服务端
Docker采用了客户端-服务端(Client-Server)架构,客户端通过Docker CLI与服务端的Docker守护进程通信。Docker CLI发送命令给Docker守护进程,后者负责执行这些命令(如构建、运行和分发容器)。
Docker的组件
Docker守护进程 (Docker Daemon):后台进程,负责管理Docker对象(如镜像、容器、网络和卷)。
Docker CLI:命令行工具,用户通过它与Docker守护进程通信。
Docker Registries:存储和分发Docker镜像的地方,包含公共的Docker Hub和私有的Docker Registry。
安装Docker
Windows
下载并安装Docker Desktop for Windows。
启动Docker Desktop并进行基本配置。
验证安装:在命令行中运行docker --version。
macOS
下载并安装Docker Desktop for Mac。
启动Docker Desktop并进行基本配置。
验证安装:在终端中运行docker --version。
Linux
更新APT包索引:sudo apt-get update
安装必要的包:sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
添加Docker的官方GPG密钥:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
设置Docker的稳定版仓库:sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
安装Docker Engine:sudo apt-get update && sudo apt-get install docker-ce docker-ce-cli containerd.io
验证安装:sudo docker --version
以Ubuntu为例:
Docker镜像
Docker镜像是构建容器的基础,它包含了应用程序运行所需的所有依赖和配置。镜像是不可变的,每次运行镜像时都会生成一个新的容器实例。
常见的Docker镜像源包括:
Docker Hub:最广泛使用的公共镜像库,包含了大量官方和社区维护的镜像。
私有镜像库:用户可以搭建自己的Docker Registry来存储和管理私有镜像。
Docker镜像的基础操作
拉取镜像 (docker pull)
docker pull命令用于从镜像仓库拉取镜像。语法如下:
docker pull <镜像名>:<标签>
例如,拉取官方的nginx镜像:
docker pull nginx:latest
查看镜像 (docker images)
docker images命令用于列出本地存储的所有Docker镜像。语法如下:
docker images
示例输出:
删除镜像 (docker rmi)
docker rmi命令用于删除本地的Docker镜像。语法如下:
docker rmi <镜像ID或镜像名>:<标签>
例如,删除nginx镜像:
docker rmi nginx:latest
构建Docker镜像
Dockerfile是一个文本文件,包含了构建Docker镜像所需的一系列指令。每个指令在构建过程中创建镜像的一层。常用的Dockerfile指令包括:
FROM:指定基础镜像
RUN:在镜像内执行命令
COPY:将文件从宿主机复制到镜像内
CMD:指定容器启动时要执行的命令
Dockerfile指令
FROM
FROM ubuntu:20.04
指定基础镜像为Ubuntu 20.04。
RUN
RUN apt-get update && apt-get install -y nginx
在镜像内执行命令,安装nginx。
COPY
COPY . /app
将当前目录下的所有文件复制到镜像内的/app目录。
CMD
CMD ["nginx", "-g", "daemon off;"]
指定容器启动时执行的命令。
构建镜像 (docker build)
docker build命令用于根据Dockerfile构建镜像。语法如下:
docker build -t <镜像名>:<标签> <Dockerfile路径>
例如,构建一个名为mynginx的镜像:
docker build -t mynginx:latest .
优化Docker镜像
多阶段构建
多阶段构建可以在一个Dockerfile中使用多个FROM指令,减少最终镜像的大小。例如:
# 第一阶段:构建应用程序
FROM golang:1.16 as builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 第二阶段:创建最终镜像
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
镜像瘦身技巧
使用轻量级基础镜像:如Alpine Linux。
减少镜像层数:合并多个RUN指令。
清理不必要的文件:在Dockerfile中删除临时文件。
管理镜像
标签用于标识镜像的不同版本。通过标签,用户可以方便地管理和拉取特定版本的镜像。例如:
docker tag nginx:latest mynginx:v1.0
通过合理使用标签和版本控制系统(如Git),可以有效管理镜像的不同版本,确保应用程序在各个环境中的一致性。
Docker容器
Docker容器是运行在Docker引擎上的独立运行环境。每个容器都是从一个镜像启动的,并在镜像的基础上添加一个可写层。容器提供了应用程序的隔离环境,使其运行所需的所有依赖和配置都封装在容器内。
镜像是静态的文件系统和应用程序配置的组合,而容器是镜像的运行实例。当我们启动一个容器时,Docker会在镜像的基础上创建一个可写层,从而使容器变得可操作。镜像可以被多次使用来创建多个容器。
Docker容器的基本操作
创建并启动容器 (docker run)
docker run命令用于创建并启动一个容器。语法如下:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
例如,运行一个nginx容器:
docker run -d -p 80:80 nginx
此命令会下载nginx镜像(如果本地没有),然后在后台运行一个nginx容器,并将主机的80端口映射到容器的80端口。
停止与重启容器 (docker stop, docker start)
停止容器
docker stop <容器ID或容器名>
例如,停止一个名为mynginx的容器:
docker stop mynginx
重启容器
docker start <容器ID或容器名>
例如,重启mynginx容器:
docker start mynginx
进入容器 (docker exec, docker attach)
使用docker exec进入容器
docker exec命令用于在运行的容器内执行命令。语法如下:
docker exec -it <容器ID或容器名> <命令>
例如,进入一个正在运行的容器的bash环境:
docker exec -it mynginx /bin/bash
使用docker attach连接到容器
docker attach命令用于连接到一个运行中的容器。语法如下:
docker attach <容器ID或容器名>
例如,连接到mynginx容器:
docker attach mynginx
容器的生命周期管理
容器的状态管理
查看运行中的容器
docker ps
该命令列出所有正在运行的容器。
查看所有容器(包括停止的)
docker ps -a
删除容器
docker rm <容器ID或容器名>
例如,删除mynginx容器:
docker rm mynginx
持久化存储 (Volumes)
Docker容器中的数据默认是临时的,当容器删除时,数据也随之删除。为了持久化数据,我们可以使用卷(Volumes)。
创建卷
docker volume create <卷名>
例如,创建一个名为myvolume的卷:
docker volume create myvolume
使用卷
在运行容器时挂载卷:
docker run -d -p 80:80 -v myvolume:/data nginx
该命令将myvolume挂载到容器内的/data目录。
查看卷
docker volume ls
删除卷
docker volume rm <卷名>
容器网络
Docker的网络模式
Docker提供了多种网络模式,用于配置容器之间的通信。
桥接网络 (Bridge Network)
默认网络模式。每个容器连接到一个桥接网络,可以通过容器IP进行通信。
docker run --network bridge <镜像>
主机网络 (Host Network)
容器与主机共享网络栈。
docker run --network host <镜像>
无网络 (None Network)
容器不连接到任何网络。
docker run --network none <镜像>
自定义网络
创建自定义桥接网络
docker network create <网络名>
例如,创建一个名为mynetwork的自定义桥接网络:
docker network create mynetwork
将容器连接到自定义网络
docker run --network mynetwork <镜像>
容器间通信
通过自定义网络,可以使用容器名直接进行通信。例如,在mynetwork中运行两个容器,一个容器可以通过另一个容器的名字进行通信:
docker run -d --network mynetwork --name container1 nginx
docker run -d --network mynetwork --name container2 nginx
此时,container2可以通过ping container1与container1通信。
容器日志与调试
容器日志查看 (docker logs)
docker logs命令用于查看容器的日志。语法如下:
docker logs <容器ID或容器名>
例如,查看mynginx容器的日志:
docker logs mynginx
容器调试技巧
查看容器内进程
docker top <容器ID或容器名>
检查容器的资源使用情况
docker stats <容器ID或容器名>
导出容器的元数据
docker inspect <容器ID或容器名>
Docker Compose
Docker Compose 是用于定义和运行多容器Docker应用程序的工具。通过一个简单的YAML文件,用户可以配置应用程序需要的所有服务,并使用单个命令启动和停止这些服务。Compose 是开发、测试和部署微服务架构应用的利器。
Docker Compose 通常与Docker一起安装,但也可以单独安装。以下是在不同平台上的安装步骤:
Linux:
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
MacOS: 使用 Homebrew 安装
brew install docker-compose
Windows: Docker Desktop 自带Docker Compose,安装 Docker Desktop 即可。
Docker Compose的基本概念
服务(Services)
在Docker Compose中,服务定义了一个容器的配置。一个服务可以是数据库、Web服务器等。Compose文件通过services关键字定义多个服务,每个服务对应一个容器。
网络(Networks)
Compose允许定义多个网络,服务可以连接到这些网络中进行通信。默认情况下,Compose会为所有服务创建一个默认网络。
卷(Volumes)
卷用于持久化存储。Compose允许定义卷,并将其挂载到服务的容器中。
Docker Compose文件格式
一个简单的docker-compose.yml文件示例如下:
version: '3'
services:
web:
image: nginx
ports:
- "80:80"
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
版本(Version)
Compose文件的版本定义了语法的格式,不同版本支持的功能有所不同。建议使用最新的版本(如3或3.8)。
version: '3.8'
服务配置详解
image: 指定使用的镜像
build: 指定构建镜像的上下文路径和Dockerfile
ports: 端口映射
environment: 环境变量
volumes: 卷的挂载
services:
web:
image: nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- db_data:/var/lib/mysql
网络配置
默认情况下,所有服务都连接到一个名为default的网络。可以定义自定义网络:
networks:
frontend:
backend:
并将服务连接到这些网络:
services:
web:
networks:
- frontend
db:
networks:
- backend
卷配置
在Compose文件中可以定义卷:
volumes:
db_data:
并将其挂载到服务的容器中:
services:
db:
volumes:
- db_data:/var/lib/mysql
Docker Compose的基本操作
启动和停止服务 (docker-compose up, docker-compose down)
启动服务:
docker-compose up
该命令将启动Compose文件中定义的所有服务,并在控制台中输出日志。
后台运行服务:
docker-compose up -d
停止服务:
docker-compose down
查看服务状态 (docker-compose ps)
docker-compose ps命令用于查看当前运行的服务状态:
docker-compose ps
重启服务 (docker-compose restart)
docker-compose restart命令用于重启服务:
docker-compose restart <服务名>
查看服务日志 (docker-compose logs)
docker-compose logs命令用于查看服务的日志:
docker-compose logs <服务名>
Docker Compose的高级功能
多环境配置
通过使用多个Compose文件,可以为不同的环境(如开发、测试、生产)定义不同的配置。
基础Compose文件 (docker-compose.yml):
version: '3.8'
services:
web:
image: nginx
ports:
- "80:80"
覆盖Compose文件 (docker-compose.override.yml):
version: '3.8'
services:
web:
environment:
- NGINX_ENV=development
启动服务时,会自动应用覆盖文件:
docker-compose up
自定义环境Compose文件:
例如,为生产环境创建docker-compose.prod.yml:
version: '3.8'
services:
web:
environment:
- NGINX_ENV=production
启动时指定环境文件:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
扩展服务
通过scale选项可以扩展服务的副本数量,用于负载均衡和高可用。
扩展服务副本:
docker-compose up -d --scale web=3
以上命令将启动3个web服务的副本。
依赖管理
可以通过depends_on选项管理服务启动的依赖关系。例如,web服务依赖于db服务:
services:
web:
image: nginx
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
假设我们要构建一个简单的Web应用程序,包括一个前端服务(使用nginx)、一个后端服务(使用Node.js)和一个数据库服务(使用MySQL)。
创建一个docker-compose.yml文件,定义前端、后端和数据库服务:
version: '3.8'
services:
frontend:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./frontend:/usr/share/nginx/html
networks:
- app-network
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "3000:3000"
networks:
- app-network
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: appdb
volumes:
- db_data:/var/lib/mysql
networks:
- app-network
networks:
app-network:
volumes:
db_data:
创建必要的目录和文件:
前端目录结构:
frontend/
└── index.html
后端目录结构:
backend/
├── Dockerfile
└── app.js
编写前端的index.html:
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<h1>Hello from Nginx</h1>
</body>
</html>
编写后端的Dockerfile:
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
编写后端的app.js:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello from Node.js');
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
启动应用:
docker-compose up -d
此时,应用的前端服务通过http://localhost访问,后端服务通过http://localhost:3000访问。
Docker Swarm
Docker Swarm是Docker原生的容器编排工具,用于在多主机上管理和编排Docker容器。Swarm集群由多个Docker引擎组成,提供了高可用性、扩展性和负载均衡等功能。使用Swarm,开发者可以像管理单个Docker实例一样,管理整个集群中的多个节点和容器。
Docker Swarm和Kubernetes是两种主要的容器编排工具。Swarm集成在Docker中,使用简单,适合中小型项目;Kubernetes功能强大,适合大规模复杂应用。根据项目需求选择合适的编排工具,是提升开发和运维效率的关键。
Docker Swarm的基本概念
节点(Nodes)
Swarm集群由多个节点组成。每个节点都是一个运行Docker的主机,分为管理节点(Manager Node)和工作节点(Worker Node)。管理节点负责集群管理和任务调度,工作节点负责实际运行容器。
服务(Services)
服务是Swarm管理的基本单位。服务定义了应用程序的容器镜像、运行参数和数量。Swarm会根据服务定义在集群中部署和管理容器。
任务(Tasks)
任务是服务的具体实例。每个任务对应一个运行中的容器,Swarm负责调度和管理任务,确保服务的高可用性和负载均衡。
堆栈(Stacks)
堆栈是由多个服务组成的应用程序。使用堆栈,开发者可以定义和管理整个应用的服务、网络和卷。堆栈文件类似于Compose文件,但适用于Swarm集群。
设置和管理Docker Swarm集群
初始化Swarm集群
在主机上初始化Swarm集群,使用docker swarm init命令:
docker swarm init --advertise-addr <管理节点IP>
初始化成功后,命令行会输出加入Swarm集群的命令和token。
加入和离开Swarm集群
在工作节点上,使用docker swarm join命令加入集群:
docker swarm join --token <worker-token> <管理节点IP>:2377
使用docker swarm leave命令离开集群:
docker swarm leave
在管理节点上使用docker swarm leave --force命令强制离开并停止集群:
docker swarm leave --force
管理节点和角色
查看节点列表:
docker node ls
提升节点为管理节点:
docker node promote <节点ID>
降级管理节点为工作节点:
docker node demote <节点ID>
创建和管理Swarm服务
创建服务
使用docker service create命令创建服务:
docker service create --name <服务名> --replicas <副本数量> <镜像>
例如,创建一个运行nginx的服务:
docker service create --name web --replicas 3 -p 80:80 nginx
更新服务
使用docker service update命令更新服务:
docker service update --replicas <新的副本数量> <服务名>
例如,将web服务的副本数量更新为5:
docker service update --replicas 5 web
删除服务
使用docker service rm命令删除服务:
docker service rm <服务名>
例如,删除web服务:
docker service rm web
查看服务状态
使用docker service ls命令查看服务列表:
docker service ls
使用docker service ps命令查看服务的任务状态:
docker service ps <服务名>
Swarm支持服务的滚动更新,确保应用程序在更新过程中保持高可用性。使用docker service update命令并指定更新参数:
docker service update --image <新镜像> <服务名>
例如,更新web服务的镜像:
docker service update --image nginx:latest web
如果服务更新出现问题,可以使用docker service rollback命令回滚到上一个版本:
docker service rollback <服务名>
Swarm支持创建覆盖网络,使容器可以跨主机通信。使用docker network create命令创建覆盖网络:
docker network create --driver overlay <网络名>
然后在服务创建时指定网络:
docker service create --name <服务名> --network <网络名> <镜像>
Swarm支持配置和密钥管理,确保敏感信息安全地传递给服务。使用docker config和docker secret命令管理配置和密钥。
例如,创建一个配置:
echo "my-config-data" | docker config create my-config -
在服务创建时使用配置:
docker service create --name <服务名> --config source=my-config,target=/path/in/container <镜像>
写在最后
Docker作为现代容器化技术的核心,极大地改变了软件开发、测试和部署的方式。
上一条:Aspose.Total for .NET 程序开发工具
下一条:如何缩小docker容器镜像
品质保证
多年的生产力软件专家
专业实力
资深技术支持项目实施团队
安全无忧
多位认证安全工程师
多元服务
软件提供方案整合,项目咨询实施
购软平台-找企业级软件,上购软平台。平台提供更齐全的软件产品、更专业的技术服务,同时提供行业资讯、软件使用教程和技巧。购软平台打造企业级数字产品综合应用服务平台。用户体验和数字类产品的专业化服务是我们不断追求的目标。购软平台您身边的企业级数字产品优秀服务商。