惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Engineering at Meta
Engineering at Meta
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
D
Docker
Vercel News
Vercel News
云风的 BLOG
云风的 BLOG
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
DataBreaches.Net
IT之家
IT之家
V
V2EX
人人都是产品经理
人人都是产品经理
F
Fortinet All Blogs
J
Java Code Geeks
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
雷峰网
雷峰网
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
MongoDB | Blog
MongoDB | Blog
P
Privacy International News Feed
F
Full Disclosure
P
Proofpoint News Feed
B
Blog RSS Feed
T
Tor Project blog
T
The Blog of Author Tim Ferriss
B
Blog
Webroot Blog
Webroot Blog
腾讯CDC
T
Troy Hunt's Blog
T
Tailwind CSS Blog
H
Heimdal Security Blog
AWS News Blog
AWS News Blog
G
Google Developers Blog
Spread Privacy
Spread Privacy
NISL@THU
NISL@THU
A
About on SuperTechFans
SecWiki News
SecWiki News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
I
InfoQ
M
MIT News - Artificial intelligence
大猫的无限游戏
大猫的无限游戏
美团技术团队
L
LangChain Blog

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19) 使用 Velero 备份 Kubernetes 集群 Kubernetes Cheat Sheet 开发 Tips(18) 如何构建一个 Java 工程 开发 Tips(17) KubeSpray 安装 Kubernetes 报错 ip in ansible_all_ipv4_addresses 基于 Kubernetes 和 Jenkins 搭建自动化测试系统 在 Kubernetes 上动态创建 Jenkins Slave 使用 Jenkins 进行服务拨测 开发 Tips(16) Kubernetes 签发 Ingress 证书及日常故障运维 Kubernetes 中 Deployment 的基本操作 Kubernetes 中的证书 如何使用 KubeBuilder 开发一个 Operator Kubernetes 1.6.0 安装问题汇总 镜像管理工具 -- Harbor 开发 Tips(15) Docker 如何拉取镜像 开发 Tips(14) 使用 Helm 安装 harbor 开发 Tips(13) 使用 S2I 构建云原生应用 在 Kubernetes 中使用 emptyDir、hostPath、localVolume 开发 Tips(12) 开发 Tips(11) 代码质量分析工具 SonarQube 使用 Kubeadm 安装 Kubernetes 集群 一起来学 Go --(4)常用函数 Kubernetes 中的 Ceph Kubernetes 之 Volumes Kubernetes 之 Labels、Selectors 开发 Tips(10) 开源正在重构商业模式 Kubernetes 之网络 Kubernetes 之 API 使用 Helm 和 Operator 快速部署 Prometheus Kubernetes 复杂有状态应用管理框架 -- Operator Kubernetes 的包管理器 -- Helm 一起来学 Go --(3)Go Modules 如何一步一步地优化博客方案 kubectl 实用指南 Kubernetes 中的基本概念 搭建远程 Kubernetes 开发环境 大公司和小公司的 ToB 思路 开发 Tips(9) Go 入门指南 一起来学 Go --(2)数据与逻辑结构 如何预防 Web 富文本中的 XSS 攻击 django-xss-cleaner 云工作时代 一起来学 Go --(1)背景与特点 SaaS 开发团队的不同阶段 你不知道的 Git 使用技巧 输出既服务 微服务设计 继续奔跑 开发 Tips(8) 从账户安全到二次验证 Django 性能之数据库查询优化 Django 性能之分库分表 敏捷开发之研发流程 打造一致性的团队 开发 Tips(7) Pytest 进阶学习之 Mock PaaS 部署之 buildpack Go 开发配置 领域输出才是 PaaS 的核心竞争力 Pytest 入门学习 开发 Tips(6) 如何使用 Jenkins、Docker、GitLab 搭建 Django 自动化部署流程
文档工具化 - Ops 工具
微信公众号 · 2023-04-11 · via 陈少文的网站

1. 什么是文档工具化

文档工具化,工具产品化,是我之前博文中反复提过的一个口号。

