Argo CD使用指南:如何构建一套完整的GitOps?

随着Kubernetes继续将自己确立为容器编排的行业标准,为你的应用和工具找到使用声明式模型的有效方法是成功的关键。在这篇文章中,我们将在AWS中建立一个K3s Kubernetes集群,然后使用Argo CD和Vault实现安全的GitOps。你可以在以下两个链接中分别查看基础架构以及Kubernetes umbrella应用程序:

https://github.com/atoy3731/aws-k8s-terraform

https://github.com/atoy3731/k8s-tools-app

以下是我们将会使用到的组件:

  • AWS——这是我们将在底层基础设施使用的云提供商。它将管理我们的虚拟机以及Kubernetes工作所需的网络,并允许Ingress从外界进入集群。
  • K3s——由Rancher开发的轻量级Kubernetes发行版。它对许多alpha功能和云插件进行了清理,同时也使用关系型数据库(本例中是RDS)代替etcd进行后端存储。
  • Rancher——API驱动的UI,可以轻松管理你的Kubernetes集群
  • Vault——Hashicorp的密钥管理实现。我将使用Banzai Cloud Vault的bank-- vaults实现,它可以通过使用Admission Webhook将密钥直接注入pod中。这大大减轻了你在Git仓库中存储密钥的需求。
  • Argo CD——这是一个GitOps工具,可以让你在Git中维护Kubernetes资源的状态。Argo CD会自动将你的Kubernetes资源与Git仓库中的资源进行同步,同时也确保集群内对manifest的手动更改会自动还原。这保证了你的声明式部署模式。
  • Cert Manager或LetsEncrypt——提供了一种为Kubernetes Ingress自动生成和更新证书的方法。

让我们先从AWS基础架构开始。

前期准备

你需要在你的系统中安装以下CLI:

  • Terraform

  • Kubectl

  • AWS

同时,你还需要AWS管理员访问权限以及一个访问密钥。如果你没有,你可以使用信用卡创建一个账户。

最后,你需要一个可以管理/更新的托管域名,以指向你的基于Kubernetes弹性负载均衡器(ELB)。如果你还没有,建议你在NameCheap上开一个账户,然后购买一个.dev域名。它价格便宜,而且效果很好。

AWS基础架构

对于我们的AWS基础架构,我们将使用Terraform与S3支持来持久化状态。这为我们提供了一种方法来声明性地定义我们的基础架构,并在我们需要的时候反复进行更改。在基础设施仓库中,你会看到一个k3s/example.tfvars文件。我们需要根据我们特定的环境/使用情况更新这个文件,设置以下值:

  • db_username — 将应用于Kubernetes后端存储的RDS实例的管理员用户名

  • db_password — RDS用户的管理员密码。这通常应该在你的terraform apply命令内联过程中传递此参数,但为了简单起见,我们将在文件中设置它。

  • public_ssh_key — 你的公共SSH密钥,当你需要SSH到Kubernetes EC2s时,你将使用它。

  • keypair_name — 要应用于你的public_ssh_key的密钥对名称。

  • key_s3_bucket_name — 生成的bucket将在集群成功创建时存储你的kubeconfig文件。

如果你想修改集群大小或设置特定的CIDRs(无类域间路由),可以设置下面的一些可选字段,但默认情况下,你会得到一个6节点(3个服务器,3个代理)的K3s集群。

同时,你将需要创建S3 bucket来存储你的Terraform状态并且在k3s/backends/s3.tfvarsk3s/main.tf文件中更改bucket字段来与其匹配。

一旦我们更新了所有的字段,并创建了S3状态bucket,我们就开始应用Terraform吧。首先,确保你在AWS账户中有一个管理IAM用户并且你已经在系统上正确设置了环境变量或AWS凭证文件,以便能够与AWS API对接,然后运行以下命令:

cd k3s/
terraform init -backend-config=backends/s3.tfvars
terraform apply -var-file=example.tfvars

一旦你执行以上命令,Terraform会在apply成功后输出预期的AWS状态。如果一切看起来都符合预期,请输入yes。这时候由于RDS集群的原因,需要5—10分钟的时间来配置AWS资源。

验证你的Kubernetes集群

Terraform成功应用之后(再多等几分钟的时间确保K3s已经部署完毕),你需要使用以下命令从S3 bucket中抓取kubeconfig文件(替换你在example.tfvars中输入的bucket名称):

aws s3 cp s3://YOUR_BUCKET_NAME/k3s.yaml ~/.kube/config

这应该成功完成,让你现在能够与你的集群通信。让我们检查一下我们的节点状态,在继续之前,确保它们都处于就绪状态。

