随着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.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资源。
验证你的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