基于Jenkins+k8s+Git等技术构建DevOps平台
创建ns和sa并授权
[root@sy-master01 ~]# kubectl create namespace jenkins-k8s
[root@sy-master01 ~]# kubectl create sa jenkins-k8s-sa -n jenkins-k8s
[root@sy-master01 ~]# kubectl create clusterrolebinding jenkins-k8s-sa-cluster -n jenkins-k8s --clusterrole=cluster-admin --serviceaccount=jenkins-k8s:jenkins-k8s-sa
创建pv pvc和jenkins
[root@sy-master01 jenkins]# kubectl apply -f pv.yaml
[root@sy-master01 jenkins]# kubectl apply -f pvc.yaml
[root@sy-master01 jenkins]# kubectl apply -f jenkins-deployment.yaml
[root@sy-master01 jenkins]# kubectl apply -f jenkins-service.yaml
[root@sy-master01 jenkins]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-k8s-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.232.128
path: /data/v1
[root@sy-master01 jenkins]# cat pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkins-k8s-pvc
namespace: jenkins-k8s
spec:
resources:
requests:
storage: 10Gi
accessModes:
- ReadWriteMany
[root@sy-master01 jenkins]# cat jenkins-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: jenkins
namespace: jenkins-k8s
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccount: jenkins-k8s-sa
containers:
- name: jenkins
image: jenkins/jenkins:2.401.2-lts-jdk11
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
failureThreshold: 12
readinessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
failureThreshold: 12
volumeMounts:
- name: jenkins-volume
subPath: jenkins-home
mountPath: /var/jenkins_home
volumes:
- name: jenkins-volume
persistentVolumeClaim:
claimName: jenkins-k8s-pvc
[root@sy-master01 jenkins]# cat jenkins-service.yaml
apiVersion: v1
kind: Service
metadata:
name: jenkins-service
namespace: jenkins-k8s
labels:
app: jenkins
spec:
selector:
app: jenkins
type: NodePort
ports:
- name: web
port: 8080
targetPort: web
nodePort: 30002
- name: agent
port: 50000
targetPort: agent
等Pod状态running
[root@sy-master01 jenkins]# kubectl get pods -n jenkins-k8s -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
jenkins-54c56df58b-z5268 1/1 Running 0 24m 10.244.244.39 sy-node02 <none> <none>
浏览器访问
直接选择安装推荐的插件了
等几分钟
创建用户
安装插件
安装kubernetes插件
安装Blue Ocean插件
等待安装完毕后重启
配置kubernetes节点
选择Clouds
添加kubernetes
添加k8s地址和namespace 然后连接测试
填写jenkins地址
添加卷
运行时需要权限,docker和kubectl都需要加权限
配置dockerhub认证,可以自己改成harbor
新建一个任务
node('jnlp') {
stage('Clone') {
echo "1.Clone Stage"
git url: "https://github.com/yangzhenyu900/jenkins-sample.git"
script {
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
}
}
stage('Test') {
echo "2.Test Stage"
}
stage('Build') {
echo "3.Build Docker Image Stage"
sh "docker build -t zhenyuyang/jenkins-demo:${build_tag} ."
}
stage('Push') {
echo "4.Push Docker Image Stage"
withCredentials([usernamePassword(credentialsId: 'docekrhubpasswd', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
sh "docker login -u ${dockerHubUser} -p ${dockerHubPassword}"
sh "docker push zhenyuyang/jenkins-demo:${build_tag}"
}
}
stage('Deploy to dev') {
echo "5. Deploy DEV"
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev.yaml"
// sh "bash running-devlopment.sh"
sh "kubectl apply -f k8s-dev.yaml --validate=false"
}
stage('Promote to qa') {
def userInput = input(
id: 'userInput',
message: 'Promote to qa?',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "YES\nNO",
name: 'Env'
]
]
)
echo "This is a deploy step to ${userInput}"
if (userInput == "YES") {
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa.yaml"
// sh "bash running-qa.sh"
sh "kubectl apply -f k8s-qa.yaml --validate=false"
sh "sleep 6"
sh "kubectl get pods -n qatest"
} else {
//exit
}
}
stage('Promote to pro') {
def userInput = input(
id: 'userInput',
message: 'Promote to pro?',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "YES\nNO",
name: 'Env'
]
]
)
echo "This is a deploy step to ${userInput}"
if (userInput == "YES") {
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod.yaml"
// sh "bash running-production.sh"
sh "cat k8s-prod.yaml"
sh "kubectl apply -f k8s-prod.yaml --record --validate=false"
}
}
}
kubectl create namespace devlopment
kubectl create namespace qatest
kubectl create namespace production
我是把https://github.com/luckylucky421/jenkins-sample.git地址Fork到自己Github
[root@sy-master01 ~]# kubectl get all -n qatest
NAME READY STATUS RESTARTS AGE
pod/jenkins-demo-96ff5d94d-22k5b 1/1 Running 0 7h7m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/demo NodePort 10.108.134.0 <none> 18888:31891/TCP 23h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/jenkins-demo 1/1 1 1 23h
NAME DESIRED CURRENT READY AGE
replicaset.apps/jenkins-demo-7c7bc556cf 0 0 0 23h
replicaset.apps/jenkins-demo-96ff5d94d 1 1 1 7h7m
[root@sy-master01 ~]# kubectl get all -n devlopment
NAME READY STATUS RESTARTS AGE
pod/jenkins-demo-96ff5d94d-m7wtv 1/1 Running 0 23h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/demo NodePort 10.104.221.90 <none> 18888:31889/TCP 23h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/jenkins-demo 1/1 1 1 23h
NAME DESIRED CURRENT READY AGE
replicaset.apps/jenkins-demo-7c7bc556cf 0 0 0 23h
replicaset.apps/jenkins-demo-96ff5d94d 1 1 1 23h
[root@sy-master01 ~]# kubectl get all -n production
NAME READY STATUS RESTARTS AGE
pod/jenkins-demo-96ff5d94d-crwk4 1/1 Running 0 7h7m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins-demo NodePort 10.106.230.156 <none> 18888:31890/TCP 23h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/jenkins-demo 1/1 1 1 23h
NAME DESIRED CURRENT READY AGE
replicaset.apps/jenkins-demo-7c7bc556cf 0 0 0 23h
replicaset.apps/jenkins-demo-96ff5d94d 1 1 1 7h7m
回滚pipeline
node('jnlp')
{ stage('git clone')
{
git url: "https://github.com/yangzhenyu900/jenkins-rollout"
sh "ls -al"
sh "pwd"
}
stage('select env') {
def envInput =
input( id: 'envInput',
message: 'Choose a deploy environment',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "devlopment\nqatest\nproduction",
name: 'Env'
]
]
)
echo "This is a deploy step to ${envInput}"
sh "sed -i 's/<namespace>/${envInput}/' getVersion.sh"
sh "sed -i 's/<namespace>/${envInput}/' rollout.sh"
sh "bash getVersion.sh"
// env.WORKSPACE = pwd()
// def version = readFile "${env.WORKSPACE}/version.csv"
// println version
}
stage('select version')
{ env.WORKSPACE =
pwd()
def version = readFile "${env.WORKSPACE}/version.csv"
println version
def userInput = input(id: 'userInput',
message: '选择回滚版本',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "$version\n",
name: 'Version'
]
]
)
sh "sed -i 's/<version>/${userInput}/' rollout.sh"
}
stage('rollout deploy')
{ sh "bash rollout.sh"
}
}
https://github.com/luckylucky421/jenkins-rollout
fork该地址