随着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集群。

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

要验证它是否有效,你可以安装/使用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可以访问它。

  2. 在resources/tools/resources/other-resources.yaml中,更改argoHostand issuerEmail,使其与你的域名和邮箱相匹配。

  3. 在resources/tools/resources/rancher.yaml中,更改主机名称和邮件以匹配各自的域名和email。

  4. 在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,登录并查看,如下所示:

既然我们的工具已经部署完成,让我们在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密钥,所以添加以下内容并点击保存:

现在我们已经为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,然后等待所有资源正常运行:

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

让我们也来验证一下我们的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就会部署新版本。

Argo CD使用指南:如何构建一套完整的GitOps?的更多相关文章

  1. Linkerd 2.10(Step by Step)—将 GitOps 与 Linkerd 和 Argo CD 结合使用

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traef ...

  2. 如何自己构建一套EasyNVR这样的无插件流媒体服务器实现摄像机硬盘录像机的网页可视化直播

    EasyNVR流媒体解决方案 EasyNVR能够通过简单的网络摄像机通道配置,将传统监控行业里面的高清网络摄像机IP Camera.NVR等具有RTSP协议输出的设备接入到EasyNVR,EasyNV ...

  3. 分享Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站

    这是个什么的项目? 使用 Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站. 博客线上地址:www.boblog.com Github地址:https: ...

  4. 部署一套完整的Kubernetes高可用集群(二进制,v1.18版)

    一.前置知识点 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部署Kubernetes集群主要有两种方式: kubeadm Kubeadm是一个K8s部署工具,提供kubeadm ...

  5. Web自动化框架之五一套完整demo的点点滴滴(excel功能案例参数化+业务功能分层设计+mysql数据存储封装+截图+日志+测试报告+对接缺陷管理系统+自动编译部署环境+自动验证false、error案例)

    标题很大,想说的很多,不知道从那开始~~直接步入正题吧 个人也是由于公司的人员的现状和项目的特殊情况,今年年中后开始折腾web自动化这块:整这个原因很简单,就是想能让自己偷点懒.也让减轻一点同事的苦力 ...

  6. Egret是一套完整的HTML5游戏开发解决方案

    Egret是一套完整的HTML5游戏开发解决方案.Egret中包含多个工具以及项目.Egret Engine是一个基于TypeScript语言开发的HTML5游戏引擎,该项目在BSD许可证下发布.使用 ...

  7. 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【六】【引入bootstrap前端框架】

    https://blog.csdn.net/linzhefeng89/article/details/78752658 基于springboot+bootstrap+mysql+redis搭建一套完整 ...

  8. 一套完整的VI包含哪些元素

    VI设计,即视觉识别系统,企业VI设计是企业品牌建设的重中之重.最近很多人都在问,一套完整的企业VI设计都包括哪些内容?笔者站在一个高级设计师的角度,来简单谈一谈VI设计包括哪些内容.文中指出,一套完 ...

  9. EasyRTMP+EasyDSS实现一套完整的紧急视频回传直播与存储回放方案

    需求来源 紧急视频回传云端:即拍即传.云端存储.紧急录像.云拍云录!这些需求现在可能对于我们来说比较远,大部分也是在行业中才会用到,但相信在不就的将来肯定会落地到每个人的手中,因为这是一个自我保护.自 ...

随机推荐

  1. Java基础教程——缓冲流

    缓冲流 "缓冲流"也叫"包装流",是对基本输入输出流的增强: 字节缓冲流: BufferedInputStream , BufferedOutputStream ...

  2. asp.net core 集成 Prometheus

    asp.net core 集成 prometheus Intro Prometheus 是一个开源的现代化,云原生的系统监控框架,并且可以轻松的集成 PushGateway, AlertManager ...

  3. SQL Alias模板

    再记不住的话就扇自己巴掌 SELECT * FROM class1 c INNER JOIN class2 p ON c.id = p.id INNER JOIN class3 s ON c.id = ...

  4. Docker实战 | 第三篇:Docker安装Nginx,实现基于vue-element-admin框架构建的项目线上部署

    一. 前言 在上一文中 点击跳转 通过IDEA集成Docker插件实现微服务的一键部署,但 youlai-mall 是前后端分离的项目,除了后端微服务的部署之外,当然还少不了前端工程的部署.所以本篇讲 ...

  5. 老猿学5G:融合计费场景的Nchf_ConvergedCharging_Create、Update和Release融合计费消息交互过程

    ☞ ░ 前往老猿Python博文目录 ░ 一.Nchf_ConvergedCharging_Create交互过程 Nchf_ConvergedCharging_Create 服务为CTF向CHF请求提 ...

  6. 转:为什么说Python是最值得学习的编程语言

    老猿作为一个老程序员,研究生毕业后就没有这么用心的学过一门新的语言,而今年4月开始学Python以来,疯狂的迷上了它,有时很想写一篇为什么要学Python的文章,可一直懒没动笔,今天看到博友" ...

  7. PyQt(Python+Qt)学习随笔:containers容器部件GroupBox分组框介绍

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.主要属性 GroupBox分组框是一个对多个部件进行编组的框架容器,可以带有标题(title属性 ...

  8. PyQt(Python+Qt)学习随笔:QListWidget插入多项的insertItems方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 除了insertItem方法能插入项外,QListWidget支持一次插入多个项,对应的方法就是in ...

  9. PyQt(Python+Qt)学习随笔:Qt Designer中的menu菜单及menu bar菜单栏

    菜单由menu bar菜单栏和menu菜单两部分构成,分别对应类QMenuBar和QMenu. menuBar是包含一系列下拉菜单项组成,menu包含两种,一种是直接对应Action的,一种是父菜单, ...

  10. 【老孟Flutter】41个酷炫的 Loading 组件库

    老孟导读:目前 loading 库中包含41个动画组件,还会继续添加,同时也欢迎大家提交自己的 loading 动画组件或者直接微信发给我也可以. Github 地址:https://github.c ...