八股取士--docker
基础概念类
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设备上的容器化- 边缘节点的容器编排