在Kubernetes上配置使用docker client的Jenkins代理

108次阅读
没有评论

问题描述

在Kubernetes集群上使用官方Helm Chart安装了Jenkins,并且该集群使用containerd作为容器运行时。用户希望配置容器化的代理(agent),这些代理需要能够运行docker client命令,例如用于构建Docker镜像。但是在Kubernetes节点上并没有docker守护进程。用户想知道是否有一种选项,可以使用containerd客户端与节点上的containerd服务器进行交互,就像容器内的docker client与节点上运行的docker守护进程交互一样。此外,用户还在考虑以下两种选项来配置Jenkins代理:

  1. 在容器中运行docker守护进程(docker daemon in docker)。
  2. 使用sysbox容器,其中包含docker守护进程。

用户想了解最佳实践是什么。

解决方案

请注意以下操作可能涉及版本差异,请确保备份数据,并了解所使用的工具及其适用性。

使用Kaniko构建Docker镜像

一种绕过问题的方式是使用Kaniko,它可以在不需要docker守护进程或套接字的情况下处理容器的构建(以及推送)部分。

以下是在K8s的Jenkins Helm Chart的values.yaml中定义代理(agent)的一部分示例:

agent:
  namespace: jenkins
  podTemplates:
    builder: |
    - name: 'builder'
      label: 'builder'
      serviceAccount: jenkins
      nodeUsageMode: EXCLUSIVE
      yamlMergeStrategy: "merge"
      yaml: |-
        apiVersion: v1
        kind: Pod
        metadata:
          name: builder
          namespace: jenkins
        spec:
          serviceAccountName: jenkins
          containers:
          - name: builder
            image: builder:latest
            imagePullPolicy: IfNotPresent
            command: ["sleep"]
            args: ["99d"]
            tty: true
            resources:
              requests:
                cpu: 1
                memory: 1Gi
              limits:
                cpu: 2
                memory: 2Gi
            workingDir: /home/jenkins/agent
          - name: kaniko
            image: gcr.io/kaniko-project/executor:debug
            imagePullPolicy: IfNotPresent
            command: ["sleep"]
            args: ["99d"]
            tty: true
            volumeMounts:
            - name: docker-config
              mountPath: /kaniko/.docker
            workingDir: /home/jenkins/agent
            env:
            - name: DOCKER_REPOSITORY
              value: "private_docker_repository"
          volumes:
          - name: docker-config
            configMap:
              name: docker-config

在上面的示例中,我们定义了两个容器:builderkanikobuilder容器负责执行一些基本操作,而kaniko容器负责构建Docker镜像。我们通过将docker-config挂载到kaniko容器来处理Docker的授权,确保Kaniko能够访问所需的Docker仓库。

要在Jenkinsfile中使用这些代理,可以按以下方式操作:

pipeline {
  agent {
    label 'builder' // 指的是在Jenkins Helm Chart的values.yaml中定义的自定义K8s Pod Template
  }
  environment {
    RELEASE_TAG = "1.0.0"
  }
  stages {
    stage('Build') {
      steps {
        container('builder') {
          echo "执行Maven构建或其他所需步骤"
        }
        container('kaniko') {
          sh "/kaniko/executor --dockerfile `pwd`/dockerfile --context `pwd` --destination=${DOCKER_REPOSITORY}:${RELEASE_TAG}"
        }
      }
    }
  }
}

使用Docker守护进程(Docker Daemon in Docker)

另一种方法是在一个长时间运行的Pod中运行Docker守护进程,并在需要时启动具有docker client的Jenkins代理。这些代理可以与容器化的Docker守护进程进行交互。

用户可以使用类似以下脚本的方式来实现:

#!/bin/bash
# 启动Docker守护进程的容器
docker run -d --name docker_daemon_container docker:latest
# 启动具有docker client的Jenkins代理
docker run -d --name jenkins_agent --link docker_daemon_container -e DOCKER_HOST=tcp://docker_daemon_container:2375 jenkins/agent

上面的脚本中,我们首先启动了一个包含Docker守护进程的容器,并将其命名为docker_daemon_container。然后,我们启动了一个Jenkins代理容器,并使用环境变量DOCKER_HOST指定了与docker_daemon_container容器的连接。

使用sysbox容器

用户还提到了使用sysbox容器,这是另一种在容器中运行Docker守护进程的方法。这是一个可行的解决方案,但具体的实现细节可能与Kubernetes版本、sysbox的版本以及其他因素有关。用户应该查看sysbox的文档以了解如何在Kubernetes中使用它来运行Jenkins代理。

无论选择哪种方式,都需要根据具体情况进行适当的配置和测试。并且请确保理解所使用的工具及其适用性,并对您的环境和需求进行适当的调整。

最佳实践选择

根据用户提供的信息以及回复,使用Kaniko构建Docker镜像是一种可靠的方法,无需在Kubernetes节点上运行docker守护进程,同时具有良好的控制和安全性。这在许多Kubernetes环境中是常见的做法,特别是在没有docker守护进程的情况下。这种方法可以避免直接在Kubernetes集群

正文完