千家信息网

如何在Kubernetes上安装和使用Jenkins?

发表于:2024-11-27 作者:千家信息网编辑
千家信息网最后更新 2024年11月27日,如何在Kubernetes上安装Jenkins首先,我们需要安装Helm,它是Kubernetes的软件包管理器:$ curl https://raw.githubusercontent.com/he
千家信息网最后更新 2024年11月27日如何在Kubernetes上安装和使用Jenkins?

如何在Kubernetes上安装Jenkins

首先,我们需要安装Helm,它是Kubernetes的软件包管理器:

$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh$ chmod 700 get_helm.sh$ ./get_helm.sh -v v2.15.0


同样,我们还需要安装Tiller,以让Helm正常运行:

$ kubectl -n kube-system create serviceaccount tillerserviceaccount/tiller created~/.kube$ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tillerclusterrolebinding.rbac.authorization.k8s.io/tiller created~/.kube$ helm init --service-account tiller$HELM_HOME has been configured at /Users/itspare/.helm.


完成这些步骤之后,我们需要运行检查命令,以查看deployment的配置值:

$ helm inspect values stable/jenkins > values.yml


仔细检查配置值并在需要的时候进行更改。然后安装Chart:

$ helm install stable/jenkins --tls \--name jenkins \--namespace jenkins


安装过程中会有一些关于下一步操作的说明:

注意:

  1. 运行以下命令获取"admin"用户的密码:
    printf $(kubectl get secret --namespace default my-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
  2. 在相同的shell中获取Jenkins URL以访问这些命令:
    export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/component=jenkins-master" -l "app.kubernetes.io/instance=my-jenkins" -o jsonpath="{.items[0].metadata.name}")echo http://127.0.0.1:8080kubectl --namespace default port-forward $POD_NAME 8080:8080


    遵循这些步骤,它们将在http://127.0.0.1:8080 启动代理服务器。

到那里输入你的用户名和密码。你将会拥有自己的Jenkins 服务器:



不过,请记住,还有许多配置选项尚未修改

在默认情况下,服务器会安装好最基本的插件,如Git和Kubernetes-Jenkins,我们可以根据自己的需要安装其他插件。

总而言之,使用Helm安装Jenkins十分轻松。

使用K8S扩展CI/CD Jenkins流水线

既然我们已经大致了解CI/CD如何在Kubernetes上运行的,那么我们来看一个在Kubernetes中部署高度可扩展的Jenkins部署的示例用例。人们通常用它(进行了少量修改)来处理基础结构的CI/CD,开始吧!

使用Jenkins固定发行版

虽然官方Jenkins镜像很适合入门,但它需要的配置超出了我们的期望。许多用户会选择一个固定的发行版,如my-bloody-jenkins(https://github.com/odavid/my-bloody-jenkins ),它提供了一个较为完整的预安装插件以及配置选项。在可用的插件中,我们使用saml插件、SonarQubeRunner、Maven和Gradle。

它能够使用以下命令通过Helm Chart安装:

$ helm repo add odavid https://odavid.github.io/k8s-helm-charts$ helm install odavid/my-bloody-jenkins


我们选择使用以下Dockerfile部署自定义镜像:

FROM odavid/my-bloody-jenkins:2.190.2-161USER jenkinsCOPY plugins.txt /usr/share/jenkins/ref/RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txtUSER root


其中plugins.txt文件是我们要预安装到镜像中的其他插件列表:

build-monitor-pluginxcode-pluginrich-text-publisher-pluginjacocoscoveragedependency-check-jenkins-plugingreenballsshiningpandapyenv-pipelines3pipeline-awsappcentermultiple-scmsTestng-plugin


然后,只要dockerfile发生更改,我们就使用此通用Jenkinsfile来构建master:

#!/usr/bin/env groovynode('generic') {try {def dockerTag, jenkins_masterstage('Checkout') {checkout([$class: 'GitSCM',branches: scm.branches,doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,extensions: [[$class: 'CloneOption', noTags: false, shallow: false, depth: 0, reference: '']],userRemoteConfigs: scm.userRemoteConfigs,])def version = sh(returnStdout: true, script: "git describe --tags `git rev-list --tags --max-count=1`").trim()def tag = sh(returnStdout: true, script: "git rev-parse --short HEAD").trim()dockerTag = version + "-" + tagprintln("Tag: " + tag + " Version: " + version)}stage('Build Master') {jenkins_master = docker.build("jenkins-master", "--network=host .")}stage('Push images') {docker.withRegistry("https://$env.DOCKER_REGISTRY", 'ecr:eu-west-2:jenkins-aws-credentials') {jenkins_master.push("${dockerTag}")}}if(env.BRANCH_NAME == 'master') {stage('Push Latest images') {docker.withRegistry("https://$env.DOCKER_REGISTRY", 'ecr:eu-west-2:jenkins-aws-credentials') {jenkins_master.push("latest")}}stage('Deploy to K8s cluster') {withKubeConfig([credentialsId: 'dev-tools-eks-jenkins-secret',serverUrl: env.TOOLS_EKS_URL]) {sh "kubectl set image statefulset jenkins jenkins=$env.DOCKER_REGISTRY/jenkins-master:${dockerTag}"}}}currentBuild.result = 'SUCCESS'} catch(e) {currentBuild.result = 'FAILURE'throw e}}


我们所使用的专用集群由AWS中的一些大中型实例组成,用于Jenkins jobs。接下来,我们进入下一个部分。

使用专用的Jenkins Slaves和标签(label)

为了扩展我们的一些Jenkins slaves,我们使用Pod模板并将标签分配给特定的agent。因此在我们的Jenkinsfiles中,我们可以为jobs引用它们。例如,我们有一些需要构建安卓应用程序的agent。因此,我们引用以下标签:

pipeline {agent { label "android" }…


并且将使用特定于安卓的pod模板。我们使用这一Dockerfile,例如:

FROM dkr.ecr.eu-west-2.amazonaws.com/jenkins-jnlp-slave:latestRUN apt-get update && apt-get install -y -f --no-install-recommends xmlstarletARG GULP_VERSION=4.0.0ARG CORDOVA_VERSION=8.0.0# SDK version and build-tools version should be differentENV SDK_VERSION 25.2.3ENV BUILD_TOOLS_VERSION 26.0.2ENV SDK_CHECKSUM 1b35bcb94e9a686dff6460c8bca903aa0281c6696001067f34ec00093145b560ENV ANDROID_HOME /opt/android-sdkENV SDK_UPDATE tools,platform-tools,build-tools-25.0.2,android-25,android-24,android-23,android-22,android-21,sys-img-armeabi-v7a-android-26,sys-img-x86-android-23ENV LD_LIBRARY_PATH ${ANDROID_HOME}/tools/lib64/qt:${ANDROID_HOME}/tools/lib/libQt5:$LD_LIBRARY_PATH/ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-toolsRUN curl -SLO "https://dl.google.com/android/repository/tools_r${SDK_VERSION}-linux.zip" \&& echo "${SDK_CHECKSUM} tools_r${SDK_VERSION}-linux.zip" | sha256sum -c - \&& mkdir -p "${ANDROID_HOME}" \&& unzip -qq "tools_r${SDK_VERSION}-linux.zip" -d "${ANDROID_HOME}" \&& rm -Rf "tools_r${SDK_VERSION}-linux.zip" \&& echo y | ${ANDROID_HOME}/tools/android update sdk --filter ${SDK_UPDATE} --all --no-ui --force \&& mkdir -p ${ANDROID_HOME}/tools/keymaps \&& touch ${ANDROID_HOME}/tools/keymaps/en-us \&& yes | ${ANDROID_HOME}/tools/bin/sdkmanager --updateRUN chmod -R 777 ${ANDROID_HOME} && chown -R jenkins:jenkins ${ANDROID_HOME}


我们还使用了Jenkinsfile,该文件与上一个文件类似,用于构建master。每当我们对Dockerfile进行更改时,agent都会重建镜像。这为我们的CI/CD基础架构提供了极大的灵活性。

使用自动伸缩

尽管我们为deployment分配了特定数量的节点,但我们还可以通过启用cluster autoscaling,来完成更多的事情。这意味着在工作负载增加和峰值的情况下,我们可以增加额外的节点来处理job。目前,如果我们有固定数量的节点,那么我们只能处理固定数量的job。基于以下事实,我们可以进行粗略地估计:每个slave通常分配500ms CPU和256MB内存,并且设置一个很高的并发。这根本不现实。

举个例子,当你的版本被大幅削减并且需要部署大量微服务时,可能会发生上述情况。然后,大量的job堆积在流水线,造成严重的延误。

在这种情况下,我们可以增加该阶段的节点数。例如,我们可以添加额外的VM实例,然后在过程结束时将其删除。

我们可以在命令行中使用自动伸缩选项来配置"Vertical"或"集群"自动伸缩选项。但是,此方法需要仔细计划和配置,因为有时会发生以下情况:

  1. 越来越多的job达到平稳阶段

  2. Autoscaler增加新的节点,但是需要10分钟来进行部署和分配

  3. 旧的job已经完成任务,新的job将填补空白,进而减少了对新节点的需求

  4. 新节点可用,但需要X分钟保持稳定且未利用,X由-scale-down-unneeded-time标志定义

  5. 同样的事情每天发生很多次

在这种情况下,最好是根据我们的特定需求进行配置,或者只是增加当天的节点数,并在流程结束后将其还原。所有这些都与寻找最佳方法来利用所有资源并使成本最小化有关。

在任何情况下,我们都应该有一个可伸缩且易于使用的Jenkins集群。对于每个job,都会创建一个pod来运行特定的流水线,并在完成后将其销毁

0