乐山市网站建设_网站建设公司_关键词排名_seo优化
2025/12/28 5:15:30 网站建设 项目流程

文章目录

    • 一、总场景:公司内网业务上线(分角色/分模块)
    • 二、任务设计
      • 任务 1:镜像规范化(所有镜像通用)
      • 任务 2:sshd 镜像“安全化”改造(不要把它当真实生产)
      • 任务 3:systemd 镜像的“代价认知 + 正确运行姿势”
      • 任务 4:nginx 生产化:反向代理 + 配置挂载 + 日志
      • 任务 5:tomcat 生产化:部署应用 + 环境变量 + 日志
      • 任务 6:MySQL 生产化:持久化 + 初始化脚本 + 权限最小化
    • 三、综合联调关卡:三层网络 + 只暴露 Nginx
      • 目标拓扑
    • 四、排障训练(最像生产的部分)
    • 五、交付物要求

下面我把这套sshd / systemd / nginx / tomcat / mysql镜像实验,整合成一套更像“生产环境”的实战场景(带任务、验收点、附加项、常见坑),按任务做完基本就能形成完整链路思维:镜像规范 → 运行参数 → 数据持久化 → 网络隔离 → 安全 → 健康检查 → 日志排障

一、总场景:公司内网业务上线(分角色/分模块)

你们是运维小组,要在一台新服务器上用 Docker 快速部署一个“教学版业务系统”:

  • Web 层:Nginx(反向代理 + 静态资源)
  • App 层:Tomcat(跑一个 demo war)
  • DB 层:MySQL(持久化 + 远程访问控制)
  • 运维入口:SSH(仅用于排障演示,不建议真实生产这样用)
  • 系统管理:systemd 容器(演示 systemctl 管理服务的方式与代价)

要求:可重复部署、可迁移、可排障、可回滚


二、任务设计

