
# Gitlab对接SWR和CCE执行CI/CD
#### 应用现状
GitLab是利用Ruby on Rails一个开源的版本管理系统，实现一个自托管的Git项目仓库，可通过Web界面进行访问公开的或者私人项目。与Github类似，GitLab能够浏览源代码，管理缺陷和注释。可以管理团队对仓库的访问，它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。
GitLab的CI/CD功能强大，在软件开发业界有着广泛的应用。
图1GitLab CI/CD流程   
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001291567729.png "点击放大")
本文介绍在Gitlab中对接SWR和CCE执行CI/CD，并通过一个具体的过程演示该过程。
#### 准备工作
1. 创建一台CCE集群，且需要给节点绑定一个EIP，用于安装Gitlab Runner时下载镜像。
2. 下载并配置kubectl连接集群。 登录CCE控制台，在集群"概览"页面找到"连接信息"版块，单击kubectl对应的"配置"按钮，按照指导配置kubectl。
   ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002094088925.png "点击放大")
   
   
3. 安装helm 3，具体请参见<https://helm.sh/zh/docs/intro/install/>。
 
#### 安装Gitlab Runner
登录[Gitlab](https://www.gitlab.com/)，进入项目视图的Settings-\>CI/CD，单击Runners旁边的Expand，查找Gitlab Runner注册URL和Token，如下图所示。
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001238489436.png "点击放大")
创建values.yaml文件，填写如下信息。
```
# 注册URL
gitlabUrl: https://gitlab.com/
# 注册token
runnerRegistrationToken: "******"
rbac:
    create: true
runners:
    privileged: true
```
创建gitlab命名空间。
```
kubectl create namespace gitlab
```
通过helm安装Gitlab Runner。
```
helm repo add gitlab https://charts.gitlab.io 
helm install --namespace gitlab gitlab-runner -f values.yaml gitlab/gitlab-runner --version=0.43.1
```
安装完成后，可以在[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)查询到gitlab-runner的工作负载，等待一段时间后在Gitlab中可以看到连接信息，如下图所示。
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001283301301.png "点击放大")
#### 创建应用
将您要创建的应用放到Gitlab项目仓库中，本文使用一个修改nginx的示例，具体请参见<https://gitlab.com/c8147/cidemo/-/tree/main>。
其中包括如下文件。
- **.gitlab-ci.yml** ：Gitlab CI文件，将在[创建流水线]中详细讲解。
- **Dockerfile**：用于制作Docker镜像。
- **index.html**：用于替换nginx的index页面。
- **k8s.yaml**：用于部署nginx应用，会创建一个名为nginx-test的Deployment，和一个名为nginx-test的Service。
以上文件仅为示例，您可以根据您的业务需求进行替换或修改。
#### 设置全局变量
流水线运行过程中，会先Build镜像上传到SWR，然后执行kubectl命令在集群中部署，这就需要能够登录SWR镜像仓库，并且要有集群的连接凭证。实际执行中可以将这些信息在Gitlab中定义成变量。
登录[Gitlab](https://www.gitlab.com/)，进入项目视图的Settings-\>CI/CD，单击Variables旁边的Expand，添加变量。
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001238903330.png "点击放大")
- kube_config： kubeconfig.json文件，用于执行kubectl命令鉴权使用，需要转换成base64格式，在配置好kubectl的机器上，执行如下命令。
  **echo $(cat \~/.kube/config \| base64) \| tr -d " "**
  回显的字符串即为kubeconfig.json的内容。
  
- project：项目名称。 登录管理控制台，将鼠标移至右上角您的用户名处，单击"我的凭证"。在"API凭证"的项目列表中查找当前区域对应的项目。
  
- swr_ak：密钥的AK。 登录管理控制台，将鼠标移至右上角您的用户名处，单击"我的凭证"。在左侧导航栏中选择"访问密钥"，单击"新增访问密钥"，输入描述信息，单击"确定"。在弹出的提示页面单击"立即下载"。下载成功后，在"credentials"文件中即可获取AK和SK信息。
  
- swr_sk：登录SWR镜像仓库的密钥。 执行如下命令获取密钥，其中$AK和$SK为上面获取的AK/SK。
  **printf "** ***$AK*** **" \| openssl dgst -binary -sha256 -hmac "** ***$SK*** **" \| od -An -vtx1 \| sed 's/\[ \\n\]//g' \| sed 'N;s/\\n//'**
  回显的字符串即为登录密钥。
  
 
 #### 创建流水线
登录[Gitlab](https://www.gitlab.com/)，在Repository中添加**.gitlab-ci.yml**文件。
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001238830246.png "点击放大")
其内容如下所示。
```
#定义pipeline中的阶段，包含打包、构建和部署三个阶段
stages:
  - package  
  - build
  - deploy
#各个构建阶段不指定镜像时，使用默认镜像docker:latest
image: swr.cn-east-3.myhuaweicloud.com/container/docker:latest
#package阶段只打印，不做任何操作
package:
  stage: package
  script:
    - echo "package"
# build阶段使用docker in docker方式
build:
  stage: build
  # 定义build阶段的环境变量
  variables:
    DOCKER_HOST: tcp://docker:2375
  # 定义docker in docker运行的镜像
  services:
    - docker:18.09-dind
  script:
    - echo "build"
    # 登录SWR
    - docker login -u $project@$swr_ak -p $swr_sk swr.cn-east-3.myhuaweicloud.com
    # 构建镜像，其中k8s-dev为SWR中的组织名称，请根据实际情况替换
    - docker build -t swr.cn-east-3.myhuaweicloud.com/k8s-dev/nginx:$CI_PIPELINE_ID .
    # 推送镜像到SWR
    - docker push swr.cn-east-3.myhuaweicloud.com/k8s-dev/nginx:$CI_PIPELINE_ID
deploy:
  # 使用kubectl镜像
  image: 
    name: swr.cn-east-3.myhuaweicloud.com/container/kubectl:latest
    entrypoint: [""]
  stage: deploy
  script:
    # 配置kubeconfig文件
    - mkdir -p $HOME/.kube
    - export KUBECONFIG=$HOME/.kube/config
    - echo $kube_config |base64 -d > $KUBECONFIG
    # 替换k8s.yaml文件中的镜像
    - sed -i "s/<IMAGE_NAME>/swr.cn-east-3.myhuaweicloud.com\/k8s-dev\/nginx:$CI_PIPELINE_ID/g" k8s.yaml
    - cat k8s.yaml
    # 部署应用
    - kubectl apply -f k8s.yaml
```
**.gitlab-ci.yml**文件保存后，会立即启动执行流水线，在Gitlab中查看流水线执行情况，如下所示。
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001283343269.png "点击放大")
#### 验证结果
流水线部署成功后，在CCE控制台找到名为nginx-test的Service，查询到nginx-test的访问地址，使用curl命令访问。
```
# curl xxx.xxx.xxx.xxx:31111
Hello Gitlab!
```
如果能得到如上回显，则说明部署正确。
#### 常见问题
- 如果在部署阶段出现如下问题： ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001520115845.png "点击放大")
  或
  ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001520396937.png "点击放大")
  请检查**.gitlab-ci.yml** 文件中是否缺少如下两行命令，如果缺少请在**.gitlab-ci.yml**中补充命令。
  ```
  ...
    script:
      # 配置kubeconfig文件
      - mkdir -p $HOME/.kube
      - export KUBECONFIG=$HOME/.kube/config
      - echo $kube_config |base64 -d > $KUBECONFIG
      # 替换k8s.yaml文件中的镜像
  ...
  ```
  
- 如果流水线执行过程出现无法执行docker的情况，如下所示。 ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001911529105.png "点击放大")
  安装gitlab runner过程中传递privileged: true参数未成功，导致没有权限运行docker命令，请在CCE控制台工作负载列表中找到gitlab runner，添加环境变量**KUBERNETES_PRIVILEGED** ，取值为**true**，如下所示。
  ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002094214629.png "点击放大")
  
  
 
