22.云原生之GitLab CICD实战及解析【干货】

云原生专栏大纲

准备工作

  1. 安装gitlab
  2. 安装配置gitlab-runner,参考本章节 《注册配置kubernetes runner》
  3. 登录gitlab配置需安全保护全局变量,如kube_config、harbor账号密码等。

image.png

gitlab-ci.yml流水线

可参考官网GitLab CI/CD examples | 预定义的 CI/CD 变量参考

CICD流程:

  1. 使用maven打包项目
  2. 制作docker镜像
  3. 推送镜像到harbor仓库
  4. 部署到k8s

mven打包项目

variables:
  MAVEN_OPTS: >-
    -Dmaven.repo.local=/builds/maven #maven下载文件路径
    -Dorg.slf4j.simpleLogger.showDateTime=true
    -Djava.awt.headless=true
  MAVEN_CLI_OPTS: >-
    --batch-mode
    --errors
    --fail-at-end
    --show-version
    --no-transfer-progress
    -DinstallAtEnd=true
    -DdeployAtEnd=true
    
package:
  stage: package
  image: maven:3.6.3-jdk-8
  tags:
    - k8s
  script:
    - pwd
    - mvn clean package -Dmaven.test.skip=true
    # 将打包后target拷贝到指定目录
    - rm -rf /builds/project-target/devops-web
    - rm -rf /builds/project-target/devops-service
    # 将打包后制品拷贝到同一目录进行管理
    - cp -rf ./devops-web /builds/project-target/devops-web
    - cp -rf ./devops-service /builds/project-target/devops-service

制作并推送镜像

kaniko方式
build:
  stage: build
  image:
    name: registry.cn-hongkong.aliyuncs.com/cmi/kaniko-project_executor:debug
    entrypoint: [""]
  tags:
    - k8s
  script:
    - /kaniko/executor
      --skip-tls-verify
      --insecure
      --context "${CI_PROJECT_DIR}"
      --dockerfile "/devops-web/Dockerfile"
      --destination "harbor.yxym.com/library/devops-web:kaniko"
  except:
    - tags
docker方式
docker-build:
#  image: docker:latest
  image: docker:cli
  services:
    - docker:dind
  stage: build
  script:
    - docker login -u admin -p Harbor12345 harbor域名
    - cd /builds/project-target
    - docker build -t devops-web:dind -f ./devops-web/Dockerfile  ./devops-web/
    - docker tag devops-web:dind harbor域名/library/devops-web:dind
    - docker push harbor域名/library/devops-web:dind

部署到k8s

deploy:
  image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/kubectl:1.16.6
  stage: deploy
  tags:
    - k8s
  script:
    - mkdir -p /etc/deploy
    # 该命令配置kube_config,用于获取k8s命令操作权限
    - echo $kube_config |base64 -d > $KUBECONFIG
    - kubectl apply -f /builds/project-target/devops-web/deploy.yml

验证执行情况

  1. 登录gitlab查看流水线:
    image.png

  2. 登录harbor查看镜像是否推送到仓库
    image.png

  3. 登录kubesphere查看部署情况
    在这里插入图片描述

GitLab Runner k8s执行器工作流程

image.png
在 GitLab Runner 中使用 Kubernetes (k8s) 执行器时,以下是其工作流程的一般概述:

  1. 配置 Kubernetes 集群:首先,你需要在 GitLab Runner 所在的机器上配置和连接到 Kubernetes 集群。这包括安装和配置 kubectl 命令行工具,并确保 Runner 具有访问 Kubernetes 集群的权限。
  2. 注册 Runner:使用 gitlab-runner register 命令注册一个新的 Runner,选择 kubernetes 作为执行器。在注册过程中,你需要提供 GitLab 实例的 URL、Runner 的描述、Kubernetes 集群的相关配置等信息。
  3. 配置 Runner:完成注册后,GitLab Runner 将生成一个配置文件,其中包含与 Kubernetes 执行器相关的配置信息,例如 Kubernetes API 的地址、访问凭证等。这些配置将被保存在 Runner 的配置目录中。
  4. 运行作业:当有作业需要执行时,GitLab CI/CD 将向 GitLab Runner 发送作业请求。Runner 将根据作业的定义和配置,使用 Kubernetes API 向 Kubernetes 集群提交一个 Pod 规范,描述作业的运行环境和要运行的容器。
  5. 创建 Pod:Kubernetes 集群接收到 Runner 提交的 Pod 规范后,将根据规范创建一个 Pod。Pod 是 Kubernetes 中的最小调度单位,可以包含一个或多个容器。
  6. 容器运行:一旦 Pod 创建成功,Kubernetes 将根据 Pod 规范在集群中选择一个合适的节点,并在该节点上创建和运行容器。容器将根据作业定义的镜像和命令来执行相应的操作,例如构建、测试或部署。
  7. 监听作业状态:GitLab Runner 会定期查询 Kubernetes API 来获取作业的状态信息。这包括容器的运行状态、日志输出等。Runner 将这些信息返回给 GitLab CI/CD,以便实时监控作业的进度和结果。
  8. 提交结果:作业完成后,GitLab Runner 将收集作业的结果,包括日志输出、环境变量等,并将其提交给 GitLab CI/CD。这些结果将在 GitLab CI/CD 界面上显示,并可以用于后续的流程控制和报告生成。
  9. 清理资源:一旦作业完成,Kubernetes 将根据配置自动清理相关的 Pod 和容器。这确保了资源的有效使用和释放。

通过将 GitLab Runner 与 Kubernetes 执行器结合使用,你可以在 Kubernetes 集群中动态地创建和管理容器化的作业环境,实现高度可扩展的持续集成和持续交付流程。

注册配置kubernetes runner

注册器kubernetes 的gitlab runner,使用参考Kubernetes executor官网Executors | GitLab
执行器 | 极狐GitLab
helm方式部署优势:

  1. 省去了注册kubernetes执行器很多细节,kubernetes执行器是最复杂的一个

helm方式部署缺点:

  1. helm方式部署的github-runner使用了特定的镜像,启动后很多目录用户没有操作权限
  2. 该镜像不能以特权用户启动
  3. 配置挂载路径和gitlab官网使用镜像挂载路径存在区别

kubernetes runner配置

通过修改 Pod 规范为每个构建作业创建一个 PVC

若要为每个生成作业创建 PersistentVolumeClaim,请确保查看如何启用 Pod Spec 功能

Kubernetes 允许创建一个附加到 Pod 生命周期的临时 PersistentVolumeClaim。 如果在 Kubernetes 集群上启用了动态预配,这将起作用,允许 每个请求一个新的卷,该也将与 Pod 的生命周期相关联。PVC

启用动态配置后,可以按如下方式修改:

[[runners.kubernetes.pod_spec]]
  name = "ephemeral-pvc"
  patch = '''
    containers:
    - name: build
      volumeMounts:
      - name: builds
        mountPath: /builds
    - name: helper
      volumeMounts:
      - name: builds
        mountPath: /builds
    volumes:
    - name: builds
      ephemeral:
        volumeClaimTemplate:
          spec:
            storageClassName: <The Storage Class that will dynamically provision a Volume>
            accessModes: [ ReadWriteOnce ]
            resources:
              requests:
                storage: 1Gi
  '''

自定义卷装载

要存储作业的 builds 目录,请定义自定义卷挂载到 已配置(默认)。 如果您使用 PVC 卷, 基于接入模式, 您可能被限制为在一个节点上运行作业。builds_dir/builds

concurrent = 4

[[runners]]
  # usual configuration
  executor = "kubernetes"
  builds_dir = "/builds"
  [runners.kubernetes]
    [[runners.kubernetes.volumes.empty_dir]]
      name = "repo"
      mount_path = "/builds"
      medium = "Memory"

持久性并发构建卷

默认情况下,Kubernetes CI 作业中的构建目录是临时的。 如果您想在作业中持久化 Git 克隆(以使其正常工作), 您必须为生成文件夹装载持久性卷声明。 由于多个作业可以同时运行,因此您必须 使用一个卷,或为每个电位设置一个卷 同一运行器上的并发作业。后者可能性能更高。

concurrent = 4

[[runners]]
  executor = "kubernetes"
  builds_dir = "/mnt/builds"
  [runners.kubernetes]
    [[runners.kubernetes.volumes.pvc]]
      # CI_CONCURRENT_ID identifies parallel jobs of the same runner.
      # name是pvc名称如"build-pvc-$CI_CONCURRENT_ID"
      name = "k8s-running-pod-data"
      mount_path = "/mnt/builds"

为容器设置安全策略

  • 设置 Pod 安全上下文。
  • 重写以及生成和帮助程序容器。run_as_userrun_as_group
  • 指定所有服务容器都继承 Pod 安全上下文并从 Pod 安全上下文继承。run_as_userrun_as_group
concurrent = 4
check_interval = 30
  [[runners]]
    name = "myRunner"
    url = "gitlab.example.com"
    executor = "kubernetes"
    [runners.kubernetes]
      helper_image = "gitlab-registry.example.com/helper:latest"
      [runners.kubernetes.pod_security_context]
        run_as_non_root = true
        run_as_user = 59417
        run_as_group = 59417
        fs_group = 59417
      [runners.kubernetes.init_permissions_container_security_context]
        run_as_user = 1000
        run_as_group = 1000
      [runners.kubernetes.build_container_security_context]
        run_as_user = 65534
        run_as_group = 65534
        [runners.kubernetes.build_container_security_context.capabilities]
          add = ["NET_ADMIN"]
      [runners.kubernetes.helper_container_security_context]
        run_as_user = 1000
        run_as_group = 1000
      [runners.kubernetes.service_container_security_context]
        run_as_user = 1000
        run_as_group = 1000
选择类型必填描述
run_as_groupint用于运行容器进程入口点的 GID。
run_as_non_root布尔指示容器必须以非 root 用户身份运行。
run_as_userint用于运行容器进程入口点的 UID。
capabilities.add字符串列表运行容器时要添加的功能。
capabilities.drop字符串列表运行容器时要删除的功能。
selinux_type字符串与容器进程关联的 SELinux 类型标签。

设置拉取策略

使用文件中的参数指定单个或多个拉取策略。 该策略控制如何提取和更新映像,并应用于生成映像、帮助程序映像和任何服务。pull_policyconfig.toml
要确定要使用的策略,请参阅有关拉取策略的 Kubernetes 文档
对于单个拉取策略:

[runners.kubernetes]
  pull_policy = "never"

对于多个拉取策略:

[runners.kubernetes]
  # use multiple pull policies
  pull_policy = ["always", "if-not-present"]

当您定义多个策略时,将尝试每个策略,直到成功获取映像。 例如,当您使用 时,如果策略由于临时注册表问题而失败,则使用该策略。[ always, if-not-present ]if-not-presentalways
要重试失败的拉取,请执行以下操作:

[runners.kubernetes]
  pull_policy = ["always", "always"]

GitLab 的命名约定与 Kubernetes 的命名约定不同。

运行器拉取策略Kubernetes 拉取策略描述
空白空白使用 Kubernetes 指定的默认策略。
if-not-presentIfNotPresent仅当执行作业的节点上尚不存在映像时,才会拉取该映像。您应该注意一些安全注意事项
alwaysAlways每次执行作业时都会拉取映像。
neverNever永远不会拉取映像,并且要求节点已经拥有它。

配置 Pod DNS 设置

使用以下选项配置 Pod 的 DNS 设置

选项类型必须描述
nameserversstring 列表将用作 Pod 的 DNS 服务器的 IP 地址列表
optionsKubernetesDNSConfigOption一个可选的对象列表,其中每个对象可能有一个名称参数(必需)和一个值参数(可选)
searchesstring 列表用于在 Pod 中查找主机名的 DNS 搜索域列表

config.toml 文件中的配置示例:

concurrent = 1
check_interval = 30
[[runners]]
  name = "myRunner"
  url = "https://gitlab.example.com"
  token = "__REDACTED__"
  executor = "kubernetes"
  [runners.kubernetes]
    image = "alpine:latest"
    [runners.kubernetes.dns_config]
      nameservers = [
        "1.2.3.4",
      ]
      searches = [
        "ns1.svc.cluster-domain.example",
        "my.dns.search.suffix",
      ]

      [[runners.kubernetes.dns_config.options]]
        name = "ndots"
        value = "2"

      [[runners.kubernetes.dns_config.options]]
        name = "edns0"

KubernetesDNSConfigOption:

选项类型必须描述
name字符串配置选项名称。
value*string配置选项值。

kubesphere应用仓库中部署

  1. 添加仓库:https://charts.gitlab.io
  2. 修改values.yml