$ kubectl get nodes
NAME                         STATUS   ROLES    AGE   VERSION
ip-10-0-1-208.ec2.internal   Ready    <none>   39m   v1.18.9+k3s1
ip-10-0-1-12.ec2.internal    Ready    master   39m   v1.18.9+k3s1
ip-10-0-1-191.ec2.internal   Ready    master   39m   v1.18.9+k3s1
ip-10-0-2-12.ec2.internal    Ready    master   39m   v1.18.9+k3s1
ip-10-0-2-204.ec2.internal   Ready    <none>   39m   v1.18.9+k3s1
ip-10-0-1-169.ec2.internal   Ready    <none>   39m   v1.18.9+k3s1

我们也来看看Argo CD的状态,它是通过manifest自动部署的:

$ kubectl get pods -n kube-system | grep argocd
helm-install-argocd-5jc9s                        0/1     Completed   1          40m
argocd-redis-774b4b475c-8v9s8                    1/1     Running     0          40m
argocd-dex-server-6ff57ff5fd-62v9b               1/1     Running     0          40m
argocd-server-5bf58444b4-mpvht                   1/1     Running     0          40m
argocd-repo-server-6d456ddf8f-h9gvd              1/1     Running     0          40m
argocd-application-controller-67c7856685-qm9hm   1/1     Running     0          40m

现在我们可以继续为我们的ingress和证书自动化配置通配符DNS。

DNS配置

对于DNS,我通过Namecheap获得atoy.dev域名,但你可以使用任何你喜欢的DNS供应商。我们需要做的是创建一个通配符CNAME条目,以将所有请求路由到AWS ELB,它正在管理应用程序的ingress。

首先,通过访问你的AWS控制台获取你的弹性负载均衡器主机名称——导航到EC2部分并在左边菜单栏上点击Load Balancers。然后你应该看到一个使用随机字符创建的新LoadBalancer。如果你检查tag,它应该引用你的新Kubernetes集群。

image

你需要从该条目复制DNS名称。为我的域名访问NamecCheap 高级DNS页面,并输入.demo.atoy.dev* 的CNAME条目。** 指向你从AWS复制的域名。你可以根据你的提供商/域名调整这个名称:

image

要验证它是否有效,你可以安装/使用nslookup来确保它解析到正确的主机名:

$ nslookup test.demo.atoy.dev
Server:  71.252.0.12
Address: 71.252.0.12#53

Non-authoritative answer:
test.demo.atoy.dev canonical name = a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com.
Name: a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com
Address: 52.20.5.150
Name: a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com
Address: 23.20.0.2

现在到Umbrella应用程序。

Argo CD和Umbrella应用程序

我们已经知道Argo CD已经部署好了,但现在我们要使用Argo CD的App-of-Apps部署模型来部署我们的其余工具套件。由于我们使用的是GitOps,你需要将k8s-tools-app仓库fork到你自己的Github账户上,然后我们需要做一些修改来匹配你各自的环境。

  1. 你需要为https://github.com/atoy3731/k8s-tools-app.git 进行全局查找/替换,并将其更改到之前fork的新存储库git URL。这使你可以管理自己的环境,让Argo CD可以从那里拉取。另外,需要确保你的Git仓库是公开的,以便Argo CD可以访问它。
  1. 在resources/tools/resources/other-resources.yaml中,更改argoHostand issuerEmail,使其与你的域名和邮箱相匹配。
  1. 在resources/tools/resources/rancher.yaml中,更改主机名称和邮件以匹配各自的域名和email。
  1. 在resources/apps/resources/hello-world.yaml中,将两个引用app.demo.aptoy.dev改为与你的域名一致。

一旦你做了这些更新,继续提交/推送你的更改到你的forked Github仓库。现在你已经准备好应用umbrella应用程序了。在本地克隆的仓库中执行以下操作:

$ kubectl apply -f umbrella-tools.yaml
appproject.argoproj.io/tools created
application.argoproj.io/umbrella-tools created

现在,Argo CD将开始配置所有其他工具,这些工具是仓库为你的集群定义的。你可以通过执行以下操作来获得已部署的应用程序的列表:

$ kubectl get applications -n kube-system
NAME                AGE
other-resources     56m
umbrella-tools      58m
rancher             57m
vault-impl          57m
vault-operator      58m
vault-webhook       57m
cert-manager        57m
cert-manager-crds   58m

你将不得不等待5分钟左右的时间,让一切都准备好,让LetsEncrypt生成暂存证书。一旦事情按预期运行,你应该看到两个生成的Ingress条目,你可以通过浏览器访问:

$ kubectl get ingress -A
NAMESPACE       NAME             CLASS    HOSTS                     ADDRESS                                                                  PORTS     AGE
cattle-system   rancher          <none>   rancher.demo.atoy.dev   a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com   80, 443   59m
kube-system     argocd-ingress   <none>   argo.demo.atoy.dev      a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com   80, 443   58m

