上手GCP Anthos之多集群管理

提前说明

1.上手anthos时日不多,有解释或者说明不对的地方,请指正!
2.细节还是比较多的,有什么问题可以直接联系我,相互讨论!

了解

Anthos 是一个现代应用管理平台,官方解释:官方文档

对于这几天上手了解后,发现非常多功能还是很有意思和借鉴意义的。目前来说,我们主要用到了多集群管理(Environ)配置管理(ACM)服务管理(ASM),以及其他暂时还没有用到的。

png

多集群管理

字面意思理解即可,不过特别说明的是,他可以纳管其他云商k8s集群以及自建k8s集群。

配置管理

我比较喜欢称它为gitops,一切皆文件。
简单描述下:你的服务部署所需要的所有yaml文件(默认在k8s里),放在这个git里,任何改动的提交,都会同步到所有的集群(默认同步所有),比如:证书更新管理,证书更新了,提交一下,发布到所有集群,不用一个一个去更新了(如果你有其他自动化,当我没有说)

注:这个是我比较喜欢的一个功能,很实用。

服务管理

对于anthos管理的工作负载,asm会管理这些服务的网格环境,提供众多功能以及istio的所有功能,可以认为是一个增强改良版istio

注:当前我还没有使用上,以后使用上了,再更新一篇文章。

额外提示

初次使用anthos,gcp会提供一个900刀的试用金,可以尽情的享受了。

温馨提示:注意他的计费方式,不算太便宜。

开始吧

试用anthos已经两三天了,基本的模型和框架都已经搭建完毕,以及简单的测试都已经ok。大致可以分为以下几个点:

  • 注册集群
  • 创建git中心
  • 抽象配置文件
  • 开启配置同步
  • 测试批量管理

注册集群

目前有两种途径来接入anthos

① 通过anthos直接创建集群(当然这个直接创建的是gke集群)
② 纳管现有集群 – 纳管gke集群、纳管三方集群

纳管gke集群

我当前都是已经有现成的gke集群,所以直接选择第二种途径纳管gke集群即可。
png1

纳管三方集群

可以选择添加外部集群,填写好你集群的标签,最终会生成一条注册命令,扔到你的集群中执行即可。
png2

效果和验证

当你纳管好集群后,可以看看是否纳管成功以及如何判断纳管成功。

① 执行gcloud命令,查看当前纳管的集群和状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@localhost ~]# gcloud container hub memberships list
NAME EXTERNAL_ID
cluster1 xxxxxx-xxxxxxxxxx-xxxxxxxxxxxx
cluster2 xxxxxx-xxxxxxxxxx-xxxxxxxxxxxx

