客座文章最初由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微信公众号。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。