Jenkins+k8s实现自动化部署

前言

jenkins是现下比较主流的CI/CD工具,Kubernetes也是现在非常流行的编排工具,这两个在devops中占据了非常重要的地位,那么在devops中,如何将两者结合起来呢?

环境配置

名称 版本 地址
Kubernetes v1.20.5 192.168.0.104:6443
Gitlab 13.11.3 192.168.0.102:13080
Harbor v2.1.5 192.168.0.102:1080
Jenkins 2.277.3 192.168.0.102:8081
kuboard v3.1.1.4 192.168.0.102:8080

组件说明

  • Harbor

Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。

  • kuboard

kuboard是一个可视化的kubernets管理web页面,包含的功能挺丰富的,可以很好的,有效的管理kubernets集群

PS:各个组件的安装我就不做说明了,毕竟这些在网上都能搜索到。

Jenkins配置

插件安装

调整插件升级站点 (提高插件下载速度)

安装Kubernetes需要的插件

  • Kubernetes :: Pipeline :: DevOps Steps
  • Kubernetes CLI Plugin
  • Kubernetes plugin
  • Kubernetes Credentials Plugin

安装gitlab需要的插件

  • GitLab Plugin
  • Generic Webhook Trigger Plugin

安装完后记得重启

Jenkins配置Kubernetes集群

首先添加k8s集群凭据

  • 系统管理->Manage Credentials->Jenkins->全局凭据->添加凭据
    image.png
    image.png

    • 字段说明:
      • Secret:k8s凭据,也叫k8s-token
        • 获取token,在k8s集群中执行
            // 1. 创建serverAccount
            kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=tools:default
            // 2. 获取serverAccountToken
            kubectl -n tools describe secret $(kubectl -n tools get secret | grep default | awk '{print $1}')
        复制代码
        • 将获取到的token复制到凭据中

配置k8s集群信息

  • 进入系统管理->节点管理->configureClouds
  • Add a new cloud选择Kubernets
    image.png
    image.png

    • 主要配置字段说明:
      • Kubernetes 地址

        Kubernetes中Api-server的地址,具体可以通过cat ~/.kube/config来进行查看

      • Kubernetes 命名空间

        jenkins-agent的pod默认执行的命名空间。

      • 凭据

        用于访问Kubernetes集群的凭据,选择上面添加到凭据

      • Jenkins 地址

        是Jenkins-agent在启动时回调的地址,如果填写错误,则会出现重复创建pod的情况

    • 配置完毕后点击【连接测试】
      image.png
      出现如图所示表示成功。

测试构建

  • 新建一个流水线任务
    image.png

  • 编写pipeline语法

    def label = "mypod-${UUID.randomUUID().toString()}"
    podTemplate(label: label, cloud: 'myk8s') {
        node(label) {
            stage('Run shell') {
                sh 'sleep 100s'
                sh 'echo hello world.'
            }
        }
    }
复制代码
  • 保存,并构建测试,并查看构建日志
    image.png
  • 在k8s集群中也可以看到对应的pod
    image.png

Jenkins配置harbor秘钥

  • 系统管理->Manage Credentials->Jenkins->全局凭据->添加凭据
  • 选择Username with password
    image.png
  • 点击保存,待会儿在Jenkinsfile中会用上.

Jekins配置Gitlab访问

  • 第一步:先获取Gitlab访问令牌
    image.png
    image.png

  • 第二步:在Jenkins中添加Gitlab访问令牌
    image.png

  • 第二步:配置Jenkins中的Gitlab配置

    • 系统管理->系统配置->gitlab
      image.png

创建测试任务

  • 新建流水线任务
    image.png

  • 配置任务

    • 构建触发器,这里是在git提交时可以自动触发构建的配置
      image.png
      image.png
    • 配置流水线,选择pipeline script from SCM
      image.png
  • Jenkinsfile脚本编写

