引言
完成前面章节的镜像构建,离自动部署到Kubernetes 就更近一步。这一节就来详解GitLab如何集成Kubernetes,以及如何配置流水线发布到Kubernetes。
集成 Kubernetes
为了方便后续配置CI/CD流水线并部署至Kubernetes,首先要集成Kubernetes至GitLab。主要分为以下几步:
- 获取Kubernetes ApiServer地址,可通过执行
kubectl cluster-info
获取。下图中红框所示即为ApiServer地址。
- 在
kube-system
命名空间下创建gitlab
ServiceAccount。可直接使用Lens按下图步骤创建:
- 创建命名为
gitlab-cluster-admin
的ClusterRoleBinding
。同样直接使用Lens创建,步骤如下图所示:
对于以上2、3两步,也可通过以下脚本创建:
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: gitlab-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: gitlab
namespace: kube-system
- 获取证书和令牌,可以通过找到创建的命名为
gitlab``ServiceAccount
对应的Secret
中获取,Secret命名格式为:gitlab-token-xxx
,可在Lens中按以下步骤获取:
- 打开集成界面,如下图所示: image
-
配置参数,点击
连接现有集群
,参考下图进行配置。其中:
-
API地址:即为上面第1步获取的Api服务器地址
-
CA证书:对应第4步中命名为
ca.crt
的值 -
服务令牌:对应第4步中命名为
token
的值
- 点击
Kubernets
菜单,即可看到集成的Kubernetes集群,如下图所示: image
配置镜像拉取凭证
在部署到集成的Kubernetes平台前,还有一点至关重要,那就是配置镜像拉取凭证(imagePullSecert)。这样自有的Kubernetes平台才能够从GitLab Registry中拉取镜像,创建Pod。创建镜像拉取凭证也相对简单,仅需两步,第一步创建一个个人访问令牌
,要求必须包含read_registry
和write_registry
两个权限范围,如下图所示,其中令牌名称
和访问令牌
将分别作为访问镜像仓库的凭证的用户名和密码。
有了访问令牌,即可创建一个类型为docker-registry
的secret
即可,具体命令如下,该命令暂无需执行,后续阶段Job中会使用。
$: kubectl create secret docker-registry \
gitlab-registry-secret \ # 指定secret 名称
--docker-server=https://registry.shengjie.dev \ # 指定 docker镜像仓库地址
--docker-username=container-registry-token \ # 指定凭证名称
--docker-password=T93Q3HbBaixAhxWZk5fy \ # 指定为凭证令牌
--docker-email=ysjshengjie@live.cn \ # 指定邮箱
-n gitlab # 指定命名空间
准备部署文件
准备工作做完了,接下来就要准备好部署文件以便执行部署。对于一个ASP.NET Core Web 项目而言,需要准备Deployment
、Service
和Ingress
三个部署文件。其中Deployment
用于管理Pod运行容器,Service
负责暴露服务,Ingress
负责配置外部可访问的服务地址等。一个基本的Deployment
定义如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment # deploy名称
labels:
app: nginx # deploy标签
spec:
replicas: 3
selector:
matchLabels:
app: nginx # 匹配标签
template:
metadata:
labels:
app: nginx #pod 标签
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.14.2 # 镜像
ports:
- containerPort: 80 # 容器端口号
因此,可以直接将上面的nginx
替换为自己应用的名称,然后替换image
即可。由于每次构建镜像的Tag
可能不一样,因此这个image
值需要动态替换。于是乎,可以定义一个通用的Deployment
如下,然后在项目根目录创建一个名为.gitlab-ci
的文件夹,并在文件夹下创建名为app.deployment.yaml
的文件保存。
apiVersion: apps/v1
kind: Deployment
metadata:
name: __AppName__-deployment # deploy名称
labels:
app: __AppName__ # deploy标签
annotations:
app.gitlab.com/app: __AppName__ #定义App注解
app.gitlab.com/env: __Environment__ #定义环境注解
spec:
replicas: 3 # 指定三副本
selector:
matchLabels:
app: __AppName__ # 匹配标签
template:
metadata:
labels:
app: __AppName__ #pod 标签
spec:
imagePullSecrets:
- name: gitlab-registry-secret # 指定上面定义的镜像拉取凭证
containers:
- name: __AppName__ # 容器名称
image: __AppImage__ # 镜像
ports:
- containerPort: 80 # 容器端口号
同理可以创建一个通用的Service
如下所示,然后创建一个名为app.service.yaml
的文件保存。
apiVersion: v1
kind: Service
metadata:
name: __AppName__-service
spec:
selector:
app: __AppName__
ports:
- protocol: TCP
port: 80
targetPort: 80
最后,也创建一个通用的Ingress
,保存到app.ingress.yaml
文件中。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: __AppName__-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: __AppHost__
http:
paths:
- path: __AppHostPath__
pathType: Prefix
backend:
service:
name: __AppName__-service
port:
number: 80
保存后,如下图所示:
image
配置自动发布Job
完成了准备工作,接下来回到流水线编辑器来创建自动发布到Kubernetes的Job。对于发布,首先需要kubectl
命令,因此可以通过使用包含kubectl
命令的镜像进行发布,其二,就是为当前命名空间创建镜像拉取凭证,第三,进行占位符替换,第四执行kubectl apply -f
命令进行部署。具体定义的deploy-job
,如下所示:
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE/$CI_PROJECT_PATH_SLUG:$CI_COMMIT_SHORT_SHA # 定义全局标签,方便后续复用
deploy-job:
stage: deploy
image: bitnami/kubectl:1.19
environment:
name: development
variables:
AppHost: demo.shengjie.dev # 注意替换为自己的域名
AppHostPath: /
before_script:
- kubectl create secret docker-registry gitlab-registry-secret --docker-server="$CI_REGISTRY" --docker-username="$CI_DEPLOY_USER" --docker-password="$CI_DEPLOY_PASSWORD" --docker-email="$GITLAB_USER_EMAIL" -o yaml --dry-run=client | kubectl apply -f -
script:
- echo $IMAGE_TAG
- cd .gitlab-ci
- sed -i "s#__AppName__#$CI_PROJECT_PATH_SLUG#g" app.deployment.yaml app.service.yaml app.ingress.yaml
- sed -i "s#__AppImage__#$IMAGE_TAG#g" app.deployment.yaml
- sed -i "s#__Environment__#$CI_ENVIRONMENT_SLUG#g" app.deployment.yaml
- sed -i "s#__AppHost__#$AppHost#g" app.ingress.yaml
- sed -i "s#__AppHostPath__#$AppHostPath#g" app.ingress.yaml
- cat app.deployment.yaml
- kubectl apply -f app.deployment.yaml #部署deploy
- cat app.service.yaml
- kubectl apply -f app.service.yaml # 部署service
- cat app.ingress.yaml
- kubectl apply -f app.ingress.yaml # 部署ingress
- echo 'succeed'
cache: [] # 无需使用缓存
needs:
- job: publish-job
- job: build-docker-job # 指定仅镜像构建成功后才进行部署
网友评论