Docker教程#

技术介绍#

Docker是一种开源的容器化平台,它允许开发者将应用程序及其依赖项打包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上。Docker已经成为现代软件开发和部署的标准工具之一。

Docker核心概念#

  • 镜像(Image):Docker镜像包含了运行应用程序所需的所有文件系统内容和配置。
  • 容器(Container):容器是镜像的运行实例,是一个隔离的运行环境。
  • 仓库(Repository):用于存储和分发Docker镜像的地方。
  • Dockerfile:定义如何构建Docker镜像的文本文件。
  • Docker Hub:官方的Docker镜像仓库。

Docker架构#

  • Docker daemon:运行在主机上的后台服务,负责管理容器。
  • Docker client:命令行工具,用于与Docker daemon通信。
  • Docker Registry:存储Docker镜像的服务。

入门级使用#

安装Docker#

在不同操作系统上安装Docker:

# Ubuntu/Debian
apt-get update
apt-get install docker.io

# CentOS/RHEL
yum install docker

# 启动Docker服务
systemctl start docker
systemctl enable docker

# 验证安装
docker --version
docker info

基本Docker命令#

使用Docker的基本命令:

# 查看Docker版本
docker --version

# 查看Docker信息
docker info

# 搜索Docker镜像
docker search ubuntu

# 下载Docker镜像
docker pull ubuntu:20.04

# 查看本地镜像
docker images

# 运行Docker容器
docker run -it --name mycontainer ubuntu:20.04 /bin/bash

# 查看运行中的容器
docker ps

# 查看所有容器
docker ps -a

# 停止容器
docker stop mycontainer

# 启动容器
docker start mycontainer

# 删除容器
docker rm mycontainer

# 删除镜像
docker rmi ubuntu:20.04

容器操作#

操作Docker容器:

# 进入运行中的容器
docker exec -it mycontainer /bin/bash

# 查看容器日志
docker logs mycontainer

# 查看容器详细信息
docker inspect mycontainer

# 复制文件到容器
docker cp localfile.txt mycontainer:/path/to/destination/

# 从容器复制文件
docker cp mycontainer:/path/to/source/file.txt localfile.txt

# 导出容器
docker export mycontainer > container.tar

# 导入容器
docker import container.tar newimage:latest

初级使用#

Docker网络#

使用Docker网络:

# 查看Docker网络
docker network ls

# 创建Docker网络
docker network create mynetwork

# 运行容器时指定网络
docker run -it --name container1 --network mynetwork ubuntu:20.04 /bin/bash
docker run -it --name container2 --network mynetwork ubuntu:20.04 /bin/bash

# 查看网络详细信息
docker network inspect mynetwork

# 删除Docker网络
docker network rm mynetwork

Docker卷#

使用Docker卷:

# 创建Docker卷
docker volume create myvolume

# 查看Docker卷
docker volume ls

# 运行容器时挂载卷
docker run -it --name mycontainer -v myvolume:/data ubuntu:20.04 /bin/bash

# 查看卷详细信息
docker volume inspect myvolume

# 删除Docker卷
docker volume rm myvolume

# 清理未使用的卷
docker volume prune

Dockerfile基础#

创建基本的Dockerfile:

# 使用官方Ubuntu镜像作为基础
FROM ubuntu:20.04

# 维护者信息
LABEL maintainer="yourname@example.com"

# 更新软件包列表
RUN apt-get update && apt-get install -y \
    curl \
    wget \
    git \
    && rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /app

# 复制文件到容器
COPY . /app

# 暴露端口
EXPOSE 8080

# 定义环境变量
ENV APP_ENV=production

# 容器启动时执行的命令
CMD ["/bin/bash"]

构建和运行Docker镜像:

# 构建Docker镜像
docker build -t myapp:latest .

# 运行Docker容器
docker run -it --name myapp -p 8080:8080 myapp:latest

中级使用#

多阶段构建#

使用多阶段构建减小镜像大小:

# 第一阶段:构建环境
FROM node:14 as builder

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .
RUN npm run build

# 第二阶段:运行环境
FROM node:14-alpine

WORKDIR /app

COPY --from=builder /app/package*.json ./
COPY --from=builder /app/build ./build

