目 录CONTENT

文章目录

GitLab使用agent方式连接k8s

cplinux98
2022-08-30 / 0 评论 / 1 点赞 / 83 阅读 / 2,237 字 / 正在检测是否收录...

00:文章简介

Gitlab使用agent方式连接k8s,pipeline中访问gitlab代理即可使用k8s集群。

之前版本可以使用证书与k8s进行连接,但在14.5版本已经弃用,现改为使用代理客户端(agent),可以通过gitlab代理来访问k8s集群。

环境说明:

  • gitlab-server:14.9
    • 需要设置TLS(https)
    • 已经添加了k8s的gitlab-runner,tags为k8s
  • 生产k8s集群环境:1.23.4
  • 测试k8s集群环境:v1.22.0
    • 这里的测试集群用sealos装的,正常应该保证测试与生产版本一致,否则会出现【测试没问题,上生产出问题】的情况

01:项目创建

1.1:gitlab项目创建

创建一个cigroup的群组,群组内创建cidevops项目。

image-20220416144338780

1.2:添加项目文件

项目文件存放位置:https://git.linux98.com/gitlab-cicd/k8s-agent.git

添加完成后,从master创建一个develop分支。

1.3:k8s-namespace创建

这里两个集群都要创建

kubectl create ns cidevops
apiVersion: v1
kind: Namespace
metadata:
  name: cidevops

1.4:k8s-SA-Rolebinding

创建一个只有cidevops名称空间权限的SA

  1. 创建一个ClusterRole
    1. 赋予所有资源的操作权限
  2. 创建一个ServiceAccount
    1. 在业务名称空间中
    2. 命名为gitlab-agent-yewu_name
  3. 使用RoleBinding绑定
    1. 绑定ClusterRole和ServiceAccount
    2. 这样就可以使SA拥有该namespace的所有权限了
    3. 默认使用的是ClusterRoleBinding,绑定后SA拥有所有namespace的权限,权限过大,有安全隐患
    4. 使用RoleBinding绑定ClusterRole和SA的好处是:不用在每个namespace下都创建Role

文件链接:https://git.linux98.com/gitlab-cicd/k8s-agent/raw/master/agent-install/gitlab-agent-sa.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: cidevops-gitlab-agent
  namespace: cidevops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cidevops-gitlab-agent-admin
  namespace: cidevops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: cidevops-gitlab-agent
  namespace: cidevops

02:设置gitlab代理

2.1:生成创建信息

在项目->基础设施->kubernetes集群中添加代理。

参考地址:https://docs.gitlab.com/ee/ci/environments/#environments-and-deployments

image-20220416145030309

复制生成的token和提示信息

image-20220416145158066

2.2:生成yaml清单

我们复制推荐安装方法里的命令,去掉| kubectl apply -f -,修改项目名称空间,让其生成yaml资源清单。

docker run --pull=always --rm \
    registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate \
    --agent-token=xx3-P2Us8_QbWdw_AELSbTkEVcLWpjb3byJpLuCzCJz3ioyTPQ \
    --kas-address=wss://gitlab.linux98.com/-/kubernetes-agent/ \
    --agent-version stable \
    --namespace cidevops  # 这里可以指定要保存的名称空间

这里我只贴出需要的部分

文件链接:https://git.linux98.com/gitlab-cicd/k8s-agent/raw/master/agent-install/gitlab-agent-deployment.yaml

# 使用secret存储gitlab的token
apiVersion: v1
data:
  # 这个token是经过base64加密后的数据
  token: eHgzLVAyVXM4X1FiV2R3X0FFTFNiVGtFVmNMV3BqYjNieUpwTHVDekNKejNpb3lUUFE=
kind: Secret
metadata:
  name: gitlab-agent-token-b2c5km4f47
  namespace: cidevops
