目录

K8s 实践经验 (k8s in action)

文章简介:总结最近几年使用 k8s 的经验

背景

  1. ToB 项目
  2. 离线安装运行环境
  3. 容器化
  4. 多组件编排

基于这个背景下,公司选择使用 k8s。

rke

选择使用 rancher/rke 这个 k8s 发行版,docker/ansible 等依赖离线化处理,支持 ubuntu 20.04/ centos 7.9。

基于 kustomize 的部署

kustomize 提供了 template free 的 k8s manifest yaml 生成工具,可以简单的为 base/prod/staging 等不同的生产环境打 patch 定制不同的环境。当前会使用 helm chart 生成 yaml 文件供 helm charts 使用。此时所有的部署相关文件是在统一的一个仓库 deploy 中维护的。这种模式下每个项目都会有自己的 deploy.sh 文件,用于持续部署 patch 项目的 image。如果某个项目的部署模式变化了,要同时修改 deploy 这个仓库。两项目耦合严重。

基于 helm charts 以 app 为单位的部署

为了解决 deploy 项目与 app 项目耦合严重的问题,将deploy 中 app 的 configmap/service/deployment 等资源移动到 app 仓库中,此时 deploy 只需要引用 app 仓库的版本号/分支即可。

longhorn + nacos 系统极不稳定来源

在第一次生产验证过程中,k8s 的分布式文件存储使用了 longhorn。使用过程中会频繁的 IO error, longhorn 官方甚至列出了非常多的已知问题。在生产使用过程中会比较频繁的出现文件系统 readonly/读写延迟过高,nacos 服务规律性不可用、重启 nacos 5-10分钟,导致依赖此服务的其他所有服务长时间不可用。由于 poc 为单机版本,考虑使用本地的文件系统替换分布式文件系统。

第一次生产 POC 阶段不可复现升级过程

由于产品是 ToB 项目,产品产出物为离线安装包。在客户离线网络下安装后,会频繁的更新某个服务的镜像。急需一个稳定可复现的升级过程,方便现场离线升级,而不是每次我们产出文字版本、有歧义的升级过程文档。

古怪的 helm upgrade

第一版本升级包有一个比较神奇 helm 升级过程

1
2
helm show values appname1 > values.yaml
helm upgrade --debug --install appname1 appname1-0.0.1.tgz -f values.yaml

app 的 values 经过重构后,很容易出现 values结构变化,变化的化,需要如此人工写新的升级逻辑

1
2
3
helm show values appname1 > values.yaml
migrate_appname1_patch_values.py
helm upgrade --debug --install appname1 appname1-0.0.1.tgz -f values.yaml

导致升级维护困难

改进后的 helm upgrade

使用 IaC 的思路,将所有的基础设施都在仓库中维护,将所有 values.yaml 也要放到升级包中,而不是 charts 放到仓库,values 使用生产中的

1
helm upgrade --debug --install appname1 appname1-0.0.1.tgz -f values.yaml

为了保证 values.yaml 部分值需要依赖生产环境,values.yaml 是一种 template 比如 golang 的 template,使用新的工具基于当前生产环境中的 deploy-env configmap 生成, 其他所有部分都放到 gitlab 中维护。

1
2
3
4
kubectl get cm deploy-env -o go-template --template='{{range $key, $value := .data}}export {{$key}}='"'"'{{$value}}'"'"';{{end}}'

gotemplate values.yaml.tmpl > values.yaml
helm upgrade --debug --install appname1 appname1-0.0.1.tgz -f values.yaml

最终所有的升级打包过程会变成:

  1. 从 gitlab 中下载所有的 charts
  2. charts + values 渲染出 k8s manifest yaml, 从其中提取出 docker img,并下载下来

最终所有的升级过程变成:

  1. skopeo copy file docker://host/xxx
  2. 遍历所有 apps,渲染 values.yaml.tmpl, helm upgrade

选择更简单的架构,k3s 改造

rke 的 k8s 发行版依赖 docker,docker 需要自己安装。当前的实现中需要使用发行版中的 docker 依赖树。客户场景需要支持很多不同中 linux 发行版,适配不同的发行版成本搞。搭上 k3s 的顺风车,单文件启动兼容 k8s 的服务,其余组件已经容器化,安装过程简化了很多适配 linux 发行版的过程。

k8s 集群回归

  1. 集群部署
  2. 文件系统采用本地存储,要求应用层面的副本机制保证服务数据不丢: rancher/local-path-provisioner

总结

  1. 小集群(<=50节点)k3s 真的很香,80% 企业的服务都是少于 50节点的(未实际统计,凭当前简单的企业集群数量估算)
  2. 分布式文件系统真的太理想化了,当前测试发现 longhorn 尽量不要在生产使用,除非他真的适合你的场景
  3. IaC 在运维场景为我们省去了太多后期维护的麻烦事,能用就用,不能用也要想方设法使用