k8s部署SpringBoot项目

一、前言

本文将介绍如何通过CICDSpringBoot框架的Web项目发布到k8s集群中,文章中有使用到eureka的注册,如果对如何在k8s集群中部署eureka,那么可以参考本人的 k8s部署eureka集群 文章。如果只是为了测试部署Web服务到k8s集群中,那么你们可以自己搭建项目时,忽略eureka的相关依赖和配置

二、k8s知识点介绍

1、Deployment

Deployment是最常用的用于部署无状态服务的方式。Deployment控制器使得您能够以声明的方式更新 Pod(容器组)和 ReplicaSet

2、Service

Kubernetes 中 Service 是一个 API 对象,通过 kubectl + YAML定义一个 Service,可以将符合 Service 指定条件的 Pod 作为可通过网络访问的服务提供给服务调用者。Service 是 Kubernetes 中的一种服务发现机制

三、搭建SpringBoot项目

1、创建项目

这里不做具体的创建项目演示,通过Idea创建非常的方便快捷,最终的pom文件如下,如果只是普通的Web服务,那么无需增加SpringCloud的相关依赖。至于其他的依赖那就根据你们项目的情况来增加了,这里只是为了演示,所以不做过多的依赖引入

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gjing.projects</groupId>
    <artifactId>k8s-web-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>k8s-web-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2020.0.3</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2、启动类增加注解

开启Eureka的支持,普通Web项目跳过

/**
 * @author Gjing
 */
@EnableEurekaClient
@SpringBootApplication
public class K8sWebDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(K8sWebDemoApplication.class, args);
    }
    
}

3、配置YML文件

这里使用了变量的形式设置配置的值,这样就可以根据不同的环境来分别配置了。如果对变量的使用不熟悉的话建议恶补一下 SpringBoot 项目在 Yaml 文件使用变量。这里只是演示的配置,在实际使用时根据业务需求来合理配置

server:
  port: ${SERVER_PORT:8081}
spring:
  application:
    name: ${SERVER_NAME:web-demo}
