记录一次jenkins持续集成k8s
jenkins部署项目到k8s
Jenkins持续集成k8s
环境搭建
1.准备三台虚拟机k8s-master:192.168.0.201,k8s-node1:192.168.0.202,k8s-node2:192.168.203
2.三台机器都要安装k8s和docker,安装教程网上搜索
3.在k8s-master,执行kubeadm init \
–apiserver-advertise-address=192.168.0.201 \
–image-repository registry.aliyuncs.com/google_containers \
–kubernetes-version v1.23.6 \
–service-cidr=10.96.0.0/12 \
–pod-network-cidr=10.244.0.0/16
–v=5
下面的证书配置,不配可能会对后面流水线发布有影响。
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null |
openssl dgst -sha256 -hex | sed ‘s/^.* //’
在节点执行:kubeadm join 192.168.0…201:6443 --token w34ha2.66if2c8nwmeat9o7 --discovery-token-ca-cert-hash sha256:20e2227554f8883811c01edd850f0cf2f396589d32b57b9984de3353a738947
加入集群
4.安装gitlab
选择安装在k8s-master
下载wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-15.9.1-ce.0.el7.x86_64.rpm
执行rpm -i gitlab-ce-15.9.1-ce.0.el7.x86_64.rpm
编辑 /etc/gitlab/gitlab.rb 文件:
修改 external_url 访问路径 http://:
gitlab_rails[‘time_zone’] = ‘Asia/Shanghai’
puma[‘worker_processes’] = 2
sidekiq[‘max_concurrency’] = 8
postgresql[‘shared_buffers’] = “128MB”
postgresql[‘max_worker_processes’] = 4
prometheus_monitoring[‘enable’] = false
更新配置并重启
gitlab-ctl reconfigure
gitlab-ctl restart
服务地址:http://192.168.0.201:28080
注意:gitlab的内存小了跑步起来
5.docker镜像仓库Harbor
这个不好下载,直接使用阿里云的docker镜像仓库即可。
可以将账号信息配置到k8s方便后面使用
kubectl create secret docker-registry harbor-secret --docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=xxx@qq.com --docker-password=xxx -n kube-devops
6.安装jenkins
可以选择用k8s helm安装,但是我遇到在k8s中安装的jenkins插件不可用,所以改成docker compose安装
在k8s-node安装
docker-compose.yaml内容如下:
version: '3.0'
services:
jenkins:
image: jenkins/jenkins:lts
privileged: true
user: root
ports:
- 8080:8080
- 50000:50000
container_name: jenkins-wg
volumes:
- /root/jenkins/conf:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker #映射docker的可执行文件
- /etc/docker/daemon.json:/etc/docker/daemon.json #映射daemon.json文件
执行docker-compose up -d
访问地址 http://192.168.0.203:8080/
配置
1.jenkins插件安装
点击系统管理》插件管理》高级配置Deploy Plugin进行安装,也可在available plugin选择安装
在高级配置》升级站点修改更新插件服务地址默认是:https://updates.jenkins.io/update-center.json
可以改为http
git, gitlab, kubernetes, pipeline, config file Provider,ssh agent搜索安装这些插件,需要什么就安装什么,第一次会花很久时间
2.设置系统配置
系统管理》系统配置,配置主目录/var/jenkins_home,Jenkins URL:http://192.168.0.203:8080/
gitlab
点击test connection测试是否与gitlab通信,这里需要配置gitlab的Credential,不然在gitlab配置webhook时会失败
2.配置全局工具
在系统管理》全局工具配置
安装git,jdk,docker,go等工具方便流水线环境使用
3.节点管理
编辑节点,配置标签(在jenkinsFile里面会使用)
点击cloud新增,配置k8s信息,这个是为了把pipeline使用到k8s,
配置k8s api-server地址,可以通过kubectl cluster-info查看
Kubernetes 服务证书 key:通过sudo cat /etc/kubernetes/pki/ca.crt查看
选择配置k8s凭据(k8s凭据),可以点击连接测试测试
填写jenkins地址:http://192.168.0.203:8080
4.配置config
系统管理》managed File,需要安装config File插件
我这里两个是一样的,cat ~/.kube/config将内容保存下来
5.配置凭证
系统管理》凭据
具体每个根据需求选择不同
6.生成cert证书
将./kube/config中的
certificate-authority-data——>base 64解码——>ca.crt
client-certificate-data——>base 64解码——>client.crt
client-key-data——>base 64解码——>client.key
如:
echo ‘client-certificate-data 内容’ | base64 -d > client.crt
openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
输入密码:一定要输入
导出cert.pfx, 可以通过scp下载
创建一个流水线
流水线选择:
配置gitlab
1.创建一个代码仓库cicd,并进入到仓库,点击设置-》webhook
可以点击测试是否可用,如果在Jenkins系统管理》系统配置的gitlab配置不正确,可能不成功
项目
项目结构
main.go 是项目的测试代码
Dockerfile是将项目打包成docker镜像的打包文件
cicd-demo.yaml是k8s部署文件
JenkinsFile是流水线脚本文件,就是选择SCM的那个文件
具体每个文件内容
main.go
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run("0.0.0.0:8082") // 监听并在 0.0.0.0:8081 上启动服务
}
Dockerfile
FROM golang:1.20 as builder
WORKDIR /go/cicd/server
COPY . .
RUN go env -w GO111MODULE=on \
&& go env -w GOPROXY=https://goproxy.cn,direct \
&& go env -w CGO_ENABLED=0 \
&& go env \
&& go mod tidy \
&& go build -ldflags="-w -s" -o server ./main.go
FROM alpine:latest
LABEL MAINTAINER="xxx@qq.com"
EXPOSE 8888
ENTRYPOINT ./server
yaml文件
---
apiVersion: v1
kind: Namespace
metadata:
labels:
kubernetes.io/metadata.name: k8s-cicd-dev
name: k8s-cicd-dev
---
apiVersion: v1
kind: Secret
metadata:
name: secret-dockercfg
namespace:
type: kubernetes.io/dockercfg
data:
.dockercfg: k8s-cicd-dev|
eyJuY29tIiiwiYXV0aCI6Ik56QTNOVEUwT0RBd1FIRnhMbU52YlRwM1lXNW5aMlZBTmpFMiJ9fX0=
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: k8s-cicd-demo
component: wolfcode-devops
tier: backend
name: k8s-cicd-demo
namespace: k8s-cicd-dev
spec:
progressDeadlineSeconds: 600
replicas: 1
selector:
matchLabels:
app: k8s-cicd-demo
component: wolfcode-devops
tier: backend
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 100%
type: RollingUpdate
template:
metadata:
labels:
app: k8s-cicd-demo
component: wolfcode-devops
tier: backend
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: k8s-cicd-demo
image: registry.cn-hangzhou.aliyuncs.com/DOCKERHUB_NAMESPACE/APP_NAME:SNAPSHOT-BUILD_NUMBER
readinessProbe:
httpGet:
path: /users
port: 8082
timeoutSeconds: 10
failureThreshold: 30
periodSeconds: 5
imagePullPolicy: Always
ports:
- containerPort: 8082
protocol: TCP
resources:
limits:
cpu: 300m
memory: 600Mi
requests:
cpu: 100m
memory: 100Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
labels:
app: k8s-cicd-demo
component: wolfcode-devops
name: k8s-cicd-demo
namespace: k8s-cicd-dev
spec:
ports:
- name: http
port: 8082
protocol: TCP
targetPort: 8082
selector:
app: k8s-cicd-demo
component: wolfcode-devops
tier: backend
sessionAffinity: None
type: NodePort
JenkinsFile
注:流水线语法可以在流水线中生成,如下图
pipeline {
agent {
kubernetes {
label 'go'
}
}
parameters {
gitParameter name: 'BRANCH_NAME', branch: '', branchFilter: '.*', defaultValue: 'origin/main', description: '请选择要发布的分支', quickFilterEnabled: false, selectedValue: 'NONE', tagFilter: '*', type: 'PT_BRANCH'
string(name: 'TAG_NAME', defaultValue: 'snapshot', description: '标签名称,必须以 v 开头,例如:v1、v1.0.0')
}
environment {
GIT_REPO_URL = '192.168.0.201:28081'
GIT_CREDENTIAL_ID = 'git-user-pass'
GIT_ACCOUNT = 'gitlab-instance-41ae79b6' // change me
KUBECONFIG_CREDENTIAL_ID = 'c8eddaaa-273f-4c18-8dd9-05dc6474'
REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
DOCKERHUB_NAMESPACE = 'wg_go' // docker hud 命名空间
APP_NAME = 'go_cicd' // docker hub 仓库名
DOCKER_CREDENTIAL_ID = 'docker-user-pass' // docker仓库凭据
SSH_HOST = 'root@192.168.0.201'
}
stages {
stage('checkout scm') {
steps {
sh 'echo 11'
checkout scmGit(branches: [[name: "$BRANCH_NAME"]], extensions: [], userRemoteConfigs: [[credentialsId: "$GIT_CREDENTIAL_ID", url: 'http://192.168.0.201:28080/gitlab-instance-41ae79b6/cicd.git']])
}
}
stage('build & push') {
steps {
sh 'echo 22'
sh 'docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER .'
withCredentials([usernamePassword(passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME', credentialsId: "$DOCKER_CREDENTIAL_ID",)]) {
sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
}
}
}
stage('deploy to dev') {
steps {
// 部署项目到k8s一定要用configFileProvider
// configFileProvider([configFile(fileId: 'c8eddaaa-273f-4c18-8dd9-05dc647e3ae4', targetLocation: 'KUBECONFIG')]) {
// // input(id: 'deploy-to-dev', message: 'deploy to dev?')
// sh '''
// sed -i'' "s#REGISTRY#$REGISTRY#" cicd-demo-dev.yaml
// sed -i'' "s#DOCKERHUB_NAMESPACE#$DOCKERHUB_NAMESPACE#" cicd-demo-dev.yaml
// sed -i'' "s#APP_NAME#$APP_NAME#" cicd-demo-dev.yaml
// sed -i'' "s#BUILD_NUMBER#$BUILD_NUMBER#" cicd-demo-dev.yaml
// scp cicd-demo-dev.yaml root@192.168.0.201:/root/devops/
// ssh root@192.168.0.201 "kubectl apply -f /root/devops/cicd-demo-dev.yaml"
// '''
// }
// 如果不是k8s节点不行
// container (name:'kubectl', shell: '/bin/sh' ) {
// withCredentials([file(credentialsId: 'fcea5464-c42e-4fb7-9038-c8672d47d919', variable: 'KUBECONFIG')]) {
// sh '''
// echo $KUBECONFIG > /.kube/config &&
// sed -i'' "s#REGISTRY#$REGISTRY#" cicd-demo-dev.yaml
// sed -i'' "s#DOCKERHUB_NAMESPACE#$DOCKERHUB_NAMESPACE#" cicd-demo-dev.yaml
// sed -i'' "s#APP_NAME#$APP_NAME#" cicd-demo-dev.yaml
// sed -i'' "s#BUILD_NUMBER#$BUILD_NUMBER#" cicd-demo-dev.yaml
// kubectl apply -f cicd-demo-dev.yaml
// '''
// }
// }
// jenkins是单独服务器,通过ssh部署k8s
sshagent(['72e9a02a-f811-448f-88d6-ae1da13500da']) {
script {
sh '''
sed -i'' "s#REGISTRY#$REGISTRY#" cicd-demo-dev.yaml
sed -i'' "s#DOCKERHUB_NAMESPACE#$DOCKERHUB_NAMESPACE#" cicd-demo-dev.yaml
sed -i'' "s#APP_NAME#$APP_NAME#" cicd-demo-dev.yaml
sed -i'' "s#BUILD_NUMBER#$BUILD_NUMBER#" cicd-demo-dev.yaml
'''
sh "scp cicd-demo-dev.yaml ${env.SSH_HOST}:/root/devops/cicd"
sh "ssh ${env.SSH_HOST} 'kubectl apply -f /root/devops/cicd/cicd-demo-dev.yaml'"
}
}
}
}
}
}
测试部署
点击代码提交,触发流水线发布:
查看日志:
错误:
根据错误消息排查
成功:
流水线常见错误
https://blog.csdn.net/skyjian10/article/details/124868230
https://blog.csdn.net/weixin_45348606/article/details/135482915
gitlab插件问题
配置jenkins文件,在流水线中选择from SCM,配置git地址
git clone http://root:wangge123@192.168.0.201:28080/gitlab-instance-41ae79b6/cicd.git
一直构建失败,jenkins默认是拉取master,但是gitLab建的库默认是main, 在流水线吧分支改为main
jenkins docker打包失败 需要安装docker
jenkins 部署应用到k8s
https://aahil13.hashnode.dev/deploying-an-application-to-kubernetes-cluster-using-jenkins-cicd-pipeline
Error loading key “/var/jenkins_home/workspace/cicd-test@tmp/private_key_12635813253284098532.key”: invalid format
原因是ssh key填的是公钥,要填写私钥
Unable to connect to the server: x509:https://www.slingacademy.com/article/solving-kubernetes-error-x509-certificate-signed-by-unknown-authority/
https://download.csdn.net/blog/column/11866583/126112342
更多推荐
所有评论(0)