任务 1:镜像规范化(所有镜像通用)

  1. 每个镜像必须:
    • 有清晰 tag:<service>:<version>-<base>(例nginx:1.12-centos7
    • Dockerfile 里写注释、分层合理
  2. yum -y update改成可控(生产里不建议 build 时全量 update)
  3. 清理缓存减小镜像:
    • yum clean all && rm -rf /var/cache/yum

验收点

  • docker images看 size 是否明显下降
  • Dockerfile 层数是否更少(例如合并 RUN)

附加项

  • 给镜像加LABEL(维护人、用途、版本、构建时间)

任务 2:sshd 镜像“安全化”改造(不要把它当真实生产)

  1. 禁止 root 密码登录(改用 key)
  2. 只允许某个普通用户(如ops)登录
  3. SSH 端口改为非 22(容器内仍可 22,宿主映射不同)
  4. 使用更安全的 sshd_config 片段(最少做到:禁用密码、禁用 root、限制用户)

验收点

  • root 不能登录
  • 未授权用户不能登录
  • 只能通过 key 登录

提示

  • PermitRootLogin no
  • PasswordAuthentication no
  • AllowUsers ops

步骤

  • 创建Dokcerfile文件
mkidr /opt/mysshcd/mysshcp/etc/yum.repos.d/CentOS-Base.repo ./teeDockerfile<<-'EOF' FROM centos:7 LABEL maintainer="this is ssh image <jixuancheng@qq.com>" ENV ALLOWED_USER=ops # 添加yum源 RUN rm -rf /etc/yum.repos.d/* ADD CentOS-Base.repo /etc/yum.repos.d/ # 安装和配置 RUN yum clean all && \ yum makecache && \ yum -y install openssh-server openssh-clients sudo && \ yum clean all && \ # 创建用户 useradd -m -s /bin/bash ${ALLOWED_USER} && \ echo "${ALLOWED_USER}:ops@123" | chpasswd && \ echo "${ALLOWED_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ # 生成主机密钥 ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && \ ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' && \ # SSH配置 sed -i \ -e 's/^#PermitRootLogin.*/PermitRootLogin no/' \ -e 's/^PasswordAuthentication.*/PasswordAuthentication no/' \ -e 's/^#PubkeyAuthentication.*/PubkeyAuthentication yes/' \ /etc/ssh/sshd_config && \ # 添加用户限制 echo "AllowUsers ${ALLOWED_USER}" >> /etc/ssh/sshd_config && \ # PAM配置 sed -ri '/^session\s+required\s+pam_loginuid.so/ s/^/#/' /etc/pam.d/sshd && \ sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config && \ sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config && \ # 创建.ssh目录 mkdir -p /home/${ALLOWED_USER}/.ssh && \ chmod 700 /home/${ALLOWED_USER}/.ssh && \ chown -R ${ALLOWED_USER}:${ALLOWED_USER} /home/${ALLOWED_USER}/.ssh EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] EOF

UsePAM no:不使用PAM认证
UseDNS no:取消DNS反向认证,加快访问速度。
sed -ri '/^session\s+required\s+pam_loginuid.so/ s/^/#/' /etc/pam.d/sshd:#取消pam限制
ssh-keygen -t rsa -A:生成密钥认证文件
CMD ["/usr/sbin/sshd" , "-D"]:/usr/sbin/sshd -D 用于前台启动sshd服务

  • 客户端连接
cd/opt/myssh# 1. 生成SSH密钥(如果没有的话)ssh-keygen -t rsa# 2. 构建镜像dockerbuild -t myssh-image.# 3. 创建authorized_keys文件。cat~/.ssh/id_rsa.pub>authorized_keys# 其他客户端需要连服务器上的myssh-server时,将客户端生成的公钥追加到authorized_keys即可。scp~/.ssh/id_ed25519.pub root@容器宿主机/opt/sshd/catid_ed25519.pub>>authorized_keys# 4. 运行容器dockerrun -d\-p2222:22\-v$(pwd)/authorized_keys:/home/ops/.ssh/authorized_keys\--name myssh-server\myssh-image# 5. 连接到容器ssh-p2222ops@容器宿主机
  • myssh-server宿主机
  • 其他客户端登录

报错日志

  • 重复创建容器会提示远程主机标识已更改,删掉~/.ssh/known_hosts该条记录或直接删掉known_hosts文件即可。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
rm~/.ssh/known_hosts

任务 3:systemd 镜像的“代价认知 + 正确运行姿势”

你已经写了 systemd 容器清理 wants 的做法,这是很典型的“能跑 systemctl”的实验。

  1. 必须解释清楚:为什么需要--privileged+ cgroup 挂载(安全影响是什么)
  2. 在 systemd 容器里通过systemctl start/stop/status管理 sshd 或 mysqld
  3. 写一份“什么时候不该用 systemd 容器”的说明

验收点

  • systemctl 能正常查看服务状态
  • 能重启服务后仍正常

附加项

  • 对比:不用 systemd 的做法(容器前台启动 vs systemctl)优缺点

任务 4:nginx 生产化:反向代理 + 配置挂载 + 日志

  1. Nginx 镜像不再把配置写死在镜像里:用 volume 挂载
    • /usr/local/nginx/conf/nginx.conf
    • /usr/local/nginx/conf/conf.d/
  2. Nginx 反向代理到 Tomcat(例如/app→ tomcat:8080)
  3. 日志持久化挂载:
    • /usr/local/nginx/logs/

验收点

  • 修改宿主机配置后,reload 生效(容器不重建)
  • curl http://宿主IP:端口/app能访问到 tomcat
  • 日志在宿主机可见

附加项

  • 做健康检查:用curl检测 200

任务 5:tomcat 生产化:部署应用 + 环境变量 + 日志

  1. Tomcat 镜像做到“应用可插拔”:
    • 通过 volume 挂载webapps/或挂载 war 包
  2. 配置 JVM 参数通过环境变量传入(如JAVA_OPTS
  3. 日志持久化(logs/

验收点

  • 替换 war 包无需重建镜像
  • 设置JAVA_OPTSps可看到
  • 日志落盘到宿主机

任务 6:MySQL 生产化:持久化 + 初始化脚本 + 权限最小化

  1. 数据必须持久化(volume)
  2. 初始化动作要可重复(首次初始化执行,已有数据不重复初始化)
  3. 权限控制:不要grant all on *.* to root@'%'作为最终答案
    • 改为创建业务库、业务用户,只授权业务库

验收点

  • 删除容器重建,数据不丢
  • 业务用户只能访问指定库
  • 远程能连,但 root 不允许随便远程(作为加分)

问题

  • 为什么生产里更推荐官方 mysql 镜像(减少编译维护成本)

三、综合联调关卡:三层网络 + 只暴露 Nginx

目标拓扑

  • frontend_net:只放 nginx,对外暴露端口
  • backend_net:tomcat + mysql 在内网,外部不可直接访问
  • nginx 同时加入两个网络做桥接(或只做反代到 backend)

任务

  1. 创建两个网络
  2. mysql 不映射宿主机端口(禁止外部直连)
  3. 只能通过 nginx 访问到业务页面
  4. tomcat 只能被 nginx 访问(外部不映射)

验收点

  • docker ps只有 nginx 有0.0.0.0:xxxx->80
  • 从宿主机直接连 mysql 失败
  • 从 nginx 容器能连 mysql(或 tomcat 能连 mysql)

四、排障训练(最像生产的部分)

要求在限定时间内定位问题并修复:

  1. nginx 502
    • tomcat 未启动 / upstream 写错 / 网络不通
      验收:能解释原因 + 修复
  2. tomcat 启动但访问 404
    • war 未部署 / context 路径错
      验收:能找到 webapps 内容并修复映射
  3. mysql 能启动但远程连不上
    • 授权、bind-address、端口没暴露、网络不通
      验收:能说明“该不该暴露端口”,并给出更安全的连接方式
  4. 数据丢失
    • 忘了 volume
      验收:能复现、能给出修复方案、能解释原理

五、交付物要求

最后提交:

  1. 每个服务的 Dockerfile(或 compose 文件)
  2. 一份部署文档(含端口、网络、账号策略)
  3. 一份回滚方案(如何回到上一版镜像)
  4. 一份安全说明(哪些设置仅用于实验、生产要怎么改)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询