Spring Boot 与 Docker
观察 GraphQL 的实际运行

本指南将引导您完成在 Kubernetes 上部署 Spring Boot 应用程序的过程。使用 Spring Boot 和 Kubernetes 有很多方法可以选择。本指南的目的是让您尽快上手,而不是讨论所有替代方案或深入探讨如何进入生产环境的细节。

您将构建什么

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

您还可以在 Docker 上找到一份入门指南和一份专题指南,这些指南涵盖了构建容器镜像的一些背景知识。

你需要什么

您需要一个 Linux 或类 Linux 的命令行。本指南中的命令行示例适用于 Linux、带有 shell 的 MacOS 终端或 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'.

您还应运行以下命令:

$ 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 上有一个您更喜欢使用的应用程序,可以在终端中克隆它(gitjava 已经安装)。或者,您可以使用 start.spring.io 从头创建一个应用程序:

curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator -d type=maven-project | 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

由于我们在下载项目时添加了actuator依赖,该应用程序具有一些内置的HTTP端点。您应该在启动时的日志中看到类似以下的输出:

...
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 访问这些端点:

$ 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 应用的方式。只要您已经在构建 Spring Boot jar 文件,您只需直接调用插件即可。以下命令使用了 Maven

$ ./mvnw spring-boot:build-image

以下命令使用 Gradle

$ ./gradlew bootBuildImage

您可以在本地运行容器:

$ docker run -p 8080:8080 demo:0.0.1-SNAPSHOT

然后您可以在另一个终端中检查它是否正常工作:

$ curl localhost:8080/actuator/health

最后停止容器。

除非您通过 Dockerhub 进行身份验证 (docker login),否则无法推送镜像,但那里已经有一个可以使用的镜像。如果您已经通过身份验证,您可以:

$ docker tag demo:0.0.1-SNAPSHOT springguides/demo
$ docker push springguides/demo

在实际应用中,镜像需要被推送到 Dockerhub(或其他可访问的仓库),因为 Kubernetes 会从其内部的 Kubelets(节点)拉取镜像,而这些节点通常不会连接到本地的 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 命令,直到 demo pod 的状态显示为 Running

现在,您需要能够连接到在 Kubernetes 中作为服务暴露的应用程序。在开发阶段,一种非常有效的方式是创建一个 SSH 隧道:

$ kubectl port-forward svc/demo 8080:8080

然后您可以在另一个终端中验证应用程序是否正在运行:

$ curl localhost:8080/actuator/health
{"status":"UP"}
本页目录