如何使用KubeSphere的DevOps系统构建dotnet core应用

因KubeSphere的DevOps系统官方未提供.net core的ci/cd解决方案,需要自己进行DIY。现把实施过程记录下来,供需要的小伙伴自取。

前提环境:

上述准备工作已列出官方文档(如需要私有镜像仓库,可以直接使用Deployment部署Nexus3,比较简单),不再赘述。

基础镜像准备

我们基于官方提供的base镜像构建dotnet的编译环境。使用如下Dockerfile构建用于打包的基础镜像:

FROM kubesphere/builder-base:v2.1.0
RUN rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
RUN yum install -y dotnet-sdk-3.1 #此处可以换成其他版本,也可以同时安装多个版本sdk一步到位
RUN dotnet tool install --global dotnet-sonarscanner --version 5.0.4  #(可选)安装dotnet的sonar-scanner
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/sonar-scanner-3.3.0.1492-linux/bin:/root/.nuget/tools:/root/.dotnet/tools
CMD ["dotnet", "--version"]

将Dockerfile置于一个空目录即可,然后打包并推送:

docker build -t builder-dotnet:v1.0.0 .
docker tag builder-dotnet:v1.0.0 xxx.com/builder-dotnet:v1.0.0
docker push xxx.com/builder-dotnet:v1.0.0

配置Jenkins Angent

如果需要使用本地docker仓库,请提前配置好仓库密钥(不赘述)。

如果要使用本地Nuget仓库,请在“配置中心->配置”中,筛选项目为kubesphere-devops-system,找到ks-devops-agent,在其中添加一条配置,比如NugetSetting,并把Nuget.config的内容粘进去。

ks安装的jenkins采用CasC进行配置,而CasC配置文件又通过ConfigMap定义,然后挂载到jenkins容器。

找到“配置中心->配置”,筛选项目为kubesphere-devops-system,找到jenkins-casc-config。修改其jenkins.yml的配置项,在containers下,在对go的描述后面添加如下内容:

          - name: "dotnetcore"
            namespace: "kubesphere-devops-system"
            label: "dotnetcore"
            nodeUsageMode: "EXCLUSIVE"
            idleMinutes: 0
            containers:
            - name: "dotnetcore"
              image: "xxx.com/builder-dotnet:v1.0.0"     #镜像地址
              command: "cat"
              args: ""
              ttyEnabled: true
              resourceRequestCpu: "100m"
              resourceLimitCpu: "4000m"
              resourceRequestMemory: "100Mi"
              resourceLimitMemory: "8192Mi"
              alwaysPullImage: true
            - name: "jnlp"
              image: "jenkins/jnlp-slave:3.27-1"
              command: "jenkins-slave"
              args: "^${computer.jnlpmac} ^${computer.name}"
              resourceRequestCpu: "50m"
              resourceRequestMemory: "400Mi"
              resourceLimitMemory: "1536Mi"
            imagePullSecrets:                            #(可选)此处如果是使用私有仓库,请提前在密钥里准备好docker仓库密钥。
              - name: docker-local
            workspaceVolume:
              emptyDirWorkspaceVolume:
                memory: false
            volumes:
            - hostPathVolume:
                hostPath: "/var/run/docker.sock"
                mountPath: "/var/run/docker.sock"
            - hostPathVolume:                            #将nuget包缓存持久化到hostPath
                hostPath: "jenkins_nuget_cache"
                mountPath: "/root/.nuget"
            - hostPathVolume:
                hostPath: "sonar_cache"
                mountPath: "/root/.sonar/cache"
            yamls:                                       #请注意,此处从ConfigMap挂载了Nuget.Config,如不需要可以删除volumnMounts和volumns部分
            - "spec:\r\n  affinity:\r\n    nodeAffinity:\r\n      preferredDuringSchedulingIgnoredDuringExecution:\r\n      - weight: 1\r\n        preference:\r\n          matchExpressions:\r\n          - key: node-role.kubernetes.io/worker\r\n            operator: In\r\n            values:\r\n            - ci\r\n  tolerations:\r\n  - key: \"node.kubernetes.io/ci\"\r\n    operator: \"Exists\"\r\n    effect: \"NoSchedule\"\r\n  - key: \"node.kubernetes.io/ci\"\r\n    operator: \"Exists\"\r\n    effect: \"PreferNoSchedule\"\r\n  containers:\r\n  - name: \"dotnetcore\"\r\n    resources:\r\n      requests:\r\n        ephemeral-storage: \"1Gi\"\r\n      limits:\r\n        ephemeral-storage: \"10Gi\"\r\n    volumeMounts:\r\n    - name: config-volume\r\n      mountPath: /root/.nuget/NuGet/NuGet.Config\r\n      subPath: NuGet.Config\r\n  volumes:\r\n    - name: config-volume\r\n      configMap:\r\n        name: ks-devops-agent\r\n        items:\r\n        - key: NugetSetting\r\n          path: NuGet.Config\r\n  securityContext:\r\n    fsGroup: 1000\r\n "

