本入门示例适合小白初次体验kubesphere devops.
以管理员身份登录kubesphere,选择左上角平台管理–>访问控制–>账号管理–>创建。
1.创建一个普通用户,角色选择platform-regular:
2.然后选择企业空间,创建新的企业空间demo-ws,创建完成点击进入该空间,选择企业空间设置–>企业成员–>邀请成员。
将创建的普通用户加入该企业空间,角色选择self-provisioner,该角色可以在企业空间下创建DevOps工程和项目:
切换到普通用户demo-user登录,创建项目kubesphere-sample-dev,创建devops工程demo-cicd。
进入devops工程创建第一个pipeline,只需填写名称demo-pipeline,其他默认,点击下一步完成创建。
点击进入pipeline–>编辑流水线,有3种代理类型可选
代理类型说明:
这里首先演示any类型,点击左侧+
添加步骤,点击步骤名称stage-xxx
技巧:该视图有很大的操作灵活性,可拖动、全屏、放大缩小。
echo "获取源码"
点击右下角确定–>保存,最后选择运行,执行成功后,点击成功状态的流水线查看详情
展开日志详情可以看到打印了执行的shell命令以及输出内容。
点击运行流水线后,由于选择代理类型为any,kubesphere使用base pod模板在kubesphere-devops-system命名空间下动态生成了一个pod,该pod包含了2个容器,base容器及jnlp容器,流水线运行完成后该pod被立马清理。
为了看到该pod,重新编辑流水线,点击活动
返回流水线执行历史视图:
将shell命令改为sleep 10000s
重新运行流水线,让其处于sleep状态。
然后新开一个浏览器窗口使用管理员用户登录,点击应用负载–>容器组,搜索base关键字可以找到该pod,包含了2个容器。
点击base名称后面的终端小图标进入容器你会发现它其实是一个centos 7.6的镜像(容器中执行cat /etc/redhat-release)。
同
最后回到流水线视图,点击编辑jenkinsfile,可以看到熟悉的声明式pipeline脚本。也就是说通过可视化界面执行的配置操作实质上转化为了jenkins标准的pipeline脚本,例如之前选择的代理类型any正对应pipeline中的agent any语法:
在编辑流水线添加步骤时如果直接选择shell,则shell命令默认在jnlp容器中执行,例如上面的sleep 10000s,可以通过在shell中执行echo $HOME来确认这一点,不同容器home目录是不一样的。
那如何指定在另一个base容器中执行命令呢,我们继续编辑流水线,添加新的步骤,这次选择指定容器
名称选择base,名称只能选择any代理pod模板中已有的容器,base模板只有2个容器base和jnlp,因此该容器名称只能是base或jnlp的一个,填写其他名称将报错找不到该容器。
点击添加嵌套步骤,选择shell类型,在指定的base容器中运行shell命令:
echo $HOME
git version
docker version
cat /etc/redhat-release
不指定容器时shell命令在jnlp容器中执行,当然我们也可以显式调用jnlp容器,同样方式添加一个jnlp容器,名称填写jnlp,嵌套步骤也选择shell,填写以下内容:
echo $HOME
git version
最终如下,步骤1和步骤3执行了相同的shell命令
重新运行流水线查看日志,你会发现步骤1和步骤3输出了相同的内容,并且与步骤2输出结果不同。
另外你可能注意到在base容器中可以执行docker命令,这是因为base容器中默认安装有docker客户端并且挂载了主机的/var/run/docker.sock,jnlp容器虽然也挂载了docker.sock,但由于没有docker客户端,是无法执行docker命令的。
kubesphere暂不支持流水线克隆,再次创建新的流水线后完全可以复制已有pipeline的jenkinsfile进行复用,免去后续繁琐的步骤定义过程。
返回流水线列表视图,创建一条新的空流水线,只配置名称pipeline1:
进入demo-pipeline1,选择编辑jenkinsfile,直接粘贴以下内容:
pipeline {
agent any
stages {
stage('获取源码') {
steps {
sh 'echo "获取源码"'
}
}
stage('单元测试') {
steps {
sh 'echo "单元测试"'
}
}
stage('代码扫描') {
steps {
sh 'echo "源代码扫描"'
}
}
stage('源码编译') {
steps {
sh 'echo "源码编译"'
}
}
stage('镜像构建') {
steps {
sh 'echo "docker镜像构建"'
}
}
stage('镜像推送') {
steps {
sh 'echo "推送镜像到harbor仓库"'
}
}
stage('应用部署') {
steps {
sh 'echo "部署应用到kubernetes集群"'
}
}
}
}
点击保存后你会看到,自动生成了可视化视图:
本示例从github拉取代码编译一个java项目,构建镜像并部署到kubernetes集群中,代码地址
https://github.com/kubesphere/devops-java-sample.git
#如果拉取较慢可以在url中加上代理
https://github.com.cnpmjs.org/kubesphere/devops-java-sample.git
创建一个空的流水线,命名为demo-pipeline2
编辑流水线,代理选择node,由于需要maven编译源码,label选择maven,该pod 模板包含了定义好的maven镜像:
步骤2:添加步骤,源码编译,类型选择指定容器,填写必要参数,名称必须是maven
mvn clean -o -gs `pwd`/configuration/settings.xml test
步骤3:添加步骤,镜像构建,类型选择指定容器,填写必要参数,名称必须是maven。
添加嵌套步骤,类型选择shell,输入以下命令
docker build -f Dockerfile-online -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER .'
步骤4:添加步骤,镜像推送,注意,这里类型选择添加凭证
添加嵌套步骤,选择容器,名称为maven,继续在容器中添加嵌套步骤,选择shell,输入以下命令
echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
继续添加嵌套步骤,选择shell输入以下命令
docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
步骤5:添加步骤,应用部署,注意,这里类型选择kubernetesDeploy
填写必要参数
点击更多操作,编辑配置
参数化构建,添加以下3个参数,定义上面引入的变量:
切换到项目kubesphere-sample-dev,查看创建的应用
点击服务获取应用端口访问应用
新建空的流水线,代理类型选择kubernete
编辑yaml为以下内容,定义了2个容器maven及docker,jnlp容器默认会附加到pod中
apiVersion: v1
kind: Pod
metadata:
labels:
app: jenkins-agent
spec:
containers:
- name: maven
image: maven
args:
- cat
tty: true
- name: docker
image: docker:dind
args:
- "--registry-mirror=https://uyah70su.mirror.aliyuncs.com"
- "--insecure-registry=127.0.0.1"
securityContext:
privileged: true
tty: true
新添加2个步骤,类型选择指定容器,并嵌套shell类型指定想要运行的命令
最终jenkinsfile如下
pipeline {
agent {
kubernetes {
label 'default'
yaml '''apiVersion: v1
kind: Pod
metadata:
labels:
app: jenkins-agent
spec:
containers:
- name: maven
image: willdockerhub/maven:mirror
args:
- cat
tty: true
- name: docker
image: docker:dind
args:
- "--registry-mirror=https://uyah70su.mirror.aliyuncs.com"
securityContext:
privileged: true
tty: true'''
defaultContainer 'maven'
}
}
stages {
stage('获取源码') {
steps {
git(url: 'https://github.com.cnpmjs.org/kubesphere/devops-java-sample.git', credentialsId: 'git-id', changelog: true, poll: false, branch: 'master')
}
}
stage('源码编译') {
steps {
container('maven') {
sh 'mvn -version'
}
}
}
stage('镜像构建') {
steps {
container('docker') {
sh 'docker version'
}
}
}
}
}
上面的yaml模板可以放在版本库中进行管理,然后在pipeline中调用
pipeline {
agent {
kubernetes {
yamlFile 'jenkinsfile/pod_template.yaml'
}
}
...
参考:https://github.com/willzhang/docker-images/tree/master/maven
kubesphere devops使用自带maven镜像可能遇到2个问题:
下面我们自行构建一个maven镜像,导入settings.xml配置文件,指示maven从阿里云镜像源或内网nexus maven私库下载依赖:
创建Dockerfile,复制settings.xml文件,并且需要安装docker命令,用于构建和推送镜像:
FROM maven:3.6.3-jdk-11-slim
ENV DOCKER_VERSION=19.03.13
COPY settings.xml /usr/share/maven/ref/
RUN curl -f https://download.docker.com/linux/static/stable/x86_64/docker-$DOCKER_VERSION.tgz | tar xvz && \
mv docker/docker /usr/bin/ && \
rm -rf docker
settings.xml需要自行配置,指定阿里云maven或内网nexus仓库,示例:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>/usr/share/maven/ref/repositorylocalRepository>
<mirrors>
<mirror>
<id>alimavenid>
<name>aliyun mavenname>
<url>https://maven.aliyun.com/repository/centralurl>
<mirrorOf>centralmirrorOf>
mirror>
mirrors>
settings>
修改kubesphere jenkins配置,找到image地址直接替换即可:
kubectl -n kubesphere-devops-system edit cm jenkins-casc-config
kubectl -n kubesphere-devops-system delete pods -l app=ks-jenkins
另外需要修改pod模板中maven容器启动参数,将command中的cat删除,改为args参数,因为原始的官方maven镜像指定了ENTRYPOINT用于复制settings.xml到目标配置文件路径,如果使用command会导致ENTRYPOINT被覆盖,进而导致自定义配置文件无法生效:
- name: "maven"
namespace: "kubesphere-devops-system"
label: "maven"
nodeUsageMode: "EXCLUSIVE"
idleMinutes: 0
containers:
- name: "maven"
image: "10.39.140.196:8081/library/maven:3.6.3-dev"
command: ""
args: "cat"