Пример развертывания 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/


Интересные статьи

Интересные статьи

Вышел релиз 13.4 с хранилищем HashiCorp для переменных CI, Kubernetes Agent и центром безопасности, а также переключаемыми фичами в Starter В GitLab мы всегда думаем о том, как пом...
Для написания эффективных и корректных многопоточных приложений очень важно знать какие существуют механизмы синхронизации памяти между потоками исполнения, какие гарантии предоставл...
Данная статья направлена, прежде всего, на начинающего специалиста, который только приступил к исследованию методов и способов обеспечения информационной безопасности исполняемого п...
Если у вас есть интернет-магазин и вы принимаете платежи через Интернет, то с 01 июля 2017 года у вас есть онлайн-касса.
Прим. перев.: Автор статьи — Reuven Harrison — имеет более 20 лет опыта в разработке программного обеспечения, а на сегодняшний день является техническим директором и соучредителем компании T...