RUN npm install --only=production

EXPOSE 3000

CMD ["npm", "start"]

Docker Compose基础#

使用Docker Compose管理多容器应用:

# docker-compose.yml
version: '3'
services:
  web:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    depends_on:
      - db
  db:
    image: postgres:12
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

使用Docker Compose:

# 启动应用
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs

# 停止服务
docker-compose down

# 清理卷
docker-compose down -v

Docker Swarm基础#

使用Docker Swarm进行集群管理:

# 初始化Docker Swarm
docker swarm init

# 查看节点信息
docker node ls

# 创建服务
docker service create --name web --replicas 3 -p 80:80 nginx

# 查看服务状态
docker service ls

# 查看服务详情
docker service inspect web

# 扩展服务
docker service scale web=5

# 删除服务
docker service rm web

# 离开Swarm
docker swarm leave --force

中上级使用#

Docker安全最佳实践#

Docker安全最佳实践:

# 使用非root用户运行容器
# 在Dockerfile中添加
FROM ubuntu:20.04
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

# 限制容器资源
docker run --memory=128m --cpus=0.5 --name limited-container ubuntu:20.04

# 使用只读文件系统
docker run --read-only --name readonly-container ubuntu:20.04

# 限制容器能力
docker run --cap-drop=ALL --name limited-capabilities ubuntu:20.04

# 使用seccomp配置
docker run --security-opt seccomp=default.json --name secure-container ubuntu:20.04

# 使用AppArmor配置
docker run --security-opt apparmor=default --name apparmor-container ubuntu:20.04

Docker镜像优化#

优化Docker镜像大小和构建速度:

# 使用更小的基础镜像
FROM alpine:3.14

# 合并RUN指令减少层数
RUN apk update && apk add --no-cache \
    curl \
    wget \
    git \
    python3 \
    py3-pip

# 使用多阶段构建
FROM golang:1.16 as builder
WORKDIR /app
COPY . .
RUN go build -o app .

FROM alpine:3.14
COPY --from=builder /app/app /app/
CMD ["/app/app"]

# 使用缓存优化
COPY package*.json ./
RUN npm install
COPY . .

Docker API使用#

使用Docker API管理Docker:

import docker

# 连接到Docker
client = docker.from_env()

# 列出所有容器
containers = client.containers.list(all=True)
for container in containers:
    print(container.name)

# 运行容器
container = client.containers.run(
    'ubuntu:20.04',
    'echo hello world',
    detach=True
)
print(container.id)

# 构建镜像
dockerfile = '''
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y curl
'''
with open('Dockerfile', 'w') as f:
    f.write(dockerfile)

image, logs = client.images.build(
    path='.',
    tag='myimage:latest'
)
print(image.id)

高级使用#

Docker与CI/CD集成#

将Docker与CI/CD集成:

# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

build:
  stage: build
  script:
    - docker build -t registry.example.com/myapp:$CI_COMMIT_SHA .
    - docker push registry.example.com/myapp:$CI_COMMIT_SHA

test:
  stage: test
  script:
    - docker run --name test-container registry.example.com/myapp:$CI_COMMIT_SHA npm test

deploy:
  stage: deploy
  script:
    - docker pull registry.example.com/myapp:$CI_COMMIT_SHA
    - docker run -d --name myapp -p 80:80 registry.example.com/myapp:$CI_COMMIT_SHA
  only:
    - main

Docker集群管理#

使用Docker Swarm管理集群:

# 初始化Swarm
docker swarm init

# 添加工作节点
docker swarm join-token worker
# 在工作节点上运行输出的命令

# 创建服务栈
docker stack deploy -c docker-compose.yml mystack

# 查看服务栈
docker stack ls

# 查看服务状态
docker stack services mystack

# 扩展服务
docker service scale mystack_web=5

# 更新服务
docker service update --image myapp:v2 mystack_web

# 删除服务栈
docker stack rm mystack

Docker监控和日志管理#

监控Docker容器:

# 使用Docker stats查看容器资源使用情况
docker stats

# 使用cAdvisor监控容器
docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  gcr.io/cadvisor/cadvisor:latest

# 使用ELK Stack收集和分析日志
docker-compose up -d

