目录

  • 1. Kubesphere开启Devops
  • 2. Kubesphere基础环境设置
  • 3. Devops项目添加凭证
  • 3.1 Git代码库凭证
  • 3.2 Docker镜像仓库凭证
  • 3.3 K8s配置凭证
  • 4. Jenkins Worker自定义maven配置
  • 5. K8s集群添加Docker镜像拉取密钥
  • 6. 代码仓库添加devops相关脚本
  • 7. 创建流水线
  • 8. 运行流水线
  • 9. 检验构建效果
  • 待续


1. Kubesphere开启Devops

注:
关于Kubesphere及K8S的搭建可参见我之前的博客:
Kubesphere All-in-one模式安装

方式1:未安装KS前进行设置
在安装KS前,可通过编辑config-sample.yaml文件,设置如下:

devops:
  enabled: true # 将“false”更改为“true”。

然后通过如下命令安装KS:

./kk create cluster -f config-sample.yaml

方式2:已安装过KS通过管理界面进行设置
若之前已安装过KS,则可通过KS管理界面左侧菜单CRD -> 搜索clusterconfiguration -> 然后编辑其下资源ks-installer,如下图:

kubesphere创建流水线显示已弃用 kubesphere 流水线_devops


同样设置devops.enabled为true:

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_02


Kubesphere Devops详细开启说明可参见:

https://kubesphere.io/zh/docs/pluggable-components/devops/设置完成后可通过KS管理界面查看系统组件 - DevOps相关资源是否已安装完成,如下图:

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_03

2. Kubesphere基础环境设置

企业空间:作为管理项目、DevOps 项目和组织成员的基本逻辑单元,企业空间是 KubeSphere 多租户系统的基础。
项目:KubeSphere 中的项目与 Kubernetes 中的命名空间相同,为资源提供了虚拟隔离。
Devops项目:不同权限的租户可以在 DevOps 项目中执行各种任务,包括创建 CI/CD 流水线凭证以及管理帐户角色
流水线:一系列插件的集合,使您可以持续地测试和构建代码。流水线将持续集成 (CI) 和持续交付 (CD) 进行结合,提供精简的工作流,使您的代码可以自动交付给任何目标。
凭证:具有所需权限的 DevOps 项目用户可以为流水线配置凭证,以便与外部环境进行交互。用户在 DevOps 项目中添加凭证后,DevOps 项目就可以使用这些凭证与第三方应用程序(例如 GitHub、GitLab 和 Docker Hub)进行交互。

整体环境设置及如下:

  • 企业空间:luo-dev
  • 项目:ks-devops-demo
  • Devops项目:luo-devops
  • 流水线:ks-devops-demo

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_04

3. Devops项目添加凭证

后续在使用流水线时,Jenkins pipeline脚本需要与外部Git仓库、Docker仓库、K8s集群进行交互,所以需要在其对应的Devops项目中添加凭证(用于访问外部环境的账号密码、密钥等),后续在Jenkins pipeline脚本中会通过凭证名称(ID)进行引用。
测试环境的外部依赖如下:

依赖

来源

凭证信息

Git代码仓库

Gitee

代码地址:https://gitee.com/luoex/ks-devops-demo

Gitee登录账号密码

Docker镜像仓库

阿里云容器镜像服务ACR - 个人版(免费版)

限额:3命名空间,300个仓库

公网地址:registry.cn-shanghai.aliyuncs.com

命名空间:luo_dev

仓库名称:ks-devops-demo

ACR docker login账号密码

K8s集群

当前Kubesphere所在K8s集群

当前K8s集群的kubeconfig文件

对应上述依赖,在luo-devops项目下新建如下3个凭证:

凭证名称(ID)

凭证类型

凭证说明

gittee-luo

用户名和密码

Gitee登录账号密码,

用于流水线拉取代码

docker-aliyun-acr

用户名和密码

阿里云容器镜像服务ACR个人版 docker login账号密码,

用于Jenkins脚本推送docker镜像

k8s-config-ks

kubeconfig

当前K8s集群的kubeconfig文件(新建时默认填充),

用于Jenkins脚本部署K8s应用负载

具体凭证列表如下图:

kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_05

3.1 Git代码库凭证

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_06

除了使用用户名和密码类型,还可以使用SSH密钥类型,具体设置方式可参见:
生成SSH密钥对(与gitlab、jenkins集成)

3.2 Docker镜像仓库凭证

kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_07

阿里云ACR docker login账号密码获取参见下图:

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_08

3.3 K8s配置凭证

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_09

4. Jenkins Worker自定义maven配置

Kubesphere流水线采用Jenkins进行构建,在构建过程中Jenkins会在创建worker实例去执行具体的构建,如下图为maven构建worker实例:

kubesphere创建流水线显示已弃用 kubesphere 流水线_devops_10


此Pod的详细配置如下:

kubesphere创建流水线显示已弃用 kubesphere 流水线_devops_11

查看Pod定义可以发现,可通过修改:
kubesphere-devops-worker命名空间下
ks-devops-agent配置(ConfigMap)中的MavenSetting
来设置自定义的Maven私服配置,
可直接通过如下命令查看对应配置:

kubectl get cm -n kubesphere-devops-worker ks-devops-agent -o yaml

通过配置自定义Maven私服可以:

  • 加速依赖下载
  • 支持企业内部Depoly代码包

本例中使用的Maven仓库为阿里云 - 云效 - 制品仓库 - Maven仓库(免费版),懒得自己再搭建一个Nexus私服,仅处于测试目的直接使用免费版比较方便,实际企业使用时或者为公有云、或者为企业内部自建Nexus私服等。

自定义maven settings.xml配置可参见如下截图:

kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_12

kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_13

kubesphere创建流水线显示已弃用 kubesphere 流水线_devops_14


关于此Maven settings.xml文件的编写,可结合具体Maven私服地址及账号进行编写,

在阿里云中的Maven仓库支持一键下载:

kubesphere创建流水线显示已弃用 kubesphere 流水线_流水线_15

5. K8s集群添加Docker镜像拉取密钥

在通过docker pull拉取镜像时,需先通过docker login进行登录,而在K8S集群中可通过为Deployment设置imagePullSecrets达到类似的登录效果,避免拉取Docker镜像失败。

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      imagePullSecrets:
        # 通过同K8s namespace的密钥secret名称来指定镜像仓库及凭证信息
        - name: docker-aliyun-acr
      containers:
        - name: app
          ...

进入Kubesphere保密字典管理页面:

kubesphere创建流水线显示已弃用 kubesphere 流水线_devops_16

创建阿里云ACR镜像仓库密钥docker-aliyun-acr:

kubesphere创建流水线显示已弃用 kubesphere 流水线_devops_17

注:
此处的docker仓库地址即为之前提到的阿里云ACR地址相同,
账号密码也和前文提到的ACR账号密码相同(即对应docker-aliyun-acr凭证),
此处的密钥docker-aliyun-acr用于K8s集群节点拉取镜像,
而前文的Devops项目凭证docker-aliyun-acr用于Jenkins脚本(即Jenkins工作实例)操作docker镜像。

6. 代码仓库添加devops相关脚本

示例中使用的Gitee代码库ks-devops-demo为一个简单的Spring Boot Web应用,仅提供一个Hello接口,具体项目中可根据需求自行替换为对应实现,该示例的重点是根路径devops目录下的相关脚本:

资源文件

说明

/devops/Jenkinsfile

Jenkins流水线脚本

/devops/Dockerfile

Docker镜像构建文件

/deploy/k8s.yaml

K8S应用负载定义

kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_18


其中devops/Dockerfile用来给示例Java应用构建Docker镜像:

