代码拉取完成,页面将自动刷新
声明1:本文内容基于kubesphere-v3.3.1
声明2:本文中的配置示例,都是比较简单的入门级配置示例。正式使用时,根据项目进行更多配置即可
注:这两个文件,放在项目下的任意位置都行,只需要在边界Jenkinsfile指定对应路径即可
其中有个API长这样(此api用于部署后的测试验证)
FROM openjdk:8-jdk
MAINTAINER JustryDeng<13548417409@163.com>
ADD target/*.jar /app.jar
ENTRYPOINT [ "java", "-jar", "/app.jar" ]
################################################# Deployment 部署应用
apiVersion: apps/v1 # api版本
kind: Deployment # yml文件类型
metadata: # 元数据
name: demo-deployment # 本deployment的名称
# 可以使用kubectl创建命名空间,如果没有的话
# kubectl create namespace {命名空间}
# kubectl get namespaces
namespace: demo-namespace
labels: # 本deployment具备的标签
app: demo-deployment
spec:
# 选择器. 将以被选择器选中的template为模板,拉起pod
selector:
matchLabels:
labelA: labelA_value
replicas: 1 # 要拉起pod副本的数量
strategy:
type: RollingUpdate # 拉起pod的策略
template: # pod模板设置
metadata:
labels:
labelA: labelA_value
podLabelB: demo-pod
spec:
containers:
- name: i-am-demo-name # 设置容器名(小写字母 or 数字 or 中划线)
# 设置拉起容器所使用的镜像, 这里通过占位符,取值到下文Jenkinsfile中相关的值, 此参数可以等Jenkinsfile写好后,再回来补充
# 注意:docker pull时,默认会先走本地镜像,本地有的话,就不会去远程拉,所以如果是拉取远程同名镜像的话,记得拉取前移除本地旧的镜像
image: '${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER}'
ports:
# 请求(直接来着node的请求、ingress转发过来的请求) -> service(service管理pod集群, 将请求分发至pod) -> pod
# service的端口:port -> pod的端口:targetPort(即:containerPort)
# 因为一个pod内可能有多个容器,即可能有多个containerPort, 所以 当service要往pod转发请求时, 就需要通过targetPort指定需要跳转到哪个containerPort
- containerPort: 8080 # pod的ip + 容器端口(containerPort) = Endpoint,代表此pod里的一个服务进程的对外通信地址
---
################################################# Service 暴露服务,使走外网可访问
apiVersion: v1
kind: Service
# 设置当前service的元信息
metadata:
name: demo-service
namespace: demo-namespace
labels:
app: demo-service
spec:
ports:
- name: http
protocol: TCP
nodePort: 30862 # 宿主机node的端口(外网访问的话,此端口需要开启才行)
port: 8080 # 当前service的端口
targetPort: 8080 # 对应上面容器暴露的端口, 不填则默认值为port
# NodePort模式下,请求依次"经过"的端口:节点机器的的nodePort -> 服务的port -> pod的targetPort
type: NodePort # 以NodePort的形式暴露service,使得可通过 node的ip + nodePort访问服务
# 匹配这些pod-template创建出来的pod
selector:
labelA: labelA_value
podLabelB: demo-pod
较简单,直接参考创建DevOps项目即可
提示:直接用
编辑流水线
图形编辑的话,对应生成的Jenkinsfile可能有问题。我们可以直接编辑Jenkinsfile,我们也可以先用图形编辑,然后在图形编辑保存后(会自动生成内容到Jenkinsfile),再去编辑jenkinsfile。
Jenkinsfile内容示例
// 基本上,按照jenkins的语法编写脚本即可
pipeline {
agent {
node {
label 'maven'
}
}
// 参数设置 TODO:根据自己的情况修改
parameters {
string(name: 'demoParamA', defaultValue: 'valueA', description: '参数示例', trim: true)
choice(name: 'BRANCH_NAME', choices: ['master', 'develop' , 'test', 'prod'], description: 'git分支名')
}
// 设置变量 TODO:根据自己的情况修改
environment {
// 项目中dockerfile文件的相对位置
DOCKERFILE_PATH = 'deploy/Dockerfile'
// 镜像仓库
IMAGE_REGISTRY = '10.8.0.101:1180'
// 镜像所属项目
IMAGE_PROJECT = 'library'
// 应用名称
APPLICATION_NAME = 'demo'
// 项目中k8s部署文件的相对位置
K8S_YAML_PATH = 'deploy/k8s-deploy.yml'
}
// 步骤
stages {
// 参数确认 TODO:根据自己的情况修改
stage('参数确认') {
agent none
steps {
container('maven') {
sh """
echo '您输入的demoParamA的值是:${demoParamA}'
echo '您选择的BRANCH_NAME的值是:${BRANCH_NAME}'
"""
//sh 'echo "您选择的BRANCH_NAME的值是:"${BRANCH_NAME}'
// 在Jenkins文件中,支持Groovy语法的脚本
script {
def tmpParamX = "${params.demoParamA}"
println "tmpParamX的值为:" + tmpParamX
tmpParamY = ''
if("${params.demoParamA}".trim() == "valueA"){
tmpParamY = '一二三四五'
} else if("${params.demoParamA}".trim() != "valueA"){
tmpParamY = '上山打老虎'
}
println "tmpParamY的值为:" + tmpParamY
// jenkinsfile中对变量进行引用一般用$,如:$currBranchName, 更多可去搜索引擎上查一下 jenkinsfile对groovy的变量引用
}
}
}
}
// 拉取代码 TODO:根据自己的情况修改
stage('拉取代码') {
agent none
steps {
container('maven') {
// 这里ds-gitee为拉取代码的凭证id。提前在kubesphere的当前devOps项目下创建好. 就可以知道凭证的id了
git(url: 'https://gitee.com/JustryDeng/demo.git', branch: '${BRANCH_NAME}', credentialsId: 'ds-gitee', changelog: true, poll: false)
// 执行多个shell指令
sh """
pwd
ls
"""
}
}
}
// maven打包
stage('maven打包') {
agent none
steps {
container('maven') {
// maven打包
sh 'mvn clean package -Dmaven.test.skip=true '
}
}
}
// 构建&推送镜像 TODO:根据自己的情况修改
stage('构建&推送镜像') {
agent none
steps {
container('maven') {
// 构建raw镜像
sh 'docker build -f ${DOCKERFILE_PATH} -t ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER} .'
// 将当前镜像tag为lastest镜像 (lastest镜像就等于当前raw镜像)
sh 'docker tag ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER} ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:latest'
// harbor-101是登录镜像仓库的凭证id。提前在kubesphere的当前devOps项目下创建好. 就可以知道凭证的id了
withCredentials([usernamePassword(credentialsId : 'harbor-101' ,usernameVariable : 'DOCKER_USERNAME' ,passwordVariable : 'DOCKER_PASSWORD' ,)]) {
// 登录镜像仓库
sh 'echo "${DOCKER_PASSWORD}" | docker login ${IMAGE_REGISTRY} -u "${DOCKER_USERNAME}" --password-stdin'
// 推送raw镜像
sh 'docker push ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER}'
// 推送lastest镜像
sh 'docker push ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:latest'
}
}
}
}
// 部署应用到k8s TODO:根据自己的情况修改
stage('部署应用到k8s') {
agent none
steps {
container('maven') {
/*
* admin-kubeconfig是将应用部署至k8s中的操作用户的凭证的id。提前在kubesphere的当前devOps项目下创建好. 就可以知道凭证的id了
* 注:此kubeconfig凭证对应的用户,应具备k8s操作权限(如:集群管理员,可以admin登录,然后在 集群管理|集群设置|集群成员 这里进行设置),否则此步可能因为权限问题执行失败.
* 可以用具有【集群管理员】角色的用户登录kubesphere,然后进入当前devOps下创建kubeconfig凭证
* 注:生成的kubeconfig凭证中,clusters.cluster.server的值可能导致dns解析失败,此时,可以尝试将值里面的域名换成ip地址,最好同时保证/etc/hosts中有对应的地址配置
* 注:实在不行,可以直接用超级管理员的kubeconfig凭证. 见:/root/.kube/config
*
* 注:当前kubesphere-v3.3.1版本下,这里用的是kubeconfigFile,其余方式可能有bug
*/
withCredentials([kubeconfigFile(credentialsId : 'admin-kubeconfig' ,variable : 'KUBECONFIG' ,)]) {
/*
* envsubst < xxx.yml: 替换xxx.yml文件中的参数引用为对应的参数值。
* 注:上面parameters、environment中定义的变量,一次此步骤设置的variable,都可以被作为参数引用
* kubectl apply -f -: 部署应用至k8s. 即:根据k8s部署配置文件进行部署
*/
sh 'echo k8s部署文件当前拉取的镜像是:${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER}'
sh 'envsubst < ${K8S_YAML_PATH} | kubectl apply -f -'
}
}
}
}
}
}
对应的图形界面长这样
修改应用controller代码,Hello
改为Hi
:
推送代码后,触发流水线部署成功后,然后再次访问:
由此可见,使用kubesphere devOps流水线往k8s中部署应用成功!
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。