大师级使用#

Docker企业级部署#

企业级Docker部署最佳实践:

# 使用Docker企业版
# 安装Docker Enterprise Engine
docker run -it --rm docker/ee-setup:19.03.14 \
  install \
  --license-url "https://store.docker.com/my-content" \
  --force

# 配置Docker企业版
# 1. 配置Docker daemon
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=cgroupfs"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2"
}
EOF

# 2. 重启Docker服务
systemctl daemon-reload
systemctl restart docker

# 3. 配置Docker信任
mkdir -p ~/.docker/tls
cp ca.pem ~/.docker/tls/
cp cert.pem ~/.docker/tls/
cp key.pem ~/.docker/tls/

# 4. 配置Docker客户端
export DOCKER_HOST=tcp://manager.example.com:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=~/.docker/tls

Docker与Kubernetes集成#

将Docker与Kubernetes集成:

# 安装Kubernetes
# 使用kubeadm安装Kubernetes集群

# 配置Docker作为Kubernetes的容器运行时
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# 重启Docker服务
systemctl daemon-reload
systemctl restart docker

# 初始化Kubernetes集群
kubeadm init --pod-network-cidr=10.244.0.0/16

# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 安装网络插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 加入工作节点
# 在工作节点上运行kubeadm join命令

Docker安全审计#

进行Docker安全审计:

# 使用Docker Bench for Security进行安全审计
docker run -it --net host --pid host --userns host --cap-add audit_control \
  -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
  -v /var/lib:/var/lib \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/lib/systemd:/usr/lib/systemd \
  -v /etc:/etc --label docker_bench_security \
  docker/docker-bench-security

# 使用Trivy扫描Docker镜像漏洞
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image myapp:latest

# 使用Notary验证Docker镜像
docker run -d -p 4443:4443 --name notary_server \
  -e NOTARY_SERVER_PORT=4443 \
  -e NOTARY_SERVER_TRUST_SERVICE_TYPE=remote \
  -e NOTARY_SERVER_TRUST_SERVICE_HOST=notary_signer \
  -e NOTARY_SERVER_TRUST_SERVICE_PORT=7899 \
  -e NOTARY_SERVER_TRUST_SERVICE_NOTARYSERVER_CA_CHAIN=/etc/ssl/certs/ca-certificates.crt \
  notary-server

# 配置Docker Content Trust
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER=https://notary-server:4443

实战案例#

案例一:部署Web应用#

场景:部署一个基于Node.js的Web应用。

解决方案:使用Docker构建和运行Web应用。

实施步骤

  1. 创建Dockerfile

    FROM node:14-alpine
    
    WORKDIR /app
    
    COPY package*.json ./
    RUN npm install --only=production
    
    COPY . .
    
    EXPOSE 3000
    
    CMD ["npm", "start"]
  2. 创建docker-compose.yml

    version: '3'
    services:
      web:
        build: .
        ports:
          - "3000:3000"
        depends_on:
          - db
      db:
        image: mongodb:4.4
        volumes:
          - mongo_data:/data/db
        environment:
          - MONGO_INITDB_ROOT_USERNAME=admin
          - MONGO_INITDB_ROOT_PASSWORD=password
    
    volumes:
      mongo_data:
  3. 构建和运行应用

    # 构建镜像
    docker build -t node-app:latest .
    
    # 运行应用
    docker-compose up -d
    
    # 查看应用状态
    docker-compose ps

结果

  • 成功构建了Node.js应用的Docker镜像
  • 部署了包含Web应用和MongoDB数据库的多容器应用
  • 应用可以通过http://localhost:3000访问

案例二:CI/CD集成#

场景:实现一个基于Docker的CI/CD流程。

解决方案:使用GitLab CI和Docker实现自动化构建、测试和部署。

