当前位置: 首页 > news >正文

【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路

探路

前篇列出的都是缓兵之计, 大部分问题还是存在, 在前几个月懵逼和饱受白名单问题煎熬后, 慢慢打起了vpc迁移的算盘.

这个迁移很大的一个问题就是, 如何将VPC和经典资源打通呢?

VPC经典互通的第一次尝试

在16年底, 风控准备上第一版服务, 将服务放在了vpc内. 以此为契机尝试打通vpc和经典的服务,但是这个时候阿里云vpc刚上没多久, 基本没有任何对这方面的支持.
第一次尝试方案如下

  • 在vpc内创建了一个openvpn server把端口暴露给经典网络
  • 在经典环境以一台空闲节点作为client保持和openvpn server的连接
  • vpn server给经典client下发vpc网段路由下一跳指向vpn server
  • 在vpn server上对vpn和经典网段分别进行SNAT
  • vpc路由器上将经典网段的10路由下一跳指向vpn server
  • 经典节点上对vpc和vpn网段SNAT

其他的经典节点由于路由不可控无法主动访问vpc, 经典client节点可以openvpn server的身份访问其他vpc所有节点.这样经典client的节点相当于和vpc完全互通了.
而vpc内的节点则可以通过vpn client访问所有经典节点, 由于是在路由器上加的路由这个访问是对于vpc节点来说是无需配置, 无感知的.

不过由于阿里云有一个神奇的100.64.0.0/10网段(RDS,DRDS,redis,部分SLB), 这个路由是无法控制的, 为了让vpc能访问到阿里云的这些资源, 只能不停在将各种不同的资源在经典的vpn client做DNAT.
DNAT规则大致如下.

firewall { '100 snat for vpn':
  chain    => 'POSTROUTING',
  jump     => 'SNAT',
  proto    => 'all',
  source   => '192.168.0.0/24',
  table    => 'nat',
  tosource => '10.165.69.144',
}
firewall { '101 snat for vpn':
  chain    => 'POSTROUTING',
  jump     => 'SNAT',
  proto    => 'all',
  source   => '172.31.255.0/24',
  table    => 'nat',
  tosource => '10.165.69.144',
}
firewall { '102 dnat for drds xxx':
  chain    => 'PREROUTING',
  table    => 'nat',
  jump     => 'DNAT',
  source   => '!10.0.0.0/8',
  destination => '10.165.69.144',
  proto    => 'tcp',
  dport    => '3306',
  todest   => '100.98.69.136',
}
firewall { '103 dnat for rds xxx.mysql.rds.aliyuncs.com':
  chain    => 'PREROUTING',
  table    => 'nat',
  jump     => 'DNAT',
  source   => '!10.0.0.0/8',
  destination => '10.165.69.144',
  dport    => '3307',
  proto    => 'tcp',
  todest   => '100.114.46.162:3306',
}
firewall { '104 dnat for redis xxxx.m.cnbja.kvstore.aliyuncs.com':
  chain    => 'PREROUTING',
  table    => 'nat',
  jump     => 'DNAT',
  source   => '!10.0.0.0/8',
  destination => '10.165.69.144',
  proto    => 'tcp',
  dport    => '6379',
  todest   => '100.99.94.201',
}
firewall { '105 dnat for slb xxx':
  chain    => 'PREROUTING',
  table    => 'nat',
  jump     => 'DNAT',
  source   => '!10.0.0.0/8',
  destination => '10.165.69.144',
  proto    => 'tcp',
  dport    => '80',
  todest   => '100.114.31.148',
}

整个结构的简单图示:
vpc经典互联

这样勉强达到了互通的要求, 但是问题也很明显, vpn client和vpn server都是单点的. 期间分别准备好了备机以防止意外随时切换, 这种状态跑了半年, 除了有时经典节点公网带宽跑满, 并未出现过其他问题, 升级过带宽后也好了. iptables的转发还是很给力的, 不过现在阿里云在互通方面做了很多支持,没必要这样做了.

正式上路

阿里云推出经典与vpc互联支持后

阿里云文档: https://help.aliyun.com/document_detail/55051.html

主要支持了 ClassicLink, 混访混挂, 单ECS迁移, 既有的java应用也是在推出上述实际支持后开始的.

迁移问题

提前规划

  • 迁移到vpc后, 自然不希望再和以前一样看着经典ip一脸懵逼. 希望看到ip就能知道是哪个集群里的, 策略可以直接根据预先设定的网段来设置. 下面是之前规划时整理的部分文档(2017年4月写的, 具体请以阿里云最新文档为准)

限制:

  • vpc限制

注意事项:

  • VPC 的交换机是一个 3 层交换机,不支持 2 层广播和组播。
  • 每个交换机的第1个和最后3个 IP 地址为系统保留地址。以 192.168.1.0/24 为例,192.168.1.0、 192.168.1.253、 192.168.1.254 和 192.168.1.255 这些地址是系统保留地址。
  • 专有网络内的 ECS 使用安全组防火墙进行三层网络访问控制。

划分原则

  • 每个分组对应至少一个或多个(可用区)交换机, 每个交换机绑定至少一个分组命名的安全组.
  • 每个分组对应至少一个分组命名的容器集群.
  • 每个分组对应单独的SNAT表或者SNAT IP POOL.
  • 每个分组之间默认完全隔离. 由安全组控制访问.访问
  • 每个分组保证至少2个可用区,核心业务三个可用区. 以可用区字母结尾, 例如 common-a 表示common分组, A可用区
  • 生产和测试vpc独立, 完全隔离
    vpc网络规划

