Menu Close

gitlab+jenkins+k8s实现自动构建并部署至集群

安装gitlab社区版

[root@localhost ~]#yum list |grep gitlab

[root@localhost ~]#yum install -y gitlab-ce

[root@localhost ~]# wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-15.9.8-ce.0.el7.x86_64.rpm

docker安装jenkins

[root@localhost ~]#docker run -d -u root -p 8888:8080 -v /data/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /etc/docker:/etc/docker -v /usr/local/jdk17:/usr/local/java -v /usr/local/maven:/usr/local/maven -v /etc/localtime:/etc/localtime:ro -e JAVA_OPTS=-Dhudson.model.DownloadService.noSignatureCheck=true –name jenkins jenkins/jenkins:2.516.2

配置maven源

创建maven配置文件目录

Doceker安装 jenkins时本地 /data/jenkins_home挂在至jenkins容器内的 /var/jenkins_home目录

创建maven配置文件目录

[root@localhost ~]# mkdir -p /data/jenkins_home/appconfig/maven

新增settings.xml

[root@localhost ~]# vim /date/jenkins_home/appconfig/maven/settings.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<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 http://maven.apache.org/xsd/settings-1.0.0.xsd”>

<pluginGroups>

</pluginGroups>

<proxies>

</proxies>

<servers>

</servers>

<mirrors>

<mirror>

<id>nexus-aliyun</id>

<url>http://maven.aliyun.com/nexus/content/groups/public</url>

</mirror>

</mirrors>

<localRepository>/root/.m2</localRepository>

<profiles>

<profile>

<id>jdk-1.8</id>

<activation>

<jdk>1.8</jdk>

</activation>

<properties>

<maven.compiler.source>1.8</maven.compiler.source>

<maven.compiler.target>1.8</maven.compiler.target>

<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>

</properties>

</profile>

</profiles>

</settings>

重启容器:

[root@localhost ~]# docker restart jenkins

Jenkins默认插件及git、镜像仓库、k8s凭证配置

Jenkins 中的 :全局安全配置 host key verification configuration修改为不验证

GitLab ssh

创建用户名密码类型的gitlab代码仓库凭证

切换至jenkins容器中创建密钥对

[root@localhost ~]# docker exec -it 910ff6ec8135 bash

root@910ff6ec8135:~# ssh-keygen -t rsa -C java@126.com

后续步骤全部enter (知识点ssh-keygen和ssh-keyscan的区别)

在git仓库上创建java@126.com并切换至此目录用户设置中SSH密钥添加此公钥id_rsa.pub

私钥 root@910ff6ec8135:/# cat /root/.ssh/id_rsa

复制到jenkins流水线项目的用户下

阿里云镜像仓库ssh

创建用户名密码类型的aliyun registry镜像仓库凭证,ID为aliyun username with password

编写pipeline安装以下常用插件

确认Pipeline、Docker Pipeline、

Pipeline: GitHub Groovy Libraries、Pipeline: Stage View Plugin (安装了pipeline默认就有)

是否已经安装

Pipeline:核心插件,通常默认安装。

Docker Pipeline:用于在 Pipeline 中使用 Docker 相关步骤(如 docker.build())。

Pipeline: GitHub Groovy Libraries:用于共享 Pipeline 库(即使你用 Gitee,也可以使用)。

Pipeline: Stage View Plugin:提供可视化构建阶段视图,通常随 Pipeline 一起安装。

Gitee Plugin:如果你使用阿里云 Code 或 Gitee,这个插件很有用(支持 Webhook 触发等)

进入 Jenkins Web 界面。

点击 “Manage Jenkins” -> “Manage Plugins”。

切换到 “Installed” 标签页。

搜索上述插件名称,确认是否已安装。

这边的 Docker Pipeline, Stage View Plugin是没有安装的,安装下

将kubectl命令文件拷贝到jenkins容器

注意 此宿主环境需要安装 kubectl

导入 kubernetes.repo 仓库

cat > /etc/yum.repos.d/kubernetes.repo << EOF

> [kubernetes]

> name=Kubernetes

> baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64

> enabled=1

> gpgcheck=0

> repo_gpgcheck=0

> gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

> EOF

再将K8S命令拷贝到jenkins容器内。

[root@k8s-master-128 ~]# docker cp /usr/bin/kubectl jenkins:/usr/bin

将k8s集群配置文件拷贝到jenkins

[root@localhost ~]# docker cp /root/kubectl jenkins:/usr/bin

进入容器合适拷贝情况

在 Jenkins 中添加 kubeconfig 凭据

有两种方法:

1:直接将 kubeconfig 集群的凭证直接拷贝至 jenkins容器内并给与权限,但不推荐,不安全

[root@master ~]# docker cp /root/.kube jenkins:/root/.kube

#进入jenkins容器增加config文件执行权限

