基礎概念類
1. 什么是Docker?它解決了什么問題?
解析:
Docker是一個開源的容器化平臺,用于開發、交付和運行應用程序。
主要解決的問題:
- 環境一致性:解決"在我機器上能跑"的問題
- 資源利用率:比虛擬機更輕量,啟動更快
- 應用隔離:不同應用間互不干擾
- 部署簡化:一次構建,到處運行
- 微服務架構:支持服務拆分和獨立部署
2. Docker容器和虛擬機有什么區別?
解析:
特性 | Docker容器 | 虛擬機 |
---|---|---|
隔離級別 | 進程級隔離 | 硬件級隔離 |
啟動時間 | 秒級 | 分鐘級 |
資源占用 | 輕量(MB級) | 重量(GB級) |
性能損耗 | 幾乎無損耗 | 5-20%損耗 |
操作系統 | 共享宿主機內核 | 獨立操作系統 |
詳細說明:
- 容器直接運行在宿主機操作系統上,共享內核
- 虛擬機需要完整的Guest OS,通過Hypervisor管理
- 容器更適合微服務架構,虛擬機更適合完全隔離的場景
3. 解釋Docker的核心組件
解析:
Docker Engine: Docker的核心運行時
- Docker Daemon (dockerd):后臺進程,管理容器生命周期
- Docker CLI:命令行接口
- REST API:程序化接口
關鍵對象:
- Image(鏡像):只讀模板,包含運行應用所需的一切
- Container(容器):鏡像的運行實例
- Registry(注冊表):存儲和分發鏡像的服務
- Dockerfile:構建鏡像的腳本文件
4. 什么是Docker鏡像的分層結構?
解析:
Docker鏡像采用聯合文件系統(Union File System),具有分層結構:
分層原理:
應用層 ← 可寫層(Container Layer)
├── App層 ← FROM ubuntu:18.04
├── 依賴層 ← RUN apt-get install
├── 基礎層 ← Ubuntu系統文件
└── 內核層 ← 宿主機內核(共享)
優勢:
- 空間效率:相同的層可以被多個鏡像共享
- 構建速度:只重新構建改變的層
- 網絡效率:只傳輸變化的層
- 版本管理:每層都有唯一ID
5. Dockerfile中的關鍵指令及其作用
解析:
# 基礎鏡像
FROM ubuntu:20.04# 維護者信息
LABEL maintainer="developer@example.com"# 工作目錄
WORKDIR /app# 復制文件
COPY . /app
ADD https://example.com/file.tar.gz /tmp/# 執行命令
RUN apt-get update && apt-get install -y python3
RUN pip install -r requirements.txt# 環境變量
ENV NODE_ENV=production
ENV PATH=$PATH:/app/bin# 暴露端口
EXPOSE 3000 8080# 掛載點
VOLUME ["/data", "/logs"]# 用戶切換
USER nobody# 啟動命令
CMD ["python3", "app.py"]
ENTRYPOINT ["./entrypoint.sh"]
CMD vs ENTRYPOINT 區別:
- CMD:可被docker run參數覆蓋
- ENTRYPOINT:不可覆蓋,run參數作為ENTRYPOINT的參數
實操命令類
6. 常用的Docker命令有哪些?
解析:
鏡像管理:
# 拉取鏡像
docker pull nginx:1.20# 查看鏡像
docker images
docker image ls# 構建鏡像
docker build -t myapp:1.0 .
docker build -f Dockerfile.prod -t myapp:prod .# 刪除鏡像
docker rmi image_id
docker image prune # 刪除懸掛鏡像
容器管理:
# 運行容器
docker run -d -p 8080:80 --name web nginx
docker run -it ubuntu bash # 交互模式# 查看容器
docker ps # 運行中的容器
docker ps -a # 所有容器# 容器操作
docker start/stop/restart container_id
docker exec -it container_id bash
docker logs container_id
docker inspect container_id
7. 如何進入正在運行的容器?
解析:
方法一:docker exec (推薦)
# 啟動新的bash會話
docker exec -it container_name bash
docker exec -it container_name sh# 執行單個命令
docker exec container_name ls -la /app
方法二:docker attach
# 附加到容器主進程
docker attach container_name
# 注意:Ctrl+C會停止容器
區別:
exec
:創建新進程,不影響容器主進程attach
:連接到主進程,退出可能影響容器運行
8. 如何實現容器間通信?
解析:
方法一:自定義網絡(推薦)
# 創建網絡
docker network create mynetwork# 運行容器并加入網絡
docker run -d --network mynetwork --name web nginx
docker run -d --network mynetwork --name db mysql# 容器間可通過服務名通信
# web容器內可以通過 'db:3306' 訪問數據庫
方法二:Link (已廢棄)
docker run -d --name db mysql
docker run -d --link db:database nginx
方法三:共享網絡棧
docker run -d --name web nginx
docker run -d --network container:web redis
9. Docker數據持久化的方式
解析:
Volume (推薦方式)
# 創建命名卷
docker volume create mydata# 使用卷
docker run -d -v mydata:/data nginx
docker run -d --mount source=mydata,target=/data nginx# 匿名卷
docker run -d -v /data nginx
Bind Mount
# 綁定宿主機目錄
docker run -d -v /host/path:/container/path nginx
docker run -d --mount type=bind,source=/host/path,target=/container/path nginx
tmpfs Mount
# 內存文件系統
docker run -d --tmpfs /tmp nginx
docker run -d --mount type=tmpfs,destination=/tmp nginx
區別對比:
- Volume:Docker管理,跨平臺,性能好
- Bind Mount:直接映射宿主機路徑,靈活但依賴宿主機
- tmpfs:內存存儲,重啟后數據丟失
10. 如何查看容器資源使用情況?
解析:
實時監控:
# 查看所有容器資源使用
docker stats# 查看特定容器
docker stats container_name# 不持續刷新
docker stats --no-stream
詳細信息:
# 查看容器詳細配置
docker inspect container_name# 查看容器進程
docker top container_name# 查看端口映射
docker port container_name
系統級監控:
# 查看Docker系統信息
docker system df # 磁盤使用
docker system events # 事件流
docker system info # 系統信息
網絡和存儲
11. Docker的網絡模式有哪些?
解析:
Bridge模式 (默認)
docker run -d --network bridge nginx
- 容器連接到docker0網橋
- 容器間可通信,需端口映射訪問外部
Host模式
docker run -d --network host nginx
- 容器直接使用宿主機網絡
- 性能最好,但端口沖突風險高
None模式
docker run -d --network none nginx
- 容器無網絡接口
- 適用于批處理作業
Container模式
docker run -d --network container:other_container nginx
- 共享其他容器的網絡棧
自定義網絡
# 創建bridge網絡
docker network create --driver bridge mynet# 創建overlay網絡(Swarm)
docker network create --driver overlay --attachable myoverlay
12. 如何配置容器的資源限制?
解析:
內存限制:
# 限制內存使用
docker run -d --memory 512m nginx
docker run -d -m 1g --memory-swap 2g nginx# 內存交換配置
--memory-swap=2g # 總計2G(包含內存)
--memory-swap=0 # 禁用交換
--memory-swap=-1 # 無限制交換
CPU限制:
# CPU份額(相對權重)
docker run -d --cpu-shares 512 nginx# CPU核心數
docker run -d --cpus 1.5 nginx
docker run -d --cpuset-cpus 0,1 nginx# CPU配額
docker run -d --cpu-period 100000 --cpu-quota 50000 nginx
磁盤IO限制:
# 讀寫速率限制
docker run -d --device-read-bps /dev/sda:1mb nginx
docker run -d --device-write-bps /dev/sda:1mb nginx# IOPS限制
docker run -d --device-read-iops /dev/sda:1000 nginx
13. Docker Compose的作用和基本使用
解析:
作用:
- 定義和運行多容器應用
- 使用YAML文件配置服務
- 一鍵啟動整個應用棧
基本配置示例:
version: '3.8'services:web:build: .ports:- "8000:8000"volumes:- .:/appenvironment:- DEBUG=1depends_on:- db- redisdb:image: postgres:13environment:POSTGRES_DB: myappPOSTGRES_USER: userPOSTGRES_PASSWORD: passwordvolumes:- postgres_data:/var/lib/postgresql/dataredis:image: redis:6-alpineports:- "6379:6379"volumes:postgres_data:networks:default:driver: bridge
常用命令:
# 啟動服務
docker-compose up -d# 查看服務狀態
docker-compose ps# 查看日志
docker-compose logs web# 停止和清理
docker-compose down
docker-compose down -v # 同時刪除卷
14. 如何實現Docker容器的健康檢查?
解析:
在Dockerfile中定義:
FROM nginx# HTTP健康檢查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \CMD curl -f http://localhost/ || exit 1# 命令執行檢查
HEALTHCHECK --interval=30s --timeout=3s \CMD service nginx status || exit 1# 自定義腳本檢查
COPY healthcheck.sh /usr/local/bin/
HEALTHCHECK --interval=30s --timeout=10s \CMD /usr/local/bin/healthcheck.sh
在docker run中定義:
docker run -d \--health-cmd "curl -f http://localhost/ || exit 1" \--health-interval 30s \--health-timeout 3s \--health-retries 3 \nginx
在docker-compose中定義:
services:web:image: nginxhealthcheck:test: ["CMD", "curl", "-f", "http://localhost"]interval: 30stimeout: 10sretries: 3start_period: 40s
健康檢查腳本示例:
#!/bin/bash
# healthcheck.sh# 檢查進程
if ! pgrep nginx > /dev/null; thenexit 1
fi# 檢查端口
if ! nc -z localhost 80; thenexit 1
fi# 檢查HTTP響應
if ! curl -f http://localhost/health; thenexit 1
fiexit 0
15. Docker鏡像的多階段構建
解析:
傳統單階段構建問題:
- 鏡像包含構建工具,體積大
- 安全風險,包含不必要的依賴
多階段構建解決方案:
# 第一階段:構建階段
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=productionCOPY . .
RUN npm run build# 第二階段:生產階段
FROM nginx:alpine AS production
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]# 第三階段:開發階段
FROM node:16 AS development
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
構建不同目標:
# 構建生產鏡像
docker build --target production -t myapp:prod .# 構建開發鏡像
docker build --target development -t myapp:dev .
復雜示例 (Go應用):
# 編譯階段
FROM golang:1.19 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o app .# 運行階段
FROM alpine:latest AS runner
WORKDIR /root/
RUN apk --no-cache add ca-certificates tzdata
COPY --from=builder /src/app .
CMD ["./app"]
高級特性
16. Docker Swarm集群的基本概念
解析:
核心概念:
- Node: 集群中的Docker引擎實例
- Manager Node: 管理集群狀態,調度任務
- Worker Node: 執行任務
- Service: 在集群上運行的應用定義
- Task: Service的最小調度單位
- Stack: 相關服務的集合
集群初始化:
# 初始化Swarm集群
docker swarm init --advertise-addr 192.168.1.100# 加入Worker節點
docker swarm join --token SWMTKN-xxx 192.168.1.100:2377# 加入Manager節點
docker swarm join-token manager
服務管理:
# 創建服務
docker service create --name web --replicas 3 -p 80:80 nginx# 擴縮容
docker service scale web=5# 更新服務
docker service update --image nginx:1.20 web# 查看服務
docker service ls
docker service ps web
17. 如何實現Docker鏡像的安全掃描?
解析:
使用Docker Scan (已集成Snyk):
# 掃描本地鏡像
docker scan myapp:latest# 掃描指定層級
docker scan --severity high myapp:latest# 輸出JSON格式
docker scan --json myapp:latest
使用Trivy進行掃描:
# 安裝Trivy
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \aquasec/trivy image myapp:latest# 掃描特定漏洞類型
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \aquasec/trivy image --vuln-type os,library myapp:latest
安全最佳實踐:
# 使用官方基礎鏡像
FROM node:16-alpine# 創建非root用戶
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001# 最小化安裝
RUN apk add --no-cache libc6-compat# 復制必要文件
COPY --chown=nextjs:nodejs package*.json ./
RUN npm ci --only=production && npm cache clean --force# 切換到非root用戶
USER nextjs# 不暴露敏感信息
ARG BUILD_TIME
ENV NODE_ENV=production
18. Docker的日志管理策略
解析:
默認日志驅動 (json-file):
# 配置日志大小和輪轉
docker run -d \--log-opt max-size=10m \--log-opt max-file=3 \nginx# 查看日志
docker logs container_name
docker logs -f --tail 100 container_name
其他日志驅動:
# Syslog
docker run -d --log-driver syslog --log-opt syslog-address=tcp://192.168.1.42:123 nginx# Journald
docker run -d --log-driver journald nginx# Fluentd
docker run -d --log-driver fluentd --log-opt fluentd-address=localhost:24224 nginx# 禁用日志
docker run -d --log-driver none nginx
集中化日志方案:
# docker-compose.yml
version: '3.8'services:app:image: myapplogging:driver: "fluentd"options:fluentd-address: localhost:24224tag: myappfluentd:image: fluent/fluentd:v1.14ports:- "24224:24224"volumes:- ./fluentd.conf:/fluentd/etc/fluent.conf- ./logs:/var/log
19. Docker性能優化技巧
解析:
鏡像優化:
# 使用多階段構建
FROM node:16 AS builder
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run buildFROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html# 使用.dockerignore
# .dockerignore內容:
node_modules
.git
*.md
.env.local
層優化:
# 錯誤方式 - 每個RUN創建一層
RUN apt-get update
RUN apt-get install -y python3
RUN apt-get install -y pip
RUN apt-get clean# 正確方式 - 合并RUN指令
RUN apt-get update && \apt-get install -y python3 pip && \apt-get clean && \rm -rf /var/lib/apt/lists/*
運行時優化:
# 限制資源使用
docker run -d \--memory 512m \--cpus 1.0 \--restart unless-stopped \myapp# 使用init進程處理僵尸進程
docker run -d --init myapp
構建緩存優化:
# 利用構建緩存
COPY package.json package-lock.json ./
RUN npm ci --only=production# 應用代碼最后復制
COPY . .
20. 容器編排和服務發現
解析:
Docker Compose服務發現:
version: '3.8'services:web:build: .ports:- "8000:8000"environment:- DATABASE_URL=postgresql://user:pass@db:5432/myapp- REDIS_URL=redis://redis:6379depends_on:- db- redisdb:image: postgres:13environment:POSTGRES_DB: myappPOSTGRES_USER: userPOSTGRES_PASSWORD: passwordredis:image: redis:6-alpinenginx:image: nginxports:- "80:80"volumes:- ./nginx.conf:/etc/nginx/nginx.confdepends_on:- web
外部服務發現 (Consul示例):
version: '3.8'services:consul:image: consul:1.11ports:- "8500:8500"command: consul agent -dev -client=0.0.0.0web:build: .environment:- CONSUL_URL=consul:8500depends_on:- consulregistrator:image: gliderlabs/registratorvolumes:- /var/run/docker.sock:/tmp/docker.sockcommand: consul://consul:8500depends_on:- consul
故障排查
21. 常見的Docker故障排查方法
解析:
容器啟動失敗:
# 查看容器詳細信息
docker inspect container_name# 查看容器日志
docker logs container_name
docker logs --details container_name# 以交互模式調試
docker run -it --entrypoint sh image_name
docker run -it --entrypoint bash image_name# 檢查退出碼
docker ps -a # 查看Exited狀態和退出碼
網絡連接問題:
# 檢查網絡配置
docker network ls
docker network inspect bridge# 測試容器間連通性
docker exec container1 ping container2
docker exec container1 nslookup container2# 檢查端口映射
docker port container_name
netstat -tlnp | grep :8080
資源問題:
# 檢查資源使用
docker stats
docker system df
docker system events# 清理資源
docker container prune # 清理停止的容器
docker image prune # 清理懸掛鏡像
docker volume prune # 清理未使用卷
docker system prune # 全面清理
22. 容器內應用調試技巧
解析:
進入容器調試:
# 安裝調試工具
docker exec -it container_name bash
apt-get update && apt-get install -y \curl wget telnet netcat-openbsd \htop strace lsof tcpdump# 檢查進程狀態
docker exec container_name ps aux
docker exec container_name top# 檢查網絡連接
docker exec container_name netstat -tlnp
docker exec container_name ss -tlnp
文件系統調試:
# 檢查文件權限
docker exec container_name ls -la /app
docker exec container_name id# 查看掛載點
docker exec container_name mount
docker exec container_name df -h# 檢查文件變化
docker diff container_name
調試容器啟動:
# 在Dockerfile中添加調試信息
RUN echo "Debug: Installing dependencies" && \apt-get update && \echo "Debug: Update completed"# 添加健康檢查
HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost:8080/health || exit 1
23. Docker性能監控和指標收集
解析:
基礎監控:
# 實時資源監控
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"# 系統級信息
docker system info
docker version
Prometheus + cAdvisor監控:
version: '3.8'services:cadvisor:image: gcr.io/cadvisor/cadvisor:latestports:- "8080:8080"volumes:- /:/rootfs:ro- /var/run:/var/run:rw- /sys:/sys:ro- /var/lib/docker/:/var/lib/docker:roprometheus:image: prom/prometheusports:- "9090:9090"volumes:- ./prometheus.yml:/etc/prometheus/prometheus.ymlgrafana:image: grafana/grafanaports:- "3000:3000"environment:- GF_SECURITY_ADMIN_PASSWORD=admin
自定義指標收集:
# 收集容器指標到文件
docker stats --no-stream --format "{{.Container}},{{.CPUPerc}},{{.MemUsage}}" > stats.csv# 使用腳本監控
#!/bin/bash
while true; doecho "$(date): $(docker stats --no-stream --format '{{.Container}} CPU:{{.CPUPerc}} MEM:{{.MemUsage}}')"sleep 60
done > docker-stats.log
24. Docker安全最佳實踐
解析:
鏡像安全:
# 使用官方基礎鏡像
FROM alpine:3.15# 創建非特權用戶
RUN addgroup -g 1001 appgroup && \adduser -D -u 1001 -G appgroup appuser# 安裝必要軟件并清理
RUN apk add --no-cache python3 py3-pip && \pip3 install --no-cache-dir flask && \rm -rf /var/cache/apk/*# 復制文件并設置權限
COPY --chown=appuser:appgroup app.py /app/
WORKDIR /app# 切換到非特權用戶
USER appuser# 設置只讀文件系統
VOLUME ["/tmp"]
運行時安全:
# 限制容器權限
docker run -d \--user 1001:1001 \--read-only \--tmpfs /tmp \--tmpfs /var/run \--cap-drop ALL \--cap-add NET_BIND_SERVICE \--security-opt no-new-privileges \--security-opt seccomp=default.json \myapp# 網絡隔離
docker network create --internal secure-net
docker run -d --network secure-net myapp
secrets管理:
# Docker Swarm secrets
echo "mysecretpassword" | docker secret create db_password -
docker service create \--name myapp \--secret db_password \myapp:latest# 環境變量文件
docker run -d --env-file .env myapp
25. Docker在CI/CD中的實踐
解析:
GitLab CI示例:
# .gitlab-ci.yml
stages:- build- test- deployvariables:DOCKER_REGISTRY: registry.gitlab.comIMAGE_NAME: $DOCKER_REGISTRY/$CI_PROJECT_PATHDOCKER_DRIVER: overlay2build:stage: buildimage: docker:20.10services:- docker:20.10-dindbefore_script:- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRYscript:- docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .- docker push $IMAGE_NAME:$CI_COMMIT_SHA- docker tag $IMAGE_NAME:$CI_COMMIT_SHA $IMAGE_NAME:latest- docker push $IMAGE_NAME:latesttest:stage: testimage: $IMAGE_NAME:$CI_COMMIT_SHAscript:- npm test- npm run lintdeploy:stage: deployscript:- docker pull $IMAGE_NAME:$CI_COMMIT_SHA- docker stop myapp || true- docker rm myapp || true- docker run -d --name myapp -p 80:8080 $IMAGE_NAME:$CI_COMMIT_SHAonly:- main
Jenkins Pipeline示例:
pipeline {agent anyenvironment {DOCKER_REGISTRY = 'your-registry.com'IMAGE_NAME = 'myapp'DOCKER_CREDENTIALS = credentials('docker-hub-credentials')}stages {stage('Checkout') {steps {checkout scm}}stage('Build') {steps {script {def image = docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}")docker.withRegistry('https://' + DOCKER_REGISTRY, 'docker-registry-credentials') {image.push()image.push('latest')}}}}stage('Test') {steps {script {docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}").inside {sh 'npm test'sh 'npm run coverage'}}}}stage('Deploy') {when {branch 'main'}steps {script {sh """docker pull ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}docker stop myapp || truedocker rm myapp || truedocker run -d --name myapp \-p 8080:8080 \--restart unless-stopped \${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}"""}}}}post {always {sh 'docker system prune -f'}}
}
GitHub Actions示例:
# .github/workflows/docker.yml
name: Docker Build and Deployon:push:branches: [ main, develop ]pull_request:branches: [ main ]jobs:build:runs-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkout@v3- name: Set up Docker Buildxuses: docker/setup-buildx-action@v2- name: Login to DockerHubuses: docker/login-action@v2with:username: ${{ secrets.DOCKERHUB_USERNAME }}password: ${{ secrets.DOCKERHUB_TOKEN }}- name: Build and pushuses: docker/build-push-action@v4with:context: .push: truetags: |myapp:latestmyapp:${{ github.sha }}cache-from: type=ghacache-to: type=gha,mode=max- name: Run testsrun: |docker run --rm myapp:${{ github.sha }} npm test- name: Deploy to stagingif: github.ref == 'refs/heads/develop'run: |echo "Deploy to staging environment"# 部署邏輯- name: Deploy to productionif: github.ref == 'refs/heads/main'run: |echo "Deploy to production environment"# 生產部署邏輯
高級應用場景
26. 微服務架構中的Docker實踐
解析:
服務拆分示例:
# docker-compose.microservices.yml
version: '3.8'services:# API網關api-gateway:image: nginx:alpineports:- "80:80"volumes:- ./nginx.conf:/etc/nginx/nginx.confdepends_on:- user-service- order-service- product-service# 用戶服務user-service:build: ./services/userenvironment:- DATABASE_URL=postgresql://user:pass@user-db:5432/users- REDIS_URL=redis://redis:6379depends_on:- user-db- redisuser-db:image: postgres:13environment:POSTGRES_DB: usersPOSTGRES_USER: userPOSTGRES_PASSWORD: passvolumes:- user_data:/var/lib/postgresql/data# 訂單服務order-service:build: ./services/orderenvironment:- DATABASE_URL=mongodb://order-db:27017/orders- USER_SERVICE_URL=http://user-service:3000depends_on:- order-dborder-db:image: mongo:5volumes:- order_data:/data/db# 產品服務product-service:build: ./services/productenvironment:- DATABASE_URL=postgresql://product:pass@product-db:5432/productsdepends_on:- product-dbproduct-db:image: postgres:13environment:POSTGRES_DB: productsPOSTGRES_USER: productPOSTGRES_PASSWORD: passvolumes:- product_data:/var/lib/postgresql/data# 共享服務redis:image: redis:6-alpinevolumes:- redis_data:/data# 消息隊列rabbitmq:image: rabbitmq:3-managementports:- "15672:15672"environment:RABBITMQ_DEFAULT_USER: adminRABBITMQ_DEFAULT_PASS: passwordvolumes:user_data:order_data:product_data:redis_data:networks:default:driver: bridge
服務發現和配置管理:
# 使用Consul作為服務發現
consul:image: consul:1.11ports:- "8500:8500"command: consul agent -dev -client=0.0.0.0 -ui# 配置中心
config-server:image: springcloud/configserverports:- "8888:8888"environment:- SPRING_CLOUD_CONFIG_SERVER_GIT_URI=https://github.com/myorg/config-repo
27. Docker的存儲驅動和性能優化
解析:
存儲驅動類型:
Overlay2 (推薦)
# 查看當前存儲驅動
docker info | grep "Storage Driver"# 配置overlay2
# /etc/docker/daemon.json
{"storage-driver": "overlay2","storage-opts": ["overlay2.override_kernel_check=true"]
}
Device Mapper
{"storage-driver": "devicemapper","storage-opts": ["dm.thinpooldev=/dev/mapper/docker-thinpool","dm.use_deferred_removal=true","dm.use_deferred_deletion=true"]
}
性能優化配置:
{"storage-driver": "overlay2","log-driver": "json-file","log-opts": {"max-size": "10m","max-file": "3"},"live-restore": true,"userland-proxy": false,"experimental": true,"metrics-addr": "127.0.0.1:9323","default-ulimits": {"nofile": {"Hard": 64000,"Name": "nofile","Soft": 64000}}
}
磁盤清理策略:
# 自動清理腳本
#!/bin/bash
# docker-cleanup.sh# 清理停止的容器
docker container prune -f# 清理未使用的鏡像
docker image prune -a -f# 清理未使用的卷
docker volume prune -f# 清理未使用的網絡
docker network prune -f# 清理構建緩存
docker builder prune -a -fecho "Docker cleanup completed"
28. Docker安全掃描和合規性
解析:
鏡像漏洞掃描流程:
# 使用Trivy進行全面掃描
trivy image --severity HIGH,CRITICAL myapp:latest# Clair掃描
docker run -d --name clair-db postgres:latest
docker run -d --name clair --link clair-db:postgres quay.io/coreos/clair:latest# Anchore掃描
docker run -d --name anchore-db postgres:latest
docker run -d --name anchore-engine --link anchore-db:anchore-db anchore/anchore-engine:latest
安全基線配置:
# 安全的Dockerfile模板
FROM alpine:3.15# 創建非特權用戶
RUN addgroup -g 1001 -S appgroup && \adduser -S appuser -u 1001 -G appgroup# 安裝必要包并清理
RUN apk add --no-cache \python3 \py3-pip \&& pip3 install --no-cache-dir flask \&& rm -rf /var/cache/apk/* \&& rm -rf ~/.cache/pip# 設置工作目錄和權限
WORKDIR /app
COPY --chown=appuser:appgroup . /app# 移除不必要的權限
RUN chmod -R 755 /app && \find /app -type f -name "*.py" -exec chmod 644 {} \;# 健康檢查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \CMD python3 -c "import requests; requests.get('http://localhost:5000/health')" || exit 1# 切換到非特權用戶
USER appuser# 暴露端口
EXPOSE 5000# 啟動應用
CMD ["python3", "app.py"]
運行時安全配置:
# 安全運行容器
docker run -d \--name secure-app \--user 1001:1001 \--read-only \--tmpfs /tmp:rw,noexec,nosuid,size=100m \--cap-drop ALL \--cap-add NET_BIND_SERVICE \--security-opt no-new-privileges:true \--security-opt seccomp:default \--security-opt apparmor:docker-default \--ulimit nofile=1024:2048 \--memory 512m \--cpus 0.5 \--restart on-failure:3 \myapp:latest
29. Docker監控和日志聚合
解析:
ELK Stack日志聚合:
version: '3.8'services:elasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0environment:- discovery.type=single-node- "ES_JAVA_OPTS=-Xms512m -Xmx512m"ports:- "9200:9200"volumes:- es_data:/usr/share/elasticsearch/datalogstash:image: docker.elastic.co/logstash/logstash:7.15.0volumes:- ./logstash.conf:/usr/share/logstash/pipeline/logstash.confports:- "5000:5000"depends_on:- elasticsearchkibana:image: docker.elastic.co/kibana/kibana:7.15.0ports:- "5601:5601"environment:ELASTICSEARCH_HOSTS: http://elasticsearch:9200depends_on:- elasticsearch# 應用容器app:image: myapp:latestlogging:driver: syslogoptions:syslog-address: "tcp://logstash:5000"tag: "myapp"volumes:es_data:
Logstash配置:
# logstash.conf
input {syslog {port => 5000}
}filter {if [program] == "myapp" {grok {match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:message}" }}date {match => [ "timestamp", "ISO8601" ]}}
}output {elasticsearch {hosts => ["elasticsearch:9200"]index => "docker-logs-%{+YYYY.MM.dd}"}
}
Prometheus監控棧:
version: '3.8'services:prometheus:image: prom/prometheus:latestports:- "9090:9090"volumes:- ./prometheus.yml:/etc/prometheus/prometheus.yml- prometheus_data:/prometheuscommand:- '--config.file=/etc/prometheus/prometheus.yml'- '--storage.tsdb.path=/prometheus'- '--web.console.libraries=/etc/prometheus/console_libraries'- '--web.console.templates=/etc/prometheus/consoles'- '--storage.tsdb.retention.time=200h'- '--web.enable-lifecycle'alertmanager:image: prom/alertmanager:latestports:- "9093:9093"volumes:- ./alertmanager.yml:/etc/alertmanager/alertmanager.ymlgrafana:image: grafana/grafana:latestports:- "3000:3000"environment:- GF_SECURITY_ADMIN_USER=admin- GF_SECURITY_ADMIN_PASSWORD=grafanavolumes:- grafana_data:/var/lib/grafananode-exporter:image: prom/node-exporter:latestports:- "9100:9100"volumes:- /proc:/host/proc:ro- /sys:/host/sys:ro- /:/rootfs:rocommand:- '--path.procfs=/host/proc'- '--path.rootfs=/rootfs'- '--path.sysfs=/host/sys'- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($|/)'cadvisor:image: gcr.io/cadvisor/cadvisor:latestports:- "8080:8080"volumes:- /:/rootfs:ro- /var/run:/var/run:rw- /sys:/sys:ro- /var/lib/docker/:/var/lib/docker:rovolumes:prometheus_data:grafana_data:
30. Docker在不同云平臺的部署
解析:
AWS ECS部署:
{"family": "myapp-task","networkMode": "awsvpc","requiresCompatibilities": ["FARGATE"],"cpu": "256","memory": "512","executionRoleArn": "arn:aws:iam::123456789:role/ecsTaskExecutionRole","taskRoleArn": "arn:aws:iam::123456789:role/ecsTaskRole","containerDefinitions": [{"name": "myapp","image": "123456789.dkr.ecr.us-west-2.amazonaws.com/myapp:latest","portMappings": [{"containerPort": 8080,"protocol": "tcp"}],"environment": [{"name": "NODE_ENV","value": "production"}],"secrets": [{"name": "DB_PASSWORD","valueFrom": "arn:aws:ssm:us-west-2:123456789:parameter/myapp/db-password"}],"logConfiguration": {"logDriver": "awslogs","options": {"awslogs-group": "/ecs/myapp","awslogs-region": "us-west-2","awslogs-stream-prefix": "ecs"}},"healthCheck": {"command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],"interval": 30,"timeout": 5,"retries": 3,"startPeriod": 60}}]
}
Google Cloud Run部署:
# cloudrun.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:name: myappannotations:run.googleapis.com/ingress: all
spec:template:metadata:annotations:autoscaling.knative.dev/maxScale: "100"run.googleapis.com/cpu-throttling: "false"run.googleapis.com/memory: "512Mi"run.googleapis.com/cpu: "1000m"spec:containerConcurrency: 80timeoutSeconds: 300containers:- image: gcr.io/my-project/myapp:latestports:- containerPort: 8080env:- name: NODE_ENVvalue: "production"- name: DB_HOSTvalueFrom:secretKeyRef:name: db-credentialskey: hostresources:limits:cpu: "1000m"memory: "512Mi"startupProbe:httpGet:path: /healthport: 8080initialDelaySeconds: 10timeoutSeconds: 5periodSeconds: 10failureThreshold: 3
Azure Container Instances:
# aci-template.yaml
apiVersion: 2019-12-01
location: eastus
name: myapp-group
properties:containers:- name: myappproperties:image: myregistry.azurecr.io/myapp:latestresources:requests:cpu: 1.0memoryInGb: 1.5ports:- port: 80protocol: TCPenvironmentVariables:- name: NODE_ENVvalue: production- name: DB_PASSWORDsecureValue: mySecretPasswordosType: LinuxrestartPolicy: AlwaysipAddress:type: Publicports:- protocol: tcpport: 80imageRegistryCredentials:- server: myregistry.azurecr.iousername: myregistrypassword: myPassword
面試技巧和總結 (31-35題)
31. Docker面試中的常見陷阱問題
解析:
問題1:容器和虛擬機的本質區別
陷阱:只說輕量、快速等表面特征
正確答案:
- 隔離級別:容器是進程級隔離,虛擬機是硬件級隔離
- 內核共享:容器共享宿主機內核,虛擬機有獨立內核
- 資源開銷:容器直接調用系統調用,虛擬機需要通過Hypervisor
- 安全邊界:容器安全邊界較弱,虛擬機安全邊界更強
問題2:如何處理容器中的數據持久化
陷阱:只知道-v參數
完整答案:
1. Volume:Docker管理的數據卷,跨平臺兼容性好
2. Bind Mount:直接掛載宿主機目錄,性能好但依賴宿主機
3. tmpfs:內存文件系統,適合臨時數據
4. 選擇原則:- 數據庫數據:使用Volume- 配置文件:使用Bind Mount- 臨時文件:使用tmpfs
問題3:容器啟動失敗如何排查
系統化排查方法:
1. 查看容器狀態:docker ps -a
2. 查看詳細信息:docker inspect container_name
3. 查看啟動日志:docker logs container_name
4. 檢查鏡像構建:docker history image_name
5. 交互式調試:docker run -it --entrypoint sh image_name
6. 檢查資源限制:內存、磁盤空間、文件描述符
7. 網絡連通性測試:端口綁定、防火墻規則
32. Docker生產環境最佳實踐總結
解析:
安全最佳實踐:
# 1. 使用官方基礎鏡像
FROM node:16-alpine# 2. 創建非root用戶
RUN addgroup -g 1001 -S nodejs && \adduser -S nextjs -u 1001 -g nodejs# 3. 只安裝必要的包
RUN apk add --no-cache libc6-compat# 4. 復制文件時設置正確權限
COPY --chown=nextjs:nodejs package*.json ./# 5. 切換到非root用戶
USER nextjs# 6. 設置健康檢查
HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost:3000/api/health || exit 1# 7. 使用多階段構建減少攻擊面
FROM node:16-alpine AS deps
# 安裝依賴...FROM node:16-alpine AS runner
# 只復制運行時需要的文件
COPY --from=deps /app/node_modules ./node_modules
性能優化策略:
# 1. 容器資源限制
docker run -d \--memory 512m \--cpus 1.0 \--memory-swap 1g \--oom-kill-disable \myapp# 2. 日志管理
docker run -d \--log-driver json-file \--log-opt max-size=10m \--log-opt max-file=3 \myapp# 3. 網絡優化
docker run -d \--network custom-network \--dns 8.8.8.8 \myapp
監控和可觀測性:
version: '3.8'
services:app:image: myapp:latestlabels:- "prometheus.io/scrape=true"- "prometheus.io/port=8080"- "prometheus.io/path=/metrics"healthcheck:test: ["CMD", "curl", "-f", "http://localhost:8080/health"]interval: 30stimeout: 10sretries: 3start_period: 40s
33. Docker與Kubernetes的關系和區別
解析:
Docker和Kubernetes的角色定位:
Docker:
- 容器運行時和鏡像格式標準
- 單機容器管理
- 開發和測試環境的快速部署Kubernetes:
- 容器編排平臺
- 集群級別的容器管理
- 生產環境的大規模部署和運維
從Docker Compose到Kubernetes的遷移:
# Docker Compose
version: '3.8'
services:web:image: nginxports:- "80:80"replicas: 3# 對應的Kubernetes資源
---
apiVersion: apps/v1
kind: Deployment
metadata:name: web
spec:replicas: 3selector:matchLabels:app: webtemplate:metadata:labels:app: webspec:containers:- name: nginximage: nginxports:- containerPort: 80---
apiVersion: v1
kind: Service
metadata:name: web-service
spec:selector:app: webports:- port: 80targetPort: 80type: LoadBalancer
什么時候選擇Docker,什么時候選擇Kubernetes:
選擇Docker的場景:
- 單機應用部署
- 開發測試環境
- 簡單的微服務架構
- 快速原型驗證選擇Kubernetes的場景:
- 大規模集群管理
- 高可用服務部署
- 復雜的微服務架構
- 需要服務發現、負載均衡、自動擴縮容
34. Docker技術發展趨勢和新特性
解析:
容器技術發展趨勢:
1. 安全加強:- Rootless容器- 用戶命名空間- SELinux/AppArmor集成2. 性能優化:- 更快的鏡像構建(BuildKit)- 優化的存儲驅動- 更好的資源隔離3. 標準化:- OCI(開放容器倡議)標準- CRI(容器運行時接口)- CNI(容器網絡接口)
Docker新特性介紹:
# BuildKit多平臺構建
FROM --platform=$BUILDPLATFORM node:16 AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "Building on $BUILDPLATFORM, targeting $TARGETPLATFORM"# 構建緩存掛載
RUN --mount=type=cache,target=/root/.npm \npm install# Secret掛載
RUN --mount=type=secret,id=mypassword \cat /run/secrets/mypassword
容器化未來發展方向:
1. Serverless容器:- AWS Fargate、Google Cloud Run- 按需計費,自動擴縮容2. WebAssembly集成:- 更輕量的運行時- 更好的安全隔離3. 邊緣計算:- IoT設備上的容器化- 邊緣節點的容器編排