#以下两个在gitlab页面获取
gitlabUrl: http://192.168.31.3:83 # 使用k8s内部gitlab svc地址
runnerRegistrationToken: "GR1348941EfP6qKATzEULxDtvkvAg" #gitlab-runner注册用到的tocken

concurrent: 10 #最大作业并发数
checkInterval: 30 #新作业检查间隔
tags: "k8s" #runner的标签
#rbac权限打开
rbac:
  create: true
  resources: ["pods", "pods/exec", "secrets","configmaps"]
  verbs: ["get", "list", "watch", "create", "patch", "delete","update"]
runners:
  # 下述配置
  config: |
  1. 查看部署情况

在kubesphere应用仓库部署结果如下,部署到了ksnode26节点上:
image.png

  1. 使用特权模式:在创建容器时,使用–privileged参数来启动特权模式。这将使容器拥有更高的权限,并允许执行需要特权的操作。例如,使用docker run --privileged命令来启动容器。
  2. 允许特权提升:如果你不想在整个容器中启用特权模式,可以使用–cap-add参数来允许特定的权限提升。例如,使用docker run --cap-add=SYS_ADMIN命令来允许容器在运行时获取系统管理权限。
  3. 挂载可写目录:如果根目录是只读的,你可以尝试将一个可写的目录挂载到容器中,并在该目录中执行需要写入的操作。使用-v参数来挂载目录,例如,使用docker run -v /path/on/host:/path/in/container命令将主机上的目录挂载到容器中。

部署细节

部署后进入终端发现一些目录无操作权限,这是Docker容器的安全限制导致,可设置容器访问控制
image.png

启动命令
/usr/bin/dumb-init,--,/bin/bash,/configmaps/entrypoint

查看/configmaps:
image.png
这个命令是使用了/usr/bin/dumb-init作为初始进程,然后运行/bin/bash作为子进程,并将/configmaps/entrypoint作为参数传递给/bin/bash。

/usr/bin/dumb-init是一个轻量级的进程初始化器,它可以帮助正确处理子进程的信号和进程间通信。它在容器环境中经常被使用,以确保进程的正确启动和终止。

/bin/bash是一个常见的Unix和Linux系统中的命令解释器。它提供了一个交互式的命令行界面,可以运行命令和脚本,并提供了丰富的功能和工具集。

/configmaps/entrypoint是一个文件路径,它可能是一个配置映射(ConfigMap)中的入口点脚本。ConfigMap是Kubernetes中用于存储配置数据的一种资源类型。入口点脚本通常用于在容器启动时执行一些初始化操作或配置加载。

综合起来,这个命令的作用是使用dumb-init作为初始进程,启动一个bash子进程,并将/configmaps/entrypoint作为参数传递给bash。这可能是在容器环境中运行的一个脚本或配置文件的启动方式。具体的功能和目的需要查看/configmaps/entrypoint文件的内容来确定。

环境变量

image.png

CI_SERVER_URL:http://192.168.31.3:83/
RUNNER_EXECUTOR:kubernetes
REGISTER_LOCKED:true
RUNNER_TAG_LIST:k8s

挂载情况

image.png

config.toml

配置文件使用临时挂载,挂载路径/home/gitlab-runner/.gitlab-runner/config.toml,默认配置如下

concurrent = 10
check_interval = 30
log_level = "info"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "gitlab-k8s-runner-gitlab-runner-6fff86bf78-nbjrn"
  url = "http://192.168.31.3:83/"
  id = 7
  token = "HxBNrMvn89soRxaKiR4v"
  token_obtained_at = 2024-01-24T09:31:39Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "kubernetes"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.kubernetes]
    host = ""
    bearer_token_overwrite_allowed = false
    image = "alpine"
    namespace = "base"
    namespace_overwrite_allowed = ""
    node_selector_overwrite_allowed = ""
    pod_labels_overwrite_allowed = ""
    service_account_overwrite_allowed = ""
    pod_annotations_overwrite_allowed = ""
    [runners.kubernetes.pod_security_context]
    [runners.kubernetes.init_permissions_container_security_context]
    [runners.kubernetes.build_container_security_context]
    [runners.kubernetes.helper_container_security_context]
    [runners.kubernetes.service_container_security_context]
    [runners.kubernetes.volumes]
    [runners.kubernetes.dns_config]

/entrypoint文件

#!/bin/sh

