持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
前言
大家好,我是陈同学,一枚前端开发者,感谢各位的点赞、收藏、评论
上一年CentOS-Stream9发布,正逢所在组织的服务器使用年限到达上限,准备更换一台物理机子
等到机器到货后马上安装了CentOS-Stream9,并逐步将旧服务器上的线上业务向新服务器进行迁移,本文将该经历形成文字描述进行分享
本文阅读成本与收益如下:
阅读耗时:10mins
全文字数:5k
预期效益
- 传统物理机服务器进行服务迁移
前言
旧服务器环境:
- 操作系统:Windows Server 2012
- 数据库:Mysql 5.7
- PHP环境:PHP 7.2
- WEB应用程序:Apache 2.4.6
- 缓存:Redis 6.2
在进行迁移之前必须明确组织线上正在运行的数字资产实际使用情况
其中包括但不限于:
- 线上应用源码
- 线上应用数据来源
- 线上应用日志
- 线上应用运行环境
- 应用服务调用链路
- 本地hosts解析
- 外部服务IP访问限制
- 等等
新服务器环境准备
在新的机器上安装好CentOS-Stream9操作系统后,需要根据业务实际情况搭建对应的web应用运行时环境,由于后续组织发展可能会使用多种后台开发语言进行代码的编写,而每一种编程语言都需要有对应的运行时环境,如java项目-jdk、node项目-nodejs、php-phpFPM等
经过一番思索后决定采用Docker容器化的方式搭建web应用基础环境
第一步:宿主机安装Docker引擎与Nginx
- 安装Docker
官方文档教程:docs.docker.com/engine/inst…
- 安装Nginx
使用yum安装Nginx
sudo yum -y install nginx # 安装 nginx
sudo yum remove nginx # 卸载 nginx
Nginx配置文件在 /etc/nginx 或者 /etc/local/nginx 目录下
sudo systemctl enable nginx # 设置开机启动
sudo service nginx start # 启动 nginx 服务
sudo service nginx stop # 停止 nginx 服务
sudo service nginx restart # 重启 nginx 服务
sudo service nginx reload # 重新加载配置,一般是在修改过 nginx 配置文件时使用。
第一步完成后新机器(宿主机)如图所示
第二步:安装Mysql容器与Redis容器
由于需要对多个项目的数据进行持久化,为了便于统一管理,我们单独一个mysql实例容器与redis实例容器
之后所有的现存业务与增量业务数据存储均由这两个容器承担(条件允许的情况下做一下主从)
- 安装Mysql容器
docker pull mysql:8.0 # 拉取mysql8.0镜像
docker images # 查看镜像列表
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=XXX -d --name ctx_mysql mysql:8.0 # 启动mysql容器
- 安装Redis容器
先在宿主机创建/usr/local/redis/config/redis.conf
example文件:download.redis.io/redis-stabl…
将example中的文件按照自己的需要进行修改,并将文本内容复制到/usr/local/redis/config/redis.conf
最后执行命令
docker run -d \
-p 6379:6379 \
-v /usr/local/redis/config/redis.conf:/etc/redis/redis.conf \
--privileged=true \
--name ctx_redis \
redis \
redis-server /etc/redis/redis.conf
这一步完成后,宿主机环境示意图如下:
第三步:安装CentOS容器
docker pull centos:7
docker images
docker run -itd -p 30:20 -p 31:21 -p 90:80 -p 453:443 -p 898:888 -p 8898:8888 --privileged=true -v /home/www:/www --name ctx_centos centos:7
这里通过Docker基于CentOS7镜像启动一个容器,接着在容器内安装宝塔,之后便可以通过宝塔面板端口来变更容器中的文件
另一个启动该容器的原因是,组织内旧服务器上有比较多的PHP项目应用,故想着直接通过将项目文件都放到该容器内,再通过宝塔安装对应的PHP环境保证原项目的正常运行,与宿主机隔离,而宿主机接收到的项目请求便可以通过宿主机上的Nginx服务反向代理转发到Docker容器内
最终,新服务器上的结构,如图所示:
旧服务器数据迁移
对应WEB应用来说,我们的数据是核心数字资产,故我们需要尽可能在数据迁移过程中做到对用户体验的无感
本次迁移采用的方案步骤如下:
- 停止所有线上应用,并挂维护公告(凌晨0:00)
- 使用数据库数据迁移工具将旧服务器数据迁移至新服务器Mysql容器
- 将所有项目对应的数据库连接属性进行修改(改为新服务器的内网IP与端口)
- 恢复线上应用服务访问
旧服务器项目迁移
- PHP项目
将旧服务器上的PHP相关的项目文件转移到新服务器宿主机的CentOS容器挂载的目录中
通过宿主机Nginx的配置以及容器宝塔配置跑通项目的链路
- 其它项目
将旧服务器上除了PHP以外的其它项目进行Docker化部署,如:nodejs项目可以基于Docker基础镜像node:14创建容器
具体的操作就是为每一个项目定制一个Dockerfile文件,在新服务器上拉下代码后以Dockerfile配置打包一个镜像并启动一个项目容器
变更域名解析
做完项目迁移工作并跑通相关验证后,就可以将域名解析映射修改至新服务器IP
此后所有的流量将会打到新服务器上
宿主机上的Nginx服务负责监听80与443端口,将外部请求按照一定的规则反向代理转发到指定的本地端口上(对应容器端口)
外部服务IP访问限制
由于组织当中有的业务需要用到基于OAuth2的统一身份验证系统,而在注册使用系统时已经登记过旧服务器的内网IP
故若从新服务器将token换票验证请求发送至统一身份验证系统,会被目标主机拒绝访问(不在允许IP范围内)
在没有更新登记信息之前,我们只能用旧服务器作为token换票验证请求中转站,将与统一身份验证系统相关的请求,通过Nginx反向代理转发给旧服务器的服务处理(当然对应数据库连接还是新服务器)
配置新服务器开机自启动项
主要配置宿主机上Nginx以及Docker引擎服务的自启动
配置Nginx开机自启动
- 创建
nginx.service文件
cd /etc/systemd/system
vi nginx.service
nginx.service文件内容如下
[Unit]
Description=nginx service
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
- 调整新文件权限,并设置开机自启动
chmod 755 nginx.service
systemctl daemon-reload
systemctl enable nginx
- 常用指令
systemctl start nginx # nginx启动
systemctl stop nginx # nginx停止
# 启动nginx服务
systemctl start nginx.service
# 重新启动nginx服务
systemctl restart nginx.service
# 查看nginx服务当前状态
systemctl status nginx.service
# 停止开机自启动
systemctl disable nginx.service
- 有条件的话可以重启测试一下
reboot
配置Docker开机自启动
- 将Docker服务加入开机自启动项
systemctl enable docker
- 设置开机自启动容器(示例)
docker run -d --restart=always ${containerName}
非线上应用文件及数据迁移
除了项目应用文件以及数据库数据以外,旧服务器上还有一些历史遗留下来的备份文件
采用建立FTP通信链路的传输方式将相关数据慢慢进行迁移
还有一部分日志以及弃用的项目文件(以后大概率也不会用的文件)留在了原服务器,不再进行迁移
新服务器运维常用
Docker常用命令
docker pull ${imageName}
docker images # 查看镜像列表
docker ps # 查看已启动的容器列表
docker ps -a # 查看所有的容器列表(包括未启动的)
docker run -di ${containerName} -p ${hostPort}:${containerPort} -v ${hostPath}:${containerPath} --name ${containerDiyName} --restart=always # 启动运行一个容器
docker stop ${containerName} # 停止一个容器
docker logs ${containerName} # 查看容器的日志信息
docker rm ${containerName} # 删除一个容器(前提:目标容器必须被stop)
docker rmi ${imageName} # 删除一个镜像
docker exec -it ${containerName} /bin/bash # 以bash交互的方式进入到容器内
docker exec ${containerName} ${command} # 在容器内执行命令command并返回结果
Nginx常用命令
/usr/local/nginx/sbin/nginx # 启动Nginx服务
/usr/local/nginx/sbin/nginx -t # 测试Nginx配置
/usr/local/nginx/sbin/nginx -s reload # 重载Nginx配置
/usr/local/nginx/sbin/nginx -s stop # 停止Nginx服务
vim /usr/local/nginx/conf/nginx.conf # 编辑Nginx配置文件(不熟悉千万不可以变更!!!)
讲到最后
本文仅用于记录一次新旧物理机服务器的迁移过程,若文中有不当之处,欢迎各位在评论区讨论交流
本人也在不断探索,服务器运维与安全是一个大话题,还需要继续学习~!
谢谢大家,我们下节再见!!!
感谢各位看到这里,如果你觉得本节内容还不错的话,欢迎各位的点赞、收藏、评论,大家的支持是我做内容的最大动力