给自己的服务器搬个家 - Docker化迁移全纪录

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Docker容器化初探,个人服务器一次小搬家纪录。

非专业运维,不会复杂配置,踩了很多坑,不断实验调整,并非最佳实践,最终目的是实现项目(vue&node)的打包部署或迁移,涉及技术:

  • Docker 容器
  • Jenkins 项目管理及自动化
  • Nginx 代理
  • Mysql 数据库
  • Nodejs 服务端
  • yarn/npm 前端包管理
  • git 附赠,无需安装
  • pm2 静态/动态服务 + 进程守护
Docker是一个在称为“容器”的孤立环境中可运行应用程序的平台。

容器分为三个:

  • 一个是放Mysql的,单独迁移数据库。
  • 一个则集成Node环境的容器,其中由Jenkins统一管理项目。
  • 独立一个Nginx容器,只用于代理。

原本计划是在服务器A做好容器后直接将容器迁移到服务器B,实际操作后发现只有nginx成功迁移了,其它两个容器启动失败。不过好在docker能帮我省去很多环境安装的步骤,mysql和nginx在服务器B手动安装也不算费力,所以实际迁移则只迁移了sql文件和nginx配置文件,而Jenkins我则简单粗暴地将整个jenkins_home打包。

首先安装Docker

系统centos7.6

curl -fsSL https://get.docker.com | bash -s docker --mirror aliyun

其它可参考这里

安装完运行

sudo systemctl start docker

常用操作

docker ps 查看正在运行的容器
docker ps -a 列出所有容器
docker stop <name> | docker start <name> | docker restart <name> 字面意思
docker rm <id> 删除容器
docker rmi <id> 删除镜像

常见参数

-d 进程守护
-uroot 使用 root 身份进入容器
-p xx:xx 主机 xx 端口映射容器的 xx 端口
-v 目录映射

安装Jenkins

update: 这一步主要将Jenkins_home打包,后续迁移往服务器的Jenkins映射目录解压

docker pull jenkinsci/blueocean

实际运行时我这里加了 --net=host,因为我的服务都将在这个容器中运行

docker run -d --name back-place -u root -p 9090:8080  -v /var/jenkins_home:/var/jenkins_home jenkinsci/blueocean

这样一个Jenkins就安装好了,少了一堆工作,Jenkins的一些配置可以参考我这篇或者上谷歌百度一下,这里不多展开,解释下上面的命令,--name后面带的是容器名,创建后都可随意修改,-p这行代表Jenkins将运行在9090端口,而且占用了Docker中的8080端口。

查看Docker目前的进程,可以看到 back-place 这个容器已经跑起来:

docker ps

此时的back-place就可以看做一个虚拟机,我们可以进入到这个容器的bash环境中:

docker exec -it back-place /bin/bash

经过一阵折腾,初始化Jenkins、Github生成新令牌、SSH、配置Git(似乎docker实例Jenkins的时候自带了git,查找路径命令为 which git )、一个个项目的构建配置复制等。

image.png

(注:如果嫌github太慢,可以使用generic-webhook-trigge插件hook码云,不过通常来讲github只要不用https连接就行,这算是一个坑,https时灵时不灵的,要用ssh项目连接)

离开bash环境:

exit

安装Mysql,迁移数据库

注:这一步实际为备份旧服务器上的mysql文件。

登录mysql,输入密码

mysql -u root -p 

输入 status 可以看到版本号:

image.png

或者在linux中mysql -V也可以直接看到版本,注意大写V。
我是将版本号复制出来直接安装,不过还是建议官网查找相关版本的镜像来安装稳一点:

docker pull mysql:5.7.34

image.png

登录旧的mysql,导完自己的sql文件,把linux的mysql关掉,释放3306端口

service mysqld stop 看不同的版本操作不同

-- 分割线: 以下在目标服务器再操作,mysql容器导入运行没成功 --

运行 docker images 看下刚才安装是否成功

image.png

修改密码并启动运行:

docker run -itd --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.34

123456为root密码,5.7.34改成自己的版本

在bash中或者外部工具连接导入数据库文件,搞定。

安装Node (Alpine)

docker exec -it back-place /bin/bash

进容器,一顿操作(这里看看就好,踩坑了,前面这些步骤是错的):

wget https://nodejs.org/dist/v14.17.1/node-v14.17.1.tar.gz
......