[root@master ~]# docker exec -it jenkins bash

[root@9c4198ba00e7 .kube]# chmod +x config

2:在 jenkins 中添加 kubeconfig 凭证,并查看修改 Jenkinsfile 使用 kubeconfig 凭据(本文中的Jenkinsfile是修改过的完整版)

准备Dockerfile

# version 1.0

# 基础镜像

FROM openjdk:8-jre

# 维护人

MAINTAINER senfel<187@sina.cn>

# 创建目录

RUN mkdir -p /home/app

# 拷贝项目jar

COPY ./target/k8s-demo-0.0.1-SNAPSHOT.jar /home/app/app.jar

# 执行命令启动jar

ENTRYPOINT [“java”,”-jar”,”/home/app/app.jar”]

# 暴露端口

EXPOSE 8888

添加k8s的deployment.yaml配置

apiVersion: apps/v1

kind: Deployment

metadata:

name: deployment-k8s-demo

namespace: default # 可选:明确指定命名空间

spec:

replicas: 3

selector:

matchLabels:

app: k8s-demo

template:

metadata:

labels:

app: k8s-demo

spec:

containers:

– name: k8s-demo

image: k8s-demo-image #image: k8s-demo-image 是一个占位符,不是真实镜像,会被 Jenkins 构建时动态替换

ports:

– name: http

containerPort: 8888

# 可选:添加就绪和存活探针(根据你的应用调整)

# readinessProbe:

# httpGet:

# path: /actuator/health

# port: 8888

# initialDelaySeconds: 20

# periodSeconds: 10

# livenessProbe:

# httpGet:

# path: /actuator/health

# port: 8888

# initialDelaySeconds: 30

# periodSeconds: 10

# 关键:添加 imagePullSecrets

imagePullSecrets:

– name: aliyun-secret # 这个名字必须和你用 kubectl 创建的 Secret 一致

— # 在一个yaml文件中通过—分割多个资源对象

apiVersion: v1

kind: Service # 声明一个Service资源对象

metadata:

name: service-k8s-demo

spec:

type: NodePort

selector: # service-k8s-demo将选择标签包含app=k8s-demo的pod

app: k8s-demo

ports:

– name: http

port: 8888 # Service监听端口

targetPort: 8888 # 转发到后端Pod的端口号

protocol: TCP # tcp协议

nodePort: 30888 # 外网访问端口,范围:30000-32767

添加Jenkinsfile

pipeline{

agent any

environment {

WS = “${WORKSPACE}” REGISTRY= “registry.cn-hangzhou.aliyuncs.com” IMAGE_NAME = “registry.cn-hangzhou.aliyuncs.com/jchj_code/devops:${env.BUILD_ID}”

K8S_NAMESPACE = “default”

}

//定义流水线的加工流程

stages {

//流水线的所有阶段

stage(‘step1:env check’){

steps {

sh ‘pwd && ls -alh’

sh ‘printenv’

sh ‘docker version’

sh ‘java -version’

sh ‘git –version’

}

}

stage(‘step2:compile’){

agent {

docker {

image ‘maven:3-alpine’

args ‘-v maven-repository:/root/.m2’

}

}

steps {

sh ‘pwd && ls -alh’

sh ‘mvn -v’

sh ‘cd ${WS} && mvn clean package -s “/var/jenkins_home/appconfig/maven/settings.xml” -Dmaven.test.skip=true’

}

}

stage(‘step3:build image’){

steps {

sh ‘pwd && ls -alh’

sh ‘docker build -t ${IMAGE_NAME} .’

}

}

stage(‘step4:push image’){

steps {

withCredentials([[$class: ‘UsernamePasswordMultiBinding’, credentialsId: ‘be16a729-67c3-4f0c-8702-abdcd4cc3f67’, usernameVariable: ‘REGISTRY_USERNAME’, passwordVariable: ‘REGISTRY_PASSWORD’]]) { sh “”” docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY}

docker push ${IMAGE_NAME} docker rmi ${IMAGE_NAME}

“””

}

}

}

stage(‘step5: deployment’) {

steps {

// 使用 Secret File 类型凭据注入 kubeconfig

withCredentials([file(

credentialsId: ‘c8fab7a3-f7a4-4a11-8212-ea947cdaf7fa’, // ← 你在 Jenkins 中创建的 kubeconfig 凭据 ID

variable: ‘KUBECONFIG’ // 注入为环境变量 KUBECONFIG

)]) {

sh ”’

echo “Using kubeconfig: $KUBECONFIG”

# 替换 deployment.yaml 中的镜像

sed -i “s#k8s-demo-image#${IMAGE_NAME}#g” deployment.yaml

echo “=== Updated deployment.yaml ===”

cat deployment.yaml

# 设置 KUBECONFIG 环境变量,kubectl 会自动读取

export KUBECONFIG=$KUBECONFIG

# 执行部署

kubectl apply -f deployment.yaml –namespace=${K8S_NAMESPACE}

”’

}

}

}

}

}