其实不太建议用 192.168.0.0/16 网段, 可用ip相对会少一些, 而且后续如果办公网或者经典互联容易出现问题.

路由问题

这里需要注意2个问题

  • 默认情况路由表条目是有限制的, 默认是48, 如果后续容器化(阿里云为了打通容器网段, 会在路由表上自动添加路由条目, 容器网段下一跳指向对应宿主机节点), 很容易达到限制配额. 可以手动控台申请配额, 或者工单申请.
  • 正常情况classiclink后, 经典网络节点可以直接访问vpc节点, 但是如果vpc网段是 192.168.0.0/16 就比较特殊了, 需要手动在经典节点上加下路由. 脚本参考这里 添加路由

新老服务交互

我们应用主要是dubbo + http方式来进行应用间的互相访问, 涉及数十个应用, 不会是一波进去, 就会存在一段时间需要vpc和经典互访的情况.

dubbo服务
  • 利用classic将zk集群和provider端链入vpc
  • vpc内新建一个zk集群
  • consumer端先迁入, 同时注册新老zk集群, 因为后续使用的容器化, 直接在启动entrypoint的脚本里做一些处理即可, 应用无需改动.
# add dubbo vpc registry
# find  /data/ -name "*.xml" -exec grep -Hn 'registry' {} \; | awk -F: '{print $1}' | xargs -i -t sed -i -r '/zookeeper.vpc.cluster/d' {}
# find  /data/ -name "*.xml" -exec grep -Hn 'registry' {} \; | awk -F: '{print $1}' | xargs -i -t sed -i -r '/registry/{h;s/dubbo:registry/& id="vpc"/;s/(address=")(.*)(")/\1${zookeeper.vpc.cluster}\3/;G}' {}
  • 后续provider迁入, 同理. 直至相关服务迁移完成后将主zk直接指向vpc的zk集群, 老zk集群下线.
http服务

这个比较简单了, 因为我们内部服务也通过slb暴露, 这里主要通过slb混挂来做.

  • vpc内起一个新的服务, 将相关节点挂入原有的经典内网slb.
  • 调整权重, 观察服务正常逐渐替换老的节点即可.
  • 一般会在vpc内也再开一个vpc内网slb提供vpc内调用, 后续迁移完成后确认老的经典slb无流量后释放即可.

公网slb其实同理. 不过由于在迁移vpc同时进行了容器化, 这里稍微有些处理(下篇专门介绍容器化会说到)

阿里云相关资源调用

后续迁移过程中阿里云其实都已经提供了相当方便的支持, 在这之前我们都是使用的相当粗暴的走公网链接方式(很不推荐, 受公网带宽限制, 而且有一定风险, 虽然traceroute测试下来公网路径貌似都是经过的阿里云节点,但终究心里没底)

  • oss, ots, ons等等直接换成vpc的endpoint即可
  • drds,rds, redis稍微麻烦一点, 需要迁移vpc后选择保留经典链接, 最多可以同时维持vpc,经典内网,公网三个链接地址, 而且经典地址保留时间可以工单延长. vpc内的应用直接使用vpc内网地址即可.

基本上在阿里云实际提供支持后, vpc和经典网络这块并没有太多的障碍, 主要根据应用状态, 逐个迁移观察, 就是一些细心的活了. 更多踩到的坑还是在容器化中, 下篇继续介绍vpc迁移同时容器化踩到的一些坑.

相关文章:

  • 经典面试题1
  • JAVA学习路线 零基础新手必备
  • Flask+jinja2 开发Puppet用户和节点管理系统
  • 痞子衡嵌入式:如果i.MX RT是一匹悍马,征服它时别忘了用马镫MCUBootUtility
  • 武汉大学2014年基础数学复试试题参考解答
  • chown: changing ownership of `.': Invalid argument
  • 面试题:数组原型上实现一个去重的方法
  • ×××案例之一路由之间的×××
  • Spring Framework 5.2.0.M1 发布
  • [詹兴致矩阵论习题参考解答]习题2.5
  • BF-9000 BMC任务关键型应急通信系统
  • appium如何切换键盘
  • 关于ios 8 7 下的模态窗口大小的控制 代碼+場景(mainstoryboard)( Resizing UIModalPresentationFormSheet )...
  • Metasploit运行环境内存不要低于2GB
  • mysql5.5升级5.6
  • 自己简单写的 事件订阅机制
  • C++11: atomic 头文件
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • node.js
  • QQ浏览器x5内核的兼容性问题
  • spring boot 整合mybatis 无法输出sql的问题
  • vue-loader 源码解析系列之 selector
  • 从PHP迁移至Golang - 基础篇
  • 聚类分析——Kmeans
  • 开源SQL-on-Hadoop系统一览
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 前端相关框架总和
  • 跳前端坑前,先看看这个!!
  • 推荐一个React的管理后台框架
  • ionic入门之数据绑定显示-1
  • kubernetes资源对象--ingress
  • #define与typedef区别
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (4)STL算法之比较
  • (pytorch进阶之路)扩散概率模型
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (三)Honghu Cloud云架构一定时调度平台
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (小白学Java)Java简介和基本配置
  • (转)h264中avc和flv数据的解析
  • . NET自动找可写目录
  • .gitignore
  • .htaccess配置重写url引擎
  • .Net CF下精确的计时器
  • .NET Core WebAPI中封装Swagger配置
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .NET的数据绑定
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually