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项目。
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
- 创建一个ClusterRole
- 赋予所有资源的操作权限
- 创建一个ServiceAccount
- 在业务名称空间中
- 命名为gitlab-agent-yewu_name
- 使用RoleBinding绑定
- 绑定ClusterRole和ServiceAccount
- 这样就可以使SA拥有该namespace的所有权限了
- 默认使用的是ClusterRoleBinding,绑定后SA拥有所有namespace的权限,权限过大,有安全隐患
- 使用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
复制生成的token和提示信息
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文件复制到生产集群并应用。
刷新gitlab页面
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
2.5:部署完成状态
03:创建environments
我们需要创建两个环境,一个是测试,一个是生产。
名称 | URL |
---|---|
production | http://prod.linux98.com |
development | http://dev.linux98.com |
正常情况下,应该按照上面的域名配置,但我这里就用ip+port来演示。
名称 | URL |
---|---|
production | http://192.168.31.11:30778 |
development | http://192.168.31.31:30778 |
04:获取context-name
创建ci文件
ci文件内容
deploy_k8s:
image:
name: bitnami/kubectl:latest
entrypoint: [""]
tags:
- k8s
stage: deploy
script:
- kubectl config get-contexts
- kubectl config view
流水线日志
可以看出当前的镜像中已经生产了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
流水线日志
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 |
添加完成后
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分支启动流水线。
流水线情况
环境查看
点击打开分别查看对应环境部署情况
对于日志信息,想查看的可以在git仓库中查看,我放在git仓库中了
其他配置参考
review环境
回滚环境
07:需要注意的地方
7.1:重设token
这里的create token实际上是reset token
7.2:删除agent
在gitlab-ui中删除agent代理,并不会删除k8s集群中的代理pod等资源
评论区