什么是 GitOps

GitOps 是一种新的持续交付的模型,其基本理念在于使用 Git 仓库作为基础架构和应用程序的配置信息的存储设施,使用 git 的版本管理功能实现对基础架构和应用程序的配置信息的控制,并且,一旦 git 中存储的配置信息发生改变,这些改变就能被自动应用到相应的基础架构或应用程序上,实现基础架构或应用程序的配置变更。

在使用 GitOps 进行持续交付,需要具备以下几个要素:

1、Git 仓库

2、配置评审流程

3、适用于 GitOps 的基础架构

Git 仓库

Git 仓库是存放所有配置信息以及配置信息历史的地方,并且,在 GitOps 实践中,Git 仓库是这些配置信息的唯一可信来源。GitOps 并不排斥 Git 以外的其他版本管理系统,但是由于 Git 的普及性,使得 Git 仓库成为 GitOps 的标配。标准的 Git 即可满足 GitOps 的需要,但是如果 Git 仓库还能提供代码评审,秘密管理等功能,则可以帮助管理员们进一步提高效率。

Git 仓库还可以对接其他的自动化系统,如代码检查系统,策略检查系统,自动化测试等。

评审流程

在 GitOps 模型中,不再有具体某个管理员拥有超级用户权限,取而代之的是管理员将要发生的变更提交到 Git 仓库中,而其他的管理员对该变更进行同行审议,通过审议后的变更会被合并到特定的分支,而 GitOps 基础架构会提取该特定分支的配置信息并予以部署,实现配置变更的操作。整个过程中管理员不需要接触基础架构,也不需要在基础架构中手工执行任何命令。这样做的好处有:

  • 降低了手工操作带来的出错风险

  • 同行审议降低了系统性出错的风险,比如设计错误

  • 由于所有的操作都在 git 仓库的历史记录中,而审议结果同样会被记录,极大的方便了后期审计和故障分析的过程

从而降低操作员本身引起的错误的可能性,提高系统可靠性。

GitOps 基础架构

GitOps 模型通过存放在 Git 中的配置信息对基础设施和应用系统进行管理,这对相关的基础设施提出了以下要求:

1、提供自动化操作的接口
GitOps 要求相关的基础设置能提供接口实现自动化,如 API 或者命令行界面,能够通过程序或者脚本控制对基础设施进行控制。这个要求还是比较直观的,如果基础设施不能提供自动化接口,那也没法跟 GitOps 结合。

2、操作能收敛
在 GitOps 模型中,需要相关的基础设施能够在发生异常时进行自动重试,直到成功执行。从管理员来说,要么等操作执行成功,要么把 git 仓库回滚。

3、幂等性
幂等性是指,同一个操作,无论执行多少次,跟执行一次的效果一样。这是一个重要的特性,这个特性能帮助 GitOps 模型在各种异常发生的情况下都能正确的恢复。

4、确定性
确定性要求基础设施的状态与存在 Git 中的配置信息的状态(版本)一一对应。通俗的说就是配置信息是哪个版本,基础设施会一定会出于对应的状态。

而 Kubernetes 能非常好的符合上述要求,使得目前的 GitOps 实践都是围绕 Kubernates 来实现的。

为什么要用 GitOps

使用 GitOps 可以为运维工作带来以下好处

1、提高生产力
GitOps 的目标在于简化发布流程,优化部署流水线,而且使用了被广泛接受的 Git,降低了学习曲线,从而能大大提高生产力

2、行为可审计
使用 GitOps 工作流管理集群,所有的操作历史都存放在 Git 仓库中,便于实现审计

3、更高的可靠性
借助 Git 的版本管理功能,可以实现配置信息方便的重现和回滚。由于基础架构提供幂等性和确定性的特性,整个系统都可以随着版本的切换改变到任何一个确定的状态,提供很好的可靠性。

4、实现一致性和标准化
GitOps 中,使用 Git 作为配置信息的唯一可信来源,使用提供确定性和操作收敛性的基础设施,实现系统在多个环境和多种部署条件下的一致性和标准化

5、更好的安全保证
使用 GitOps 可以实现配置信息和基础设施之间的强解耦,方便进一步简化密码等敏感信息的管理,提升了系统的安全性