type: Opaque
---
# 使用deployment部署agent的pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-agent
  namespace: cidevops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab-agent
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      annotations:
        prometheus.io/path: /metrics
        prometheus.io/port: "8080"
        prometheus.io/scrape: "true"
      labels:
        app: gitlab-agent
    spec:
      containers:
      - args:
        - --token-file=/config/token
        - --kas-address
        - wss://gitlab.linux98.com/-/kubernetes-agent/
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        image: registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:stable
        livenessProbe:
          httpGet:
            path: /liveness
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
        name: agent
        readinessProbe:
          httpGet:
            path: /readiness
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        volumeMounts:
        - mountPath: /config
          name: token-volume
      serviceAccountName: cidevops-gitlab-agent  # 这里改为我们创建好的sa账户
      volumes:
      - name: token-volume
        secret:
          secretName: gitlab-agent-token-b2c5km4f47

2.3:生产集群部署

将修改的yaml文件复制到生产集群并应用。

image-20220416151255607

刷新gitlab页面

image-20220416151319715

2.4:测试集群部署

使用同样的方法,再创建一个名为ci-development的agent,部署在测试集群中。

可以复用上面的资源清单,使用 echo -n “token” | base64 生成加密的token,替换上面资源清单的token

# 使用secret存储gitlab的token
apiVersion: v1
data:
  # 这个token是经过base64加密后的数据
  token: dk1yUGdDaXl5SmctUkJjOURoVEh3TnlxNmhQVjJ4bVpTWkxaR1ljbUx0a0NMWmZZYUE=
kind: Secret
metadata:
  name: gitlab-agent-token-b2c5km4f47
  namespace: cidevops
type: Opaque
---
# 使用deployment部署agent的pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-agent
  namespace: cidevops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab-agent
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      annotations:
        prometheus.io/path: /metrics
        prometheus.io/port: "8080"
        prometheus.io/scrape: "true"
      labels:
        app: gitlab-agent
    spec:
      containers:
      - args:
        - --token-file=/config/token
        - --kas-address
        - wss://gitlab.linux98.com/-/kubernetes-agent/
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        image: registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:stable
        livenessProbe:
          httpGet:
            path: /liveness
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
        name: agent
        readinessProbe:
          httpGet:
            path: /readiness
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        volumeMounts:
        - mountPath: /config
          name: token-volume
      serviceAccountName: cidevops-gitlab-agent  # 这里改为我们创建好的sa账户
      volumes:
      - name: token-volume
        secret:
          secretName: gitlab-agent-token-b2c5km4f47

image-20220416151938012

2.5:部署完成状态

image-20220416152002026

03:创建environments

我们需要创建两个环境,一个是测试,一个是生产。

名称 URL
production http://prod.linux98.com
development http://dev.linux98.com

image-20220416154229948

正常情况下,应该按照上面的域名配置,但我这里就用ip+port来演示。

名称 URL
production http://192.168.31.11:30778
development http://192.168.31.31:30778

04:获取context-name

创建ci文件

image-20220416154330833

ci文件内容

deploy_k8s:
  image: 
    name: bitnami/kubectl:latest
    entrypoint: [""]
  tags:
    - k8s
  stage: deploy
  script:
   - kubectl config get-contexts
   - kubectl config view

流水线日志

image-20220416154836490

可以看出当前的镜像中已经生产了2个context,命名的规律为:project_name:agent_name

我们测试一下能否获取对应集群的信息。

ci文件

deploy_k8s:
  image: 
    name: bitnami/kubectl:latest
    entrypoint: [""]
  tags:
    - k8s
  stage: deploy
  script:
   - kubectl config use-context cigroup/cidevops:ci-development
   - kubectl get pods -n cidevops
   - echo "======================================="
   - kubectl config use-context cigroup/cidevops:ci-production
   - kubectl get pods -n cidevops

流水线日志

image-20220416163635106

05:配置项目cicd环境变量

参考:https://server_ip/help/ci/environments/index.md

我们根据不同的environments配置不同的cicd环境变量,这样可以使集群信息更安全,也可以简化ci文件内容。

项目-> 设置-> CI/CD -> 变量 -> 添加变量

这里只有master是受保护的分支,其他分支不受保护,如果设置了保护变量,其他分支无法获取

类型 保护变量 隐藏变量 环境范围 备注
KUBE_CONTEXT cigroup/cidevops:ci-development 变量 no yes development 测试集群连接context
KUBE_NAMESPACE cidevops 变量 no yes development 测试集群namespace
KUBE_CONTEXT cigroup/cidevops:ci-production 变量 yes yes production 生产集群连接context
KUBE_NAMESPACE cidevops 变量 yes yes production 生产集群namespace

