八股取士--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:
      - .:/app
    environment:
      - DEBUG=1
    depends_on:
      - db
      - redis

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:6-alpine
    ports:
      - "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: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

健康检查脚本示例:

#!/bin/bash
# healthcheck.sh

# 检查进程
if ! pgrep nginx > /dev/null; then
    exit 1
fi

# 检查端口
if ! nc -z localhost 80; then
    exit 1
fi

# 检查HTTP响应
if ! curl -f http://localhost/health; then
    exit 1
fi

exit 0

15. Docker镜像的多阶段构建

解析:

传统单阶段构建问题:

  • 镜像包含构建工具,体积大
  • 安全风险,包含不必要的依赖

多阶段构建解决方案:

# 第一阶段:构建阶段
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .
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: myapp
    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: myapp

  fluentd:
    image: fluent/fluentd:v1.14
    ports:
      - "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 build

FROM 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:6379
    depends_on:
      - db
      - redis

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password

  redis:
    image: redis:6-alpine

  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - web

外部服务发现 (Consul示例):

version: '3.8'

services:
  consul:
    image: consul:1.11
    ports:
      - "8500:8500"
    command: consul agent -dev -client=0.0.0.0

  web:
    build: .
    environment:
      - CONSUL_URL=consul:8500
    depends_on:
      - consul

  registrator:
    image: gliderlabs/registrator
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    command: consul://consul:8500
    depends_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:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

自定义指标收集:

# 收集容器指标到文件
docker stats --no-stream --format "{{.Container}},{{.CPUPerc}},{{.MemUsage}}" > stats.csv

# 使用脚本监控
#!/bin/bash
while true; do
  echo "$(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
  - deploy

variables:
  DOCKER_REGISTRY: registry.gitlab.com
  IMAGE_NAME: $DOCKER_REGISTRY/$CI_PROJECT_PATH
  DOCKER_DRIVER: overlay2

build:
  stage: build
  image: docker:20.10
  services:
    - docker:20.10-dind
  before_script:
    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
  script:
    - 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:latest

test:
  stage: test
  image: $IMAGE_NAME:$CI_COMMIT_SHA
  script:
    - npm test
    - npm run lint

deploy:
  stage: deploy
  script:
    - 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_SHA
  only:
    - main

Jenkins Pipeline示例:

pipeline {
    agent any
    
    environment {
        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 || true
                        docker rm myapp || true
                        docker 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 Deploy

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    
    - name: Login to DockerHub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    
    - name: Build and push
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: |
          myapp:latest
          myapp:${{ github.sha }}
        cache-from: type=gha
        cache-to: type=gha,mode=max
    
    - name: Run tests
      run: |
        docker run --rm myapp:${{ github.sha }} npm test
    
    - name: Deploy to staging
      if: github.ref == 'refs/heads/develop'
      run: |
        echo "Deploy to staging environment"
        # 部署逻辑
    
    - name: Deploy to production
      if: 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:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - user-service
      - order-service
      - product-service

  # 用户服务
  user-service:
    build: ./services/user
    environment:
      - DATABASE_URL=postgresql://user:pass@user-db:5432/users
      - REDIS_URL=redis://redis:6379
    depends_on:
      - user-db
      - redis

  user-db:
    image: postgres:13
    environment:
      POSTGRES_DB: users
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - user_data:/var/lib/postgresql/data

  # 订单服务
  order-service:
    build: ./services/order
    environment:
      - DATABASE_URL=mongodb://order-db:27017/orders
      - USER_SERVICE_URL=http://user-service:3000
    depends_on:
      - order-db

  order-db:
    image: mongo:5
    volumes:
      - order_data:/data/db

  # 产品服务
  product-service:
    build: ./services/product
    environment:
      - DATABASE_URL=postgresql://product:pass@product-db:5432/products
    depends_on:
      - product-db

  product-db:
    image: postgres:13
    environment:
      POSTGRES_DB: products
      POSTGRES_USER: product
      POSTGRES_PASSWORD: pass
    volumes:
      - product_data:/var/lib/postgresql/data

  # 共享服务
  redis:
    image: redis:6-alpine
    volumes:
      - redis_data:/data

  # 消息队列
  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "15672:15672"
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: password

volumes:
  user_data:
  order_data:
  product_data:
  redis_data:

networks:
  default:
    driver: bridge

服务发现和配置管理:

# 使用Consul作为服务发现
consul:
  image: consul:1.11
  ports:
    - "8500:8500"
  command: consul agent -dev -client=0.0.0.0 -ui

# 配置中心
config-server:
  image: springcloud/configserver
  ports:
    - "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 -f

echo "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.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
    volumes:
      - es_data:/usr/share/elasticsearch/data

  logstash:
    image: docker.elastic.co/logstash/logstash:7.15.0
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    ports:
      - "5000:5000"
    depends_on:
      - elasticsearch

  kibana:
    image: docker.elastic.co/kibana/kibana:7.15.0
    ports:
      - "5601:5601"
    environment:
      ELASTICSEARCH_HOSTS: http://elasticsearch:9200
    depends_on:
      - elasticsearch

  # 应用容器
  app:
    image: myapp:latest
    logging:
      driver: syslog
      options:
        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:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--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:latest
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=grafana
    volumes:
      - grafana_data:/var/lib/grafana

  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--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:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

volumes:
  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: myapp
  annotations:
    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: 80
      timeoutSeconds: 300
      containers:
      - image: gcr.io/my-project/myapp:latest
        ports:
        - containerPort: 8080
        env:
        - name: NODE_ENV
          value: "production"
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: host
        resources:
          limits:
            cpu: "1000m"
            memory: "512Mi"
        startupProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          timeoutSeconds: 5
          periodSeconds: 10
          failureThreshold: 3

Azure Container Instances:

# aci-template.yaml
apiVersion: 2019-12-01
location: eastus
name: myapp-group
properties:
  containers:
  - name: myapp
    properties:
      image: myregistry.azurecr.io/myapp:latest
      resources:
        requests:
          cpu: 1.0
          memoryInGb: 1.5
      ports:
      - port: 80
        protocol: TCP
      environmentVariables:
      - name: NODE_ENV
        value: production
      - name: DB_PASSWORD
        secureValue: mySecretPassword
  osType: Linux
  restartPolicy: Always
  ipAddress:
    type: Public
    ports:
    - protocol: tcp
      port: 80
  imageRegistryCredentials:
  - server: myregistry.azurecr.io
    username: myregistry
    password: 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:latest
    labels:
      - "prometheus.io/scrape=true"
      - "prometheus.io/port=8080"
      - "prometheus.io/path=/metrics"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

33. Docker与Kubernetes的关系和区别

解析:

Docker和Kubernetes的角色定位:

Docker:
- 容器运行时和镜像格式标准
- 单机容器管理
- 开发和测试环境的快速部署

Kubernetes:
- 容器编排平台
- 集群级别的容器管理
- 生产环境的大规模部署和运维

从Docker Compose到Kubernetes的迁移:

# Docker Compose
version: '3.8'
services:
  web:
    image: nginx
    ports:
      - "80:80"
    replicas: 3

# 对应的Kubernetes资源
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 80
  type: 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设备上的容器化
   - 边缘节点的容器编排
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值