# gitlab-runner data directory
DATA_DIR="/etc/gitlab-runner"
CONFIG_FILE=${CONFIG_FILE:-$DATA_DIR/config.toml}
# custom certificate authority path
CA_CERTIFICATES_PATH=${CA_CERTIFICATES_PATH:-$DATA_DIR/certs/ca.crt}
LOCAL_CA_PATH="/usr/local/share/ca-certificates/ca.crt"

update_ca() {
  echo "Updating CA certificates..."
  cp "${CA_CERTIFICATES_PATH}" "${LOCAL_CA_PATH}"
  update-ca-certificates --fresh >/dev/null
}

if [ -f "${CA_CERTIFICATES_PATH}" ]; then
  # update the ca if the custom ca is different than the current
  cmp -s "${CA_CERTIFICATES_PATH}" "${LOCAL_CA_PATH}" || update_ca
fi

# launch gitlab-runner passing all arguments
exec gitlab-runner "$@"

这个Shell脚本的作用是更新GitLab Runner的CA证书。
首先,它定义了一些变量:

  • DATA_DIR 变量设置为 /etc/gitlab-runner,表示GitLab Runner的数据目录。
  • CONFIG_FILE 变量使用了KaTeX parse error: Expected '}', got 'EOF' at end of input: {CONFIG_FILE:-DATA_DIR/config.toml}的语法,表示如果CONFIG_FILE变量未定义,则使用$DATA_DIR/config.toml作为默认值。
  • CA_CERTIFICATES_PATH 变量使用了KaTeX parse error: Expected '}', got 'EOF' at end of input: …IFICATES_PATH:-DATA_DIR/certs/ca.crt}的语法,表示如果CA_CERTIFICATES_PATH变量未定义,则使用$DATA_DIR/certs/ca.crt作为默认值。
  • LOCAL_CA_PATH 变量设置为 /usr/local/share/ca-certificates/ca.crt,表示本地系统中的CA证书路径。

接下来,脚本定义了一个名为 update_ca 的函数。该函数的作用是更新CA证书。它执行以下操作:

  • 打印消息 “Updating CA certificates…”。
  • 使用 cp 命令将 C A C E R T I F I C A T E S P A T H 的内容复制到 {CA_CERTIFICATES_PATH}的内容复制到 CACERTIFICATESPATH的内容复制到{LOCAL_CA_PATH}。
  • 使用 update-ca-certificates --fresh 命令更新系统的CA证书。

然后,脚本使用条件语句检查${CA_CERTIFICATES_PATH}文件是否存在。如果文件存在,则执行以下操作:

  • 使用 cmp 命令比较 C A C E R T I F I C A T E S P A T H 和 {CA_CERTIFICATES_PATH}和 CACERTIFICATESPATH{LOCAL_CA_PATH}的内容是否相同。如果不相同,则调用 update_ca 函数更新CA证书。

最后,脚本使用 exec 命令运行 gitlab-runner 命令,并将脚本的参数(“$@”)传递给 gitlab-runner 命令。这将启动GitLab Runner并执行相应的操作。

总体而言,这个脚本的目的是确保GitLab Runner的CA证书是最新的,并在启动GitLab Runner之前执行必要的更新操作。

/configmaps 目录

image.png

  • check-live
#!/bin/bash
set -eou pipefail

if ! /usr/bin/pgrep -f ".*register-the-runner"  > /dev/null && ! /usr/bin/pgrep -f "gitlab.*runner"  > /dev/null ; then
  exit 1
fi

name=$(awk -F'"' '/^  name = ".*"/ { print $2 }' "${HOME%/root}/.gitlab-runner/config.toml")
url=$(awk -F'"' '/^  url = ".*"/ { print $2 }' "${HOME%/root}/.gitlab-runner/config.toml")

gitlab-runner verify -n "$name" -u "$url" 2>&1 | grep -E "is alive|is valid"
  • config.template.toml
[[runners]]
  [runners.kubernetes]
    namespace = "base"
    image = "alpine"
  • config.toml
shutdown_timeout = 0
concurrent = 10
check_interval = 30
log_level = "info"
  • entrypoint
#!/bin/bash
set -e

export CONFIG_PATH_FOR_INIT="/home/gitlab-runner/.gitlab-runner/"
mkdir -p ${CONFIG_PATH_FOR_INIT}
cp /configmaps/config.toml ${CONFIG_PATH_FOR_INIT}

