Docker 技术详解
一、概述
Docker官网:https://docs.docker.com/
菜鸟教程:https://www.runoob.com/docker/docker-tutorial.html
1.1 什么是Docker?
Docker 是一个开源的容器化平台,它允许开发者将应用程序和其依赖项打包到一个称为容器的标准化单元中。容器可以在任何支持 Docker 的环境中运行,确保了应用程序在不同环境中的一致性。
1.2 Docker的发展历程
- 2013年:Docker项目启动
- 2014年:Docker 1.0发布
- 2015年:Docker Compose发布
- 2016年:Docker Swarm发布
- 2017年:Docker企业版发布
- 2018年:Docker Desktop发布
- 2019年:Docker Desktop for Windows 2.0发布
- 2020年:Docker Desktop for Mac with Apple Silicon发布
- 2021年:Docker Compose V2发布
- 2022年:Docker Desktop 4.0发布
1.3 Docker的优势
- 环境一致性:确保开发、测试、生产环境的一致性
- 快速部署:容器化应用可以快速部署和扩展
- 资源隔离:每个容器都有独立的资源空间
- 轻量级:相比虚拟机,容器更加轻量级
- 可移植性:一次构建,到处运行
1.4 Docker的应用场景
- 微服务架构
- 持续集成/持续部署(CI/CD)
- 开发环境标准化
- 应用程序隔离
- 快速原型开发
二、安装与配置
2.1 下载地址
官方下载地址
- Docker Desktop for Windows: https://www.docker.com/products/docker-desktop
- Docker Desktop for Mac: https://www.docker.com/products/docker-desktop
- Docker Engine for Linux: https://docs.docker.com/engine/install/
阿里云镜像下载地址
- Docker CE 镜像:https://mirrors.aliyun.com/docker-ce/linux/ubuntu/dists/
- Docker Desktop for Windows:https://mirrors.aliyun.com/docker-toolbox/
- Docker Desktop for Mac:https://mirrors.aliyun.com/docker-toolbox/
2.2 镜像加速器配置
阿里云镜像加速器
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
腾讯云镜像加速器
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
网易云镜像加速器
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2.3 Windows安装
- 下载Docker Desktop for Windows
- 运行安装程序
- 启用WSL2(Windows Subsystem for Linux)
- 配置系统要求:
- Windows 10/11 专业版、企业版或教育版
- 启用Hyper-V和Windows容器功能
- 至少4GB RAM
2.4 Linux安装
bash
# Ubuntu安装
sudo apt-get update
sudo apt-get install docker.io
# CentOS安装
sudo yum install docker-ce docker-ce-cli containerd.io
2.5 配置Docker
bash
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 配置镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
三、Docker命令
3.1 基础命令
bash
# 查看Docker版本
docker version
# 查看Docker信息
docker info
# 查看帮助
docker --help
3.2 镜像命令
bash
# 查看本地镜像
docker images
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 删除镜像
docker rmi -f 镜像ID
3.3 容器命令
bash
# 运行容器
docker run [参数] 镜像名
# 常用参数
-d # 后台运行
-it # 交互式运行
-p # 端口映射
--name # 容器命名
-v # 数据卷挂载
--network # 网络设置
3.4 高级命令
bash
# 查看容器资源使用情况
docker stats
# 查看容器日志
docker logs -f 容器ID
# 进入容器内部
docker exec -it 容器ID /bin/bash
# 查看容器详细信息
docker inspect 容器ID
# 查看容器端口映射
docker port 容器ID
# 查看容器变更
docker diff 容器ID
# 复制文件到容器
docker cp 本地文件路径 容器ID:容器内路径
# 从容器复制文件
docker cp 容器ID:容器内路径 本地文件路径
3.5 批量操作命令
bash
# 停止所有容器
docker stop $(docker ps -aq)
# 删除所有容器
docker rm $(docker ps -aq)
# 删除所有镜像
docker rmi $(docker images -q)
# 清理未使用的数据卷
docker volume prune
# 清理未使用的网络
docker network prune
# 清理所有未使用的资源
docker system prune -a
四、Docker镜像
4.1 镜像原理
- 镜像是一个轻量级、可执行的独立软件包
- 包含运行某个软件所需的所有内容
- 采用分层存储架构
4.2 镜像操作
bash
# 构建镜像
docker build -t 镜像名:标签 .
# 推送镜像
docker push 镜像名:标签
# 导入导出镜像
docker save -o 文件名.tar 镜像名
docker load -i 文件名.tar
五、容器数据卷
5.1 数据卷概念
- 数据卷是宿主机中的一个目录或文件
- 容器数据卷可以实现数据持久化
- 支持容器间数据共享
5.2 数据卷操作
bash
# 创建数据卷
docker volume create 数据卷名
# 挂载数据卷
docker run -v 数据卷名:容器内路径 镜像名
# 查看数据卷
docker volume ls
六、DockerFile
6.1 DockerFile指令
dockerfile
# 基础镜像
FROM 镜像名:标签
# 维护者信息
MAINTAINER 作者名
# 构建参数
ARG 参数名=默认值
# 环境变量
ENV 环境变量名=值
# 工作目录
WORKDIR 路径
# 复制文件
COPY 源路径 目标路径
# 添加文件
ADD 源路径 目标路径
# 执行命令
RUN 命令
# 暴露端口
EXPOSE 端口号
# 启动命令
CMD ["命令", "参数"]
6.2 构建过程
- 编写Dockerfile
- 构建镜像:
docker build -t 镜像名 .
- 运行容器:
docker run -d 镜像名
七、Docker网络原理
7.1 网络模式
- bridge:桥接模式(默认)
- host:主机模式
- none:无网络模式
- container:容器模式
7.2 网络操作
bash
# 创建网络
docker network create 网络名
# 查看网络
docker network ls
# 连接容器到网络
docker network connect 网络名 容器名
八、IDEA整合Docker
8.1 安装插件
- 打开IDEA设置
- 搜索"Docker"
- 安装Docker插件
8.2 配置Docker
- 配置Docker连接
- 设置Docker主机地址
- 配置证书路径(如需要)
8.3 使用Docker
- 构建镜像
- 运行容器
- 管理容器
- 查看日志
九、Docker Compose
9.1 基本概念
- 用于定义和运行多容器Docker应用
- 使用YAML文件配置应用服务
- 一键部署多个容器
9.2 常用命令
bash
# 启动服务
docker-compose up -d
# 停止服务
docker-compose down
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs
十、Docker Swarm
10.1 集群管理
- 创建Swarm集群
- 添加节点
- 部署服务
- 管理集群
10.2 常用命令
bash
# 初始化Swarm
docker swarm init
# 加入集群
docker swarm join
# 部署服务
docker service create
# 查看服务
docker service ls
十一、CI/CD Jenkins
11.1 Jenkins安装
- 拉取Jenkins镜像
bash
# 拉取Jenkins LTS版本镜像
docker pull jenkins/jenkins:lts
# 创建Jenkins数据卷
docker volume create jenkins_home
# 运行Jenkins容器
docker run -d \
--name jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:lts
- 配置Jenkins
- 访问 http://localhost:8080
- 获取初始管理员密码:
bash
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
- 安装推荐插件
- 创建管理员账户
- 配置Jenkins URL
11.2 配置Docker集成
- 安装Docker插件
- 进入 Manage Jenkins > Manage Plugins
- 安装以下插件:
- Docker Pipeline
- Docker plugin
- Docker API Plugin
- docker-build-step
- 配置Docker凭据
- 进入 Manage Jenkins > Manage Credentials
- 添加Docker凭据:
- 类型选择:Username with password
- 添加Docker Hub账号信息
- 或添加私有镜像仓库凭据
- 创建Docker构建任务
groovy
// Jenkinsfile示例
pipeline {
agent any
environment {
DOCKER_IMAGE = 'your-app'
DOCKER_TAG = 'latest'
}
stages {
stage('Checkout') {
steps {
git 'your-git-repo-url'
}
}
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Docker Build') {
steps {
script {
docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
}
}
}
stage('Docker Push') {
steps {
script {
docker.withRegistry('https://registry.example.com', 'registry-credentials') {
docker.image("${DOCKER_IMAGE}:${DOCKER_TAG}").push()
}
}
}
}
stage('Deploy') {
steps {
sh """
docker pull ${DOCKER_IMAGE}:${DOCKER_TAG}
docker-compose up -d
"""
}
}
}
}
11.3 自动化部署流程
- 代码提交触发构建
-
配置Git Webhook
bash# 在Git仓库中配置Webhook - URL: http://your-jenkins-url/github-webhook/ - Content type: application/json - 选择触发事件:Push events
-
设置构建触发器
groovy// Jenkinsfile中的触发器配置 triggers { githubPush() // 或使用cron表达式定时触发 cron('H/15 * * * *') }
-
配置分支策略
groovy// 多分支流水线配置 pipeline { agent none stages { stage('Build') { when { branch 'main' // 主分支 } steps { // 构建步骤 } } stage('Test') { when { branch 'develop' // 开发分支 } steps { // 测试步骤 } } } }
- 构建Docker镜像
-
编写Dockerfile
dockerfile# 多阶段构建示例 FROM maven:3.8.4-openjdk-11 AS builder WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTests FROM openjdk:11-jre-slim WORKDIR /app COPY --from=builder /app/target/*.jar app.jar EXPOSE 8080 CMD ["java", "-jar", "app.jar"]
-
配置构建参数
groovy// Jenkinsfile中的参数配置 parameters { string(name: 'VERSION', defaultValue: '1.0.0', description: '版本号') choice(name: 'ENVIRONMENT', choices: ['dev', 'test', 'prod'], description: '部署环境') booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: '是否跳过测试') }
-
设置构建环境
groovy// Jenkinsfile中的环境配置 environment { DOCKER_BUILDKIT = 1 MAVEN_OPTS = '-Xmx2048m' JAVA_HOME = tool 'JDK11' }
- 推送到镜像仓库
-
配置镜像仓库地址
groovy// Jenkinsfile中的仓库配置 environment { REGISTRY = 'registry.example.com' REGISTRY_CREDENTIALS = 'registry-credentials' }
-
设置镜像标签策略
groovy// Jenkinsfile中的标签策略 script { def imageTag = "${env.BUILD_NUMBER}-${env.GIT_COMMIT.take(7)}" docker.build("${REGISTRY}/${DOCKER_IMAGE}:${imageTag}") docker.tag("${REGISTRY}/${DOCKER_IMAGE}:${imageTag}", "${REGISTRY}/${DOCKER_IMAGE}:latest") }
-
配置推送权限
bash# 配置Docker登录 docker login registry.example.com -u username -p password # 或使用Jenkins凭据 withCredentials([usernamePassword(credentialsId: 'registry-credentials', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASSWORD')]) { sh "docker login ${REGISTRY} -u ${DOCKER_USER} -p ${DOCKER_PASSWORD}" }
- 部署到目标服务器
-
配置部署环境
yaml# docker-compose.yml示例 version: '3.8' services: app: image: ${DOCKER_IMAGE}:${DOCKER_TAG} ports: - "8080:8080" environment: - SPRING_PROFILES_ACTIVE=${ENVIRONMENT} - DB_HOST=db depends_on: - db db: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=${DB_PASSWORD} volumes: - db_data:/var/lib/mysql
-
设置部署策略
groovy// Jenkinsfile中的部署策略 stage('Deploy') { when { branch 'main' // 仅主分支部署 } steps { script { // 滚动更新策略 sh """ docker-compose pull docker-compose up -d --no-deps --build app """ } } }
-
配置健康检查
yaml# docker-compose.yml中的健康检查 services: app: healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] interval: 30s timeout: 10s retries: 3
11.4 最佳实践
- 安全性配置
-
使用Docker安全扫描
bash# 使用Trivy进行安全扫描 docker run aquasec/trivy image your-image:tag # 使用Snyk进行安全扫描 snyk test --docker your-image:tag
-
配置镜像签名
bash# 使用Docker Content Trust export DOCKER_CONTENT_TRUST=1 docker push your-image:tag
-
实施访问控制
yaml# 配置Docker访问控制 { "authorization-plugins": ["authz-broker"], "tls": true, "tlscacert": "/path/to/ca.pem", "tlscert": "/path/to/server-cert.pem", "tlskey": "/path/to/server-key.pem" }
- 性能优化
-
使用多阶段构建
dockerfile# 优化后的多阶段构建 FROM node:16 AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf
-
优化镜像大小
dockerfile# 使用.dockerignore排除文件 .git node_modules npm-debug.log Dockerfile .dockerignore
-
配置缓存策略
yaml# docker-compose.yml中的缓存配置 services: app: build: cache_from: - your-image:latest cache_to: - type=inline
- 监控告警
-
配置构建通知
groovy// Jenkinsfile中的通知配置 post { success { emailext body: '构建成功!', subject: '构建通知', to: '[email protected]' } failure { emailext body: '构建失败!', subject: '构建失败通知', to: '[email protected]' } }
-
设置部署状态监控
yaml# Prometheus监控配置 metrics: - name: container_cpu_usage type: gauge help: "Container CPU usage" - name: container_memory_usage type: gauge help: "Container memory usage"
-
配置错误告警
groovy// Jenkinsfile中的错误处理 try { sh 'docker-compose up -d' } catch (Exception e) { currentBuild.result = 'FAILURE' error "部署失败: ${e.message}" }
- 备份策略
-
定期备份Jenkins配置
bash# Jenkins配置备份脚本 #!/bin/bash BACKUP_DIR="/backup/jenkins" DATE=$(date +%Y%m%d) # 备份Jenkins配置 tar -czf ${BACKUP_DIR}/jenkins_config_${DATE}.tar.gz /var/jenkins_home/ # 保留最近30天的备份 find ${BACKUP_DIR} -name "jenkins_config_*.tar.gz" -mtime +30 -delete
-
备份Docker镜像
bash# Docker镜像备份脚本 #!/bin/bash BACKUP_DIR="/backup/docker" DATE=$(date +%Y%m%d) # 备份所有镜像 docker images | grep -v "REPOSITORY" | awk '{print $1":"$2}' | while read image; do docker save -o ${BACKUP_DIR}/${image//\//_}_${DATE}.tar $image done
-
配置数据恢复方案
bash# 数据恢复脚本 #!/bin/bash BACKUP_FILE=$1 # 恢复Jenkins配置 tar -xzf ${BACKUP_FILE} -C /var/jenkins_home/ # 重启Jenkins服务 docker restart jenkins
十二、故障排查与常见问题
12.1 常见问题解决方案
- 容器无法启动
bash
# 查看容器日志
docker logs 容器ID
# 检查容器状态
docker inspect 容器ID
# 检查端口占用
netstat -tulpn | grep 端口号
# 检查容器资源限制
docker stats 容器ID
- 镜像构建失败
bash
# 查看构建日志
docker build -t 镜像名 . --progress=plain
# 清理构建缓存
docker builder prune
# 检查Dockerfile语法
docker build -t 镜像名 . --no-cache
- 网络连接问题
bash
# 检查网络配置
docker network inspect 网络名
# 检查DNS配置
docker run --rm busybox nslookup 域名
# 检查防火墙规则
iptables -L
12.2 性能优化建议
- 容器资源限制
bash
# 限制CPU使用
docker run --cpus=2 镜像名
# 限制内存使用
docker run --memory=512m 镜像名
# 限制IO
docker run --device-read-bps=/dev/sda:1mb 镜像名
- 存储优化
bash
# 使用数据卷
docker run -v 数据卷名:容器内路径 镜像名
# 使用绑定挂载
docker run -v 本地路径:容器内路径 镜像名
# 使用tmpfs
docker run --tmpfs /tmp 镜像名
十三、Docker与Kubernetes集成
13.1 基本概念
- Pod:Kubernetes中最小的部署单元
- Service:服务发现和负载均衡
- Deployment:声明式更新
- ConfigMap:配置管理
- Secret:密钥管理
13.2 部署示例
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: your-image:tag
ports:
- containerPort: 8080
resources:
limits:
cpu: "1"
memory: "512Mi"
requests:
cpu: "500m"
memory: "256Mi"
13.3 服务配置
yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
13.4 配置管理
yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data:
config.json: |
{
"database": {
"host": "db-service",
"port": 3306
}
}