添加完成后

image-20220416205745081

06:测试部署

6.1:修改ci文件

使用ci文件测试:https://git.linux98.com/gitlab-cicd/k8s-agent/raw/master/.gitlab-ci.yml

环境关系,我把域名改为主机地址了,请注意查看。

variables:
  SERVICE: "testapp"
  APP: "testapp"


prod_k8s:
  image: 
    name: bitnami/kubectl:latest
    entrypoint: [""]
  tags:
    - k8s
  stage: deploy
  script:
   - echo $ENVIRONMENT
   - echo ${CI_COMMIT_BRANCH}
   - echo ${CI_COMMIT_REF_NAME}
   - kubectl config use-context ${KUBE_CONTEXT}
   - kubectl get pods -n ${KUBE_NAMESPACE}
   - sed -i "s@__namespace__@${KUBE_NAMESPACE}@g" myapp-deploy.yaml
   - sed -i "s@__service_name__@${SERVICE}@g" myapp-deploy.yaml
   - sed -i "s@__app_name__@${APP}@g" myapp-deploy.yaml
   - sed -i "s@__enviroment__@prod.linux98.com@g" myapp-deploy.yaml
   - kubectl apply -f myapp-deploy.yaml -n ${KUBE_NAMESPACE}
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^master-*/ 
      when: on_success
    - when: never
  environment:
    name: production
    url: http://192.168.31.11:30778
    # on_stop: rollout_k8s

dev_k8s:
  image: 
    name: bitnami/kubectl:latest
    entrypoint: [""]
  tags:
    - k8s
  stage: deploy
  script:
   - echo ${CI_ENVIRONMENT_NAME}
   - echo ${CI_ENVIRONMENT_SLUG}
   - echo $CI_ENVIRONMENT_URL
   - echo ${CI_COMMIT_BRANCH}
   - echo ${CI_COMMIT_REF_NAME}
   - echo ${KUBE_CONTEXT}
   - echo ${KUBE_NAMESPACE}
   - kubectl config use-context ${KUBE_CONTEXT}
   - kubectl get pods -n ${KUBE_NAMESPACE}
   - sed -i "s@__namespace__@${KUBE_NAMESPACE}@g" myapp-deploy.yaml
   - sed -i "s@__service_name__@${SERVICE}@g" myapp-deploy.yaml
   - sed -i "s@__app_name__@${APP}@g" myapp-deploy.yaml
   - sed -i "s@__enviroment__@dev.linux98.com@g" myapp-deploy.yaml
   - kubectl apply -f myapp-deploy.yaml -n ${KUBE_NAMESPACE}
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^develop-*/ 
      when: on_success
    - when: never
  environment:
    name: development
    url: http://192.168.31.31:30778

6.2:增加部署资源清单

部署资源清单文件:https://git.linux98.com/gitlab-cicd/k8s-agent/raw/master/myapp-deploy.yaml

apiVersion: v1
kind: Service
metadata:
  name: __service_name__
  labels:
    app: __app_name__
spec:
  type: NodePort
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: http
      nodePort: 30778
  selector:
    app: __app_name__
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: __app_name__
  labels:
    app: __app_name__
spec:
  replicas: 3
  selector:
    matchLabels:
      app: __app_name__
  template:
    metadata:
      name: __app_name__
      labels:
        app: __app_name__
    spec:
      containers:
      - name: __app_name__
        image: 'nginx'
        command: ["/bin/sh", '-c']
        args: 
          - "echo '__enviroment__' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"
        ports:
        - name: http
          containerPort: 80
          protocol: TCP

6.3:测试

分别从master和develop分支启动流水线。

流水线情况

image-20220417000439574

环境查看

image-20220417000510417

点击打开分别查看对应环境部署情况

image-20220417000607938

对于日志信息,想查看的可以在git仓库中查看,我放在git仓库中了

其他配置参考

review环境

回滚环境

07:需要注意的地方

7.1:重设token

这里的create token实际上是reset token

image-20220413221508579

7.2:删除agent

在gitlab-ui中删除agent代理,并不会删除k8s集群中的代理pod等资源

1

评论区