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

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