服务器迁徙大作战:从虚拟到物理的服务迁移全攻略

时光匆匆,发现自己已经很久没有动笔写博客了。瞥了一眼掘金,上一篇博客居然还停留在22年。五年间,似乎自己变得越发慵懒,或许是因为一旦进入舒适区,就不太愿意再去挑战自己,不管是在技术上还是生活中。刚毕业时,心怀梦想,全力钻研各种新技术,渴望进入大厂一窥天地,然而渐渐发现,这一切似乎并没有给自己带来太多的惊喜。最近和一位同学聊天,他说自己坚持工作的动力就是知道下周就发工资了。或许对我来说也是如此,只有在即将面试时才会匆匆刷技术文档,编写开源代码。废话不多说,直入正题吧。

简单说一下写这篇博客的原因吧,一是最近闲着也是闲着,写与不写周末这样都过去了;二是用最近很火的庆余年2中话说就是做事要留痕,毕竟也是实打实的将云服务迁移到了自建服务器上嘛,写写日志。

物联网应用基建

云服务器,大家熟悉到不能在熟悉的词,不管什么岗位,只要是和计算机沾边的工作,什么阿里云、腾讯云、华为云
天翼云,国内外有一大批的云服务商。
不讨论企业级的应用,单说对于个人开发者和技术爱好者来说,云服务器给确实带来了许多便利和好处。云服务器的灵活性和方便性大大降低了技术学习的试错成本,通过云服务器可以随意的折腾系统,部署服务,有问题大不了直接重置服务器,也不用担心主板烧了,开不了机。
但是,就像所有事物一样,云服务器也有它的弊端。首先是价格问题,虽然云服务器提供了按需付费的方式,但长期使用可能会带来不小的花费,特别是对于个人开发者来说,这就是是个负担。此外,对于一些技术水平较低的人来说,如果要基于物理机自己搭建和管理服务器可能会有一定的技术难度,需要花费额外的时间和精力来学习和解决各种技术问题。因此,这篇博客的意义就在于给技术萌新指一条除云服务器之外的一条道 ,当然技术大佬们也可以一起指点指点。

起因

这几年断断续续的做了一些个人的项目,都部署在云服务器上,这些服务器大都是三年前捡漏购置的云服务器,比如三年前以极低价买了台某讯云4核8G的。最近这几台服务器都濒临到期,一看账单就是不想掏的冤枉钱,比如说这个,2核4g 续一年就是一千多。

image.png
再比如说这个更离谱一年七千多
image.png
因为大部分都是流量非常小的应用,还不如自己搞台物理机搭建,搞搞穿透,配置又高,成本又低,尔乐而不为,说干就干,所以说到底还是穷,不想掏这些资源的费用。

准备台物理主机

搭建服务器受首先就得有台主机,家里其实是有废弃的台式电脑,最开始想想也能用,但看了下能耗和噪音,确实是有些不太理想,服务器这东西总不能频繁的关机吧,耗电确实是个问题,而且分贝太高,风扇呼呼的转影响睡眠。所以目光最后投向了最近这两年特火的迷你主机,千元内的新机大部分配置相当可以,能耗、配置、造影都是相当能打的,之前论坛说零刻系列性价比可以,但看了看价格还是在预期之外,最后还是选了铭凡系列的UNI100,4核CPU + 500G存储 + 16G内存,配置杠杠的, 可以把之前的的伪K83集群直接改成单节点,物理机准备就绪接下来就是系统改造。

系统装配

Ubuntu Server安装

服务器端的操作系统很多,随便选一个适合自己的操作系统就行,我个人习惯 Ubuntu, Ubuntu有各种的发行版,常见的 Ubuntu Desktop、Ubuntu Server、Kubuntu等,直接上Ubuntu Server 中规中矩。Ubuntu Desktop 它是面向桌面、笔记本电脑和工作站的版本。该版本包括了大量的预装软件,当作服务器来说太重了。

IOS 下载