好的文档,不如好用的工具。一个脚本、一条命令,比阅读文档更加直接,更能快速解决问题。同时,有很多文档会让读者对知识产生眩晕,在急于解决问题的窗口期无法补全知识体系的情况下,很容易出现错误的理解。

这种有领域壁垒的知识,需要融入一点设计对其进行转换,才能让用户更好的使用。这就是文档工具化的意义。

从文档到工具,从工具到产品,雕琢地痕迹会越来越明显,这是一个很有趣的过程,不断地去掉冗余,去掉不必要的东西,让用户更加专注于解决问题。

2. Ops 工具

有了上述想法之后,我一直希望能够将平时工作中的一些操作,通过工具的方式进行封装,让这些操作能够得到更好的复用。

半年多前,我新建了一个项目,叫做 ops,主要用来辅助我完成工作中的一些操作。

如上图,是这个项目的一个构想。设计理念在于,运维工具的核心在于文本分发和脚本执行,实现了这两种能力就能够满足运维的功能需求。

目前,我面向的运维对象是 Host 主机、Kubernetes 集群,很少直接面向容器。因此在 OpsObject 层实现了 Host 和 Cluster 对象,分别对应主机和 Kubernetes 集群。

而在此之上,分别实现了面向主机的文件分发、脚本执行,以及面向 Kubernetes 集群的文件分发、脚本执行,也就是 Core 核心能力层。

得益于 Core 层的能力,我已经可以实现一些简单的运维功能,比如:批量添加 hosts,批量安装、变更 Prometheus 等。

但这还不够,很多运维操作不是单步能够完成,因此需要一些流程控制,比如: 备份集群之前,需要先安装 Velero,安装 Velero 之前,需要先安装 Helm 等。因此引入了一个新的对象 Task,用于完成编排,这样其实就和 Ansible 很像了。

在 Tools 层,我提供了三个入口,:opscli、opsserver、opscontroller。目前主要完成了 opscli 和 opscontroller 两个部分。

3. opscli

opscli 是一个静态的二进制文件,支持 Linux 和 macOS 系统,可以通过 curl 命令直接下载使用。

3.1 安装

如果网络连接 GitHub 很好,可以使用下面的命令安装:

1
curl -sfL https://raw.githubusercontent.com/shaowenchen/ops/main/getcli.sh | VERSION=latest sh -

如果网络连接 GitHub 不好,可以使用下面的命令安装:

1
curl -sfL https://raw.githubusercontent.com/shaowenchen/ops/main/getcli.sh |VERSION=latest sh -

3.2 配置自动补全

  • 如果使用 bash
1
echo 'source <(opscli completion bash)' >>~/.bashrc
  • 如果使用 zsh
1
echo 'source <(opscli completion zsh)' >>~/.zshrc

3.3 使用

  • 查看帮助
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
opscli --help

