Пример развертывания Spring Boot-приложения в Kubernetes

от автора

Перевод статьи подготовлен специально для студентов курса «Разработчик на Spring Framework».

Давайте создадим простейшее Spring Boot-приложение, которое будет запускаться в кластере Kubernetes.


Структура проекта

├── 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 содержит простой контроллер, который мапит корень («/») на метод index, возвращающий строку приветствия:

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 

Шаги в нашем Dockerfile:

  • копирование проекта в /app
  • сборка проекта с помощью Gradle
  • запуск приложения, используя результат предыдущего шага

docker build -t marounbassam/hello-spring . docker push marounbassam/hello-spring 

Файл манифеста K8s тоже простой. Он состоит из развертывания (Deployment) и сервиса (Service):

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 определяет две реплики пода, в которых будет выполняться контейнер, созданный из образа, указанного в атрибуте image.

У сервиса (Service) тип ClusterIP (тип сервиса по умолчанию). Он предоставляет внутри кластера возможность подключаться к нам другим приложениям.

Создаем ресурсы в кластере:

kubectl create -f <yaml_file>

Визуально ресурсы можно представить следующим образом:

Внутри кластера

$ 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! 

Мы видим, что сервер запустился и работает внутри подов. Вы также можете настроить службу типа LoadBalancer (зависит от вашего облачного провайдера) и получить доступ к приложению из-за пределов кластера.

Заключение

Мы создали простое приложение на Spring Boot, запустили его в Docker-контейнере в поде K8s, который управляется через K8s deployment и доступен через сервис.

У нас получилась простая балансировка нагрузки для двух созданных подов и легкая масштабируемость в соответствии с потребностями приложения.

Разработчик на Spring Framework

ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/527394/