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 鏡像加速器配置
阿里云鏡像加速器
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
騰訊云鏡像加速器
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
網易云鏡像加速器
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安裝
# 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
# 啟動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 基礎命令
# 查看Docker版本
docker version# 查看Docker信息
docker info# 查看幫助
docker --help
3.2 鏡像命令
# 查看本地鏡像
docker images# 搜索鏡像
docker search nginx# 拉取鏡像
docker pull nginx:latest# 刪除鏡像
docker rmi -f 鏡像ID
3.3 容器命令
# 運行容器
docker run [參數] 鏡像名# 常用參數
-d # 后臺運行
-it # 交互式運行
-p # 端口映射
--name # 容器命名
-v # 數據卷掛載
--network # 網絡設置
3.4 高級命令
# 查看容器資源使用情況
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 批量操作命令
# 停止所有容器
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 鏡像操作
# 構建鏡像
docker build -t 鏡像名:標簽 .# 推送鏡像
docker push 鏡像名:標簽# 導入導出鏡像
docker save -o 文件名.tar 鏡像名
docker load -i 文件名.tar
五、容器數據卷
5.1 數據卷概念
- 數據卷是宿主機中的一個目錄或文件
- 容器數據卷可以實現數據持久化
- 支持容器間數據共享
5.2 數據卷操作
# 創建數據卷
docker volume create 數據卷名# 掛載數據卷
docker run -v 數據卷名:容器內路徑 鏡像名# 查看數據卷
docker volume ls
六、DockerFile
6.1 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 網絡操作
# 創建網絡
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 常用命令
# 啟動服務
docker-compose up -d# 停止服務
docker-compose down# 查看服務狀態
docker-compose ps# 查看服務日志
docker-compose logs
十、Docker Swarm
10.1 集群管理
- 創建Swarm集群
- 添加節點
- 部署服務
- 管理集群
10.2 常用命令
# 初始化Swarm
docker swarm init# 加入集群
docker swarm join# 部署服務
docker service create# 查看服務
docker service ls
十一、CI/CD Jenkins
11.1 Jenkins安裝
- 拉取Jenkins鏡像
# 拉取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
- 獲取初始管理員密碼:
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構建任務
// Jenkinsfile示例
pipeline {agent anyenvironment {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
# 在Git倉庫中配置Webhook - URL: http://your-jenkins-url/github-webhook/ - Content type: application/json - 選擇觸發事件:Push events
- 設置構建觸發器
// Jenkinsfile中的觸發器配置 triggers {githubPush()// 或使用cron表達式定時觸發cron('H/15 * * * *') }
- 配置分支策略
// 多分支流水線配置 pipeline {agent nonestages {stage('Build') {when {branch 'main' // 主分支}steps {// 構建步驟}}stage('Test') {when {branch 'develop' // 開發分支}steps {// 測試步驟}}} }
- 構建Docker鏡像
- 編寫Dockerfile
# 多階段構建示例 FROM maven:3.8.4-openjdk-11 AS builder WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTestsFROM openjdk:11-jre-slim WORKDIR /app COPY --from=builder /app/target/*.jar app.jar EXPOSE 8080 CMD ["java", "-jar", "app.jar"]
- 配置構建參數
// 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: '是否跳過測試') }
- 設置構建環境
// Jenkinsfile中的環境配置 environment {DOCKER_BUILDKIT = 1MAVEN_OPTS = '-Xmx2048m'JAVA_HOME = tool 'JDK11' }
- 推送到鏡像倉庫
- 配置鏡像倉庫地址
// Jenkinsfile中的倉庫配置 environment {REGISTRY = 'registry.example.com'REGISTRY_CREDENTIALS = 'registry-credentials' }
- 設置鏡像標簽策略
// 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") }
- 配置推送權限
# 配置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}" }
- 部署到目標服務器
- 配置部署環境
# docker-compose.yml示例 version: '3.8' services:app:image: ${DOCKER_IMAGE}:${DOCKER_TAG}ports:- "8080:8080"environment:- SPRING_PROFILES_ACTIVE=${ENVIRONMENT}- DB_HOST=dbdepends_on:- dbdb:image: mysql:8.0environment:- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}volumes:- db_data:/var/lib/mysql
- 設置部署策略
// Jenkinsfile中的部署策略 stage('Deploy') {when {branch 'main' // 僅主分支部署}steps {script {// 滾動更新策略sh """docker-compose pulldocker-compose up -d --no-deps --build app"""}} }
- 配置健康檢查
# docker-compose.yml中的健康檢查 services:app:healthcheck:test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]interval: 30stimeout: 10sretries: 3
11.4 最佳實踐
- 安全性配置
- 使用Docker安全掃描
# 使用Trivy進行安全掃描 docker run aquasec/trivy image your-image:tag# 使用Snyk進行安全掃描 snyk test --docker your-image:tag
- 配置鏡像簽名
# 使用Docker Content Trust export DOCKER_CONTENT_TRUST=1 docker push your-image:tag
- 實施訪問控制
# 配置Docker訪問控制 {"authorization-plugins": ["authz-broker"],"tls": true,"tlscacert": "/path/to/ca.pem","tlscert": "/path/to/server-cert.pem","tlskey": "/path/to/server-key.pem" }
- 性能優化
- 使用多階段構建
# 優化后的多階段構建 FROM node:16 AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run buildFROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf
- 優化鏡像大小
# 使用.dockerignore排除文件 .git node_modules npm-debug.log Dockerfile .dockerignore
- 配置緩存策略
# docker-compose.yml中的緩存配置 services:app:build:cache_from:- your-image:latestcache_to:- type=inline
- 監控告警
- 配置構建通知
// Jenkinsfile中的通知配置 post {success {emailext body: '構建成功!', subject: '構建通知', to: 'team@example.com'}failure {emailext body: '構建失敗!', subject: '構建失敗通知', to: 'team@example.com'} }
- 設置部署狀態監控
# Prometheus監控配置 metrics:- name: container_cpu_usagetype: gaugehelp: "Container CPU usage"- name: container_memory_usagetype: gaugehelp: "Container memory usage"
- 配置錯誤告警
// Jenkinsfile中的錯誤處理 try {sh 'docker-compose up -d' } catch (Exception e) {currentBuild.result = 'FAILURE'error "部署失敗: ${e.message}" }
- 備份策略
- 定期備份Jenkins配置
# 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鏡像
# Docker鏡像備份腳本 #!/bin/bash BACKUP_DIR="/backup/docker" DATE=$(date +%Y%m%d)# 備份所有鏡像 docker images | grep -v "REPOSITORY" | awk '{print $1":"$2}' | while read image; dodocker save -o ${BACKUP_DIR}/${image//\//_}_${DATE}.tar $image done
- 配置數據恢復方案
# 數據恢復腳本 #!/bin/bash BACKUP_FILE=$1# 恢復Jenkins配置 tar -xzf ${BACKUP_FILE} -C /var/jenkins_home/# 重啟Jenkins服務 docker restart jenkins
十二、故障排查與常見問題
12.1 常見問題解決方案
- 容器無法啟動
# 查看容器日志
docker logs 容器ID# 檢查容器狀態
docker inspect 容器ID# 檢查端口占用
netstat -tulpn | grep 端口號# 檢查容器資源限制
docker stats 容器ID
- 鏡像構建失敗
# 查看構建日志
docker build -t 鏡像名 . --progress=plain# 清理構建緩存
docker builder prune# 檢查Dockerfile語法
docker build -t 鏡像名 . --no-cache
- 網絡連接問題
# 檢查網絡配置
docker network inspect 網絡名# 檢查DNS配置
docker run --rm busybox nslookup 域名# 檢查防火墻規則
iptables -L
12.2 性能優化建議
- 容器資源限制
# 限制CPU使用
docker run --cpus=2 鏡像名# 限制內存使用
docker run --memory=512m 鏡像名# 限制IO
docker run --device-read-bps=/dev/sda:1mb 鏡像名
- 存儲優化
# 使用數據卷
docker run -v 數據卷名:容器內路徑 鏡像名# 使用綁定掛載
docker run -v 本地路徑:容器內路徑 鏡像名# 使用tmpfs
docker run --tmpfs /tmp 鏡像名
十三、Docker與Kubernetes集成
13.1 基本概念
- Pod:Kubernetes中最小的部署單元
- Service:服務發現和負載均衡
- Deployment:聲明式更新
- ConfigMap:配置管理
- Secret:密鑰管理
13.2 部署示例
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: my-app
spec:replicas: 3selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: my-appimage: your-image:tagports:- containerPort: 8080resources:limits:cpu: "1"memory: "512Mi"requests:cpu: "500m"memory: "256Mi"
13.3 服務配置
# service.yaml
apiVersion: v1
kind: Service
metadata:name: my-app-service
spec:selector:app: my-appports:- port: 80targetPort: 8080type: LoadBalancer
13.4 配置管理
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: my-app-config
data:config.json: |{"database": {"host": "db-service","port": 3306}}
參考資料
- Docker 官方文檔
- Docker Hub
- Docker Compose 文檔
- Jenkins 官方文檔