eureka:
  client:
    service-url:
      defaultZone: ${EUREKA_URL:http://localhost:8761/eureka/}
  instance:
    hostname: ${HOST_NAME:localhost}
    lease-renewal-interval-in-seconds: 5 # 续约间隔时间
    lease-expiration-duration-in-seconds: 10 # 服务失效时间
    prefer-ip-address: true # 开启服务IP注册,如果网关使用了Cloud-Gateway那么一定要增加该配置

4、编写Dockerfile

FROM openjdk:8-jdk
COPY target/*.jar app.jar
ENTRYPOINT java $JAVA_OPTS  -jar $CONFIG app.jar

5、编写CI脚本文件

不是很熟悉CI写法的建议先看阅读:SpringBoot使用CICD

before_script:
    - export IMAGE_FULL_NAME=$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHA
stages:
 - compile
 - build
 - run
variables:
  MAVEN_REPO: "/.m2"
  PROJECT_NAME: "k8s-web"
  K8S_FILE: "web-k8s.yml"
compile:
  stage: compile
  image: 172.20.9.4:5001/gjing/maven:1.0
  only:
   - master
  tags:
   - pub
  script:
   - mvn -Dmaven.repo.local=$MAVEN_REPO clean package -Dmaven.test.skip=true
  artifacts:
    name: $PROJECT_NAME
    expire_in: 1 week
    paths:
     - target/*.jar
build:
  stage: build
  image: docker:stable
  only:
    - master
  tags:
    - pub
  script:
    - docker login --username $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE_FULL_NAME .
    - docker push $IMAGE_FULL_NAME
    - docker rmi -f $IMAGE_FULL_NAME
run:
  stage: run
  image: roffe/kubectl
  only:
   - master
  tags:
   - pub
  variables:
    PROJECT_PORT: 8081
    PROJECT_NAMESPACE: gj # 命名空间需要提前在k8s中创建好
  script:
   - mkdir -p /root/.kube # 配置 kubectl, ${KUBE_CONFIG}这个变量会在下面发布的章节介绍如何配置
   - echo $KUBE_CONFIG | base64 -d > /root/.kube/config
   - export KUBECONFIG=/root/.kube/config
   - kubectl version
   - sed -i "s#{PROJECT_NAME}#$PROJECT_NAME#g;
     s#{PROJECT_PORT}#$PROJECT_PORT#g;
     s#{PROJECT_NAMESPACE}#$PROJECT_NAMESPACE#g;
     s#{PROJECT_IMAGE}#$IMAGE_FULL_NAME#g" $K8S_FILE
   - kubectl apply -f $K8S_FILE

6、编写k8s配置文件

创建一个名为web-k8s.yml文件,文件名要和CI文件中的K8S_FILE变量的值一致,如果是普通Web项目,那么下方配置中,忽略掉env中的EUREKA_URL环境变量配置即可

apiVersion: v1
kind: Service
metadata:
  name: {PROJECT_NAME}
  namespace: {PROJECT_NAMESPACE}
  labels:
    app: {PROJECT_NAME}
spec:
  selector:
    app: {PROJECT_NAME}
  ports:
    - port: {PROJECT_PORT}
      targetPort: {PROJECT_PORT}
      name: {PROJECT_NAME}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {PROJECT_NAME}
  namespace: {PROJECT_NAMESPACE}
  labels:
    app: {PROJECT_NAME}
spec:
  replicas: 3
  selector:
    matchLabels:
      app: {PROJECT_NAME}
  template:
    metadata:
      labels:
        app: {PROJECT_NAME}
    spec:
      containers:
        - name: {PROJECT_NAME}
          image: {PROJECT_IMAGE}
          ports:
            - containerPort: {PROJECT_PORT}
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: {PROJECT_PORT}
            failureThreshold: 3 # 探测失败的阈值,超过则认定该pod失败状态
            initialDelaySeconds: 60 # pod启动延迟多久进行检查
            periodSeconds: 10 # 检查的周期
            successThreshold: 1 # 探测成功的阈值,只要成功一次就认定pod为正常
            timeoutSeconds: 10 # 超时时间,如果超时则认为pod是失败状态
          env:
            - name: SERVER_PORT
              value: "{PROJECT_PORT}"
            - name: SERVER_NAME
              value: {PROJECT_NAME}
            - name: EUREKA_URL
              valueFrom:
                configMapKeyRef: # 这里是取eureka项目里定义的configMap里的值
                  name: eureka-host
                  key: registry_url
            - name: HOST_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name

这时候我们的项目准备工作都做好了,不过好像少了点接口用来测试,我们先增加几个测试接口,项目中创建个控制器,代码如下

/**
 * @author Gjing
 **/
@RestController
public class TestController {
    @PostMapping("/test1")
    public ResponseEntity<String> test1() {
        return ResponseEntity.ok("web-demo test1 is ok");
    }

    @GetMapping("/test2")
    public ResponseEntity<String> test2(String user) {
        return ResponseEntity.ok("web-demo test2 is ok: " + user);
    }
}

到此,我们的项目才算准备完成了,接下来就是发布了

四、发布

由于我们配了CI文件,那么当我们代码提交到Gitlab的时候,就会自动进行构建并启动啦

1、配置KUBE_CONFIG变量

首先,我们先登陆到 k8s master节点服务器上,进入到/etc/kubernetes/目录,然后通过cat admin.conf将这个文件的内容输出到控制台,最后将复制出来的内容先保存到
自己电脑的文本编辑器中,然后修改红色框中的地址,将dns修改为你的ApiServer的IP,如果是多master的话就是填写ApiServer的LoadBalance IP了

updateapiserver.png

然后我们复制修改后的所有内容,到浏览器随便搜索一个在线的base64加密工具将内容进行加密。随后,我们来到GitLab,进到具体项目或者项目组里,点击下方图中的选项

gitlabci.png

点击后进到下方页面并添加变量,注意:要和你ci里面写的保持一致,的话就是刚刚加密后的内容了

gitlabvar.png

最好将此变量配置在项目组中,这样该项目组的所有项目都会继承该变量

2、提交

上面已经配置了KUBE_CONFIG变量了,这时候我们就可以直接提交代码到GitLab啦,提交成功后就可以在GitLab项目左侧的CICD选项中看到流水线在执行

cirun.png

当三个阶段都打勾了就说明执行成功啦,如果出现了错误,那就可以点击指定阶段进去查看下错误日志进行针对性修改了

cisucc.png

这时我们可以去master服务器上执行kubectl get pod -n gj查看下pod启动成功没
run

可以看到三个Pod都是running状态了,这时我们也可以通过kubectl logs -f <pod name> -n gj命令进行查看下其中一个Pod的日志,这里我们可以看到web服务已经成功起来了
nb

五、访问

由于我们定义了Service,且配置了Port,那么我们可以在集群内部通过IP去访问,首先我们通过kubectl get svc -n gj去查看下运行的 Service
svc
可以看到名叫 k8s-web 的 Service,这就是我们 web 服务的 Service,这时候我们通过它的 IP 进行测试
get
可以看到正常返回,那就说明成功了

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值