Kubernetes与Spring Boot简单HelloWorld教程 - Maroun


让我们构建最简单的Java Spring Boot应用程序,将其包装在Docker容器中,然后在K8s pod中使用该容器,该容器由K8s部署进行编排并通过服务公开。服务由两个pod和一个简单的负载平衡器提供支持,可以根据应用程序的需求轻松扩展。
 
项目结构:

├── Dockerfile
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── k8s
│   └── depl.yaml
├── settings.gradle
└── src
    └── main
        └── java
            └── hello
                ├── App.java
                └── HelloWorldCtrl.java

 App.java是应用入口:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

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

}

上面的代码包含创建Spring Boot应用程序所需的最少代码。
下面HelloWorldCtrl.java包含一个简单的控制器,其映射的根路径(“/”),并返回问候语的字符串:

package hello;

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

@RestController
public class HelloWorldCtrl {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Spring Boot!";
    }

}

 
构建应用程序
我正在使用Gradle作为构建工具。该build.gradle文件也是最小文件,由以下几行组成:

plugins {
    id 'org.springframework.boot' version '2.3.3.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id 'java'
}

group = 'com.test'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

 
创建K8s资源
为了创建K8s部署,我们需要一个Docker映像/镜像。让我们在我们的代码中添加以下几行Dockerfile:

FROM gradle:jdk10

COPY --chown=gradle:gradle . /app
WORKDIR /app
RUN gradle build

EXPOSE 8080
WORKDIR /app

CMD java -jar build/libs/gs-spring-boot-0.1.0.jar

Docker文件中的步骤:

  • 将项目复制到 /app
  • 使用Gradle构建项目
  • 使用上一步的结果运行应用程序

现在,我们可以构建映像并推送到中心:
docker build -t marounbassam/hello-spring .
docker push marounbassam/hello-spring

 
K8s的部署很简单。
它由部署服务组成

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: hello-world
        visualize: "true"
    spec:
      containers:
      - name: hello-world-pod
        image: marounbassam/hello-spring
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  labels:
    visualize: "true"
  name: hello-world-service
spec:
  selector:
    app: hello-world
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
  type: ClusterIP

部署Deployment部分定义了Pod的两个副本,这些副本将运行根据image属性中指定的映像构建的容器。
服务Service部分是类型的ClusterIP(默认的Kubernetes服务)。它为我们提供了群集中其他应用程序可以访问的服务。
在集群中创建资源:

kubectl create -f <yaml_file>

+---------------------+
| hello-world-service |
|              |
|    10.15.242.210  |
+---------O-----------+
          |
          +-------------O--------------------------O
                    |                  |
              +---------O-----------+   +---------O-----------+
              |        pod 1  |    |        pod 2   |
              |             |    |               |
              |     hello-world  |    |     hello-world   |
              +---------------------+    +---------------------+

 
安装集群

$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
hello-world-5bb87c95-6h4kh   1/1       Running   0          7h
hello-world-5bb87c95-bz64v   1/1       Running   0          7h
$ kubectl get svc
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
hello-world-service   ClusterIP   10.15.242.210   <none>        8080/TCP   5s
kubernetes            ClusterIP   10.15.240.1     <none>        443/TCP    7h
$ kubectl exec -it hello-world-5bb87c95-6h4kh bash
$ (inside the pod) curl 10.15.242.210:8080
$ (inside the pod) Greetings from Spring Boot!

我们可以看到服务器已启动并且正在pod内运行。根据您的云提供商,您可以设置服务类型LoadBalancer并从集群外部访问应用程序。