+-
使用Argo CD自动化Kubernetes多集群配置

客座文章最初由DoiT International高级云架构师Mike Sparr在DoiT博客上发布

在我看来,谷歌Anthos企业解决方案中,最酷的方面是Anthos配置管理(Anthos Config Management,ACM)。你可以设置一个Git repo,并将各种集群连接到它,它们将以GitOps的方式标准化配置,并防止漂移。这对于在不同托管位置管理成百上千个集群的大型企业尤其重要。


使用Argo CD自动化Kubernetes多集群配置

受到ACM的启发,我想知道是否可以使用另一种GitOps解决方案,Argo CD,重新创建这种类型的功能。我很高兴与大家分享它的工作原理,当我在Git repo中修改配置文件时,它们无缝地应用到两个集群中。


架构概述

设置

为了简单起见,我在谷歌云的托管Kubernetes服务GKE上,分别在两个区域创建了两个集群,以模拟东和西的场景。当然,你可以在集群的任何地方安装Argo CD,并确保它们能够访问你的Git repo。

我创建了下面的shell脚本来引导一切;然而,对于生产用途,我建议在可能的情况下使用Terraform来管理基础设施。

create-k8s-clusters.sh:

#!/usr/bin/env bash
export PROJECT_ID=<YOUR-PROJECT-ID>
export AUTH_NETWORK="<YOUR-IP-ADDRESS>/32" # change to your IP or use dotenv of course
# enable apis
gcloud services enable container.googleapis.com # Kubernetes Engine API
# helper functions
set_location () {
 case $1 in
 "west")
 export ZONE="us-west2-b"
 export REGION="us-west2"
 ;;
 "central")
 export ZONE="us-central1-a"
 export REGION="us-central1"
 ;;
 "east")
 export ZONE="us-east1-c"
 export REGION="us-east1"
 ;;
 *)
 echo $"Usage: $0 {west|central|east}"
 exit 1
 esac
}
install_argo_cd () {
 echo "Installing Argo CD ..."
 kubectl create clusterrolebinding cluster-admin-binding 
 --clusterrole=cluster-admin --user="$(gcloud config get-value account)"
 kubectl create namespace argocd
 kubectl apply -n argocd 
 -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
 # configure app-of-apps git repo
 echo "Configuring app-of-apps repo ..."
 kubectl apply -f app-of-apps.yaml
}
create_cluster () {
 CLUSTER_NAME=$1
 set_location $CLUSTER_NAME
 echo "Creating cluster $CLUSTER_NAME in zone $ZONE ..."
 gcloud beta container --project $PROJECT_ID clusters create "$CLUSTER_NAME" 
 --zone "$ZONE" 
 --no-enable-basic-auth 
 --cluster-version "1.16.9-gke.6" 
 --machine-type "e2-standard-2" 
 --image-type "COS" 
 --disk-type "pd-standard" --disk-size "100" 
 --node-labels location=west 
 --metadata disable-legacy-endpoints=true 
 --scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_write","https://www.googleapis.com/auth/sqlservice.admin","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/pubsub","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" 
 --preemptible 
 --num-nodes "1" 
 --enable-stackdriver-kubernetes 
 --enable-ip-alias 
 --network "projects/${PROJECT_ID}/global/networks/default" 
 --subnetwork "projects/${PROJECT_ID}/regions/${REGION}/subnetworks/default" 
 --default-max-pods-per-node "110" 
 --enable-autoscaling --min-nodes "0" --max-nodes "3" 
 --enable-network-policy 
 --enable-master-authorized-networks --master-authorized-networks $AUTH_NETWORK 
 --addons HorizontalPodAutoscaling,HttpLoadBalancing 
 --enable-autoupgrade 
 --enable-autorepair --max-surge-upgrade 1 --max-unavailable-upgrade 1 
 --labels env=sandbox 
 --enable-vertical-pod-autoscaling 
 --identity-namespace "${PROJECT_ID}.svc.id.goog" 
 --enable-shielded-nodes 
 --shielded-secure-boot 
 --tags "k8s","$1"
 
 # authenticate
 echo "Authenticating kubectl ..."
 gcloud container clusters get-credentials $CLUSTER_NAME --zone $ZONE
 # install argo cd
 echo "Installing Argo CD ..."
 install_argo_cd
 echo "Cluster $CLUSTER_NAME created in zone $ZONE"
}
# create clusters
echo "Creating and configuring clusters ..."
locations=("west" "east")
for loc in ${locations[@]}; do
 create_cluster $loc
