0. 写在前面:为什么你需要“神器”而非“常用命令
大家好,欢迎来到干货、技术、专业全方位遥遥领先的老杨的博客.
帮老杨点赞、转发、在看以及打开小星标哦
攒今世之功德,修来世之福报
乡亲们是不是都在好多个云厂商服务间来回穿梭?一会跟这个谈崩了,一会那个降价了.咱们就得来回搬家.
不管你是不是,反正老杨是,因为业务的问题,国内外厂商,各厂家私有云,多地开发和测试环境等等歪瓜裂枣,各种品相的都有.
今天不聊私有云的事,那玩意太复杂了,咱们简单聊聊多个公有云的事.
把可迁移性当成设计目标。 把迁移能力做成流水线。
我建议把 provider 抽成 alias。 再把通用模块做成独立模块。
provider "alicloud" {
region = var.alicloud_region
alias = "ali"
}
provider "aws" {
region = var.aws_region
alias = "aws"
}
module "network" {
source = "./modules/network"
providers = {
alicloud = alicloud.ali
aws = aws.aws
}
name = var.name
}
初始化并计划:
$ terraform init
# 省略网络和 provider 下载...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Finding latest version of alicloud/alicloud...
$ terraform plan -out plan.tf
输出:
Plan: 4 to add, 0 to change, 0 to destroy.
Note: resources created via ali and aws providers are separate.
要点很简单。 把云相关细节放在模块内。 通用逻辑不要引用厂商 API。
容器化后,把 Kubernetes 清单当合同。 同一份清单,按不同 context 部署。
$ kubectl config get-contexts
# 查看上下文列表
输出:
CURRENT NAME CLUSTER AUTHINFO
* prod-ali prod-ali admin@prod-ali
prod-tencent prod-tencent admin@prod-tencent
$ kubectl --context prod-ali apply -f k8s/app.yaml
输出:
deployment.apps/myapp created
service/myapp created
$ kubectl --context prod-tencent apply -f k8s/app.yaml
输出:
deployment.apps/myapp created
service/myapp created
实践中只在 StorageClass、LoadBalancer 注解等少数点做云差异化。 其它都保持一致。
镜像如果只在某家仓库,切换会很慢。 我会在 CI 里同时推到两家仓库,或者用中立仓库。
$ skopeo copy docker://registry.aliyuncs.com/my/app:1.0 docker://quay.io/myorg/app:1.0
输出:
Getting image source signatures
Copying blob sha256:...
Copying config sha256:...
Done
策略上,标签要明确。 CI 把镜像推到国内仓和外部仓。 切换时只改镜像拉取源。
对象与数据库是最容易被绑住的地方。 必须做两个动作:抽象和跨云复制。
$ rclone copy oss:my-bucket cos:my-bucket --progress
输出:
Transferred: 123 files, 1.2 GB
Elapsed: 10m
数据库迁移示例:
$ mysqldump -h rds-ali -u backup -p'P@ss' mydb | gzip > mydb.sql.gz
$ scp mydb.sql.gz user@tencent-db:/tmp/
$ gunzip < mydb.sql.gz | mysql -h rds-tencent -u restore -p'P@ss' mydb
输出:
Dump completed: 2024-12-01 12:00
Restore completed: 2024-12-01 12:10
我建议定期在另一云做一次恢复演练。 别把唯一备份放在同一云里。
把认证接入统一 IdP。 再按最小权限分配。
$ kubectl create rolebinding dev-read \
--clusterrole=view \
--user=dev@example.com \
--namespace=dev
输出:
rolebinding.rbac.authorization.k8s.io/dev-read created
不要共享 root。 每个人独立账号。 审计记录要能追溯到人。
把变更放到 Git。 用 ArgoCD 或 Flux 做多集群同步。
$ argocd login argocd.example.com --username admin --password ****
$ argocd cluster add kube-context-prod-ali --name prod-ali
输出:
Context "kube-context-prod-ali" added
变更必须走审批流程。 这样就有证据,能证明不是单点误操作导致的问题。
DNS 是切换慢的常见原因。 把服务放在可控的 DNS 下。 把 TTL 设为合理的短值。
$ dig +nocmd app.example.com @8.8.8.8 +noall +answer
输出:
app.example.com. 60 IN A 1.2.3.4
TTL 太长切换慢。 TTL 太短会增加解析压力。 通过演练找到平衡值。
跨云可观测性很关键。 Prometheus federation、Thanos,或写入统一时序库都行。 日志用 Fluentd/Fluent Bit 汇总。
$ curl -s 'http://prometheus.example.com/api/v1/query?query=histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))'
输出:
{"status":"success","data":{"result":[{"metric":{"service":"myapp"},"value":[1620000000,"0.23"]}]}}
告警要在多个平台都能触发。 把告警流程写成 runbook。 触发时按步骤执行。
合同不是法律课的东西。 它能给你时间和保障。 写清数据导出接口和导出速率。 写明迁移费用和支持窗口。
演练能把问题暴露出来。 我习惯把一次完整切换做成工单。 记录耗时和失败点。
演练示例:
# 在 ali 集群把 deployment scale 到 0
$ kubectl --context prod-ali scale deployment myapp --replicas=0 -n prod
输出:
deployment.apps/myapp scaled
# 在 tencent 集群把 replicas 提到 5
$ kubectl --context prod-tencent scale deployment myapp --replicas=5 -n prod
输出:
deployment.apps/myapp scaled
演练会暴露镜像同步、配置差异或 DNS TTL 问题。 把发现的点写成改进项。
运维人挑灯守夜,为亿万连接负重前行,机器轰鸣中,运维人以鲜血与诗意修补世界的脆弱,朝露未晞,使命已沉。 亿万方阵,任将帅坐帷帐指点江山,运维人护军旗立于风雨之夜.挽大厦于将倾,填江湖与决口.运维不死,只是慢慢凋零. 评论区等你们!
这里老杨先声明一下,日常生活中大家都叫老杨波哥,跟辈分没关系,主要是岁数大了.就一个代称而已. 老杨的00后小同事老杨喊都是带哥的.张哥,李哥的. 但是这个称呼呀,在线下参加一些活动时.金主爸爸也这么叫就显的不太合适. 比如上次某集团策划总监,公司开大会来一句:“今个咱高兴!有请IT运维技术圈的波哥讲两句“ 这个氛围配这个称呼在互联网这行来讲就有点对不齐! 每次遇到这个情况老杨老杨周末浅聊服务器开在公网的那些坑老杨干了,你们随意!” 所以以后咱们改叫老杨,即市井又低调.还挺亲切,老杨觉得挺好.
运维X档案系列文章:
企业级 Kubernetes 集群安全加固全攻略( 附带一键检查脚本)
看完别走.修行在于点赞、转发、在看.攒今世之功德,修来世之福报
老杨AI的号: 98dev