出师未捷身先死,nodejs.org在容器内部能ping通,但却怎么也下载不了,查了一些资料似乎说是容器网络模式设置的问题,默认是桥接模式,要让容器直接使用宿主的网络命名空间就得重新安装容器了,算了,采取折中方法,先退出bash,回到宿主linux中:

docker inspect -f '{{.Id}}' back-place

image.png
然后通过局域网拷贝文件:docker cp 本地文件路径 ID全称:容器路径

docker cp node-v14.17.1.tar.gz afe6f75d24f72b48826a5396c62e8efeb35c2cba30b5460bf20378817a8881f1:/usr/local/src/node.tar.gz

重新回到docker容器back-place中一顿操作:

docker exec -it back-place /bin/bash
cd /usr/local/src
tar zxvf node.tar.gz
cd node-v14.17.1
./configure --prefix=/usr/local/node/14.17.1

很好,又崩了,python找不到,原来我之前一直安装node的方法是基于CentOS的,已经集成了python环境,突然发觉事情不对劲了,查了一下目前docker容器的linux版本:

image.png
好家伙,又赶紧查了一下各个系统版本对应的包管理工具:

  • centos:yum
  • ubuntu:apt-get
  • alpine:apk

我是一条无奈的分割线

以下需要按照顺序操作,否则npm与node可能对不上先设置apk为国内镜像源:

推荐使用中科大镜像
sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
apk update && apk upgrade
-----------
以下为清华镜像,node版本有问题
echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/main/" > /etc/apk/repositories
apk update && apk upgrade

安装node执行:

apk add nodejs

需要手动安装npm

apk add --update npm
npm config set registry https://registry.npm.taobao.org

node 安装完毕


检查node版本,如果是8(中科大镜像无问题),手动升级一下node最新稳定版

npm install -g n
n stable

上一步如果遇到报错,尝试运行以下命令(坑真的多)

npm config set unsafe-perm true

根据提示运行以下命令,不然全局 node 命令还是旧版

PATH="$PATH"

image.png

安装PM2

用来在Jenkins容器中守护各个服务的进程。

npm install pm2 -g

常用命令

pm2 list
pm2 start ./xxx
pm2 restart all
pm2 flush          # 清空所有日志文件
pm2 delete 0       # 删除指定应用 id 0

跑静态服务

pm2 serve <path> <port> --name  <name>

如果你的Vue项目是history路由,需要这么跑

pm2 serve --spa <path> <port> --name  <name>

跑动态服务

pm2 start <path>

eg:
pm2 start /home/service.js

安装 Nginx (Alpine 失败)

就在我安装到一半的时候,linux突然崩溃,尝试了很久,依然是不行,最终决定把Nginx独立出来一个容器。

image.png
就这样搞废了几个容器,虽然很不服气,但最后还是选择放弃 TvT

image.png

安装 Nginx(Docker)

先停掉宿主的Nginx服务,Docker拉一份镜像

docker pull nginx

实例化镜像,绑定80端口(桥接模式)

docker run --name nginx -p 80:80 -d nginx

桥接模式需要指定端口,考虑到以后可能会配置更多的端口,所以实例还是直接使用net模式方便些

docker run --name nginx -d --net=host nginx

进入Nginx容器,查看配置目录

docker exec -it nginx /bin/bash
nginx -t

可以看到配置文件在 /etc/nginx 目录下,按需要进行修改,或利用docker cp将原Nginx的配置迁移过来。

docker inspect -f '{{.Id}}' nginx
docker cp <本地文件路径> <ID全称>:<容器路径>
docker cp /conf/nginx.conf xxxxxxxxxxxx:/etc/nginx

导入导出(放弃)

导出前需要查看复制出容器的COMMAND,这在导入时需要用到

docker ps -a --no-trunc

image.png

导出镜像 docker export <id> > <path>

docker export 7691a814370e > /home/test.tar

这样就有了镜像文件:test.tar,将镜像文件放到静态服务中,从服务器B远程拉取服务器A的镜像安装(理想很美好,实际上最终只有nginx容器移花接木成功,故放弃)。

导入镜像 docker import <url> <name>

docker import http://xxx.com/nginx.tar test/nginx

image.png

由于该镜像为容器实例,所以导入运行时需要最后面加上容器对应的COMMAND命令:

docker run --name=xxx -d xxx /docker-entrypoint.sh nginx -g 'daemon off;'

image.png

大文件传输

第一次打包后的文件大概是这样的:

image.png

然后放到静态服务上,根本下载不了:
image.png