直接进入官网Ubuntu Server 找到适合的版本下载,文件比较大,耐心等待下载完毕即可。

启动盘

大部分重装系统方式都是通过启动盘的方式。找一个口碑比较好的启动盘制作工具,此处以 UltraISO 为例, 插入空闲的U盘后直接写入IOS即可,按提示步骤即可。
image.png

系统安装

启动盘制作完成后,插入主机,通过 BIOS 启动进入系统安装界面,不同型号的电脑进入方式可能不一样,大部分 长按 F2 或者 F7 再或者 F8。

进入安装引导菜单

选择 【**Try or Install Ubuntu Server 】**安装系统。
image.png

选择安装语言 && 不更新安装

默认选择 【 English 】,没有中文,可以不用找了,然后继续选择 【Continue without updating】
image.png

选择键盘布局

默认就好,不用修改
image.png

选择安装类型

默认Ubuntu Server, 不用改直接下一步;
image.png

Network配置(非常重要)

网络配置非常重要,不熟悉的建议第一次配置成DHCP(自动获取IP地址),系统装配完成后再设置静态IP,新手上路第一次建议直接配置wifi,配置wifi 时选中 对应的端口选中DHCP 即可进入wifi的连接界面(这里忘记截图了)。
image.png

代理配置默认不填

image.png

atp源 配置

这个看自己情况吧,也可以配置成国内的,像阿里的,清华的都可以

分区配置

新手不建议改,默认就好,老手其实也可以不改(没有截图,网上找了张顶一顶);
image.png

配置登录的普通用户和主机名

image.png

安装ssh

image.png

重启

安装完成后重启
image.png

服务器组网

系统安装完成后,建议将机器的IP固定,一是 连接SSH 方便,二是代码开发时服务时不用每次调整Api。
先通过 ip addr查看当前主机的ip 地址(安装系统时配置了 DHCP, 已经获取了一个可用的 ip ),如果没有特殊要求,可以直接拿这个 IP 当作静态IP, 按正常的架构来说,服务器应该有独立的路由,单本次因为只有单节点,故家中的路由器直接拿来用。
image.png

网络配置

Ubuntu 的网络配置文件一般在 /etc/netplan 目录下,至于哪个文件,不同的版本不太一样,例如50-cloud-init.yaml,找到配置文件后直接编辑配置

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp1s0:
            dhcp4: false   # 宽带的接口也禁用掉自动获取IP
        enp3s0:
            dhcp4: false   # 宽带的接口也禁用掉自动获取IP
    version: 2
    wifis:
        wlo1:
            access-points:
                "wifi 名称":  # wifi 名称,无法直接输入中文的,需要先进行ascii 编码
                    password: 'wifi密码'  # wifi的密码
            dhcp4: false  # 禁用掉自动获取IP
            routes:  # 路由配置
              - to: 0.0.0.0/0   # 所有的来源
                via: x.x.x.x   # 全部路由到网关层面
            addresses: [192.168.3.26/24] # 需要固定的IP
            nameservers:
                addresses:   ## DNS 配置 国内建议配置国内的解析
                  - 180.76.76.76
                  - 114.114.114.114
                  - 8.8.8.8


编辑设置完成后执行更新即可

sudo netplan apply
sudo systemctl restart systemd-networkd

国内常用的DNS
  • 114DNS服务 114.114.114.114
  • 阿里DNS服务 223.5.5.5
  • 百度DNS服务 180.76.76.76
  • 腾讯DNS(DNSPod ) 119.29.29.29
常见问题

有部分的 Ip、域名无法 ping 通

设置wifi 后 可以ping 通 www.baidu.com 但无法ping 通外部的 ip 例如 ping 114.114.114.114 显示ping: connect: Network is unreachable
这是目前的 route , 发现当前并未配置网关。

Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 wlo1     