[root@localhost ~]# gcloud container hub memberships describe cluster1
createTime: '2021-03-17T06:41:47.422321701Z'
endpoint:
gkeCluster:
resourceLink: //container.googleapis.com/projects/******
kubernetesMetadata:
kubernetesApiServerVersion: v1.17.15-gke.800
memoryMb: 8282
nodeCount: 2
nodeProviderId: gce
updateTime: '2021-03-23T12:46:37.348171277Z'
vcpuCount: 8
externalId: xxxxxx-xxxxxxxxxx-xxxxxxxxxxxx
lastConnectionTime: '2021-03-23T12:42:31.571643848Z'
name: projects/***********
state:
code: READY
uniqueId: xxxxxx-xxxxxxxxxx-xxxxxxxxxxxx
updateTime: '2021-03-23T12:46:37.689233201Z'

② 使用kubectl查看到底安装了什么(其实跟绝大多数集群管理平台一样,就安装了一个agent的服务,参考rancher)

1
2
3
[root@localhost ~]# kubectl get pods -n gke-connect
NAME READY STATUS RESTARTS AGE
gke-connect-agent-20210305-01-00-54f7dcc455-l5x2f 1/1 Running 0 31h
注意事项
  • 集群需要有足够的资源
  • 节点需要有拉取git的权限

关于git的权限,你就简单认为他拿着你的配置文件然后做应用即可。
在gke中,我们需要对节点池进行配置权限:(节点池权限Cloud Source Repositories开放read only即可)
png3
png4

如果你是命令行创建的nodepool,可以参考这个:

1
gcloud container node-pools create my-nodepool  --cluster=*** --zone ***  --num-nodes=2  --disk-size=40 --machine-type=custom-4-4096 --project *** --scopes=cloud-source-repos-ro

scopes这个是权限列表,你可以按需添加,官方文档:scopes说明

创建git中心

顾名思义,把我们所有的配置和服务都抽象出yaml文件来,然后放到这个git里(正常anthos就是一个kubectl工具,你提交一个yaml文件,他apply一个)。
这个git仓库可以有很多中类型:github、gitlab、gcp仓库,这里我直接使用gcp的仓库服务,其他的你可以自己研究,还是比较简单的。

png5

抽象配置文件

在一步,我们首先要了解两个概念,层级结构(hierarchy)非结构化模式(unstructured)

层级结构是gcp提供的一种具有约束力的文件目录结构,比如目录下有cluster和namespace两个目录,那么在这两个目录里就分别存放集群级别的配置和namespace级别的配置。
非结构化模式是用户自己定义的一种文件模式,有点类似于helm、kustomize,不过值得注意的是,在这种模式下,我们每一个文件都需要标准的yaml文件。

nomos

在整体操作之前,我们先了解一个工具nomos,这个工具能让我们快速创建Config Sync代码库,包括初始化以及语法校验。官方文档

安装一下:

1
2
3
1.下载对应系统版本的二进制文件
2.chmod +x nomos
3.加入到环境变量中
层级结构
1.初始化层级结构目录
1
2
$ cd my-repo/
$ nomos init

这时候你就可以看到一个完整层级目录的结构:

1
2
3
4
5
6
7
8
9
$ tree
.
├── cluster # 集群级别的配置文件,role、rolebinding等
├── clusterregistry # 集群注册配置文件,比如我在这里定义了集群A的标签,在下面可以使用这个标签A表示只在A集群中安装,在其他集群不安装
├── namespaces # namespace级别的一些配置文件,如:svc、ingress、configmap、secret等
├── README.md
└── system
├── README.md
└── repo.yaml
2.编写集群注册的文件

加入我们有两个集群,cluster1和cluster2,那么我们需要在clusterregistry这个目录加入一下文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ cat cluster1.yaml
kind: Cluster
apiVersion: clusterregistry.k8s.io/v1alpha1
metadata:
name: cluster1
labels:
cluster: cluster1

$ cat selector-cluster1.yaml
kind: ClusterSelector
apiVersion: configmanagement.gke.io/v1
metadata:
name: selector-cluster1
spec:
selector:
matchLabels:
cluster: cluster1

上述文件表示:首先我们有一个cluster1.yaml表示我当前anthos管理的cluster1这个集群,selector-cluster1.yaml表示定义一个标签,当你满足我这个标签,就表示你选择了我这个集群。
这个标签就是我们后续会用到的configmanagement.gke.io/cluster-selector: selector-cluster1,这个需要写在我们的annotations中。

3.编写namespace相关

比如我们在namespace目录下创建一个test文件夹,那么表示我所管理的集群都会创建出一个名称为test的namespace(当然前提是你没有加cluster-selector)。
然后你就可以在这个文件夹下创建一系列的yaml文件了,比如你的deployment、service、ingress、configmap、secret、hpa等,如下所示:

1
2
3
4
5
6
7
8
$ ll -lh test/
total 36K
-rw-r--r-- 1 root root 2.9K Mar 22 15:52 deployment.yaml
-rw-r--r-- 1 root root 359 Mar 22 15:52 image-pull-secret.yaml
-rw-r--r-- 1 root root 276 Mar 22 15:52 hpa-cpu.yaml
-rw-r--r-- 1 root root 461 Mar 22 15:52 ingress.yaml
-rw-r--r-- 1 root root 9.4K Mar 22 15:52 ssl-tls.yaml
-rw-r--r-- 1 root root 264 Mar 22 15:52 service.yaml

刚刚说的集群选择标签,当前我们有两个集群cluster1和cluster2,那么假如我只想让hpa创建在cluster1怎么做呢,可以看如下配置(重点关注annotations):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat hpa-cpu.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: test-hpa
annotations:
configmanagement.gke.io/cluster-selector: cluster1
spec:
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: test-deployment
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 30
4.验证语法
1
$ nomos vet
非结构化模式

在非结构化模式中,我们采用的是helm的模式(需要对helm有一定基础,不熟悉的同学可以暂时跳过)。
注:他有一个特殊之处,就是我前面提到anthos只认标准的k8s yaml文件,像helm chart中的values这种他就不认,那么我们怎么去把这种应用到anthos呢?

带着问题,经过实践,我们得到如下结论:
① 首先我们还是需要初始化一个标准的helm chart模板 – helm init
② 我们需要打包出chart包 – helm package ChartName --debug
③ 生成yaml模板 – helm template ChartName ChartName-Version.tgz
④ 最终复制输出的结果到一个yaml文件中,上传到git仓库中

以下是我写的最简单的一个helm Chart,为了演示作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@localhost mychart]# tree
.
├── Chart.yaml
├── templates
│   └── namespace.yaml
└── values.yaml

1 directory, 3 files

[root@localhost mychart]# cat values.yaml
version: 0.0.1
namespace: "mynamespace"

[root@localhost mychart]# cat templates/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.namespace }}

[root@localhost]# helm package mychart --debug
Successfully packaged chart and saved it to: /www/anthos/repohelm/mychart-0.1.0.tgz

[root@localhost]# helm template mychart mychart-0.1.0.tgz
---
# Source: mychart/templates/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: mynamespace

[root@localhost]# 然后把输出的内容另存到一个init.yaml中,丢到git仓库里

当然,采用非结构化模式,我们也需要校验一下语法是否正确:

1
$ nomos vet --source-format=unstructured

开启配置同步

当我们编写好以上的文件,我们就可以配置acm了。

选择合适的git仓库类型

png6

填写git地址等信息

这一步填写好git地址,分支,同步间隔时间(多久从git同步一次),源格式(层级或非结构化)
png7

开始安装

在这里我们也可以直接看看他到底安装了什么东西,可以从下面看出他也是类似安装了一个服务,来定时同步我们的git文件到集群中。

1
2
3
4
[root@localhost]# kubectl get pods -n config-management-system
NAME READY STATUS RESTARTS AGE
git-importer-69699fd8b7-jzkhm 4/4 Running 1 31h
monitor-65b649fbd4-7wvps 1/1 Running 0 34h
查看状态

当我们安装好之后,可以从控制台查看当前的一个状态,也可以使用nomos来查看当前同步的状态:

png8

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost]# nomos status
Connecting to clusters...

*cluster1
--------------------
<root> https://source.developers.google.com/p/******@master
SYNCED e160b119

cluster2
--------------------
<root> https://source.developers.google.com/p/******@master
SYNCED e160b119

测试批量管理

当我们一切就绪之后,可以测试下同步功能,修改任意一个文件,等待一会(取决于你配置的同步时间),然后直接去集群中验证即可。

注意事项

① 层级结构中,namespace目录下每一个文件夹都代表着你对应集群下的namespace,你加了这个目录则表示我要通过acm管理这个namespace了;当然没加的,但是集群又存在的,不会影响。
② 层级结构中,不用再写namespace.yaml这个创建namespace的文件了,默认他会读取目录名称,并创建相应的namespace。
③ 如果集群存在一个deployment为A,那么我创建一个deployment-A.yaml,配置名称完全跟集群中的一致,那么他不会重新创建,而是直接纳管。
④ 非结构化模式中也可以使用cluster-selector,你只需要在git仓库里新建一个clusterregistry目录即可,文件内容和用法跟层级结构一样。
⑤ …