Anthos Config Management 与 GitOps

Anthos Config Management (简称 ACM) 是 Google Anthos 平台上实践 GitOps 模型,提供跨 K8S 集群的全局配置管理和同步的工具。除此之外,ACM 还提供一个全局策略引擎 (Policy Controller),借助 GitOps 理念,提供跨 K8S 集群同步的策略强制。
GitOPS 与Anthos Config Management

通过下面的 Demo,我们可以体验到使用 ACM 进行跨集群统一应用发布的便利性。

准备工作

在工作机上先安装好 kubectl:

复制代码
apt-get install kubectl -y

然后我们需要为 Anthos 组件创建 Service Account,并设置好相应的权限:

复制代码
gcloud iam service-accounts create anthos-test
gcloud projects add-iam-policy-binding your-project-id \
--member="serviceAccount:anthos-test@your-project-id.iam.gserviceaccount.com" \
--role=roles/editor \
--role=roles/container.admin \
--role=roles/resourcemanager.projectIamAdmin \
--role=roles/iam.serviceAccountAdmin \
--role=roles/iam.serviceAccountKeyAdmin \
--role="roles/gkehub.connect"
gcloud iam service-accounts keys create ./anthos-test.json \
--iam-account anthos-test@your-project-id.iam.gserviceaccount.com

创建 GKE 集群,并把刚才创建的 ServiceAccount 赋给这个集群

复制代码
gcloud beta container clusters create "mycluster" \
--zone "us-central1-c" --cluster-version "1.15" \
--machine-type "n1-standard-4" --image-type "COS" \
--service-account "anthos-test@your-project-id.iam.gserviceaccount.com" \
--num-nodes "3" --enable-ip-alias

最后,为了让 ACM 正常工作,我们需要激活相关 API:

复制代码
gcloud services enable \
cloudresourcemanager.googleapis.com \
container.googleapis.com \
gkeconnect.googleapis.com \
gkehub.googleapis.com \
serviceusage.googleapis.com \
sourcerepo.googleapis.com \
iamcredentials.googleapis.com \
contextgraph.googleapis.com \
stackdriver.googleapis.com

把刚才创建 GKE 集群注册到 Anthos:

复制代码
gcloud container hub memberships register mycluster \
--project=your-project-id \
--gke-cluster=us-central1-c/mycluster \
--service-account-key-file=./anthos-test.json

注册成功后,我们可以在 Anthos 的控制台看到刚才创建的集群,如下图:
GitOPS 与Anthos Config Management

安装 ACM

向刚才创建的 GKE 集群中添加角色,这个角色会被 ACM 用来管理 k8s。

复制代码
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole cluster-admin \
--user anthos@your-project-id.iam.gserviceaccount.com

安装 ACM Operator;

安装 config-management-operator:

复制代码
gsutil cp \
gs://config-management-release/released/latest/config-management-operator.yaml \
config-management-operator.yaml
kubectl apply -f config-management-operator.yaml
kubectl get deployment --all-namespaces|grep config-management-operator

上面最后一条命令应该可以看到 config-management-operator 已经在运行:

复制代码
config-management-operator 1/1 1 1 2m27s

创建 Git 仓库

我们需要一个 Git 仓库来放配置信息,我们可以用 github 来实现:
GitOPS 与Anthos Config Management

选择 Repository 相关参数:
GitOPS 与Anthos Config Management

我们拿到该仓库的的 ssh 链接:

复制代码
git@github.com:xxxx/ACM.git

通过 ssh 访问该仓库,我们还需要一个 SSH Key,

我们可以用以下命令创建这个 key:

复制代码
ssh-keygen -t rsa -b 4096 \
-C "xxxx" -N ''

我们把这个 key 的公钥作为该仓库的部署用密钥
GitOPS 与Anthos Config Management

我们把这个仓库克隆下来,并往里面加一个 Readme.md 文件:

复制代码
git clone git@github.com:xxxx/ACM.git
cd ACM/
git remote -v
touch Readme.md
echo 2020/05/14 > Readme.md
git add .
git commit -m 'add readme'
git push

访问此仓库的 ssh 密钥需要以 secret 资源的形式保存在 k8s 集群中:

复制代码
$kubectl create secret generic git-creds \
--namespace=config-management-system \
--from-file=ssh=/root/.ssh/id_rsa
$kubectl get secret git-creds -n config-management-system
NAME TYPE DATA AGE
git-creds Opaque 1 35s

创建 Config-management

创建 config-management.yaml 文件:

复制代码
cat <<EOF > config-management.yaml
apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
name: config-management
spec:
# clusterName is required and must be unique among all managed clusters
clusterName: mycluster
git:
syncRepo: git@github.com:xxxx/ACM.git
syncBranch: master
secretType: ssh
policyDir: "policy"
EOF

同时我们需要在 Git 仓库里面创建 policy 目录和 repo.yaml 文件:

复制代码
mkdir -p policy/system
cat <<EOF > policy/system/repo.yaml
kind: Repo
apiVersion: configmanagement.gke.io/v1
metadata:
name: repo
spec:
version: "0.1.0"
EOF

我们把这些改动推到 Github 去:

复制代码
git add .
git commit -m 'add repo.yaml in policy/system dir'
git push

使用 kubcectl 部署 config-management.yaml

复制代码
kubectl apply -f config-management.yaml

查看日志

复制代码
kubectl logs -n config-management-system -l app=git-importer -c git-sync

可以在 console 页面上看到 ACM 安装成功:
GitOPS 与Anthos Config Management

使用 ACM 部署应用

我们有一个样例应用,是一个 B2C 的电子商务网站,Online Boutique,我们使用 Gitops 的方法来部署它。

先看看我们刚才克隆下来的 git 仓库中的结构:

复制代码
$ find policy/
policy/
policy/system
policy/system/repo.yaml

我们在 policy 目录中创建一个 namespaces 目录,并在其中创建 onlineboutique 目录,如以下命令:

复制代码
mkdir -p policy/namespaces/onlineboutique

并将以下内容放在 policy/namespaces/onlineboutique/namespace.yaml 中:

复制代码
apiVersion: v1
kind: Namespace
metadata:
name: onlineboutique
labels:
istio-injection: enabled

这将在 GKE 集群中创建一个命名空间叫 onlineboutique。

接下来,我们希望在这个命名空间中部署 Online Boutique 应用。我们可以在该链接找到这个应用,在它的 release 目录下有一个

复制代码
kubernetes-manifests.yaml

我们把它下载下来,放到

复制代码
policy/namespaces/onlineboutique/

目录中:

复制代码
curl -o policy/namespaces/onlineboutique/kubernetes-manifests.yaml
https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-
demo/master/release/kubernetes-manifests.yam

这时,我们的仓库会变成这样:

复制代码
$ find policy/
policy/
policy/system
policy/system/repo.yaml
policy/namespaces
policy/namespaces/onlineboutique
policy/namespaces/onlineboutique/kubernetes-manifests.yaml
policy/namespaces/onlineboutique/namespace.yaml

把刚才创建的这两个文件提交到 git 中,并推送到 github:

复制代码
git add git add policy/namespaces/onlineboutique/kubernetes-manifests.yaml \
policy/namespaces/onlineboutique/namespace.yaml
git commit -m "new namespace and deployment"
git push

部署完成后,查看 Cluster 中的应用情况。查看 namespace 会发现刚刚创建的命名空间 onlineboutique:

复制代码
$ kubectl get namespaces|grep onlineboutique
onlineboutique Active 19m

查看 deployment:

复制代码
# kubectl get deployment -n onlineboutique
NAME READY UP-TO-DATE AVAILABLE AGE
adservice 1/1 1 1 6m
cartservice 1/1 1 1 6m
checkoutservice 1/1 1 1 6m
currencyservice 1/1 1 1 6m
emailservice 1/1 1 1 6m
frontend 1/1 1 1 6m
loadgenerator 1/1 1 1 6m
paymentservice 1/1 1 1 6m
productcatalogservice 1/1 1 1 6m
recommendationservice 1/1 1 1 6m
redis-cart 1/1 1 1 6m
shippingservice 1/1 1 1 6m

我们看到,这个应用已经被成功的部署了。

评论

发布