本文的k8s部署在KubeSphere中,利用了当中的devops组件进行CI/CD 的建设,尽管不是在原生k8s中,也可以从中借鉴CI/CD建设的一些思路。
本文主要参考:使用图形编辑面板创建流水线 ,实践部分请参考该文。本文只提供关键步骤和过程中遇到的一些问题及相关的解决方法。
创建流水线项目

这里的两个配置和jenkins中的是一样的作用,可以分别以时间和数量来设定保留的构建记录,可以把时间给取消掉避免有些项目长时间没有迭代,就没有构建记录了。
这里是我的一个项目的构建记录,我们后续可以利用这些记录回滚到某一版本。
再往下可以配置构建过程中使用的一些参数,例如镜像仓库、代码仓库等等,会再后续配置流水线的过程中用到。
当你配置参数之后,点击运行的时候可以修改你设置的默认值
编辑流水线
在流水线项目中通过“编辑流水线”或是“编辑 Jenkinsfile”来编辑我们的流水线。这里选择使用 “编辑流水线” 它是图形化的配置完成后会自动生成 jenkinsfile


这里是我经过配置之后的流水线,详细的配置过程 请参考 使用图形编辑面板创建流水线 。
我这里只有三个过程 :
- 拉取代码
- 对代码进行打包编译并制作docker镜像上传到harbor
- 部署到k8s中
拉取代码就不用说了很简单,如果你看生成后的jenkinsfile的话,就是下面这样。
// 拉取代码}stages {stage('git clone') {agent nonesteps {//我拉取代码会报错,所以加了这个配置,感兴趣的朋友可以查一下作用sh 'git config --global http.sslverify false'git(url: 'https://gitee.com/cyt_0906/Project_Sky_CASMAP.git', credentialsId: 'gitee', branch: 'master', changelog: true, poll: false)}}
下面说一下第二个步骤,有两个关键步骤。
docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BUILD_NUMBER .
根据 Dockerfile 使用打包构建之后生成的jar来生成镜像并打上标签。BUILD_NUMBER 应该是内置的变量它的值是运行记录中的运行次数,以此把镜像的版本和发布记录关联到一起。DOCKERHUB_NAMESPACE 、APP_NAME ,这个是在 第一个步骤中的 构建参数那里配置的。
Dockerfile 是在项目中的
然后就是把生成的镜像上传到 harbor
echo “$DOCKER_PASSWORD” | docker login $REGISTRY -u “$DOCKER_USERNAME” —password-stdin docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BUILD_NUMBER
先登录再进行docker push。
// 构建、生成docker镜像、Push到镜像仓库
stage('Build and Push') {
agent none
steps {
container('maven') {
sh '''
cd jeecg-boot
mvn package
'''
sh '''
cd jeecg-boot/jeecg-boot-module-system
docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BUILD_NUMBER .'''
withCredentials([usernamePassword(credentialsId : 'docker' ,usernameVariable : 'DOCKER_USERNAME' ,passwordVariable : 'DOCKER_PASSWORD' ,)]) {
sh '''echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin
'''
}
sh '''docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BUILD_NUMBER
'''
}
}
}
最后一个步骤就是部署了
// 生成 k8s的 Deployment 和 Service 资源文件,进行部署
stage('Deploy to QA') {
agent none
steps {
container('maven') {
withCredentials([kubeconfigContent(credentialsId : 'kubeconfig' ,variable : 'KUBECONFIG_CONTENT' ,)]) {
sh '''mkdir ~/.kube
echo "$KUBECONFIG_CONTENT" > ~/.kube/config
cd jeecg-boot/jeecg-boot-module-system
envsubst < k8s/casmap-svc.yaml | kubectl apply -n $DOCKERHUB_NAMESPACE -f -
envsubst < k8s/casmap.yaml | kubectl apply -n $DOCKERHUB_NAMESPACE -f -
'''
}
}
}
}
这里需要创建一个凭据里面放的是k8s集群的 kubeconfig 文件,并赋值给了变量 KUBECONFIG_CONTENT(详情参考使用图形编辑面板创建流水线 )。我们通过在docker构建容器中配置这个文件,使其可以拥有对集群的操作权限。
envsubst 命令是用来替换 k8s/casmap-svc.yaml 文件中的变量,关于这个命令可以自行百度,这个文件如同Dockerfile一样需要在项目中提前配置好,其后就是通过这两个文件分别创建 Deployment 和 Service 了。
完整的 jenkinsfile 如下
pipeline {
agent {
node {
label 'maven'
}
// 拉取代码
}
stages {
stage('git clone') {
agent none
steps {
sh 'git config --global http.sslverify false'
git(url: 'https://gitee.com/cyt_0906/Project_Sky_CASMAP.git', credentialsId: 'gitee', branch: 'master', changelog: true, poll: false)
}
}
// 构建、生成docker镜像、Push到镜像仓库
stage('Build and Push') {
agent none
steps {
container('maven') {
sh '''
cd jeecg-boot
mvn package
'''
sh '''
cd jeecg-boot/jeecg-boot-module-system
docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BUILD_NUMBER .'''
withCredentials([usernamePassword(credentialsId : 'docker' ,usernameVariable : 'DOCKER_USERNAME' ,passwordVariable : 'DOCKER_PASSWORD' ,)]) {
sh '''echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin
'''
}
sh '''docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BUILD_NUMBER
'''
}
}
}
// 生成 k8s的 Deployment 和 Service 资源文件,进行部署
stage('Deploy to QA') {
agent none
steps {
container('maven') {
withCredentials([kubeconfigContent(credentialsId : 'kubeconfig' ,variable : 'KUBECONFIG_CONTENT' ,)]) {
sh '''mkdir ~/.kube
echo "$KUBECONFIG_CONTENT" > ~/.kube/config
cd jeecg-boot/jeecg-boot-module-system
envsubst < k8s/casmap-svc.yaml | kubectl apply -n $DOCKERHUB_NAMESPACE -f -
envsubst < k8s/casmap.yaml | kubectl apply -n $DOCKERHUB_NAMESPACE -f -
'''
}
}
}
}
}
}
部署
总结
关于整个CI/CD的流程,就已经讲完了,其中的一些细节和思路这里再说明一下。当点击运行进行发布的时候,会运行一个docker 容器,上述所讲的所有过程都在该容器中进行,流水线运行完成后它会自行销毁。再上述的jenkinfile有下面这个配置:
agent {
node {
label 'maven'
}
它其实是用来标记你要使用那个docker镜像来进行这个容器的,例如文中的项目是java那么这里就是maven 还有nodejs、go等等。如此一来我们的打包构建环境就可以区分开来了。在构建java或是前端项目的时候会拉取很多依赖,有了这些依赖在第二次构建的时候速度就会快很多,KubeSphere中的解决方式是通过 hostPathVolume 把主机的目录挂载到容器中,这样下载的依赖就在主机上面存储。但需要使你的构建容器刚好调度到这台k8s节点上面,KubeSphere中的方法(为依赖项缓存设置 CI 节点)。上面说的构建镜像在KubeSphere中叫 jenkins Agent ,我们可以 自定义 Jenkins Agent ,改一下jdk的版本之类的。
[
](https://kubesphere.com.cn/docs/devops-user-guide/examples/customize-jenkins-agent/)


