基于GitLab CI/CD + Kubernetes的自动化部署平台搭建
一、系统架构
| 主机名 | IP地址 | 角色 | 软件 |
|---|---|---|---|
| harbor | 172.25.254.200 | harbor | docker,harbor |
| k8s-master | 172.25.254.20 | master | kubeadm, kubelet, kubectl, etcd,api-server,controller-manager,scheduler |
| k8s-node 1 | 172.25.254.21 | node 1 | kubelet,kube-proxy,docker |
| k8s-node 2 | 172.25.254.22 | node 2 | kubelet,kube-proxy,docker |
| gitlab-server | 172.25.254.23 | server | docker, gitlab |
| gitlab-runner | 172.25.254.24 | runner | docker, gitlab-runner |
二、初始化环境(所有主机)
2.1 关闭防火墙和SELinux
# 关闭防火墙 [root@harbor ~]# systemctl stop firewalld [root@harbor ~]# systemctl disable firewalld # 关闭SELinux [root@harbor ~]# setenforce 0 [root@harbor ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config2.2 配置本地YUM源
# 挂载光盘 [root@harbor ~]# mount /dev/sr0 /mnt # 创建本地yum源 [root@harbor ~]# cat > /etc/yum.repos.d/local.repo << 'EOF' [base01] name=base baseurl=/mnt/BaseOS enable=1 gpgcheck=0 [base02] name=app baseurl=/mnt/AppStream enable=1 gpgcheck=0 EOF # 安装工具依赖 [root@harbor ~]# yum install vim net-tools tree zip git -y2.3 配置主机名
[root@harbor ~]# cat >> /etc/hosts << 'EOF' 172.25.254.20 k8s-master master 172.25.254.21 k8s-node1 node1 172.25.254.22 k8s-node2 node2 EOF2.4 关闭swap
[root@harbor ~]# sed '/swap/s/^/#/g' -i /etc/fstab [root@harbor ~]# swapoff -a [root@harbor ~]# swapon -s #没有显示才是对的2.5 内核参数配置(缺失会导致CRI通信失败)
# 添加内核参数 [root@harbor ~]# cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF # 生效参数 [root@harbor ~]# sysctl --system # 加载 br_netfilter 模块 [root@harbor ~]# modprobe br_netfilter [root@harbor ~]# modprobe vxlan [root@harbor ~]# echo "br_netfilter" >> /etc/modules-load.d/k8s.conf [root@harbor ~]# echo "vxlan" >> /etc/modules-load.d/k8s.conf [root@harbor ~]# lsmod | grep br_netfilter # 有输出则正确2.6 部署Docker
# 安装依赖 [root@harbor ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加Docker阿里云镜像源 [root@harbor ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装Docker(指定版本) [root@harbor ~]# yum install -y docker-ce # 启动Docker [root@harbor ~]# systemctl enable docker [root@harbor ~]# systemctl start docker2.7 配置Docker阿里云镜像加速器
# 创建docker配置目录 [root@harbor ~]# mkdir -p /etc/docker # 配置镜像加速器 [root@harbor ~]# cat > /etc/docker/daemon.json << 'EOF' { "registry-mirrors": [ "https://docker.1ms.run", "https://p1umdw8d.mirror.aliyuncs.com", "https://docker.xuanyuan.cn", "https://registry.docker-cn.com", "https://mirror.ccs.tencentyun.com" ], "insecure-registries": ["172.25.254.200"] } EOF # 重启Docker [root@harbor ~]# systemctl daemon-reload [root@harbor ~]# systemctl restart docker # 验证加速器是否生效 [root@harbor ~]# docker info | grep -A 10 "Registry Mirrors"三、部署Harbor
3.1 获取docker-compose文件
[root@harbor ~]# wget https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 # 查看文件 [root@harbor ~]# ls docker-compose-linux-x86_64 # 移动位置 [root@harbor ~]# mv docker-compose-linux-x86_64 /usr/bin/docker-compose # 添加执行权限 [root@harbor ~]# chmod +x /usr/bin/docker-compose # 查看版本 [root@harbor ~]# docker-compose version Docker Compose version v2.2.33.2 版本:Harbor 2.10.2
# 下载Harbor(选择需要的版本) [root@harbor ~]# wget https://github.com/goharbor/harbor/releases/download/v2.4.1/harbor-offline-installer-v2.4.1.tgz # 解压 [root@harbor ~]# tar -zxf harbor-offline-installer-v2.14.0.tgz [root@harbor ~]# cd harbor # 复制配置文件 [root@harbor harbor]# cp harbor.yml.tmpl harbor.yml # 修改配置 [root@harbor harbor]# vim harbor.yml # 第5行:hostname改为服务器IP hostname: 172.25.254.200 #https: 注释 #https port for harbor, default is 443 #port: 443 注释 #The path of cert and key files for nginx #certificate: /your/certificate/path 注释 #private_key: /your/private/key/path 注释3.3 启动Harbor
# 运行安装脚本 [root@harbor harbor]# ./install.sh # 启动Harbor(后台运行) [root@harbor harbor]# docker-compose up -d # 查看状态 [root@harbor harbor]# docker-compose ps3.4 Harbor页面配置
第一步:访问Harbor
- 打开浏览器,输入:http://172.25.254.200
- 用户名:admin
- 密码:Harbor12345
- 点击"Log in"
第二步:创建项目
1. 登录后,点击"Projects"(项目)
2. 点击"New Project"(新建项目)
3. 填写:
- Project Name(项目名):k8s
- Access Level(访问级别):选择"Public"(公开)
4. 点击“OK”
四、部署K8S
4.1 安装cri-docerd(master/node节点中安装)
[root@master ~]# ls anaconda-ks.cfg cri-dockerd-0.3.14-3.el8.x86_64.rpm libcgroup-0.41-19.el8.x86_64.rpm [root@master ~]# rpm -ivh *.rpm [root@master ~]# vim /lib/systemd/system/cri-docker.service ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=172.25.254.200/k8s/pause:3.10.1 [root@master ~]# systemctl daemon-reload [root@master ~]# systemctl enable --now cri-docker [root@master ~]# systemctl status cri-docker [root@master ~]# docker login 172.25.254.200 -u admin -p Harbor12345 [root@node1 ~]# docker login 172.25.254.200 -u admin -p Harbor12345 [root@node2 ~]# docker login 172.25.254.200 -u admin -p Harbor12345 # 所有主机配置kubernetes安装源 [root@master ~]# vim /etc/yum.repos.d/kubernetes.repo [kubernetes] name = kubernetes baseurl = https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/ gpgcheck = 04.2 安装构建kubernetes集群所需软件
[root@master ~]# dnf install kubelet kubeadm kubectl -y [root@master ~]# systemctl enable --now kubelet.service # 所有节点执行:配置 kubelet 默认使用 cri-dockerd 套接字 [root@master ~]# cat > /etc/sysconfig/kubelet << EOF KUBELET_EXTRA_ARGS="--container-runtime-endpoint=unix:///var/run/cri-dockerd.sock --runtime-request-timeout=15m" EOF # 重启 kubelet 生效 [root@master ~]# systemctl daemon-reload [root@master ~]# systemctl restart kubeletmaster节点中 kubectl 和kubeadm 补齐
[root@master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc [root@master ~]# echo "source <(kubeadm completion bash)" >> ~/.bashrc [root@master ~]# source ~/.bashrc4.3 下载kubernetes集群所需镜像
下载镜像
[root@master ~]# kubeadm config images pull \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.35.3 \ --cri-socket=unix:///var/run/cri-dockerd.sock上传到本地harbor
[root@master ~]# docker login 172.25.254.200 -u admin -p Harbor12345 [root@master ~]# docker images --format "{{.Repository}}:{{.Tag}}" | awk -F "/" '/google_containers/{system("docker tag "$0" 172.25.254.200/k8s/"$3)}' [root@master ~]# docker images --format "{{.Repository}}:{{.Tag}}" | awk -F "/" '/172.25.254.200/{system("docker push "$0)}'4.4 在master中初始化kubernetes集群
在master中完成集群初始化
[root@master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 \ --image-repository 172.25.254.200/k8s \ --kubernetes-version v1.35.3 \ --cri-socket=unix:///var/run/cri-dockerd.sock 。。。 [root@master ~]# mkdir -p $HOME/.kube [root@master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@master ~]# chown $(id -u):$(id -g) $HOME/.kube/config [root@master ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" > ~/.bash_profile [root@master ~]# source ~/.bash_profile 在node1\node2上执行: #每个人不一样,其他主机加入本集群的凭证 [root@node1/node2 ~]# kubeadm join 172.25.254.20:6443 --token 5myaaa.bivwm2319b1be73i \ --discovery-token-ca-cert-hash sha256:789e1df79316e434e3864a2e243f3488f6652ebd5cf48885bdfdd83ef73cd9a5 \ --cri-socket unix:///var/run/cri-dockerd.sock [root@master ~]# kubectl get nodes4.5 安装网络插件
4.5.1 加载离线镜像
# 加载离线镜像 [root@master ~]# ls 172.25.254.200-flannel-io-flannel-cni-plugin-v1.9.0-flannel1.tar 172.25.254.200-flannel-io-flannel-v0.28.1.tar # 推送到私有仓库 [root@master ~]# docker load -i 172.25.254.200-flannel-io-flannel-v0.28.1.tar [root@master ~]# docker load -i 172.25.254.200-flannel-io-flannel-cni-plugin-v1.9.0-flannel1.tar4.5.2 打标签
[root@master ~]# docker tag 172.25.254.200/flannel-io/flannel:v0.28.1 172.25.254.200/flannel-io/flannel:v0.28.1 [root@master ~]# docker tag 172.25.254.200/flannel-io/flannel-cni-plugin:v1.9.0-flannel1 172.25.254.200/flannel-io/flannel-cni-plugin:v1.9.0-flannel14.5.3 推送到私有仓库
[root@master ~]# docker push 172.25.254.200/flannel-io/flannel:v0.28.1 [root@master ~]# docker push 172.25.254.200/flannel-io/flannel-cni-plugin:v1.9.0-flannel14.5.4 修改kube-flannel.yml
[root@master ~]# vim kube-flannel.yml三个修改的地方:
4.6 应用网络插件
[root@master ~]# kubectl apply -f kube-flannel.yml4.7 测试
五、搭建CI/CD环境
5.1 部署GitLab代码仓库
5.1.1 在gitlab-server服务器执行如下命令来创建挂载卷
[root@gitlab-server ~]# docker volume create gitlab-etc [root@gitlab-server ~]# docker volume create gitlab-log [root@gitlab-server ~]# docker volume create gitlab-opt5.1.2 修改systcl.conf文件,防止后续运行是报错信息
[root@gitlab-server ~]# cat >> /etc/sysctl.conf <<-'EOF' kernel.perf_event_max_sample_rate=79000 vm.max_map_count=262144 EOF sysctl -p5.1.3 执行如下命令来安装gitlab服务容器
[root@gitlab-server ~]# docker run --detach \ --hostname 172.25.254.23 \ -p 443:443 \ -p 80:80 \ --name gitlab \ --restart always \ --volume gitlab-etc:/etc/gitlab \ --volume gitlab-log:/var/log/gitlab \ --volume gitlab-opt:/var/opt/gitlab \ --shm-size 256m \ gitlab/gitlab-ee:17.3.1-ee.0 [root@gitlab-server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE gitlab/gitlab-ce 17.3.1-ce.0 b3c3467dc55c 5 weeks ago 3.03GB [root@gitlab-server ~]# docker psGitlab 服务器的登录密码可通过如下命令来查看
[root@gitlab-server ~]# docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password Password: oJhP0nKx3SniZWHzgY+ckL7aYqxpMHabsrTwQ6n7YU0=5.2 初始化GitLab
打开浏览器,输入http://172.25.254.23后,输入root用户名以及前面查询到的密码
点击登录按钮后,进入到界面
点击左上角的圆形图片,进入到User链接后点击Preferences
再点击Password便能修改密码
5.3 部署GitLab Runner
# 执行如下命令下载GitLab提供的YUM安装源 [root@gitlab-runner local]# curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash # 查看仓库源 [root@gitlab-runner local]# ls /etc/yum.repos.d/ base.repo docker-ce.repo kubernetes.repo redhat.repo runner_gitlab-runner.repo # 执行如下命令安装GItLab-Runner [root@gitlab-runner local]# yum install -y gitlab-runner-17.3.1 # 接下来再执行如下命令查看所有用户 [root@gitlab-runner local]# cut -d: -f1 /etc/passwd # 我们直接使用 root 用户来操作,执行如下命令来卸载原始信息 [root@gitlab-runner local]# sudo gitlab-runner uninstall # 然后执行如下命令安装并设置 root 用户为操作用户 [root@gitlab-runner local]# gitlab-runner install --working-directory /home/gitlab-runner --user root Runtime platform arch=amd64 os=linux pid=20348 revision=66269445 version=17.3.1 # 接下执行如下命令来重新加载 [root@gitlab-runner local]# systemctl daemon-reload # 然后启动 gitlab-runner 并设置为开机自启 [root@gitlab-runner local]# systemctl enable --now gitlab-runner # 为了验证,我们可查看当前 runner 用户 [root@gitlab-runner local]# ps aux | grep gitlab-runner [root@gitlab-runner local]# git config --system --add safe.directory '*' [root@gitlab-runner local]# chmod -R 777 /home/gitlab-runner [root@gitlab-runner local]# systemctl restart gitlab-runner5.4 注册Runner
回到 Gitlab 服务管理界面并点击界面左下角的 Admin 按钮,点击后再点击左右菜单中的 CI/CD 链接下的 Runners 链接
然后点击上图中的New instance runner按钮
填写好一个标签后,其它都不选也不用输入。然后点击界面下的Create runner按钮
在这个界面中选择好操作系统后,复制上图指定的代码,然后在 gitlab-runner 主机上运行这段复制的代码
[root@gitlab-runner local]#gitlab-runner register --url http://172.25.254.23 --token glrt-no-xtLxm8Hq1XgxLKoi_就会生成一个配置文件,路径为 /etc/gitlab-runner/config.toml。操作完成后,在 Gitlab 服务管理界面中就 Runner 面板中就会看到如下图所示的配置
六、项目文件结构
在Gitlab上创建项目:
七、核心配置文件
把代码放到 GitLab 仓库根目录,只需要 1 个配置文件,系统自动生成其他文件:
[root@master ~]# mkdir /root/k8s/deploy -p [root@master ~]# cd /root/k8s/deploy/ [root@master deploy]# mkdir my-page [root@master deploy]# cd my-page [root@master my-page]# echo "hello,CICD" > index.html配置 K8s 集群访问权限
# 1. 从K8s Master节点(192.168.223.20)拷贝config文件 # 先在Master节点执行: [root@master ~]# cat ~/.kube/config 复制内容 # 在Runner节点执行: [root@gitlab-runner ~]# mkdir -p ~/.kube [root@gitlab-runner ~]# vim ~/.kube/config # 粘贴Master节点的config内容(确保内容完整,包含集群、用户、上下文信息) [root@gitlab-runner ~]# vim /etc/yum.repos.d/kubernetes.repo [kubernetes] name = kubernetes baseurl = https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/ gpgcheck = 0 [root@gitlab-runner ~]# yum install kubectl -y # 2. 验证kubectl权限 [root@master ~]# kubectl get nodes -n default # 若报错需检查: # - Master节点的API Server地址是否可访问(6443端口) # - config文件中的证书/令牌是否有效 # - Runner节点与Master节点的网络连通性在项目根目录新建文件.gitlab-ci.yml,复制以下全部内容:
stages: - build - push - deploy variables: HARBOR_REGISTRY: "192.168.223.200" HARBOR_PROJECT: "k8s-project" IMAGE_NAME: "my-page" TAG: "$CI_COMMIT_SHORT_SHA" NAMESPACE: "default" # 构建镜像 build: stage: build tags: - shared script: - echo "=== 构建镜像 ===" - docker build -t ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} . # 推送镜像 push: stage: push tags: - shared script: - echo "=== 登录Harbor并推送镜像 ===" - docker login ${HARBOR_REGISTRY} -u admin -p Harbor12345 - docker push ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} - docker tag ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest - docker push ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest # 部署(完美无错版) deploy: stage: deploy tags: - shared script: - echo "=== 开始部署 my-page ===" - export IMAGE=${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} - echo "使用镜像:$IMAGE" # 渲染变量 - envsubst '$IMAGE' < nginx-deploy.yaml > rendered.yaml # 部署 - kubectl apply -f rendered.yaml # 等待发布完成 - kubectl rollout status deployment my-page -n ${NAMESPACE} --timeout=120s # 清理异常Pod - kubectl delete pod -l app=my-page -n ${NAMESPACE} --field-selector=status.phase!=Running 2>/dev/null || true - rm -f rendered.yaml - echo "=== ✅ 部署成功 ===" - kubectl get pods -n ${NAMESPACE}八、一键自动化部署
场景 1:首次部署(代码没上传过)
1、创建项目仓库
2、把前端代码.gitlab-ci.yml放到项目根目录
[root@master my-page]# yum install git -y git config --global user.name "Administrator" git config --global user.email "gitlab_admin_dc9ff2@example.com" [root@master deploy]# cd my-page [root@master deploy]# git init --initial-branch=main [root@master deploy]# git remote add origin http://172.25.254.23/root/my-page.git [root@master deploy]# git add . [root@master deploy]# git commit -m "Initial commit" [root@master deploy]# git push --set-upstream origin main3、打开终端,执行 3 条命令:
[root@master ~]# git add . [root@master ~]# git commit -m "首次部署前端项目" [root@master ~]# git push4、全自动运行:GitLab 自动构建镜像 → 推送到 Harbor → 部署到 K8s
场景 2:修改代码后自动更新
1、 直接修改你的前端代码(比如index.html)
2、 执行 3 条命令,触发自动更新:
[root@master ~]# git add . [root@master ~]# git commit -m "修改前端页面" [root@master ~]# git push3、 等待 1~2 分钟,刷新浏览器就是最新页面
九、查看部署进度
打开你的 GitLab 项目页面
左侧菜单栏 → 点击Build → Jobs
看到绿色对勾 ✅ = 部署成功;红色 ❌ = 失败(看下面常见问题)
十、验证部署成果
方法一:浏览器访问
打开浏览器,输入地址:
http://172.25.254.20:30083方法二:命令行检查
查看pod状态:
[root@master my-page]# kubectl get pods -n default | grep my-page my-page-c45f78574-nh6c4 1/1 Running 0 97s [root@master my-page]# kubectl get svc -n default | grep my-page my-page-svc NodePort 10.97.86.56 <none> 80:30083/TCP 5m22s [root@master my-page]# kubectl logs -f $(kubectl get pods -n default | grep my-page | awk '{print $1}') -n default基于 CI/CD + K8s 环境部署 Java 项目
整体思路
Java 项目需要先编译打包(Maven) → 构建 Docker 镜像 → 推送 Harbor → 部署 K8s,核心是用 Docker 镜像封装 Java 运行环境,避免 Runner 装 Maven/JDK
【第一步】创建 Java 项目目录(和前端项目同级)
# 回到部署根目录 [root@master ~]# cd /root/k8s/deploy # 创建java项目目录 [root@master ~]# mkdir java-demo [root@master ~]# cd java-demo【第二步】编写 4 个核心文件(直接复制)
1. Java 源代码(SpringBoot 最简 Web 项目)
生成正确的HelloController.java(java-demo 版)
[root@master ~]# mkdir -p src/main/java/com/demo [root@master ~]# cat > src/main/java/com/demo/HelloController.java <<EOF package com.demo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/") public String hello() { return "Java-Demo 部署成功!K8s + GitLab CI 正常运行!"; } } EOF生成启动类DemoApplication.java(war 包必备)
[root@master ~]# cat > src/main/java/com/demo/DemoApplication.java <<EOF package com.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class DemoApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(DemoApplication.class); } } EOF2. Maven 配置文件(pom.xml)
[root@master ~]# cat > pom.xml <<EOF <?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.demo</groupId> <artifactId>java-demo</artifactId> <version>1.0-SNAPSHOT</version> <!-- 固定为 war 包,适配 Tomcat --> <packaging>war</packaging> <!-- 统一 JDK 11 编译版本,避免版本不兼容 --> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <!-- SpringBoot 父依赖(2.7.15 适配 JDK 11 + Tomcat 9) --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.15</version> <relativePath/> </parent> <dependencies> <!-- Web 核心依赖,排除内置 Tomcat(用外部 Tomcat) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- Tomcat 9 适配的 Servlet API(固定版本) --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <!-- 固定 WAR 包名称为 ROOT,避免访问路径加项目名 --> <finalName>ROOT</finalName> <plugins> <!-- SpringBoot 打包插件(固定) --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.7.15</version> </plugin> </plugins> </build> </project> EOF3. Dockerfile
[root@node1 ~]# docker load -i tomcat-9.0-jdk11.tar Loaded image: tomcat:9.0-jdk11 [root@node1 ~]# docker tag tomcat:9.0-jdk11 172.25.254.200/k8s-project/tomcat:9.0-jdk11 [root@node1 ~]# docker push 172.25.254.200/k8s-project/tomcat:9.0-jdk11 [root@node1 ~]# cat Dockerfile FROM 172.25.254.200/k8s-project/tomcat:9.0-jdk11 WORKDIR /usr/local/tomcat RUN rm -rf webapps/* COPY target/ROOT.war webapps/ROOT.war EXPOSE 8080 CMD ["catalina.sh", "run"]4. K8s 部署文件(java.yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: java-demo spec: replicas: 1 selector: matchLabels: app: java-demo template: metadata: labels: app: java-demo spec: containers: - name: java-demo image: $IMAGE imagePullPolicy: Always ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: java-demo-svc spec: type: NodePort ports: - port: 8080 targetPort: 8080 nodePort: 30084 selector: app: java-demo5. 在【Master +gitlab-runner节点】安装 Maven+JDK11(避免 Runner 拉取镜像报错)
# 安装 JDK + Maven(编译环境) # 1. 上传 jdk-11.tar.gz 到 /root 目录,执行解压 [root@gitlab-runner ~]# tar -zxf jdk-11_linux-x64_bin.tar.gz [root@gitlab-runner ~]# mv jdk-11 jdk11 # 2. 配置全局环境变量(永久生效) [root@gitlab-runner ~]# cat > /etc/profile.d/jdk.sh << 'EOF' export JAVA_HOME=/root/jdk11 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib EOF # 3. 生效并验证 [root@gitlab-runner ~]# source /etc/profile.d/jdk.sh [root@gitlab-runner ~]# java -version # 输出JDK版本即成功 # 再gitlab-runner部署 # 1. 下载 Maven 3.9.6(适配JDK 11) [root@gitlab-runner ~]# cd /root [root@gitlab-runner ~]# wget https://archive.apache.org/dist/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz # 2. 解压并重命名 [root@gitlab-runner ~]# tar -zxf apache-maven-3.9.14-bin.tar.gz [root@gitlab-runner ~]# mv apache-maven-3.9.14 maven # 3. 配置全局环境变量 [root@gitlab-runner ~]# cat > /etc/profile.d/maven.sh << 'EOF' export MAVEN_HOME=/root/maven export PATH=$MAVEN_HOME/bin:$PATH EOF [root@gitlab-runner ~]# source /etc/profile.d/maven.sh [root@gitlab-runner ~]# mvn -version # 输出Maven版本即成功 [root@gitlab-runner package]# vim /root/maven/conf/settings.xml ..... <mirror> <id>tencentmaven</id> <mirrorOf>central</mirrorOf> <url>https://maven.aliyun.com/repository/public/</url> </mirror> .... # 3. 进入 java-demo 项目目录,本地编译 [root@gitlab-runner package]# cd /root/k8s/deploy/java-demo [root@gitlab-runner package]# mvn clean package -DskipTests【第三步】编写 GitLab CI/CD 配置(.gitlab-ci.yml)
[root@master ~]# vim .gitlab-ci.yml stages: - build - push - deploy variables: HARBOR_REGISTRY: "172.25.254.200" HARBOR_PROJECT: "k8s-project" IMAGE_NAME: "java-demo" TAG: "$CI_COMMIT_SHORT_SHA" NAMESPACE: "default" build: stage: build tags: - shared script: - echo "=== 编译打包 ===" - mvn clean package -DskipTests - docker build -t ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} . - docker tag ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest push: stage: push tags: - shared script: - docker login ${HARBOR_REGISTRY} -u admin -p Harbor12345 - docker push ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} - docker push ${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest deploy: stage: deploy tags: - shared script: - export IMAGE=${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${IMAGE_NAME}:${TAG} - envsubst '$IMAGE' < java.yaml > java-deploy.yaml - kubectl apply -f java-deploy.yaml - kubectl rollout status deployment java-demo -n ${NAMESPACE} --timeout=120s - rm -f java-deploy.yaml - kubectl get pods -n ${NAMESPACE}【第四步】推送到 GitLab 仓库(触发自动部署)
# 初始化Git仓库 [root@master ~]# git init # 添加所有文件 [root@master ~]# git add . # 提交 [root@master ~]# git commit -m "init java demo: hello CICD, i am java" # 添加远程仓库(替换成你的GitLab地址) [root@master ~]# git remote add origin http://192.168.223.23/root/java-demo.git # 推送 [root@master ~]# git push -u origin main【第五步】验证部署结果
1. 查看 CI/CD 流水线
打开 GitLab → 项目 → CI/CD → Pipelines,确认build/push/deploy三个阶段都显示绿色 ✅。
2. 查看 K8s Pod 状态
[root@master ~]# kubectl get pods -n default | grep java-demo # 正常输出:java-demo-xxxxxx-xxxx 1/1 Running 0 10s3. 访问 Java 页面
http://172.25.254.20:30084