开发文档#
为你的团队启用 lain#
使用 lain 是轻松高效的, 但为你的团队启用 lain, 却不是一件轻松的事情. 这是由 lain 本身的设计决定的: lain 没有 server side component (因为功能都基于 helm), 而且不需要用户维护集群配置(可以写死在 集群配置 里, 随包发布). 这是 lain 的重要特点与卖点, 针对用户的易用性都不是免费的, 都要靠 SA 的辛勤劳作才能挣得.
目前而言, 在你的团队启用 lain, 需要满足以下条件:
Kubernetes 集群, Apiserver 服务向内网暴露, kubeconfig 发布给所有团队成员
Docker Registry, 云原生时代, 这应该是每一家互联网公司必不可少的基础设施, lain 目前支持一系列 Registry: Harbor, 阿里云, 腾讯云, 以及原生的 Docker Registry.
[可选] 你熟悉 Python, 有能力维护 lain 的内部分支. lain 是一个内部性很强的软件, 有很多定制开发的可能性.
[可选] 打包发版, 这就需要有内部 PyPI, 比如 GitLab Package Registry, lain 的代码里实现了检查新版, 自动提示升级. 如果你们是一个快节奏的开发团队, lain 的使用必定会遇到各种需要维护的情况, 因此应该尽量有一个内网 Package Index.
[可选] Prometheus, Grafana, Kibana, 这些将会给 lain 提供强大的周边服务, 具体有什么用? 那就任君想象了, 云平台和监控/日志系统整合以后, 能做的事情那可太多了.
[可选] 你的团队使用 GitLab 和 GitLab CI, 以我们内部现状, 大部分 DevOps 都基于 GitLab CI + lain, 如果你也恰好如此, 那便有很多工作可以分享.
[可选] 你的团队对 Kubernetes + Helm 有着基本的了解, 明白 Kubernetes 的基本架构, 以及 Pod / Deploy / Service / Ingress / Ingress Controller 等基本概念.
假设你满足以上条件, 并且对路上的麻烦事有足够心理准备, 可以按照以下步骤, 让 lain 能为你的团队所用.
Fork GitHub Repository#
lain 的最新进展在 GitHub 仓库, 你需要对这个仓库做内部 Fork, 这样才能开始做定制化, 以及内部发版.
git clone https://github.com/timfeirg/lain-cli
cd lain-cli
# 将 remote origin 更名为 upstream, 我这里用的是 https://github.com/tj/git-extras 提供的功能
git-rename-remote origin upstream
git remote add origin https://gitlab.mycompany.com/dev/lain-cli
书写集群配置#
将 lain 据为己有的第一步就是, 将自己团队使用的集群加入 lain 的 cluster config, 就在这里书写: lain_cli/cluster_values/values-[CLUSTER].yaml
, 示范如下:
# lain_cli/cluster_values/values-test.yaml
# namespace: default # k8s namespace
# serviceAccountName: default
# # lain 每次运行前都会检查是否最新版, 在这里配置对应的 pypi 地址
# # 这里用的是 gitlab pypi registry, 你可以换成你自己喜欢的, 例如 devpi-server
# pypi_index: https://gitlab.example.com/api/v4/projects/[PORJECT_ID]/packages/pypi/simple
# pypi_extra_index: https://mirrors.cloud.tencent.com/pypi/simple/
# 镜像仓库
registry: docker.io/timfeirg
# 有一些 PaaS 提供内网镜像加速, 集群内外用的镜像 tag 不一样
# internalRegistry: registry.in.example.com
# # lain 整合了一系列 gitlab 相关功能, 在这里配置 gitlab 地址
# gitlab: http://gitlab.example.com
# 内网域名写在这里, 至于公网地址, 就不写在这里了, lain 要求公网域名完整声明在 values 里 (更加显式)
domain: info
secrets_env:
# 调用 registry 接口的认证信息, 用途就是从 registry api 获取可供使用的镜像列表
dockerhub_username: DOCKERHUB_USERNAME
dockerhub_password: DOCKERHUB_PASSWORD
extra_docs: |
在这里书写额外的欢迎信息
# 比如 TKE 需要将 kube-apiserver 的地址写到 hosts 里, lain 会根据以下配置, 提醒用户添加相应记录到 /etc/hosts
# 同时, 同样的配置还会进入 Kubernetes manifests, 因此容器里也能解析这些域名
clusterHostAliases:
- ip: "127.0.0.1"
hostnames:
- "local"
# # 内外网的服务使用不同的 ingressClass
# # 这样一来, 外部人士就没办法通过内网域名, 直接经由公网流量入口, 访问内部服务了
# # 这些配置当然也可以写在应用级别的 chart/values-[CLUSTER].yaml 下
# # 但这样一来, 每一个应用都需要重复一遍, 因此抽出放在 cluster_values 里, 加强复用
# ingressClass: lain-internal
# externalIngressClass: lain-external
# # 这是 cert-manager 配置, 同样出于复用的考虑, 放在 cluster_values 下, 开发者可没精力维护这种基础设施配置
# clusterIssuer: cert-manager-webhook-dnspod-cluster-issuer
# # 填写 grafana url, 让 lain 在恰当的时候给出监控页面链接
# grafana_url: https://grafana.example.com/d/xxxxx/container-monitoring
# # 填写 kibana host, 让 lain 在恰当的时候给出应用日志链接
# kibana: kibana.behye.cn
我们推荐把集群配置一起打包进 Python Package, 随包发布. 但如果你愿意, 也可以超载 CLUSTER_VALUES_DIR
来定制集群配置的目录, 这样就能直接引用本地的任意集群配置了.
集群配置写好了, 本地也测通各项功能正常使用, 那就想办法发布给你的团队们用了.
打包发版#
这是一个可选(但推荐)的步骤, 打包到内部 PyPI 上, 意味着你可以把 集群配置 和代码一起打包, 随包发布, 这样一来, 大家就无需在自己本地维护集群配置了.
打包有很多种方式, 既可以上传私有 PyPI 仓库, 也可以把代码库打包, 直接上传到任意能 HTTP 下载的地方, 简单分享下我们曾经用过的打包方案:
# 以下均为 GitLab CI Job
upload_gitlab_pypi:
stage: deliver
rules:
- if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE != "schedule"'
allow_failure: true
script:
- python setup.py sdist bdist_wheel
- pip install twine -i https://mirrors.cloud.tencent.com/pypi/simple/
- TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token python -m twine upload --repository-url https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/packages/pypi dist/*
upload_devpi:
stage: deliver
rules:
- if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE != "schedule"'
variables:
PACKAGE_NAME: lain_cli
script:
- export VERSION=$(cat lain_cli/__init__.py | ag -o "(?<=').+(?=')")
- devpi login root --password=$PYPI_ROOT_PASSWORD
- devpi remove $PACKAGE_NAME==$VERSION || true
- devpi upload
deliver_job:
stage: deliver
except:
- schedules
script:
- ./setup.py sdist
# 用你自己的方式发布 dist/lain_cli-*.tar.gz
打包发布好了, 大家都顺利安装好了, 但要真的操作集群, 还得持有 kubeconfig 才行, 那我们接下来开始安排发布 kubeconfig.
暴露 Apiserver, 发布 kubeconfig#
有 kubeconfig 才能和 Kubernetes 集群打交道, 你可以用以下步骤获得合适的 kubeconfig:
lain 调用的 kubectl, helm, 都是直接和 Kubernetes Apiserver 打交道的, 因此你需要让 Apiserver 对内网可访问.
[可选] 配置好 Kubernetes ServiceAccount, 加入私有 Registry 的 imagePullSecrets.
如果你在用阿里云, 可能需要注意关闭 aliyun-acr-credential-helper, 否则这玩意会持续覆盖你的 ServiceAccount Secrets. 禁用的命令类似
kubectl scale --replicas=0 deployment -n kube-system aliyun-acr-credential-helper
.lain 需要 admin 权限的 kubeconfig, 并且要提前设置好 namespace:
kubectl config set-context --current --namespace=[namespace]
. 如果没什么特别要求, 并且这个集群仅使用 lain 来管理, 那么建议直接用 default namespace 就好.接下来就是想方设法发布给你的团队, 比如用 1password. 大家下载以后, 放置于各自电脑的
~/.kube/kubeconfig-[CLUSTER]
目录, 目前 lain 都是在小公司用, 没那么在意权限问题. 关于安全性问题请阅读 安全性.
kubeconfig 也就位了, 那事情就算完成了, 接下来就是教育你的团队, 开始普及 lain, 可以参考 快速上手 的内容.
从上游获取更新#
lain 的开发非常考虑普适性, 通用性, 你一定希望能获取到 lain 的最新功能. 如果你是按照 Fork GitHub Repository 来做的内部 fork, 那你只需要做 rebase, 就能获取到新代码:
git pull --rebase upstream master
如果你的定制部分不涉及代码变更, 那么 rebase 是不太容易产生冲突的. 但若你对代码做了修改, 那想必你也熟悉代码仓库, 知道如何进行适配.
做好 rebase 以后, 你肯定担心会引入 bug, 或者破坏原有的功能. 这时候如果你能自己运行下 lain 的测试, 甚至根据自己团队的情况, 进行定制化测试, 那将会大大提高维护的简易度和自信心. lain 有着还算全面的端到端测试, 欢迎参考.
搭建配套基础设施#
lain 的诸多丰富功能都是由各种周边基础设施提供的, 比如 Prometheus, Grafana, Kibana, 这些组件都需要你一一部署, 并且按照 lain 的要求来进行配置. lain 的要求也并不复杂, 在本节进行介绍.
Prometheus#
在 Kubernetes 下一般都直接用社区的 Helm chart 来搭建吧, 默认的配置就已经包含了 Kubernetes 下的服务发现, 因此安装 Prometheus 没什么特别的注意事项.
不过为了提供完整功能, 除了必要的 node-exporter, cadvisor, kube-state-metrics 之外, 最好把 grok-exporter 也一并搭建, 这是为了在宿主机层面做 OOM 监控, 具体可参考 拿什么拯救 OOM.
Grafana#
lain 鼓励开发者自行使用 Grafana, 查看自己的应用的监控. 在看板里给出了应用容器的基础指标, 这也是我们研发团队主要关心的数据:
图中的 dashboard 可以在 这里
下载, 导入以后, 将对应的 Grafana URL 填写到集群配置里(参考 书写集群配置), 然后就能在 lain status -s
里看到打印出来的 Grafana URL 了, 点击这个 URL, 直接就会进入该应用的 Grafana 监控页面.
Kibana#
我们用 EFK 来搭建 Kubernetes 的容器日志收集系统, 也就是 Elasticsearch + Fluentd + Kibana. 搭建方面没有特殊要求, 遵循社区最佳实践即可.
lain 和 EFK 的关系主要在于 Kibana, 你需要配置好 Log monitoring, 然后将 URL 填写到集群配置里(依然是参考 书写集群配置), 然后就能用 lain logs --kibana
打开 Kibana 链接, 直接阅读该应用的日志流了.
本地开发与测试#
参考 lain 的 CircleCI 不难发现, lain 的 E2E 测试就是用 minikube 拉起来一个本地集群, 然后在上边用 dummy 作为测试应用, 来对各种关键流程做正确性验证. 本地运行这个测试也很简单, 介绍下大致步骤:
# 运行测试之前, 如果执行过 lain use, 那就需要先删掉 kubeconfig, 否则 minikube 会篡改 link 对应的源文件
rm ~/.kube/config
# 安装好 minikube 以后, 拉起一个集群
minikube start
# 安装好 minikube 以后, 默认的 kubeconfig 文件内容就被修改成本地的 minikube 集群了, 因此我们把他改成 lain 默认的 kubeconfig-test
mv ~/.kube/config ~/.kube/kubeconfig-test
# 运行 lain use, 让 lain 来管理本地 minikube 集群
lain use test
# 接下来就可以在本地运行各种 E2E 测试啦
pytest --pdb tests/test_workflow.py::test_workflow