随着Kubernetes继续将本身确立为容器编排的行业标准,为你的应用和工具找到使用声明式模型的有效方法是成功的关键。在这篇文章中,咱们将在AWS中创建一个K3s Kubernetes集群,而后使用Argo CD和Vault实现安全的GitOps。你能够在如下两个连接中分别查看基础架构以及Kubernetes umbrella应用程序:node
https://github.com/atoy3731/aws-k8s-terraformgit
https://github.com/atoy3731/k8s-tools-appgithub
如下是咱们将会使用到的组件:web
AWS——这是咱们将在底层基础设施使用的云提供商。它将管理咱们的虚拟机以及Kubernetes工做所需的网络,并容许Ingress从外界进入集群。
redis
让咱们先从AWS基础架构开始。
数据库
你须要在你的系统中安装如下CLI:
后端
Terraform浏览器
Kubectl安全
同时,你还须要AWS管理员访问权限以及一个访问密钥。若是你没有,你可使用信用卡建立一个帐户。
服务器
最后,你须要一个能够管理/更新的托管域名,以指向你的基于Kubernetes弹性负载均衡器(ELB)。若是你尚未,建议你在NameCheap上开一个帐户,而后购买一个.dev域名。它价格便宜,并且效果很好。
对于咱们的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的密钥对名称。
若是你想修改集群大小或设置特定的CIDRs(无类域间路由),能够设置下面的一些可选字段,但默认状况下,你会获得一个6节点(3个服务器,3个代理)的K3s集群。
同时,你将须要建立S3 bucket来存储你的Terraform状态而且在k3s/backends/s3.tfvars和k3s/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资源。
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,我经过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已经部署好了,但如今咱们要使用Argo CD的App-of-Apps部署模型来部署咱们的其他工具套件。因为咱们使用的是GitOps,你须要将k8s-tools-app仓库fork到你本身的Github帐户上,而后咱们须要作一些修改来匹配你各自的环境。
你须要为https://github.com/atoy3731/k8s-tools-app.git 进行全局查找/替换,并将其更改到以前fork的新存储库git URL。这使你能够管理本身的环境,让Argo CD能够从那里拉取。另外,须要确保你的Git仓库是公开的,以便Argo CD能够访问它。
在resources/tools/resources/rancher.yaml中,更改主机名称和邮件以匹配各自的域名和email。
一旦你作了这些更新,继续提交/推送你的更改到你的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管理员令牌和端口转发命令:
$ 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应用程序:
$ 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容器。在日志的顶部,你应该看到你的密钥在两行等号之间:
如今咱们来测试一下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就会部署新版本。