# Set up environment variables for cache
if [[ -f /secrets/accesskey && -f /secrets/secretkey ]]; then
  export CACHE_S3_ACCESS_KEY=$(cat /secrets/accesskey)
  export CACHE_S3_SECRET_KEY=$(cat /secrets/secretkey)
fi

if [[ -f /secrets/gcs-applicaton-credentials-file ]]; then
  export GOOGLE_APPLICATION_CREDENTIALS="/secrets/gcs-applicaton-credentials-file"
elif [[ -f /secrets/gcs-application-credentials-file ]]; then
  export GOOGLE_APPLICATION_CREDENTIALS="/secrets/gcs-application-credentials-file"
else
  if [[ -f /secrets/gcs-access-id && -f /secrets/gcs-private-key ]]; then
    export CACHE_GCS_ACCESS_ID=$(cat /secrets/gcs-access-id)
    # echo -e used to make private key multiline (in google json auth key private key is oneline with \n)
    export CACHE_GCS_PRIVATE_KEY=$(echo -e $(cat /secrets/gcs-private-key))
  fi
fi

if [[ -f /secrets/azure-account-name && -f /secrets/azure-account-key ]]; then
  export CACHE_AZURE_ACCOUNT_NAME=$(cat /secrets/azure-account-name)
  export CACHE_AZURE_ACCOUNT_KEY=$(cat /secrets/azure-account-key)
fi

if [[ -f /secrets/runner-registration-token ]]; then
  export REGISTRATION_TOKEN=$(cat /secrets/runner-registration-token)
fi

if [[ -f /secrets/runner-token ]]; then
  export CI_SERVER_TOKEN=$(cat /secrets/runner-token)
fi

# Register the runner
if ! sh /configmaps/register-the-runner; then
  exit 1
fi

# Run pre-entrypoint-script
if ! bash /configmaps/pre-entrypoint-script; then
  exit 1
fi

# Start the runner
exec /entrypoint run \
  --working-directory=/home/gitlab-runner

这个Shell脚本的作用是配置GitLab Runner的运行环境,并执行GitLab Runner的入口点命令。

首先,set -e 表示在脚本中如果有任何命令执行失败(返回非零退出码),则立即退出脚本。
接下来,脚本导出了一个名为 CONFIG_PATH_FOR_INIT 的环境变量,设置为 /home/gitlab-runner/.gitlab-runner/。然后使用 mkdir -p 命令创建了该路径。

然后,脚本使用 cp 命令将 /configmaps/config.toml 文件复制到 ${CONFIG_PATH_FOR_INIT} 目录中。

接下来,脚本使用条件语句检查一些文件是否存在。如果文件存在,则将其内容读取到相应的环境变量中。具体的环境变量如下:

  • CACHE_S3_ACCESS_KEY 和 CACHE_S3_SECRET_KEY:从 /secrets/accesskey 和 /secrets/secretkey 读取内容。
  • GOOGLE_APPLICATION_CREDENTIALS:从 /secrets/gcs-applicaton-credentials-file 或 /secrets/gcs-application-credentials-file 读取文件路径。
  • CACHE_GCS_ACCESS_ID 和 CACHE_GCS_PRIVATE_KEY:从 /secrets/gcs-access-id 和 /secrets/gcs-private-key 读取内容。
  • CACHE_AZURE_ACCOUNT_NAME 和 CACHE_AZURE_ACCOUNT_KEY:从 /secrets/azure-account-name 和 /secrets/azure-account-key 读取内容。
  • REGISTRATION_TOKEN:从 /secrets/runner-registration-token 读取内容。
  • CI_SERVER_TOKEN:从 /secrets/runner-token 读取内容。

然后,脚本分别执行 /configmaps/register-the-runner 和 /configmaps/pre-entrypoint-script 脚本。如果其中任何一个脚本执行失败(返回非零退出码),则脚本会退出并返回1。

最后,脚本使用 exec 命令执行 /entrypoint run 命令,并传递 --working-directory=/home/gitlab-runner 参数。这将启动GitLab Runner,并设置工作目录为 /home/gitlab-runner。

总体而言,这个脚本的目的是设置GitLab Runner的配置文件和环境变量,然后执行GitLab Runner的入口点命令以启动Runner。

  • pre-entrypoint-script

  • register-the-runner