注意项:Jenkinsfile文件中的仓库地址需要更改为自己阿里云仓库的地址以及登录阿里云仓库凭证的 ID

项目根目录下新增Dockerfile、deployment.yaml、Jenkinsfile

创建 Java 代码和 pom.xml文件

在 Git 仓库 Web 界面进入你的项目

创建 pom.xml文件

<?xml version=”1.0″ encoding=”UTF-8″?>

<project xmlns=”http://maven.apache.org/POM/4.0.0″

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0

http://maven.apache.org/xsd/maven-4.0.0.xsd”>

<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>

<artifactId>k8s-demo</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>jar</packaging>

<name>k8s-demo</name>

<description>Demo project for Jenkins CI/CD</description>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.7.18</version> <!– 兼容 Java 8 –>

<relativePath/>

</parent>

<properties>

<java.version>1.8</java.version>

<maven.compiler.source>1.8</maven.compiler.source>

<maven.compiler.target>1.8</maven.compiler.target>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>

<dependencies>

<!– Spring Boot Web Starter –>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!– Spring Boot Test Starter –>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

</dependencies>

<build>

<plugins>

<!– Spring Boot Maven Plugin –>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<configuration>

<excludes>

<exclude>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-configuration-processor</artifactId>

</exclude>

</excludes>

</configuration>

</plugin>

</plugins>

</build>

</project>

创建 Java 源码文件(src/main/java/com/example/k8sdemo/Application.java)多级目录下的文件

package com.example.k8sdemo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication

@RestController

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

@GetMapping(“/”)

public String home() {

return “Hello from Jenkins CI/CD!”;

}

}

创建 src/main/resources/application.yml(可选)

server:

port: 8080

spring: application:

name: k8s-demo

点击 Add file → Create new file

在文件名输入框中输入完整路径:

配置jenkins pipeline任务

创建jenkins pipeline任务,并设置需要的参数。

新建pipeline任务

点击“新建任务”,输入名称并选择“流水线”(pipeline),然后点击确定。

新建pipeline任务

新建pipeline

配置 pipeline任务

进入任务的配置界面,在流水线(pipeline)设置部分,选择“Pipeline script from SCM”。SCM选项选为“Git”,配置好工程的git地址以及获取代码的凭证信息。然后在“Additional Behaviours”中添加“Clean before checkout”。

测试pipeline任务

在创建的pipeline任务中,点击“立即构建”即可立即执行pipeline任务。

构建成功

查看k8s是否已经部署k8s

k8s 已经部署完成,但是deployment处于READY状态,

查看deployment的pod

[root@k8s-master-128 ~]# kubectl get pods -n default

[root@k8s-master-128 ~]# kubectl describe pod deployment-k8s-demo-7775656d96-47h26 -n default

这个错误说明:

Kubernetes 的 kubelet(运行在节点上)无法从阿里云私有仓库拉取镜像,因为没有认证权限。

虽然我在 Jenkinsfile中执行 docker login 并成功推送了镜像 ,Jenkins 服务器登录了阿里云registry

但Kubernetes 集群节点并没有登录,所以无法拉取私有镜像

解决方案:创建 imagePullSecret

你需要在 Kubernetes 中创建一个 Secret,用于存储阿里云镜像仓库的登录凭证,并在 Deployment 中引用它。

创建 imagePullSecret

在任意能执行 kubectl 的机器上运行(如 master 节点或 Jenkins 服务器):

kubectl create secret docker-registry aliyun-registry-secret \

–docker-server=registry.cn-hangzhou.aliyuncs.com \

–docker-username=你的阿里云账号 \ # 通常是邮箱或主账号ID

–docker-password=你的阿里云容器镜像密码 \ # 注意:不是登录密码!

–docker-email=你@aliyun.com \

-n default

创建成功后验证

[root@k8s-master-128 ~]# kubectl get secret aliyun-secret -n default -o yaml

显示成功

最后:在 deployment.yaml 中引用它

确保你的 deployment.yaml 包含:

查看k8s集群已部署成功

至此,Jenkins已经将git 分支部署在k8s集群

设置GitLab自动触发jenkins

前面的步骤中已经完成了手动执行jenkins执行pipeline任务完成构建部署任务,下面说明如何在代码提交后让gitlab自动触发jenkins执行pipeline任务。

插件确认

jenkins中安装gitlab插件,我们在初始已经安装了gitlab并配置了凭证。

以下直接以gitee测试,gitlab也是一样的步骤和操作。

查看jenkins webhook调用路径并生成密匙

webhook调用路径

在高级选项中生成 生成webhook调用密匙

GitLab配置webhook

点击测试

查看K8S自动触发部署成功

无觅评论,优化体验,加强品牌价值