修改并更新后,接下来需要去配置Jenkins使其生效。

打开你的Jenkins,点击“Manage Jenkins->Configuration as Code->Apply new configuration”。等待一会儿,如果没有报错,则配置完成。可以点击此页下的“View Configuration”检查配置是否生效。

此步骤其他细节还可以参考官方文档

使用

在KubeSphere的DevOps项目中,提前准备好git密钥。

建立一条流水线。编辑Jenkinsfile如下:(sonar分析部分可选,请自行替换其中变量)

pipeline {
  agent {
    node {
      label 'dotnetcore'
    }

  }
  stages {
    stage('拉代码') {
      steps {
        git(url: 'https://你的域名.com/你的项目.git', credentialsId: 'git密钥名', branch: 'master', changelog: true, poll: false)
      }
    }
    stage('代码分析') {
      steps {
        withSonarQubeEnv('sonar') {
          container('dotnetcore') {
            sh 'dotnet sonarscanner begin /k:"项目名" /n:项目名'
            sh 'dotnet publish -c Release 源码目录/项目名.csproj -o 源码目录/bin/publish/'
            sh 'dotnet sonarscanner end'
          }

        }

        waitForQualityGate 'true'
      }
    }
   
    stage('打镜像') {
      steps {
        container('dotnetcore') {
          sh '''cat > 源码目录/Dockerfile << EOF
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim
WORKDIR /app
EXPOSE 80
COPY 源码目录/bin/publish/. .
ENTRYPOINT [ "dotnet","项目名.dll" ]
EOF
docker build -f 源码目录/Dockerfile -t 项目名:版本号 .'''
        }

      }
    }
    
  }
}

特别提醒

开启/关闭Devops系统、配置sonarqube等需修改CRD(自定义资源)下的ClusterConfiguration中的ks-install,该修改会导致ks-install服务工作,并对集群组件进行重新安装。从而可能导致jenkins的CasC配置和ks-jenkins-agent等配置被复位。如果修改了CRD后发现找不到标签为dotnetcore的jenkins agent,请考虑是配置复位,需要重新覆盖上述提到的devops系统的相关配置项。

    sslyc8991 更改标题为「如何使用KubeSphere的DevOps系统构建dotnet core应用

    欢迎把你的方案提交到社区,大大的赞

    1 个月 后
    10 天 后

    sslyc8991 请问你有兴趣来给 kubesphere 社区贡献 .net core 的 agent 么?

    8 个月 后

    mafeifan

    可以检查一下命名空间 kubesphere-devops-system 或者 kubesphere-devops-worker 下 Pod 的运行状态。

    可能存在的原因:

    1. Pod 正在拉取镜像,耗时比较长;
    2. Pod template 配置不正确,导致 Pod 不断 Crash。
      4 天 后
      1 个月 后

      mafeifan 需要你在jenkins的casc配置里添加dotnetcore的配置,并且重新加载casc配置

      16 天 后

      不需要这么麻烦的。我就是使用ks自带的devops的basePodTemplate来构建.netcore5项目的。

      dockerfile文件直接使用vs2019自动生成的就可以。

        11 天 后

        @sslyc8991

        Apply new configuration完成, 没有报错。点击此页下的“View Configuration”检查配置 里面没有配置的dotnetcore的信息 是什么问题。?

          3 个月 后

          muxue 自带是可以的。 它是拉了.net的sdk的镜像下来,在sdk镜像起的容器里打包,然后再输出到运行时镜像里。这个还需要解决两个问题啊:1. 使用了私有nuget仓库,要配仓库地址和账密 2. nuget包的缓存问题,不然每次都会完整拉一遍。私有仓库也可以改dockerfile解决,缓存问题要看看怎么弄哈,虽然也不是必需。

          ivanmissu 检查下配置文件选的对不对哈。而且,在3.2版本还是哪个版本之后,改用jenkins_user.yaml了,而且agent挂载的configmap的命名空间也换了(devops-worker那个空间)。

            1 年 后

            打开你的Jenkins,点击“Manage Jenkins->Configuration as Code->Apply new configuration”。等待一会儿,如果没有报错,则配置完成。可以点击此页下的“View Configuration”检查配置是否生效。

            我问下这些操作是在内置的jenkins里面操作吗?http://xxxxx:30180/manage,我在内置的jenkins里面没有找到这些按钮

              lld 是在内置的 jenkins 里操作的:

              • lld 回复了此帖

                yudong

                谢谢你的回复,可是我这把没有看到这些按钮

                • lld 回复了此帖