// 定义Jenkins-agent在k8s中的pod名称,不要重名
def label = "build-testserverone-${UUID.randomUUID().toString()}"
podTemplate(
    cloud: "myk8s",
    namespace: "tools",
    label: label,
    // 配置容器信息
    containers: [
        containerTemplate(
            name: "jnlp",
            image: "${HARBOR_REG}/jenkins/k8s-agent:1.0.1"
        ),
    ],
    // 挂载,主要是为了使用宿主机的docker
    volumes: [
        hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
        hostPathVolume(mountPath: '/usr/bin/docker', hostPath: '/usr/bin/docker'),
        hostPathVolume(mountPath: '/root/.m2', hostPath: '/root/.m2')
    ]
) {
    node(label) {
        // 拉取代码
        stage("clone") {
            checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'jenkinsgitlab', url: 'ssh://git@192.168.0.102:13022/istiodemo/testserverone.git']]])
        }

        // 构建镜像
        stage("build") {
            echo "开始构建docker镜像"
            sh "docker build -t ${HARBOR_REG}/istio-demo/testserverone:${env.BUILD_TIMESTAMP} ."
            echo "构建结束"
        }
        // 上传镜像到私有镜像库
        stage("publish") {
            // 获取harbor的用户命和密码
            withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'HARBOR_SECRET_PSW', usernameVariable: 'HARBOR_SECRET_USR')]) {
                echo "开始推送镜像"
                sh "docker login -u ${HARBOR_SECRET_USR} -p ${HARBOR_SECRET_PSW} http://${HARBOR_REG}"
                sh "docker push ${HARBOR_REG}/istio-demo/testserverone:${env.BUILD_TIMESTAMP}"
                sh "docker rmi ${HARBOR_REG}/istio-demo/testserverone:${env.BUILD_TIMESTAMP}"
                echo "推送结束"
            }
        }
        // 进行k8s发布
        stage("deploy") {
            dir('deploy') {
                def image_name = "${HARBOR_REG}\\/istio-demo\\/testserverone:${env.BUILD_TIMESTAMP}"
                echo "替换image路径"
                sh """
                sed -i 's/IMAGE_PATH/${image_name}/g' deployment.yaml
                """
                echo "部署app"
                sh "kubectl apply -f deployment.yaml"
                echo "部署service"
                sh "kubectl apply -f service.yaml"
                echo "部署ingress"
                sh "kubectl apply -f ingress.yaml"
                echo "部署结束"
            }
        }
    }
}
复制代码
  • 在使用时需要注意,Jenkins-agent在启动时,默认用的是jenkins/inbound-agent这个镜像,但是这个镜像将用户设置为了Jenkins,当我们宿主机的docker是用root启动时,会提示docker没有权限,所以我重新构建了这个镜像,并将k8s相关命名打包进去。DOCKERFILE如下
    FROM jenkins/inbound-agent:4.7-1-alpine
    # 修改为root用户启动
    USER root

    ARG KUBECTL_VERSION=1.17.5
    ARG KUSTOMIZE_VERSION=v3.8.1
    ARG KUBESEAL_VERSION=v0.15.0

    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

    RUN apk add curl

    # Install kubectl (same version of aws esk)
    RUN curl -sLO https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl && \
        mv kubectl /usr/bin/kubectl && \
        chmod +x /usr/bin/kubectl

    # Install kustomize (latest release)
    RUN curl -sLO https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz && \
        tar xvzf kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz && \
        mv kustomize /usr/bin/kustomize && \
        chmod +x /usr/bin/kustomize

    # Install kubeseal
    RUN curl -sL https://github.com/bitnami-labs/sealed-secrets/releases/download/${KUBESEAL_VERSION}/kubeseal-linux-amd64 -o kubeseal && \
        mv kubeseal /usr/bin/kubeseal && \
        chmod +x /usr/bin/kubeseal

    ENTRYPOINT ["/usr/local/bin/jenkins-agent"]
复制代码
  • Gitlab hook配置
    image.png
    image.png

  • 构建测试
    image.png

  • Gitlab推送构建测试
    image.png
    image.png
    image.png

总结

在自己进行配置的时候,很多配置去查资料的时候,都写的很模糊,需要靠猜测,所以自己整理了一下在搭建过程中的一些配置,并记录下来吗,方便下次搭建时使用。

此篇文章重点在于Jenkins和k8s的结合配置,希望对看到这篇文章的同学有所帮助。