实施步骤

  1. 创建.gitlab-ci.yml

    stages:
      - build
      - test
      - deploy
    
    build:
      stage: build
      script:
        - docker build -t registry.example.com/myapp:$CI_COMMIT_SHA .
        - docker push registry.example.com/myapp:$CI_COMMIT_SHA
    
    test:
      stage: test
      script:
        - docker run --name test-container registry.example.com/myapp:$CI_COMMIT_SHA npm test
    
    deploy:
      stage: deploy
      script:
        - docker pull registry.example.com/myapp:$CI_COMMIT_SHA
        - docker run -d --name myapp -p 80:80 registry.example.com/myapp:$CI_COMMIT_SHA
      only:
        - main
  2. 配置GitLab Runner

    • 安装GitLab Runner
    • 注册GitLab Runner
    • 配置Runner使用Docker执行器
  3. 触发CI/CD流程

    • 提交代码到GitLab仓库
    • 查看CI/CD流程执行状态
    • 验证应用部署结果

结果

  • 成功实现了基于Docker的CI/CD流程
  • 代码提交后自动构建、测试和部署应用
  • 提高了开发和部署效率

案例三:Docker Swarm集群部署#

场景:部署一个高可用的Docker Swarm集群。

解决方案:使用Docker Swarm创建和管理集群。

实施步骤

  1. 初始化Swarm集群

    # 在管理节点上初始化Swarm
    docker swarm init --advertise-addr 192.168.1.100
    
    # 添加工作节点
    docker swarm join-token worker
    # 在工作节点上运行输出的命令
    
    # 添加管理节点(可选)
    docker swarm join-token manager
    # 在其他管理节点上运行输出的命令
  2. 部署服务栈

    # docker-compose.yml
    version: '3.8'
    services:
      web:
        image: nginx:latest
        ports:
          - "80:80"
        deploy:
          replicas: 3
          restart_policy:
            condition: on-failure
          placement:
            constraints:
              - node.role == worker
      db:
        image: postgres:12
        volumes:
          - db_data:/var/lib/postgresql/data
        deploy:
          replicas: 1
          restart_policy:
            condition: on-failure
          placement:
            constraints:
              - node.role == manager
    
    volumes:
      db_data:
  3. 部署服务

    # 部署服务栈
    docker stack deploy -c docker-compose.yml myapp
    
    # 查看服务状态
    docker stack services myapp
    
    # 查看服务日志
    docker service logs myapp_web

结果

  • 成功创建了Docker Swarm集群
  • 部署了高可用的Web应用和数据库服务
  • 服务可以自动扩展和故障转移

总结#

Docker是一种强大的容器化平台,通过本教程的学习,您已经掌握了从入门到大师级的Docker使用技术。

主要技术回顾#

  • 基础操作:Docker镜像、容器、网络和卷的基本操作
  • Dockerfile:创建和构建Docker镜像
  • Docker Compose:管理多容器应用
  • Docker Swarm:管理容器集群
  • 高级功能:多阶段构建、安全最佳实践、CI/CD集成
  • 企业级应用:企业级部署、安全审计、监控和日志管理

最佳实践#

  1. 使用官方镜像:从Docker Hub获取官方镜像,确保安全性和稳定性
  2. 使用非root用户:在容器中使用非root用户运行应用,提高安全性
  3. 优化镜像大小:使用多阶段构建和最小基础镜像,减小镜像大小
  4. 限制容器资源:设置容器的内存和CPU限制,避免资源争用
  5. 使用卷管理数据:使用Docker卷持久化数据,避免数据丢失
  6. 实施安全措施:使用Docker Bench for Security检查安全配置,使用Trivy扫描漏洞
  7. 监控容器:使用cAdvisor、Prometheus等工具监控容器状态
  8. 自动化部署:与CI/CD集成,实现自动化构建、测试和部署

注意事项#

  1. 版本管理:定期更新Docker版本,获取最新的安全补丁和功能
  2. 网络配置:合理配置Docker网络,确保容器间通信安全
  3. 存储管理:定期清理未使用的镜像、容器和卷,释放存储空间
  4. 安全审计:定期进行Docker安全审计,发现和修复安全问题
  5. 备份策略:制定容器数据备份策略,确保数据安全
  6. 灾难恢复:建立容器环境的灾难恢复计划,应对突发情况

通过合理学习和使用Docker,您可以显著提高软件开发和部署的效率,降低运维成本,实现应用的快速交付和弹性扩展。Docker已经成为现代云原生技术栈的核心组件,掌握Docker技术将为您的职业发展带来更多机会。