SpringBoot 2 应用部署至 Kubernetes

开篇词

该指南将引导你在 Kubernetes 上部署 Spring Boot 应用的过程。如何使用 Spring Boot 和 Kuberntes 进行操作有很多选择 - 该指南的目的是使你尽快起步并运行,而不是讨论所有替代方案或部署至生产环境的所有细节(当然,这是我们最喜欢地方)。

有一些交互式教程可以补充和扩展 Katacoda/springguides 上该指南的内容。如果我们遵循这些教程,则所有代码都将在浏览器中的云中运行。或者,我们可以创建自己的集群并在本地安装所需的所有工具,然后从指南中复制粘贴。
 
Kuberntes 上的 Spring Boot 入门:与该指南相同的材料,但是在我们的浏览器中运行。
 
安装 Kuberntes:使用 Kind 在本地安装 Kubernetes 的指南。如果我们希望在笔记本上运行教程,可以使用它在笔记本电脑上进行设置。
 
Spring Boot 的 Kubernetes 探针:Spring Boot 的活跃性和就绪性探针指南。

你将创建的应用

Kubernetes 是一个开源系统,用于自动化容器化应用的部署、扩展及管理。它将组成应用的容器分组为逻辑单元,以便于管理及发现。在该指南中,我们将构建并部署一个简单的 Spring 引导应用。

在 Docker 上还有一个入门指南主题指南,涵盖了构建容器镜像的一些背景。

你将需要的工具

我们将需要 Linux 或类似 Linux 的命令行。该指南中的命令行示例适用于 Linux,带 Shell 的 MaxOS 终端或 Windows 上的 WSL

我们还需要一个 Kubernetes 集群和命令行工具 kubectl。我们可以使用 Kind(在 Docker 上)或 Minikube 在本地创建集群。或者,我们可以使用云提供商,例如 Google Cloud PlatformAmazon Web ServicesMicrosoft Azure。在继续进行之前,请确认我们可以从 shell 运行 kubectl 命令。例如(使用 kind):

$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:46253
KubeDNS is running at https://127.0.0.1:46253/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

and

$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.43.0.1    <none>        443/TCP   7m13s

创建 Spring Boot 应用

我们要做的第一件事是创建一个 Spring Boot 应用。如果我们希望在 github 中使用它,则可以在终端中将其克隆(已经安装了 git 和 java)。或者,我们可以使用 start.spring.io 从头开始创建应用:

curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator | tar -xzvf -

然后,我们可以构建该应用:

./mvnw install

第一次将花费几分钟,但是一旦所有依赖项都被缓存,它将很快。

我们可以看到构建的结果。如果构建成功,则应该看到一个 JAR 文件,如下所示:

ls -l target/*.jar
-rw-r--r-- 1 root root 19463334 Nov 15 11:54 target/demo-0.0.1-SNAPSHOT.jar

JAR 是可执行的:

$ java -jar target/*.jar

该应用具有一些内置的 HTTP 端点,这取决于我们在下载项目时添加的 “actuator” 依赖。因此,我们将在启动日志中看到以下内容:

...
2019-11-15 12:12:35.333  INFO 13912 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2019-11-15 12:12:36.448  INFO 13912 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
...

因此,我们可以在另一个终端中请求端点:

$ curl localhost:8080/actuator | jq .
{
  "_links": {
    "self": {
      "href": "http://localhost:8080/actuator",
      "templated": false
    },
    "health-path": {
      "href": "http://localhost:8080/actuator/health/{*path}",
      "templated": true
    },
    "health": {
      "href": "http://localhost:8080/actuator/health",
      "templated": false
    },
    "info": {
      "href": "http://localhost:8080/actuator/info",
      "templated": false
    }
  }
}

要完成该步骤,请发送 Ctrl + C 终止该应用。
 

容器化应用

有多个选项可用于容器化 Spring Boot 应用。对于本地开发和测试,从 Dokerfile 开始是有意义的,因为构建工作流程通常是众所周知的。

如果我们在本地没有 docker,或者想自动将镜像推送到注册表,那么 Jib 将是一个不错的选择。在企业环境中,当我们需要 CI/CD 管道的受信构建服务时,可以查看 Cloud Native Buildpacks

首先创建一个 Dockerfile

FROM openjdk:8-jdk-alpine AS builder
WORKDIR target/dependency
ARG APPJAR=target/*.jar
COPY ${APPJAR} app.jar
RUN jar -xf ./app.jar

FROM openjdk:8-jre-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY --from=builder ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=builder ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=builder ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.demo.DemoApplication"]

然后构建容器镜像,并为其提供标签(如果我们要使用 Dockerhub,请选择我们自己的 ID 而不是 “springguides”):

$ docker build -t springguides/demo .

我们可以在本地运行容器:

$ docker run -p 8080:8080 springguides/demo

并检查它是否可以在另一个终端上运行:

$ curl localhost:8080/actuator/health

通过终止容器结束。

除非我们通过 Dockerhub 进行身份验证(docker login),否则我们将无法推送该图像,但是已经有一个图像应该可以工作了。如果我们通过了身份验证,则可以:

$ docker push springguides/demo

在现实生活中,需要将镜像推送到 Dockerhub(或其他可访问的存储库),因为 Kubernetes 会从其 Kubelet(节点)内部拉取镜像,这些 Kubelet 通常不连接到本地 docker 守护进程。对于这种情况,我们可以省略推送,而只使用已有的图像。

仅出于测试目的,有一些变通办法,例如,使 docker push 与不安全的本地注册表一起使用,但在该方案的范围之外。
 

部署应用至 Kubernetes

我们有一个运行并公开 8080 端口的容器,因此,要使 Kubernetes 运行,只需要一些 YAML。为了避免不得不查看或编辑 YAML,现在,我们可以要求 kubectl 为我们生成它。唯一可能有所不同的地方是 --image 名称。如果将容器部署到自己的存储库,请使用其标记而不是以下标记:

$ kubectl create deployment demo --image=springguides/demo --dry-run -o=yaml > deployment.yaml
$ echo --- >> deployment.yaml
$ kubectl create service clusterip demo --tcp=8080:8080 --dry-run -o=yaml >> deployment.yaml

我们可以采用上面生成的 YAML 并根据需要进行编辑,也可以仅应用它:

$ kubectl apply -f deployment.yaml
deployment.apps/demo created
service/demo created

检查应用是否正在运行:

$ kubectl get all
NAME                             READY     STATUS      RESTARTS   AGE
pod/demo-658b7f4997-qfw9l        1/1       Running     0          146m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes   ClusterIP   10.43.0.1       <none>        443/TCP    2d18h
service/demo         ClusterIP   10.43.138.213   <none>        8080/TCP   21h

NAME                   READY     UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demo   1/1       1            1           21h

NAME                              DESIRED   CURRENT   READY     AGE
replicaset.apps/demo-658b7f4997   1         1         1         21h
d

继续执行 kubectl get all 知道演示窗格显示其状态为 “正在运行” 为止。

现在,我们需要能够连接到在 Kubernetes 中做为服务公开的应用。一种在开发时有效的方法是创建 SSH 通道:

$ kubectl port-forward svc/demo 8080:8080

那么我们可以验证该应用是否在其他终端上运行:

$ curl localhost:8080/actuator/health
{"status":"UP"}

概述

恭喜你!我们刚刚在 Kubernetes 上运行了项目。
 

想看指南的其他内容?请访问该指南的所属专栏:《Spring 官方指南

发布了228 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/stevenchen1989/article/details/105097518