Usage:
  opscli [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  create      command about Ops Resource
  file        transfer between local and remote file
  help        Help about any command
  shell       run shell on hosts
  task        command about task
  upgrade     upgrade to latest version
  version     get current version
  • 面向主机,远程执行命令
1
2
3
opscli shell -i 1.1.1.1 --port 2222 --username root --content "uname -a"

Linux node1 5.4.219-1.el7.elrepo.x86_64 #1 SMP Sun Oct 16 10:03:45 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux

这里的 -i 可以指向一个 ip,也可以指向一个文件,文件中包含多个 ip,每行一个 ip。--content 指向要执行的命令,也可以是脚本文件。

  • 面向集群,远程执行命令
1
opscli shell -i ~/.kube/config --content "docker pull shaowenchen/ops-cli:latest" --sudo  --all

这里的 -i 指向一个 kubeconfig 文件,--all 表示对集群中的所有节点都执行命令,如果不加 --all,则只会在 master 节点执行命令,使用 --nodename 可以指定指向命令的节点。

另外有一个特殊的参数 --incluster 表示这条命令将会在集群的某一个 Pod 运行,这在集群内部检测问题时非常有用。

  • 面向主机,文件分发

文件的分发,是一个映射的过程,本地、远程两个目标 + 数据流方向。

1
opscli file --remotefile /etc/hosts --localfile ./file1 --direction download -i 1.1.1.1 --port 2222 --username root

这里的 --direction 表示数据流方向,download 表示从远程下载到本地,upload 表示从本地上传到远程。

  • 面向集群,文件分发
1
opscli file --remotefile /etc/hosts --localfile ./file1 --direction download -i ~/.kube/config --nodename node1

这里的 --nodename 表示目标节点。

实际上文件分发,还支持源文件来自镜像、S3,这里就不一一列举了。

  • task 使用
1
2
3
4
5
6
7
8
ls ~/.ops/tasks/

add-file2image.yaml          alert-http-status.yaml       app-openebs.yaml             get-kubeconfig.yaml          pull-file.yaml               upgrade-1.16m.yaml           upgrade-kernel3to5.yaml
add-imagepullsecret.yaml     alert-promql.yaml            app-prometheus.yaml          get-osstaus.yaml             push-file.yaml               upgrade-1.16n.yaml           velero-backup.yaml
add-localbinpath.yaml        app-descheduler.yaml         clear-docker.yaml            k8s-drain-node.yaml          renew-kube-cert.yaml         upgrade-1.17m.yaml           velero-install.yaml
add-opscli.yaml              app-grafana.yaml             clear-kube.yaml              k8s-hpa.yaml                 set-docker-liverestore.yaml  upgrade-1.17n.yaml           velero-restore.yaml
add-reqlimit.yaml            app-istio.yaml               clear-opstask.yaml           list-podimage.yaml           set-hosts.yaml               upgrade-1.19m.yaml           velero-status.yaml
add-superuser.yaml           app-metricsserver.yaml       get-imagefile.yaml           list-svc.yaml                set-kernel.yaml              upgrade-base.yaml

~/.ops/tasks/ 目录下,有很多的 task yaml 文件,可以直接使用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
opscli task -f ~/.ops/tasks/get-osstaus.yaml -i 1.1.1.1 --port 2222 --username root

> Run Task  /  on  1.1.1.1
(1/11) Kernel Version
5.4.219-1.el7.elrepo.x86_64
(2/11) CPU Usage Percent/Load/Total
10.11%/0.00/4
(3/11) Mem Usage Percent/Total
33.02%/7.8G
(4/11) Disk Usage Percent/Total
69%/52G /dev/mapper/centos-root
35%/1.1G /dev/sda1
4%/26G /dev/mapper/centos-home
(5/11) NF_Conntrack Usage/Total
1344/131072
(6/11) PID Usage
1.57%/65535
(7/11) ARP Router
0.02%/80000
(8/11) Open Files Number
1.29%/1048576
(9/11) User Instances
0.23%/8192
(10/11) User Watches
0.00%/524288
(11/11) User Processes
360/31711

如果是面向集群,只需要将 -i 指向一个 kubeconfig 文件,然后加上 --all 或者指定 --nodename 即可。

4 opsserver

这部分还在开发中,主要是为了提供一个 HTTP API,以供其他系统、脚本调用。

5 opscontroller

5.1 安装

  • 安装 Helm
1
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
  • 添加 Helm 仓库
1
helm repo add ops https://www.chenshaowen.com/ops/charts
  • 安装 ops-controller
1
helm install myops ops/ops --version 1.0.0 --namespace ops-system --create-namespace
  • 查看安装结果
1
kubectl get pods -n ops-system

opscontroller 默认只会处理 ops-system 命名空间下的 CRD 资源对象。

如果需要变更,可以修改 Env 中 ACTIVE_NAMESPACE 的值,指定某一个命令空间,如果为空,则表示处理所有命名空间。

5.2 使用

  • 创建一个主机对象
1
opscli create host --name dev1 -i 1.1.1.1 --port 2222 --namespace ops-system
1
2
3
4
5
6
7
8
kubectl -n ops-system get hosts

NAME   HOSTNAME   ADDRESS       DISTRIBUTION   ARCH     CPU   MEM    DISK   HEARTTIME   HEARTSTATUS
dev1   node1      1.1.1.1       centos         x86_64   4     7.8G   52G    59s         successed
dev2   node2      1.1.1.1       centos         x86_64   4     7.8G   52G    60s         successed
dev3   node3      1.1.1.1       centos         x86_64   4     7.8G   52G    0s          successed
dev4   node4      1.1.1.1       centos         x86_64   4     7.8G   52G    2s          successed
dev5   node5      1.1.1.1       centos         x86_64   1     1.8G   95G    0s          successed

controller 会定时检测主机的状态,并将主机的状态更新到 host 对象中。

  • 创建一个集群对象
1
opscli create cluster --name dev1 -i ~/.kube/config --namespace ops-system
1
2
3
4
5
6
7
8
kubectl -n ops-system get cluster

NAME   SERVER                       VERSION   NODE   RUNNING   TOTALPOD   CERTDAYS   STATUS
dev1   https://1.1.1.1:6443         v1.21.0   1      14        14         193        successed
dev2   https://1.1.1.1:6443         v1.23.0   3      22        22         350        successed
intl   https://1.1.1.1:6443         v1.21.4   1      18        95         268        successed
prod   https://1.1.1.1:6443         v1.21.4   10     134       1098       183        successed
test   https://1.1.1.1:6443         v1.21.4   1      23        23         227        successed

controller 会定时检测集群的状态,并将集群的状态更新到 cluster 对象中。

  • task 任务也可以通过 opscli 创建,但我更希望的是用 yaml 直接创建

controller 主要是定时执行 task 对象中的任务。比如清理集群,提供告警等。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
kubectl -n ops-system get task

NAME                             CRONTAB       TYPEREF   NAMEREF   NODENAME   ALL    STARTTIME   RUNSTATUS
alert-http-status-dockermirror   */1 * * * *
alert-http-status-harbor        */1 * * * *
alert-http-status-git           */1 * * * *
alert-http-status-mirror-go      */1 * * * *
alert-http-status-mirror-maven   */1 * * * *
alert-http-status-mirror-npm     */1 * * * *
alert-http-status-mirror-pypi    */1 * * * *
alert-promql-node-cpu            */1 * * * *
alert-promql-node-disk           */1 * * * *
alert-promql-node-io             */1 * * * *
alert-promql-node-mem            */1 * * * *
alert-promql-pending             */1 * * * *
alert-promql-pending-pod         */1 * * * *
alert-promql-pvc                 */1 * * * *
alert-trigger-autotest           */5 * * * *
clear-docker                     15 * * * *    cluster   prod                 true
clear-opstask-dev1               10 * * * *    cluster   dev1
clear-opstask-dev2               10 * * * *    cluster   dev2
clear-opstask-prod               10 * * * *    cluster   prod
clear-opstask-test               10 * * * *    cluster   test

通过 TYPEREF 指向对象类型,NAMEREF 指向对象名称。上面是我生产环境的配置,下面是发出的告警通知。

alert 告警如上图,主要支持两种方式,一种是通过 promql 查询,另一种是通过 http 请求。

定时任务 clear-docker 会清理集群每个节点上的构建残留物,clear-opstask 会清理因执行集群 Ops 错误时产生的 Pod。

6. 总结

这个项目主要是为了方便我自己运维主机和管理集群,同时提供了周期任务能力,以及告警能力。目前还在开发中,后续会继续完善。

在工作中去抽取项目,不是一件容易的事,需要找到项目和工作之间的契合点。很多工作中的项目和业务紧密耦合,无法抽取;而如果脱离工作,没有实际的业务场景打磨,项目也很难有价值。

起初 opscli 有很多的子命令用于满足各种场景,但是后来我又通过 task 对象来重新实现。这样做的好处是,task 对象可以作为公司敏感数据单独存放和配置,而功能实现部分可以放开限制,不用担心敏感信息泄露。

当然,Ansible 也实现了类似的功能,程序员的快乐之一也是不断地重复造轮子。在造轮子的过程中,我也重新学习了一遍 CRD 开发,也学习了 Helm Chart 的开发,并将其发布到了 https://artifacthub.io/

7. 参考