任何能够被描述的内容都必须存储在Git库中
这个GitOps的理念, 今天来践行一下,不借助其它devops平台, 看看是不是能够实现工具闭环
Git是GitOps形成的最基础的内容,就像第一条原则“任何能够被描述的内容都必须存储在Git库中 ”描述的那样:通过使用Git作为存储声明性基础架构和应用程序代码的存储仓库,可以方便地监控集群,以及检查比较实际环境的状态与代码库上的状态是否一致。所以,我们的目标是描述系统相关的所有内容:策略,代码,配置,甚至监控事件和版本控制等,并且将这些内容全部存储在版本库中,在通过版本库中的内容构建系统的基础架构或者应用程序的时候,如果没有成功,则可以迅速的回滚,并且重新来过
当然如果团队内有自己的devops平台的话,那其实就没必要接着看了,这篇post主要给大家一种思路,如何借助已有的工具来实现端到端的CI/CD, 只适合于团队较小,没有多余的资源来开发自己的平台的场景.
开源工具
以下3个开源工具, 不在这里介绍, 大家可参考相应的连接
kustomize
kustomize是kubernetes官方推荐的声明式配置形式
https://izsk.me/2020/07/01/Kubernetes-kustomize/
sealed-secrets
sealed-secrets主要提供可以在git上以密文的形式存储敏感数据, 当发布到k8s集群时用私钥进行解密,解密之后就变成了正常的secret文件.
https://izsk.me/2020/06/24/Kubernetes-sealed-secrets/
configmapsecret
kubernetes官方是不支持在configmap中直接引用secret中的内容, 因此configmapsecret主要用于在配置中引用secret或者是configmap中的内容
https://izsk.me/2020/06/28/Kubernetes-configmap-reference-var-from-secret/
Demo实践
这个demo用于实践以下功能:
- 使用配置端到端的、使用kubernetes推荐的声明式配置管理的方式(kustomize)
- 敏感的密码之类的数据在git源文件中进行脱敏处理(sealed-secrets)
- 结合gitlab的ci/cd方式完成多环境部署
到这一步默认在集群中已安装了以上的开源库.
目录结构
1 | app-kustomize |
以上文件的具体内容大家可参考这篇post
数据加密
业务中敏感的数据其实不会很多,大多都是k-v的形式,比如mysql的密码,token等,既然要在git上存储这些数据,那自然是要进行脱敏才放心, 以最小的知情范围存在
可以把敏感的数据都放在一个配置文件中,类似下面的形式,怎么简单怎么来
cat senserealty-secret-data.yaml
1 | mongodb_password: mysql1234 |
然后通过sealed-secrets
进行加密,发布到集群中, 如何操作, 请参考上面的链接.
发布到集群后会发现已经生成了一个secret文件, senserealty-secret-data用于存储敏感信息
那在配置文件中就可以通过configmapsecret
直接引用这些数据了
Kustomize
通过使用kustomize来组织所有需要发布到集群中的文件, 是非常方便的, 特别是应对多套环境的时候,通过派生的形式来生成配置,大大减少维护成本.
如何使用请参考上面的链接
CI/CD
使用gitlab自带的CI/CD工具同样可以实现很不错的效果, 只需要为其搭建一个k8s集群做为Runner即可, 很大一部分都会围绕gitlab-ci.yaml文件展开, gitlab实现了自己的语法, 拓展性非常强, 参考
这里给一个参考
1 | image: ubuntu:latest # Pipeline中各个步骤阶段的构建镜像没有指定时,默认使用这里指定的镜像 |
对于只修改配置文件的场景, 由于业务上不想升级一个版本, 因此通过给pod打一个annotation
来实现pod的重启.
验证
进入到容器的/etc/config/config.yml
目录会看到生成了两个配置文件,且敏感信息已经被解密成明文.
其实还有一种情况: 业务中可能很多的应用都会连接mysql, 那么, 当需要修改mysql的账号时, 还需要一个一个地去只需要这些应用的参数然后重启, 一次还好, 如何碰到安全部门定时修改的要求时更苦逼, 这其实是可以优化的
通过上面的方式, 其它应用都引用的senserealty-secret-data
这个secret里的内容, 那只需要修改这一个文件,重新发布一下即可
应用通过watch的方式来监听该文件的变动,一有变动自动重启即可, 这个其实也有开源工具: reloader,有兴趣的可以参考一下
这种方式本人已经在生产环境中得到了验证,非常实用.
当然上面的例子中只是使用了几种最常用的配置, 其实完全可以将其它的资源对象以声明式的形式保存在git中
就像GitOps推荐的一样:任何能够被描述的内容都必须存储在Git库中
目前有很多的开源库可以直接实现以上功能, 比如Flux,能够同步git的变更直接发布到集群中. 功能上更强大. 感兴趣的可以参考
问题
kubectl apply -k
出现error: rawResources failed to read Resources
1 | error: rawResources failed to read Resources: Load from path ../../base/ failed: '../../base/' must be a file (got d='/Users/zhoushuke/git_uni/gitlab.bj.sensetime.com/gitlabci-golang-demo/deploy/base') |
出现这种情况是因为kustomize
与kubectl apply -k
版本不匹配, 可以使用kustomiz build . | kubectl apply -f -
另外一个情况下, bases
已经在kustomize v2.1.0+ 版本中给去掉了,高版本的会直接将bases
转换成resources
,这个可以从渲染后的kustomization.yaml中看出
patch时到底是覆盖还是新增
cat base/deployment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# ... 省略
containers:
name: p-expoter
volumeMounts:
- mountPath: "/etc/config/config.yml"
name: demo-config
readOnly: true
subPath: config.yml
volumes:
- secret:
items:
- key: alertmanager.yaml
path: config.yml
secretName: p-expoter-senserealty-cms
name: demo-configcat overlay/1box/patch-deploy.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# ... 省略
containers:
name: p-expoter
volumeMounts:
- mountPath: "/etc/config/grafana.yml"
name: demo-config
readOnly: true
subPath: grafana.yml
volumes:
- secret:
items:
- key: grafana.yaml
path: grafana.yml
secretName: p-expoter-senserealty-cms
name: demo-config最终build的结果为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# ... 省略
containers:
name: p-expoter
volumeMounts:
- mountPath: /etc/config/grafana.yml
name: demo-config
readOnly: true
subPath: grafana.yml
- mountPath: /etc/config/config.yml
name: demo-config
readOnly: true
subPath: config.yml
volumes:
- name: demo-config
secret:
items:
- key: grafana.yaml
path: grafana.yml
secretName: p-expoter-senserealty-cms可以看到 mountPath是合并了, 而volumes则是覆盖了. 这里可以使用在
kustomization.yaml
中使用patch
或者patchJson6902
, 参考这里,如果无法确认是合并还是覆盖, 多多使用kustomize build
命令当然这里只是举个例子, 如果想实现叠加的话, 完全可以把base/deployment.yaml下的volumes复制一份过来, 不用把结构搞的太复杂
参考文章:
- https://kubernetes-sigs.github.io/kustomize/api-reference/glossary/#generator
- https://blog.fleeto.us/post/crud-with-kustomize/
- https://zhuanlan.zhihu.com/p/92153378
- https://izsk.me/2020/06/24/Kubernetes-sealed-secrets/
- https://izsk.me/2020/06/28/Kubernetes-configmap-reference-var-from-secret/
- https://kubernetes-sigs.github.io/kustomize/api-reference/kustomization/
- https://izsk.me/2020/05/10/Kubernetes-deploy-hot-reload-when-configmap-update/