Docker进阶与容器编排实践-第三章

一、Docker Compose进阶操作与数据验证

Docker Compose进阶操作:练习容器日志査看、单个容器重启、配置更新操作,验证配置更新生效,练习docker-compose down命令清理容器、网络、数据卷

进阶操作

还是一样的先执行

bash 复制代码
cd ~/docker_experiment/lesson17

进入目录。

bash 复制代码
cp -r ../lesson16/* .
docker-compose up -d
docker-compose logs web
docker-compose restart db
# 修改端口映射(如将 web 端口改为 8081)
sed -i 's/"8080:80"/"8081:80"/' docker-compose.yml
docker-compose up -d --force-recreate web
curl http://localhost:8081
docker-compose down -v

cp复制上一章的Compose文件到当前目录,作为基础。

up启动所有服务。

logs web查看web服务的日志,用于排查问题。

restart db重启db服务(mysql容器),不影响web服务。

sed修改端口映射(8080→8081)

--force-recreate web强制重新创建web容器

curl进行验证。

-v会删除卷,数据丢失。

多容器通信验证:进入nginx容器,安装mysql客户端,尝试连接mysql容器(通过容器名) 验证通信 正常。

多容器通信验证

bash 复制代码
# 重新启动服务(卷会被重新创建)
docker-compose up -d

# 进入 nginx 容器安装 MySQL 客户端(nginx:latest 基于 Debian)
docker exec -it lesson17-web-1 bash -c "apt-get update && apt-get install -y default-mysql-client"

# 通过容器名 "db" 连接 MySQL 并查询数据库
docker exec -it lesson17-web-1 mysql -h db -u root -proot123 --ssl=0 -e "SHOW DATABASES;"

输出中应该有information_schema,mydb,mysql,sys,performance_schema。

数据持久化验证:在mysql容器中创建数据库、 表并插入数据,停止并删除容器后重新启动编排,验证数 据未丢失;验证nginx数据卷的数据持久化效果。

数据持久化验证

MySQL数据持久化
bash 复制代码
# 在 MySQL 中创建表并插入数据
docker exec -it lesson17-db-1 mysql -uroot -proot123 -e "USE mydb; CREATE TABLE test (id INT); INSERT INTO test VALUES (1);"

# 停止并删除容器(不删除卷,因为没有 -v)
docker-compose down

# 重新启动容器
docker-compose up -d

# 验证数据是否存在
docker exec -it lesson17-db-1 mysql -uroot -proot123 -e "SELECT * FROM mydb.test;"

输出结果是1证明数据持久化成功

Nginx 数据卷持久化
bash 复制代码
# 向 nginx 数据卷写入自定义内容
echo "Nginx persistent data" > /var/lib/docker/volumes/lesson17_web-data/_data/index.html

# 或者通过容器写入(两种方式等效)
docker exec lesson17-web-1 sh -c "echo 'Nginx persistent data' > /usr/share/nginx/html/index.html"

# 验证访问
curl http://localhost:8081   # 显示 "Nginx persistent data"

# 停止并删除容器
docker-compose down

# 重新启动容器
docker-compose up -d

# 再次验证,内容应仍然存在
curl http://localhost:8081   # 仍然显示 "Nginx persistent data"

容器编排优化:修改配置文件,设置容器CPU、内存资源限制,优化容器启动顺序。

容器编排优化(资源限制+启动顺序)

创建优化后的docker-compose.yml,使用cpus和men_limit语法而非deploy.resources。

bash 复制代码
cat > docker-compose.yml <<'EOF'
version: '3.8'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql
    cpus: '0.5'           # 限制使用 0.5 个 CPU 核心
    mem_limit: 512M       # 限制内存 512 MB
    healthcheck:          # 健康检查,用于依赖等待
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - web-data:/usr/share/nginx/html
    cpus: '0.2'
    mem_limit: 256M
    depends_on:
      db:
        condition: service_healthy   # 等待 db 健康后再启动 web
volumes:
  web-data:
  db-data:
EOF

创建完进行启动和查看

bash 复制代码
docker-compose up -d

# 查看启动顺序和健康状态
docker-compose ps
docker-compose logs web   # 可以看到 web 等待 db 健康后才启动

# 验证服务仍然正常
curl http://localhost:8080
docker exec -it lesson17-db-1 mysql -u root -proot123 -e "SHOW DATABASES;"

进行完所有操作后执行清理命令

二、综合实操

自定义镜像与数据卷综合:编写Dockerfile构建包含静态页面的nginx自定义镜像,创建数据卷并绑定容器,实现数据持久化与容器间数据同步。

编写Dockerfile(优化镜像大小:合并RUN指令)

先进去专属目录

bash 复制代码
cd ~/docker_experiment/lesson18

bash 复制代码
cat > Dockerfile <<'EOF'
FROM debian:12
RUN apt-get update && \
    apt-get install -y nginx curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN mkdir -p /usr/share/nginx/html
COPY ./static /usr/share/nginx/html
VOLUME /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
EOF

创建静态页面并构建镜像

bash 复制代码
mkdir -p static
echo "<h1>Custom Nginx with Volume - Debian12</h1>" > static/index.html
docker build -t my-nginx-static:debian12 .

创建数据卷并启动两个容器,验证容器间数据同步

bash 复制代码
# 创建数据卷
docker volume create static-volume

# 启动第一个容器(写入端)
docker run -d --name nginx-writer -p 8080:80 -v static-volume:/usr/share/nginx/html my-nginx-static:debian12

# 启动第二个容器(读取端),共享同一数据卷
docker run -d --name nginx-reader -p 8081:80 -v static-volume:/usr/share/nginx/html my-nginx-static:debian12

# 验证初始内容
curl http://localhost:8080
curl http://localhost:8081

# 通过 writer 容器修改内容
docker exec nginx-writer bash -c "echo '<h1>Updated by writer container (Debian12)</h1>' > /usr/share/nginx/html/index.html"

# 验证 reader 容器同步看到更新
curl http://localhost:8081   # 显示更新后的内容

验证数据持久化

bash 复制代码
# 停止并删除两个容器
docker stop nginx-writer nginx-reader
docker rm nginx-writer nginx-reader

# 启动新容器挂载同一数据卷
docker run -d --name nginx-new -p 8082:80 -v static-volume:/var/www/html my-nginx-static:debian12

# 验证数据仍然存在
curl http://localhost:8082   # 显示 Updated by writer container (Debian12)

容器编排综合:编写docker-compose.yml文件,编排nginx+mysql+tomcat三个容器,验证多容器协同运行、两两通信正常,练习配置更新、日志查看、容器重启操作。

编写docker-compose.yml

bash 复制代码
cat > docker-compose.yml <<'EOF'
version: '3.8'

services:
  mysql:
    image: mysql:5.7          # 基于 Debian
    container_name: lesson18-mysql
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: appdb
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p$MYSQL_ROOT_PASSWORD"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  tomcat:
    image: tomcat:latest  # 基于 Debian
    container_name: lesson18-tomcat
    ports:
      - "8080:8080"
    volumes:
      - ./webapps:/usr/local/tomcat/webapps
    depends_on:
      mysql:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  nginx:
    image: nginx:latest        # 官方 nginx 基于 Debian
    container_name: lesson18-nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      tomcat:
        condition: service_started
    deploy:
      resources:
        limits:
          cpus: '0.2'
          memory: 256M

volumes:
  mysql-data:
EOF

准备Nginx反向代理配置

bash 复制代码
cat > nginx.conf <<'EOF'
server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://tomcat:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /nginx_status {
        stub_status on;
        access_log off;
    }
}
EOF

准备Tomcat测试应用

bash 复制代码
mkdir -p webapps/ROOT
cat > webapps/ROOT/index.html <<'EOF'
<!DOCTYPE html>
<html>
<head><title>Tomcat + Nginx Demo</title></head>
<body>
<h1>Hello from Tomcat (Debian-based) via Nginx reverse proxy</h1>
<p>If you see this, Nginx -> Tomcat communication works.</p>
</body>
</html>
EOF

启动并验证

bash 复制代码
docker-compose up -d
curl http://localhost   # 应显示 Tomcat 页面内容
# 进入 Nginx 容器(基于 Debian)安装 MySQL 客户端并连接 MySQL
docker exec -it lesson18-nginx bash -c "apt-get update && apt-get install -y default-mysql-client && mysql -h mysql -u root -proot123 -e 'SHOW DATABASES;'"
# 进入 Tomcat 容器(基于 Debian)安装 MySQL 客户端并连接
docker exec -it lesson18-tomcat bash -c "apt-get update && apt-get install -y default-mysql-client && mysql -h mysql -u root -proot123 -e 'SHOW DATABASES;'"

练习配置更新、日志查看、容器重启

bash 复制代码
# 查看日志
docker-compose logs nginx
docker-compose logs tomcat
docker-compose logs mysql

# 修改 Nginx 配置(增加自定义响应头)
cat >> nginx.conf <<'EOF'
    location /test {
        add_header X-Custom "Hello";
        return 200 "OK";
    }
EOF
# 重新加载 Nginx 配置
docker exec lesson18-nginx nginx -s reload
curl http://localhost/test   # 应返回 "OK"

# 重启 Tomcat 容器
docker-compose restart tomcat
# 重启后验证
curl http://localhost   # 依然正常

# 更新 Tomcat 应用(修改页面内容)
echo "<h1>Updated Tomcat App (Debian12)</h1>" > webapps/ROOT/index.html
curl http://localhost   # 显示 Updated Tomcat App
相关推荐
willhuo2 小时前
Docker 存储目录迁移:解决 No space left on device
docker·容器·eureka
啦啦啦~~~3302 小时前
【装机工具】电脑重装系统!office安装管理软件!一键自动化下载、安装、部署Office的办公增强工具
运维·c语言·windows·自动化·电脑
Legend NO242 小时前
从数据中台到 Data Fabric:数据价值落地,终究要回归本质(二)
大数据·运维·fabric
vortex52 小时前
解决 Alpine Linux 虚拟机从 VirtualBox 迁移到 VMware 的内核崩溃问题
linux·运维
Dontla2 小时前
WSL卡死解决办法(wsl2卡死、WSL死机、WSL无响应、WSL无法启动、Docker Desktop卡死)(重启后解决了)
docker
qq_白羊座2 小时前
Linux 压缩 / 解压(tar)命令 + 参数详解
linux·运维·github
极客先躯2 小时前
高级java每日一道面试题-2026年02月07日-实战篇[Docker]-如何使用存储插件(如 NFS、Ceph)?
运维·分布式·容器·自动化·文件·插件·高可用
“码”力全开2 小时前
打通安防孤岛:基于 Docker 与 GB28181/RTSP 架构的 AI 视频管理平台,全源码交付解锁二次开发自主权
人工智能·docker·架构
IT探索2 小时前
服务器 BIOS 测试
运维·服务器·网络