#!/bin/bash
MAX_REGISTER_ATTEMPTS=30

# Reset/unset the not needed flags when an authentication token
RUN_UNTAGGED=""
ACCESS_LEVEL=""

for i in $(seq 1 "${MAX_REGISTER_ATTEMPTS}"); do
  echo "Registration attempt ${i} of ${MAX_REGISTER_ATTEMPTS}"
  /entrypoint register \
    ${RUN_UNTAGGED} \
    ${ACCESS_LEVEL} \
    --template-config /configmaps/config.template.toml \
    --non-interactive

  retval=$?

  if [ ${retval} = 0 ]; then
    break
  elif [ ${i} = ${MAX_REGISTER_ATTEMPTS} ]; then
    exit 1
  fi

  sleep 5
done

exit 0

/secrets

runner-token文件内容空
runner-registration-token文件内容:GR1348941EfP6qKATzEULxDtvkvAg

runner 默认配置问题

上述方式部署存在runner pod重启,config.toml配置被重置情况,原因在于下述启动命令中,/configmaps中的脚本。

/usr/bin/dumb-init,--,/bin/bash,/configmaps/entrypoint

/configmaps挂载为了ConfigMap,默认存在如下问题:

  1. 重启runner 后config.toml配置会被重置为初始配置
  2. 重启runner 后构建后的文件丢失
  3. 内网harbor域名解析问题

需修改ConfigMap下config.template.toml配置:
在这里插入图片描述
在这里插入图片描述

[[runners]]
  builds_dir = "/builds"
  [runners.kubernetes]
    namespace = "base"
    image = "alpine"
    pull_policy = "if-not-present"      # 拉取镜像策略,本地有是有本地无需拉取
    [[runners.kubernetes.volumes.pvc]]  # 挂载数据卷持久化
      name = "k8s-running-pod-data"
      mount_path = "/builds"
    [[runners.kubernetes.volumes.host_path]]  # 使用docker命令需要配置引擎
      name = "docker"
      mount_path = "/var/run/docker.sock"
      host_path = "/var/run/docker.sock"
    [[runners.kubernetes.host_aliases]]  # 用于解析内网中的harbor域名
      ip = "192.168.31.11"
      hostnames = ["harbor域名"]
    [[runners.kubernetes.host_aliases]]  # 用于解析k8s集群中Kubernetes API Server 的地址
      ip = "192.168.31.21"               # k8s集群master ip
      hostnames = ["lb.kubesphere.local"]

最后生成config.toml 配置如下

runner注册配置可直接修改config.toml 配置文件,无需重启即可生效

concurrent = 10
check_interval = 30
log_level = "info"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "k8s-gitlab-runner-gitlab-runner-58cbcc57d5-8kbfz"
  url = "http://192.168.31.3:83"
  id = 65
  token = "Qvdu1hpsUpYNa3dzrjqP"
  token_obtained_at = 2024-01-29T05:21:04Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "kubernetes"
  builds_dir = "/builds"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.kubernetes]
    host = ""
    bearer_token_overwrite_allowed = false
    image = "alpine"
    namespace = "base"
    namespace_overwrite_allowed = ""
    pull_policy = ["if-not-present"]
    node_selector_overwrite_allowed = ""
    pod_labels_overwrite_allowed = ""
    service_account_overwrite_allowed = ""
    pod_annotations_overwrite_allowed = ""
    [runners.kubernetes.pod_security_context]
    [runners.kubernetes.init_permissions_container_security_context]
    [runners.kubernetes.build_container_security_context]
    [runners.kubernetes.helper_container_security_context]
    [runners.kubernetes.service_container_security_context]
    [runners.kubernetes.volumes]

      [[runners.kubernetes.volumes.host_path]]
        name = "docker"
        mount_path = "/var/run/docker.sock"
        host_path = "/var/run/docker.sock"

      [[runners.kubernetes.volumes.pvc]]
        name = "k8s-running-pod-data"
        mount_path = "/builds"

    [[runners.kubernetes.host_aliases]]
      ip = "192.168.31.11"
      hostnames = ["harbor域名"]

    [[runners.kubernetes.host_aliases]]
      ip = "192.168.31.21"
      hostnames = ["lb.kubesphere.local"]
    [runners.kubernetes.dns_config]
  • 39
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值