# 基础JDK镜像
FROM openjdk:11.0.6-jdk-slim-buster
# 维护者
MAINTAINER luo.hq <luohengquan@yeah.net>
# 环境变量设置
ENV TZ "Asia/Shanghai"
ENV JVM_OPTIONS ""
# 拷贝maven构建后的jar包到镜像内/app.jar
ADD /target/*.jar /app.jar
# 暴露端口
EXPOSE 8080
# 启动命令 - 执行Jar
ENTRYPOINT ["sh", "-c", "java ${JVM_OPTIONS} -jar /app.jar"]

devops/k8s.yaml为示例应用对应的K8S部署脚本(Deployment、Service):

注: 可根据具体部署需要进行调整

# K8S服务定义
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ks-devops-demo
    version: v1
  name: ks-devops-demo
spec:
  # 使用NodePort类型(替换默认ClusterIP,便于测试)
  type: NodePort
  sessionAffinity: None
  selector:
    app: ks-devops-demo
    version: v1
  ports:
    - name: http-web
      protocol: TCP
      port: 8080
      targetPort: 8080
---
# K8S工作负载定义
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ks-devops-demo
    version: v1
  name: ks-devops-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ks-devops-demo
      version: v1
  template:
    metadata:
      labels:
        app: ks-devops-demo
        version: v1
    spec:
      # 设置Docker仓库密钥(用于拉取镜像)
      # 通过同K8s namespace的密钥secret名称来指定镜像仓库及凭证信息
      imagePullSecrets:
        - name: docker-aliyun-acr
      containers:
        - name: app
          # 设置Docker镜像(同Jenkinsfile脚本中的环境变量)
          image: $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$APP_NAME:$IMAGE_TAG
          imagePullPolicy: Always
          # 资源限制
          resources:
            requests:
              cpu: 10m
              memory: 128Mi
            limits:
              cpu: '1'
              memory: 1000Mi
          # 健康检查
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /actuator/health
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 60
            successThreshold: 1
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 20
            successThreshold: 1
            failureThreshold: 3
          # 容器端口映射
          ports:
            - name: http-web
              protocol: TCP
              containerPort: 8080
  strategy:
    # 滚动更新策略
    type: RollingUpdate
    rollingUpdate:
      # 最多不可用比例
      maxUnavailable: 25%
      # 最多新增比例
      maxSurge: 25%

devops/Jenkinsfile为Jenkins流水线的核心构建脚本,用来编排整个流水线的执行过程:
generate tag -> maven build -> docker build & push -> k8s deploy 并将之前的devops/Dockerfiledevops/k8s.yaml串联起来:

pipeline{

  agent {
    node {
      //选择Jenkins agent工作节点
      //支持label值:maven | nodejs | go
      //具体参见:https://kubesphere.io/zh/docs/devops-user-guide/how-to-use/choose-jenkins-agent/
      label 'maven'
    }
  }

  //环境变量设置
  environment {
       //Docker凭证ID
       DOCKER_CREDENTIAL_ID = 'docker-aliyun-acr'
       //Docker仓库地址
       DOCKER_REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
       //Docker仓库命名空间
       DOCKER_NAMESPACE = 'luo_dev'
       //应用名称(即Docker镜像名称)
       APP_NAME = 'ks-devops-demo'
       //K8S配置凭证ID
       K8S_CONFIG_CREDENTIAL_ID = 'k8s-config-ks'
       //K8S部署命名空间(对应Kubesphere项目)
       K8S_NAMESPACE = 'ks-devops-demo'
  }

  //构建阶段
  stages {

    //生成镜像版本
    stage('generate tag') {
        steps {
            script {
                //commitId.buildNum
                env.COMMIT_ID = sh(script: 'git rev-parse  --short HEAD ', returnStdout: true).trim()
                env.IMAGE_TAG = "${COMMIT_ID}.$BUILD_NUMBER"
                }
            }
    }

    //maven构建
    stage('maven build') {
        steps {
          container ('maven') {
             //maven打包(生产环境建议支持test)
             sh 'mvn clean package -Dmaven.test.skip=true'
             //归档文件(若不需要可无需归档)
             archiveArtifacts 'target/*.jar'
          }
        }
    }

    //构建Docker镜像并推送到远程Docker仓库
    stage('docker build & push') {
        steps {
          container ('maven') {
             //构建docker镜像
             sh 'docker build -f devops/Dockerfile -t $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$APP_NAME:$IMAGE_TAG .'
             //登录Docker并推送镜像到远程Docker仓库
             withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,credentialsId : "$DOCKER_CREDENTIAL_ID" ,)]) {
                sh 'echo "$DOCKER_PASSWORD" | docker login $DOCKER_REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
                sh 'docker push $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$APP_NAME:$IMAGE_TAG'
             }
          }
        }
    }

    //K8S部署
    stage('k8s deploy') {
        steps {
          container ('maven') {
                //使用对应K8s配置
                withCredentials([
                    kubeconfigFile(
                    credentialsId: env.K8S_CONFIG_CREDENTIAL_ID,
                    variable: 'KUBECONFIG')
                    ]) {
                    //替换部署脚本中的环境变量后执行k8s部署
                    sh 'envsubst < devops/k8s.yaml | kubectl apply -n $K8S_NAMESPACE -f -'
                }
          }
        }
    }
  }
}

7. 创建流水线

在Devops项目luo-devops下新建流水线ks-devops-demo,具体过程如下:

kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_19

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_20


kubesphere创建流水线显示已弃用 kubesphere 流水线_devops_21


如上设置后,Jenkins在拉取代码后,根据脚本路径(即对应代码根目录下devops/Jenkinfile)提取出Jenkins Pipeline脚本,并据此脚本执行流水线CI/CD。

8. 运行流水线

kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_22

点击进入具体的流水线活动即可查看当前活动的构建状态:

kubesphere创建流水线显示已弃用 kubesphere 流水线_jenkins_23


查看流水线构建日志页面:

kubesphere创建流水线显示已弃用 kubesphere 流水线_流水线_24

9. 检验构建效果

如下状态标记为成功的即为执行成功的流水线,若构建失败,可通过查看流水线日志排查相应问题。

kubesphere创建流水线显示已弃用 kubesphere 流水线_jenkins_25

流水线推送docker镜像到阿里云ACR:

kubesphere创建流水线显示已弃用 kubesphere 流水线_devops_26

流水线部署K8s相应资源:

kubesphere创建流水线显示已弃用 kubesphere 流水线_k8s_27


kubesphere创建流水线显示已弃用 kubesphere 流水线_kubesphere_28

测试ks-devops-demo服务是否可以正常访问:

kubesphere创建流水线显示已弃用 kubesphere 流水线_jenkins_29


综上便完成了一个Java应用的整个流水线集成及运行。

待续

  • S2I、B2I
  • 自定义Agent