done

启动集群

在8-10分钟内,两个集群都处于活动状态,并部署了Argo CD工作负载。


东和西地区的Kubernetes集群


部署到每个集群的Argo CD

应用程序的应用程序(App of Apps)

这个设置的独特之处在于,我还在每个集群上安装了Argo CD,初始化的应用程序使用App of Apps模式,指向我的Github仓库。这提供了在将来向repo添加任意数量的配置,以及自定义部署到其中的集群或应用程序的灵活性。

app-of-apps.yaml:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: applications
 namespace: argocd
 finalizers:
 - resources-finalizer.argocd.argoproj.io
spec:
 destination:
 namespace: argocd
 server: https://kubernetes.default.svc
 project: default
 source:
 path: applications
 repoURL: https://github.com/mikesparr/multi-cluster-argo-demo
 targetRevision: HEAD
 syncPolicy:
 automated:
 selfHeal: true
 prune: true

注意,自动同步完全是可选的。如果集群的数量很大,我建议你这样做,这样你的集群就可以自愈和管理漂移。然而,自动同步的一个缺点是回滚功能无法工作。

applications/文件夹(路径)中有一个应用程序(目前来说),叫做k8s-config。这是另一个Argo应用程序,它指向另一个带有Kubernetes configs的文件夹。

k8s-config.yaml:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: k8s-config
 namespace: argocd
 finalizers:
 - resources-finalizer.argocd.argoproj.io
spec:
 destination:
 namespace: argocd
 server: https://kubernetes.default.svc
 project: default
 source:
 path: k8s-config
 repoURL: https://github.com/mikesparr/multi-cluster-argo-demo
 targetRevision: HEAD
 syncPolicy:
 automated:
 selfHeal: true
 prune: true

k8s-config/文件夹(路径)包含我们想要应用到kubernetes集群的所有YAML文件。如果有很多文件需要组织,也可以选择声明一个应用程序来递归地应用configs。

源代码仓库

对于我的实验,我在Github上的mikesparr/multi-cluster-argo-demo上发布了一个源代码库,目录结构如下。


源代码仓库结构

本例中的所有内容都在单个仓库中,但是你可以通过使用不同的存储库,并授予不同团队编辑它们的权限,来分离关注点。

Argo UI

从命令行,你可以端口转发到argo-server服务。

kubectl -n argocd port-forward svc/argo-server 8080:443

在浏览器中访问http://localhost:8080,并在提示时接受安全异常(无https)。提示:默认情况下,你用admin和argocd server pod的全名登录:


复制argocd-server-XXXXXXX作为默认密码


刚开始时应用程序(应用程序的应用程序)出现,直到同步

在你的应用程序的应用程序同步之后,它会识别出你的第一个应用程序k8s-config。


在两个应用程序同步之后

如果单击k8s-config应用程序面板,你可以看到它在服务器上安装的所有内容的详细视图。


仓库上/k8s-config目录中的所有YAML文件都应用到服务器

确认集群配置

将kubectl上下文切换到每个集群,并检查namespaces,test-namespace的serviceaccounts、roles和rolebindings。你可以看到它们都安装在两个集群上。恭喜你!


集群自动从Git repo安装工作负载

无限的潜力

假设你想要向堆栈添加一个API网关,并决定使用Ambassador,或者是Kong,两者都配置了CRD和YAML。你可以简单地添加另一个文件夹或repo,然后在applications/文件夹中添加另一个app YAML,ArgoCD会自动为你安装和配置它。

对于工程团队发布的每个应用程序,他们可以在部署清单中编辑Docker镜像版本,为更改创建一个pull request,并且你有内置的手动判断和职责分离。PR合并后,Argo CD将分别将其部署到该集群和环境中。

另一个用例是支持多云部署,并使用DNS平衡流量,实现真正的active-active配置。另一个用例可能是从一个云迁移到另一个云。

我期待着尝试更多的可能性,并希望你喜欢另一种在不同环境中保持集群同步的方法。

清理

如果你使用了脚本和/或仓库,请不要忘记清理和删除你的资源,以避免不必要的账单。最简单的方法是使用下面的命令(或你的项目)删除集群。

gcloud container clusters delete west --zone us-west2-b
gcloud container clusters delete east --zone us-east1-c

在DoiT International和Mike一起工作!请到我们的招聘网站申请工程职位。

点击阅读网站原文。

CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux  Foundation,是非营利性组织。
CNCF(云原生计算基金会)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。扫描二维码关注CNCF微信公众号。
image