针对这种问题,只需要编辑 配置网关路由即可 sudo vi /etc/netplan/50-cloud-init.yaml

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp1s0:
            dhcp4: false   # 宽带的接口也禁用掉自动获取IP
        enp3s0:
            dhcp4: false   # 宽带的接口也禁用掉自动获取IP
    version: 2
    wifis:
        wlo1:
            access-points:
                "wifi 名称":  # wifi 名称,无法直接输入中文的,需要先进行ascii 编码
                    password: 'wifi密码'  # wifi的密码
            dhcp4: false  # 禁用掉自动获取IP
            routes:  # 路由配置
              - to: 0.0.0.0/0   # 所有的来源
                via: x.x.x.x   # 全部路由到网关层面
            addresses: [192.168.3.26/24] # 需要固定的IP
            nameservers:
                addresses:   ## DNS 配置 国内建议配置国内的解析
                  - 180.76.76.76
                  - 114.114.114.114
                  - 8.8.8.8

发现配置后还是无法ping 通 发现是114.114.114.144 的dns 解析有问题时可以替换别的 DNS,例如百度的dns (180.76.76.76)。此时大概率就可以了,不论是内网还是公网。

marvin@ubuntu:~$ ping www.baidu.com
PING www.baidu.com (36.155.132.76) 56(84) bytes of data.
64 bytes from 36.155.132.76: icmp_seq=1 ttl=52 time=13.7 ms
64 bytes from 36.155.132.76: icmp_seq=2 ttl=52 time=15.4 ms
64 bytes from 36.155.132.76: icmp_seq=3 ttl=52 time=15.0 ms
^C
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 13.687/14.681/15.373/0.720 ms
marvin@ubuntu:~$ ping 180.76.76.76
PING 180.76.76.76 (180.76.76.76) 56(84) bytes of data.
64 bytes from 180.76.76.76: icmp_seq=1 ttl=50 time=38.9 ms
64 bytes from 180.76.76.76: icmp_seq=2 ttl=50 time=40.7 ms
64 bytes from 180.76.76.76: icmp_seq=3 ttl=50 time=40.6 ms
^C
--- 180.76.76.76 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 38.917/40.068/40.675/0.814 ms
marvin@ubuntu:~$ ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.114 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.116 ms
^C
--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2063ms
rtt min/avg/max/mdev = 0.089/0.106/0.116/0.012 ms

至此基于服务器的基础已经安装完毕,接下来就是安装一些底层的基座,例如 docker 、k8s 集群等。

基础设施

docker

Docker 提供了一键脚本,可以直接使用进行安装,安装命令如下所示:

curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh

安装完成以后通过可以 docker version 即可确认到版本信息:

root@canyuegongzi:~# docker version
Client: Docker Engine - Community
 Version:           20.10.6
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        370c289
 Built:             Fri Apr  9 22:46:01 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true
 
Server: Docker Engine - Community
 Engine:
  Version:          20.10.6
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       8728dd2
  Built:            Fri Apr  9 22:44:13 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.4
  GitCommit:        05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc:
  Version:          1.0.0-rc93
  GitCommit:        12644e614e25b05da6fd08a38ffa0cfe1903fdec
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

通过 systemctl start docker 启动 Docker:

systemctl start docker  // 启动 docker
docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

k3s

k3s 是简化版的K8S,麻雀虽小,五脏俱全,特别喜欢轻量级的集群部署,详细信息可以移步 K3S
k3s 早期时候因为国内网络的原因,无法通过官方的提供的脚本一键安装,只能通过离线安装的方式。2020 年之后官方提供了国内环境下的安装脚本。

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - --docker

通过 k3s kubectl get node 验证 k3s 是否安装成功。

k3s kubectl get node
k3s kubectl get node
NAME           STATUS   ROLES                  AGE   VERSION
ubuntu  Ready    control-plane,master   87s   v1.20.6+k3s1

至此一些底层的软件部署完毕,开始部署一些上层的应用,诸如 Mysql, redis 等

mysql

此处只是简单贴了下 mysql 的部署 yml 配置,其中的具体配置信息,感兴趣的可以深度钻研下 k8S 的配置。

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-data-dev.cnf
  namespace: test