现在你可以通过 https://rancher.YOUR-DOMAIN 浏览 Rancher,通过 https://argo.YOUR-DOMAIN 浏览 Argo CD。

NOTE 1:为了避免LetsEncrypt的任何速率限制,我们使用的是无效的暂存证书。这有一个好处是当你在你的浏览器访问Argo、Rancher或你的hello world应用程序,它会给你一个SSL异常。使用Chrome浏览器,在你的异常页面加载时输入thisisunsafe,它会让你绕过它。你也可以了解更新Cert-manager的ClusterIssuer,以使用生产级的可信证书。

NOTE 2:K3s预装了一个Traefik作为ingress controller,出于简单起见,我们直接使用它。

NOTE 3:首次登录Rancher后,你需要生成一个密码,并接受用于访问Rancher的URI。URI应该是预先加载在表单中的,所以您可以直接点击 "Okay"。

NOTE 4: 要登录Argo CD,它使用admin作为用户名,使用argocd-server pod名作为密码。你可以通过下面的操作来获得这个服务器的pod名(本例中是argocd-server-5bf58444b4-mpvht)。

$ kubectl get pods -n kube-system | grep argocd-server
argocd-server-5bf58444b4-mpvht                   1/1     Running     0          64m

现在你应该能够访问Argo CD UI,登录并查看,如下所示:

image

既然我们的工具已经部署完成,让我们在Vault中存储密钥,以便hello world应用程序提取。

在Vault中创建密钥

为了让事情变得简单,在你的工具库中有一个帮助脚本。运行以下命令来获取Vault管理员令牌和端口转发命令:

$ sh tools/vault-config.sh
Your Vault root token is: s.qEl4Ftr4DR61dmbH3umRaXP0

Run the following:
export VAULT_TOKEN=s.qEl4Ftr4DR61dmbH3umRaXP0
export VAULT_CACERT=/Users/adam.toy/.vault-ca.crt
kubectl port-forward -n vault service/vault 8200 &

You will then be able to access Vault in your browser at: [https://localhost:8200](https://localhost:8200)

运行输出的命令,然后导航到https://localhost:8200。输入上面的root token进行登录。

当你登录时,你应该在一个密钥引擎页面。点击Secret/条目,然后点击右上方的创建密钥。我们将创建一个demo密钥,所以添加以下内容并点击保存:

image

现在我们已经为hello world应用程序准备好密钥了。

部署Hello World 应用程序

现在,回到我们的父版本,让我们运行下面的代码来部署hello world应用程序:

$ kubectl apply -f umbrella-apps.yaml
appproject.argoproj.io/apps created
application.argoproj.io/umbrella-apps created

创建完成后,回到Argo CD UI,你先应该看到两个新应用程序,umbrella-apps和demo-app。单击demo-app,然后等待所有资源正常运行:

image

一旦状态都是healthy之后,你应该能够通过访问https://app.YOUR-DOMAIN 导航到你的应用程序。

image

让我们也来验证一下我们的Vault密钥是否被注入到我们的应用程序pod中。在Argo CD UI的demo-app中,点击应用程序的一个Pod,然后点击顶部的日志标签。左边应该有两个容器,选择 test-deployment容器。在日志的顶部,你应该看到你的密钥在两行等号之间:

测试GitOps

现在我们来测试一下Argo CD,确保当我们在仓库中做一些更改时它能够自动同步。

在你的工具库中,找到resources/apps/resources/hello-world.yaml文件,将replicaCount的值从5改到10。提交并推送你的更改到主分支,然后在Argo CD UI中导航回demo-app。当Argo CD达到它的刷新间隔时,它会自动开始部署其他5个应用程序副本(如果你不想等待,可以点击你的** umbrella-apps ** Argo应用程序 ** 中的刷新按钮):

清 除

如果你准备拆掉你的集群,你需要先进入AWS控制台、EC2服务,然后点击Load Balancers。你会看到Kubernetes云提供商创建了一个ELB,但不是由Terraform管理的,你需要清理它。你还需要删除该ELB正在使用的安全组。

清理了ELB之后,运行以下命令并在出现提示时输入yes

terraform destroy -var-file=example.tfvars

下一步是什么?

我们已经有一个很好的工具集来使用GitOps部署应用程序。那么下一步是什么?如果你愿意接受挑战,可以尝试在hello world应用旁边部署自己的应用,甚至尝试通过在应用manifest仓库中更新镜像标签来实现CI/CD。这样一来,当构建新的应用镜像时,新的标签就会在manifest仓库中自动更新,Argo CD就会部署新版本。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容