这里比较占空间的是Jenkins容器,后面因为容器迁移跑不起来,实际我只迁移了jenkins_home目录(可以看做是Jenkins的所有配置,我压缩完大概200M),记得把工作空间清空一下,这块是比较占用容量的,然后用gzip压缩,效果是非常的Amazing啊:

image.png
压缩

gzip -c mysql.tar > mysql.tar.gz

解压

gunzip mysql.tar.gz

服务器之间的大文件传输我们可以使用scp来实现:

scp mysql.tar.gz root@服务器B的IP:/data/

gzip只能压缩文件,打包目录要用 tar :

tar -zcvf jk.tar.gz /var/jenkins_home

上面这个-zcvf的缩写就代表了打包完顺便使用gzip压缩,解压:

tar -xzvf

结尾

一开始想的是把所有线上的服务,统统放到docker独立容器中,通过克隆镜像来一次性迁移,目的是为了减少再次部署安装以及各种配置的时间,最后虽然不如理想中美好,但也算达成了目的:以最低成本搬家,并且在最低改动下保持我原有的生态——项目统一管理、自动化部署等等,在新服务器中使用docker安装环境并不复杂,只有少量配置需要重新弄(如SSH-key这种),这样下次服务器需要变更的时候也轻松许多了。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
13天前
|
存储 Linux Docker
docker在欧拉服务器上编译安装应该注意什么?如何操作?
【10月更文挑战第31天】docker在欧拉服务器上编译安装应该注意什么?如何操作?
38 2
|
1月前
|
弹性计算 Linux Windows
跨账号和同账号的ECS云服务器之间迁移教程
跨账号和同账号的ECS云服务器之间迁移教程
|
25天前
|
关系型数据库 MySQL Linux
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
207 3
|
26天前
|
弹性计算 数据库连接 Nacos
阿里云ECS服务器在docker中部署nacos
docker pull nacos 失败,docker部署nacos遇到的问题,nacos数据库连接,nacos端口映射
98 1
|
1月前
|
网络安全 虚拟化 Docker
SSH后判断当前服务器是云主机、物理机、虚拟机、docker环境
结合上述方法,您可以对当前环境进行较为准确的判断。重要的是理解每种环境的特征,并通过系统的响应进行综合分析。如果在Docker容器内,通常会有明显的环境标志和受限的资源视图;而在云主机或虚拟机上,虽然它们也可能是虚拟化的,但通常提供更接近物理机的体验,且可通过硬件标识来识别虚拟化平台。物理机则直接反映硬件真实信息,较少有虚拟化痕迹。通过这些线索,您应该能够定位到您所处的环境类型。
27 2
|
30天前
|
前端开发 Docker 容器
主机host服务器和Docker容器之间的文件互传方法汇总
Docker 成为前端工具,可实现跨设备兼容。本文介绍主机与 Docker 容器/镜像间文件传输的三种方法:1. 构建镜像时使用 `COPY` 或 `ADD` 指令;2. 启动容器时使用 `-v` 挂载卷;3. 运行时使用 `docker cp` 命令。每种方法适用于不同场景,如静态文件打包、开发时文件同步及临时文件传输。注意权限问题、容器停止后的文件传输及性能影响。
130 0
|
1月前
|
Apache 数据中心 Windows
将网站迁移到阿里云Windows系统云服务器,访问该站点提示连接被拒绝,如何处理?
将网站迁移到阿里云Windows系统云服务器,访问该站点提示连接被拒绝,如何处理?
|
1月前
|
弹性计算 网络协议 Linux
云服务器评估迁移时间与测试传输速度
云服务器评估迁移时间与测试传输速度
|
敏捷开发 存储 安全
传统应用的docker化迁移
Docker是云技术和IT技术的未来,这一点正在被越来越多的公司认识到,但是对于传统企业来说,如何将传统的应用迁移到Docker是一个迫切需要解决的问题。传统企业,尤其是国内的传统企业,IT建设普遍滞后,当大多数互联网公司都在大面积使用Docker的时候,传统企业还在为虚拟化、公有云[注]和敏捷开发挣扎。很多企业都在提工业4.0,但是信息化建设却没有提高到一定的高度。企业的信息化程度,很大程度上决定了企业的生产效率,而 Docker则从应用层面提出了非常好的解决方案。本文也将从迁移的角度来阐述如何在传统企业中使用Docker。 传统应用容器化迁移的思考 对于传统应用来说,使用和不使用Dock
354 0
|
7天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
30 2