data:
  my.cnf: |
    [mysqld]
    port = 3306
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    skip-character-set-client-handshake=1
    default-storage-engine=INNODB
    max_allowed_packet = 500M
    explicit_defaults_for_timestamp=1
    long_query_time = 10

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-1gi-mysql-data
  labels:
    type: local
spec:
  storageClassName: manual-mysql-data
  capacity:
    storage: 4Gi
  accessModes:
    - ReadWriteOnce # 卷可以被一个节点以读写方式挂载
  hostPath:
    path: "/mnt/data"

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data-pvc
  namespace: gpt
spec:
  storageClassName: manual-mysql-data
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi

---
# https://www.cnblogs.com/JoePotter/p/16703055.html
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-data-deployment
  namespace: gpt
  labels:
    app: mysql-data
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql-data
  template:
    metadata:
      labels:
        app: mysql-data
    spec:
      containers:
        - name: mysql-data
          #image: mysql:8.0.24 #  mysql:8.0.30-debian
          image: mysql:8.0.24
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: 123456
          ports:
            - containerPort: 3306
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: mysql-data
            - name: mysql-config
              mountPath: /etc/mysql/mysql.conf.d
      imagePullSecrets:
        - name: aliyun-register-pwd
      volumes:
        - name: mysql-data
          hostPath:
            path: /data/mysql
            type: Directory
        - name: mysql-config
          hostPath:
            path: /data/mysql-config
            type: Directory



## --tls-san 参数是可以允许公网 ip 证书

---
apiVersion: v1
kind: Service
metadata:
  name: mysql-data-service
  namespace: gpt
spec:
  type: LoadBalancer
  selector:
    app: mysql-data
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
      nodePort: 3306


redis

redis 也类似,K8S 的内容不在本次博客之内,感兴趣的可以深度学习 K8S 的运维之道。

apiVersion: v1
kind: ConfigMap
metadata:
  name: redis
  namespace: test
data:
  redis.conf: |+
    requirepass 123456
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize no
    supervised no
    pidfile /var/run/redis_6379.pid
    loglevel notice
    logfile ""
    databases 16
    always-show-logo yes
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb
    dir /data
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    lazyfree-lazy-eviction no
    lazyfree-lazy-expire no
    lazyfree-lazy-server-del no
    slave-lazy-flush no
    appendonly yes
    appendfilename "appendonly.aof"
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    aof-use-rdb-preamble no
    lua-time-limit 5000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events Ex
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    aof-rewrite-incremental-fsync yes

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-pv-1gi
  labels:
    type: local
spec:
  storageClassName: manual-redis
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce # 卷可以被一个节点以读写方式挂载
  hostPath:
    path: "/mnt/data"


# deploy nacos pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-pvc
  namespace: gpt
spec:
  storageClassName: manual-redis
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: gpt
  labels:
    app: redis
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          #image: redis
          image: registry.cn-hangzhou.aliyuncs.com/redis:2.1.1
          imagePullPolicy: Always
          command: ["redis-server","/etc/redis/redis.conf"]
          ports:
            - containerPort: 6379
          volumeMounts:
            - name: redis-config
              mountPath: /etc/redis/redis.conf
              subPath: redis.conf
            - name: redis-persistent-storage
              mountPath: /data
      imagePullSecrets:
        - name: aliyun-register-pwd
      volumes:
        - name: redis-config
          configMap:
            name: redis
            items:
              - key: redis.conf
                path: redis.conf
        - name: redis-persistent-storage
          persistentVolumeClaim:
            claimName: redis-pvc

---
kind: Service
apiVersion: v1
metadata:
  name: redis
  namespace: gpt
spec:
  type: LoadBalancer
  selector:
    app: redis
  ports:
    - port: 6379
      protocol: TCP
      targetPort: 6379

业务应用

业务应用 此处也不再录累赘,后续有时间刻印挑几个应用做示例

网络穿透

暂时还没有做这部分的能力,马上完成后再做博客分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值