在前面的章节中,我们将每个应用的配置都单独放到一个目录,并使用 kustomize 的方式组织目录结构。当需要对配置进行改动时,修改相应的配置文件后需重新 apply 一下,操作起来相对繁琐,另外还存在一个难题:这些配置存放在哪,以谁的为准?如果放到路由器内,每次修改配置需要先 SSH 登录路由器进行修改并重新 apply;如果存放到自己电脑,每次修改配置都要指定用这台电脑进行修改;如果在多个设备都有保存配置,那还需要保证每个设备的配置保持同步,否则容易导致配置错乱。
为了解决前面提到的配置管理问题,我们可以采用 GitOps
的理念,将路由器里所有应用的配置,放到一个 Git 仓库中,然后 GitOps
工具会对比集群中的配置与 Git 仓库中声明的配置,确保集群中的配置始终符合 Git 仓库中的配置。
当要修改配置时,直接将修改提交到 Git 仓库即可,GitOps
工具会自动拉取 Git 仓库并进行调谐,将改动 apply 到集群中。
Argo CD 是 Kubernetes 生态中流行的 GitOps
工具,支持 kustomize
、helm
、jsonnet
以及 YAML
和 JSON
方式定义 kubernetes manifests。本文将介绍如何利用 Argo CD 来管理云原生家庭网络的配置。
通常我们需要将配置存放到私有的 Git 仓库中,在国内你可以使用 gitee 来托管私有仓库,国内速度快,而且免费。
前面我们已经将所有应用配置都用单独的目录保存,并采用 kustomize
方式组织结构,现在我们将其放到 Git 仓库目录下 apps
的子目录下:
apps
├── alist
│ ├── daemonset.yaml
│ └── kustomization.yaml
├── aria2
│ ├── daemonset.yaml
│ └── kustomization.yaml
├── ddns
│ ├── config
│ ├── daemonset.yaml
│ └── kustomization.yaml
├── dnsmasq
│ ├── config
│ ├── daemonset.yaml
│ └── kustomization.yaml
├── filebrowser
│ ├── daemonset.yaml
│ └── kustomization.yaml
├── home-assistant
│ ├── daemonset.yaml
│ └── kustomization.yaml
├── homepage
│ ├── config
│ ├── daemonset.yaml
│ └── kustomization.yaml
将所有配置提交并 push 到 Git 仓库。
Argo CD 可以安装在路由器,也可以安装在其它地方。由于我有自己的 linux 开发机,并且也装了 k3s,而且家里路由器也部署了 DDNS 服务,电信宽带也支持独占公网 IP,从外部可以远程连上家里路由器的 k3s 集群,所以我将 Argo CD 安装在自己的开发机,由开发机远程管理多个 k8s 集群,其中就包括家里路由器的 k3s 集群。
具体 Argo CD 的安装方法可参考官方文档: https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/
建议是给 argocd 加点自定义配置(见注释解释):
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
# argocd 默认会给管理的应用打上 app.kubernetes.io/instance 这个常见注解,
# 而其它很多开源项目部署的应用也使用了这个注解,会导致冲突,改成其它的注解以避免冲突。
application.instanceLabelKey: argocd.argoproj.io/instance
# 让 kustomization.yaml 中能够使用 helmCharts 引用 helm chart,
# resources 中能够引用本目录之外目录下的内容。
kustomize.buildOptions: --enable-helm --load-restrictor=LoadRestrictionsNone
我是通过 kustomize
安装的 Argo CD,可以将上面的配置作为 patch 引用:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: argocd
patches:
- path: argocd-cm-patch.yaml
resources:
- install.yaml
安装完 Argo CD 并配置好 argocd
命令后,我们来使用 argocd
命令添加下集群和 Git 仓库。
如果你的 Argo CD 就安装在路由器的 k3s 集群中,那么无需添加集群,会自动添加一个名为 in-cluster
的集群,代表本集群,后续可通过 in-cluster
来引用。如果你像我一样将 Argo CD 部署在外部的集群中,先确保你的 kubeconfig 当前的 context 能从外部操作家里的 k3s 集群,然后使用如下命令将集群添加到 Argo CD 中:
argocd cluster add home
home 改为 context 名称,也将作为后续在 Argo CD 引用的集群名称。
下面来添加 Git 仓库到 Argo CD 中:
argocd repo add --ssh-private-key-path $HOME/.ssh/id_rsa --insecure-skip-server-verification git@gitee.com:your-name/your-repo.git
要点解析:
ApplicationSet
是 Argo CD 支持的 CRD 资源,相当于是应用模版,会根据 ApplicationSet
所声明的配置自动创建 Application
,每个 Application
就是 Argo CD 所管理的一个应用:
在 Argo CD 所在集群创建类似如下的 ApplicationSet
:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: apps-home-router
namespace: argocd
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- git:
repoURL: git@gitee.com:your-name/your-repo.git
revision: HEAD
directories:
- path: apps/*
template:
metadata:
name: "{{.path.basename}}-home-router"
namespace: argocd
spec:
project: default
source:
repoURL: git@gitee.com:your-name/your-repo.git
targetRevision: HEAD
path: "apps/{{.path.basename}}"
destination:
name: home
syncPolicy:
automated:
prune: true
selfHeal: true
要点解析:
repoURL
替换为我们前面添加的 Git 仓库地址。directories
的 path
定义为 apps/*
,表示会自动扫描 Git 仓库 apps
目录下的子目录,然后在 template
下的 source.path
通过 {{.path.basename}}
引用子目录的名称,表示为每个子目录生成一个 Application
,Argo CD 会自动识别到子目录下通过 kustomize
方式组织的配置,会自动用 kustomize
渲染出 YAML 并 apply 到集群。destination.name
替换为集群名称,如果 Argo CD 部署在当前路由器,就固定是 in-cluster
。syncPolicy.automated.prune
置为 true,表示配置变更时,会对比 Git 前后差异,如果是变更后某些资源删除了,Argo CD 也会将其从集群中删除该资源,即完全以 Git 仓库中声明的为准,拒绝多余的资源。创建好后,可以通过 argocd appset list
查看已创建的 ApplicationSet
,通过 argocd app list
查看通过 ApplicationSet
自动创建的 Application
列表,也可以通过登录 Argo CD 的后台管理网页进行查看和手动触发同步。
当 Application
都被自动创建出来后,可以尝试提交一些修改到 Git 仓库,等待一会儿的时间,验证下修改是否被同步到了集群中。
验证成功后,后续有任何修改,都可以直接提交到 Git 仓库,无论在哪个设备都一样,完全以 Git 仓库中的内容为准。
如果觉得每次修改都要 commit 和 push 这样的操作太麻烦,可以写一个 shell 函数:
gg () {
git add -A
msg="update at $(date '+%Y-%m-%d %H:%M:%S')"
git commit -m "${1:-$msg}"
git push
}
将此函数放到里所使用的 shell 的 rc 文件里,这样每次在 shell 里执行 gg
就是调用此函数实现一键自动 commit 并 push 所有改动到 Git 仓库,让改动变得非常方便。
我本人更懒,命令都不用执行,直接快捷键自动提交。因为我用的 Neovim 编辑器,可以自己配自定义快捷键和相应的后台脚本操作,下面分享我的配置(基于 LazyVim):
local Util = require("lazyvim.util")
local map = Util.safe_keymap_set
---@param command string Command to run
---@param args? string[] List of arguments to pass
run = function(command, args)
local Job = require("plenary.job")
local absolute_path = vim.fn.expand("%:p")
local cwd = string.match(absolute_path, "(.+)/[^/]+$")
Job:new({
command = command,
args = args,
cwd = cwd,
on_exit = function(job)
local result = job:stderr_result()
if next(result) == nil then
result = job:result()
end
if next(result) ~= nil then
local msg = table.concat(result, "\n")
if not vim.g.vscode then
vim.notify(msg, vim.log.levels.INFO)
end
else
if not vim.g.vscode then
vim.notify("done", vim.log.levels.INFO)
end
end
end,
}):start()
end
---@param script string Bash script to run
run_script = function(script)
return run("bash", { "-c", script })
end
-- git
local git_push = function()
local git_push_script = [[
git add -A
msg="update at $(date '+%Y-%m-%d %H:%M:%S')"
git commit --author="roc <roc@imroc.cc>" -m "$msg"
git push
]]
run_script(git_push_script)
end
map("n", "<leader>gp", git_push, { desc = "Git Push" })
map("n", "gp", git_push, { desc = "Git Push" })
Normal
模式下执行gp
或<leader>gp
就会自动提交并推送。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。