在gitlab-ci里通过kubectl set image来更新镜像

2022/8/26 single-spasystem.js微前端

这篇笔记是转载的我们组长写的前端部署相关的实践文章、仅用于个人学习。

K8S 有提供一个 api server,可以通过创建 service account,只要给这个 service account 定义足够的权限,就可以通过远程的方式来控制 k8s

# 创建 service account

登录集群管理服务器,新建一个文件: service-account-test.yml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: test
  namespace: my-namespace
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test
  namespace: my-namespace
rules:
  - apiGroups: ["*"]
    resources: ["*"]
    verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test
  namespace: my-namespace
subjects:
  - kind: ServiceAccount
    name: test
    namespace: my-namespace
roleRef:
  kind: Role
  name: test
  apiGroup: rbac.authorization.k8s.io
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

然后执行命令 kubectl apply -f service-account-test.yml,这样就能创建一个名为 test 的 service account,同时还给这个 service account 赋予了 my-namespace 命名空间下的所有权限

# 创建 token

再新建一个文件:  service-account-test-token.yml

apiVersion: v1
kind: Secret
metadata:
  name: test-token
  namespace: my-namespace
  annotations:
    kubernetes.io/service-account.name: test
type: kubernetes.io/service-account-token
1
2
3
4
5
6
7
8

然后执行 kubectl apply -f service-account-test-token.yml,这样就能为 test  这个 service account 创建对应的 token

然后执行: kubectl get secret test-token --namespace=my-namespace -o yaml,获取如下信息:

apiVersion: v1
data:
  ca.crt: Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEU....
  namespace: cmVka...
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbX....
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: test
    kubernetes.io/service-account.uid: ae35a575-b78...
  creationTimestamp: 2019-08-05T14:41:46Z
  name: test-token
  namespace: my-namespace
  resourceVersion: "120822377"
type: kubernetes.io/service-account-token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

里面的 ca.crt  是证书文件的 base64 编码,下面会用到,但是需要注意,这里的 token 也是 base64 编码的,不能直接用。

获取 token,需要用另外一个命令:kubectl describe secret test-token --namespace=my-namespace,获取到如下信息:

Name:         test-token
Namespace:    my-namespace
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: test
              kubernetes.io/service-account.uid: xxxxxx

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1102 bytes
namespace:  7 bytes
token:      xxxxxxx
1
2
3
4
5
6
7
8
9
10
11
12
13

这里面的 token 可用于下面的配置

# 配置.gitlab-ci.yml

stages:
  - deploy
job deploy-beta:
  image: roffe/kubectl:v1.13.2
  stage: deploy
  script:
    - IMAGE_NAME=qinyang/test
    - VERSION=0.0.1
    - kubectl config set-cluster k8s --server="${api_server}"
    - kubectl config set clusters.k8s.certificate-authority-data ${ca_crt}
    - kubectl config set-credentials reditor-deploy --token="${k8s_deploy_token}"
    - kubectl config set-context my-namespace --cluster=k8s --user=test
    - kubectl config use-context my-namespace
    - kubectl set image deployment/${deployment_name} ${container_name}=$IMAGE_NAME:$VERSION --namespace=my-namespace
1
2
3
4
5
6
7
8
9
10
11
12
13
14

api_server: 如果是在 gitlab runner 所在的集群里部署,则为: https://kubernetes.default.svc, 如果部署的集群和 runner 所在集群不一样,则可以到集群里去找到对应的 API Server 公网连接端点或者 API Server 内网连接端点

ca_crt: 是我们上面获取到的 ca.crt 的 base64 字符串格式

k8s_deploy_token: 是我们上面获取到的 token

deployment_name: deployment 名字

container_name: 容器名字

需要注意,如果 gitlab-ci 执行命令的时候,报无法获取 deployment 的错,很可能是 token 或者 ca.crt 内容不对,需要注意,ca.crt 需要 base64 编码的,但是 token 不能用 base64 编码的,就 jwt 原始格式就行

Last Updated: 2022/8/30 下午6:11:52