Skip to content

sladkkkov/rest-api-calculator

Repository files navigation

RestApiCalculator

Сладков Данила Алексеевич sladkkov@yandex.ru

Программа выполенна на языке Java. Программа отражает функционал простого калькулятора

Использованы: Java, JUnit, Swagger, Spring Web.

Java 17 Run app: src/main/java/ru/sladkkov/calculator/CalculatorApplication.java

Swagger Doc: http://localhost:9090/swagger-ui/index.html#/

Сладков Данила

Задание

Шаг 1.

  • Был установлен Docker.
  • Был создан аккаунт на Docker Hub.
  • В качестве приложения выбрал Rest Calculator написанный на Java.

Шаг 2.

Создадим Dockerfile

FROM openjdk:8
ADD . /src
WORKDIR /src

ARG UID=1001 ARG GID=1001

RUN addgroup --system --gid ${GID} user RUN adduser --system --uid ${UID} --group user RUN chown -R user:user /src
USER user

COPY /target/Calculator-0.0.1-SNAPSHOT.jar Calculator.jar

EXPOSE 8080 ENTRYPOINT ["java","-jar", "Calculator.jar"]

Выполним команды

  • docker build -t sladkkov/calculator:1.0.0 -t sladkkov/calculator:1.0.0 . (Создаем image c тэгом 1.0.0 и названием sladkkov/calculator)
    -docker run -ti --rm -p 9090:9090 --name calculator sladkkov/calculator:1.0.0

После этого я проверил, что всё работает. Открыл Docker Desktop и увидел, что размер имейджа 534 Мб, что мне показалось слишком много и второе, что мне не понравилось, то что проект использует готовый jar файл, который был получен до этого.

Шаг 3

Создадим новый Dockerfile.

# syntax=docker/dockerfile:1
FROM openjdk:16-alpine3.13

WORKDIR /RestApiCalculator

COPY .mvn/ .mvn COPY mvnw pom.xml ./ RUN ./mvnw dependency:go-offline COPY src ./src

CMD ["./mvnw", "spring-boot:run"]

Также был добавлен файл .dockeringore, в котором папка target
Изучив документацию, пришёл к вот такому варианту, который сам загружает зависимости, и запускает spring-boot:run.

В этом варианте размер составляет 604.06 MB

Здесь я не добавлял нового user’a, потому что это не финальная версия, а с разными базовыми образами приходится каждый раз менять свойства.

Шаг 4

Изучив ещё больше статей, видео и документации, пришел к такому варианту, используя multi-stage построение image.

FROM adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine as builder

ADD . /src WORKDIR /src RUN ./mvnw package -DskipTests

ARG UID=1001 ARG GID=1001

RUN addgroup --system --gid ${GID} user && adduser --system --uid ${UID} user --ingroup user RUN chown -R user:user /opt RUN chown -R user:user /src

USER user

FROM alpine:3.10.3 as packager RUN apk --no-cache add openjdk11-jdk openjdk11-jmods ENV JAVA_MINIMAL="/opt/java-minimal" RUN /usr/lib/jvm/java-11-openjdk/bin/jlink
--verbose
--add-modules
java.base,java.naming,java.desktop,java.management,java.security.jgss,java.instrument
--compress 2 --strip-debug --no-header-files --no-man-pages
--output "$JAVA_MINIMAL"

FROM alpine:3.10.3 ENV JAVA_HOME=/opt/java-minimal ENV PATH="$PATH:$JAVA_HOME/bin"

COPY --from=packager "$JAVA_HOME" "$JAVA_HOME" COPY --from=builder /src/target/Calculator-0.0.1-SNAPSHOT.jar Calculator.jar EXPOSE 9090 ENTRYPOINT ["java","-jar","/Calculator.jar"]

Здесь мы вручную конфигурируем модули, которые нам нужны для работы приложения.
Начальную версию кода, я нашёл в статье на Хабре. Было миллион ошибок в процессе допиливания под себя. Изучил много видео, статей и документации, о том как всё здесь работает, и достаточно хорошо разобрался.

По этой команде узнаем модули в нашем проекте

 jdeps C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator

Размер image удалось сократить до 81.46 MB. Что меня вполне устроило.

Выполним команды

  • docker build -t sladkkov/calculator:1.0.0 -t sladkkov/calculator:1.0.0 . (Создаем image c тэгом 1.0.0 и названием sladkkov/calculator)
[+] Building 101.7s (20/20) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                                                                                               0.0s
 => => transferring dockerfile: 1.01kB                                                                                                                                                                                                                                             0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                                                                  0.0s
 => => transferring context: 34B                                                                                                                                                                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/alpine:3.10.3                                                                                                                                                                                                                   2.6s
 => [internal] load metadata for docker.io/adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine                                                                                                                                                                                             2.5s
 => [auth] adoptopenjdk/openjdk11:pull token for registry-1.docker.io                                                                                                                                                                                                              0.0s
 => [auth] library/alpine:pull token for registry-1.docker.io                                                                                                                                                                                                                      0.0s
 => [internal] load build context                                                                                                                                                                                                                                                  0.0s
 => => transferring context: 7.92kB                                                                                                                                                                                                                                                0.0s
 => [stage-2 1/3] FROM docker.io/library/alpine:3.10.3@sha256:c19173c5ada610a5989151111163d28a67368362762534d8a8121ce95cf2bd5a                                                                                                                                                     0.0s
 => => resolve docker.io/library/alpine:3.10.3@sha256:c19173c5ada610a5989151111163d28a67368362762534d8a8121ce95cf2bd5a                                                                                                                                                             0.0s
 => CACHED [builder 1/7] FROM docker.io/adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine@sha256:651c0c23656fe6e57c5ae6b9953a8c9bb23ba3f53e55b2c6df6ef243a3d07d8b                                                                                                                        0.0s
 => => resolve docker.io/adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine@sha256:651c0c23656fe6e57c5ae6b9953a8c9bb23ba3f53e55b2c6df6ef243a3d07d8b                                                                                                                                       0.0s
 => [builder 2/7] ADD . /src                                                                                                                                                                                                                                                       0.1s
 => [builder 3/7] WORKDIR /src                                                                                                                                                                                                                                                     0.1s
 => [builder 4/7] RUN  ./mvnw package -DskipTests                                                                                                                                                                                                                                 90.3s
 => [builder 5/7] RUN addgroup --system --gid 1001  user && adduser --system --uid 1001  user --ingroup  user                                                                                                                                                                      0.7s
 => [builder 6/7] RUN chown -R user:user /opt                                                                                                                                                                                                                                      6.0s
 => [builder 7/7] RUN chown -R user:user /src                                                                                                                                                                                                                                      1.4s
 => CACHED [packager 2/3] RUN apk --no-cache add openjdk11-jdk openjdk11-jmods                                                                                                                                                                                                     0.0s
 => CACHED [packager 3/3] RUN /usr/lib/jvm/java-11-openjdk/bin/jlink     --verbose     --add-modules         java.base,java.naming,java.desktop,java.management,java.security.jgss,java.instrument     --compress 2 --strip-debug --no-header-files --no-man-pages       --output  0.0s
 => CACHED [stage-2 2/3] COPY  --from=packager /opt/java-minimal /opt/java-minimal                                                                                                                                                                                                 0.0s
 => [stage-2 3/3] COPY  --from=builder /src/target/Calculator-0.0.1-SNAPSHOT.jar Calculator.jar                                                                                                                                                                                    0.1s
 => exporting to image                                                                                                                                                                                                                                                             0.1s
 => => exporting layers                                                                                                                                                                                                                                                            0.1s
 => => writing image sha256:b0fdb510c783e96e3e5f4f78e42210370b5ef4250df91771d06b997a39515355                                                                                                                                                                                       0.0s
 => => naming to docker.io/sladkkov/calculator:1.0.0

Посмотрим список image

REPOSITORY                    TAG       IMAGE ID       CREATED          SIZE
sladkkov/calculator           1.0.0     b0fdb510c783   3 minutes ago    81.5MB

Запустим Docker container из созданного image
-docker run -ti --rm -p 9090:9090 --name calculator sladkkov/calculator:1.0.0


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.6)

2022-06-17 03:32:16.273 INFO 1 --- [ main] r.s.calculator.CalculatorApplication : Starting CalculatorApplication v0.0.1-SNAPSHOT using Java 11.0.4 on 35ff9db9b783 with PID 1 (/Calculator.jar started by root in /) 2022-06-17 03:32:16.278 INFO 1 --- [ main] r.s.calculator.CalculatorApplication : No active profile set, falling back to 1 default profile: "default" 2022-06-17 03:32:17.758 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9090 (http) 2022-06-17 03:32:17.780 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-06-17 03:32:17.781 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.60] 2022-06-17 03:32:17.862 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-06-17 03:32:17.862 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1477 ms 2022-06-17 03:32:19.339 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9090 (http) with context path '' 2022-06-17 03:32:19.356 INFO 1 --- [ main] r.s.calculator.CalculatorApplication : Started CalculatorApplication in 3.746 seconds (JVM running for 4.293)

Проверим перейдя по ссылке, http://localhost:9090/swagger-ui/index.html#/Calculation controller/multiply, что приложение работает.

Отправим Docker image в Registry Docker Hub
docker push sladkkov/calculator:1.0.0

Шаг 5

PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator>  docker push sladkkov/calculator:1.0.0
The push refers to repository [docker.io/sladkkov/calculator]
aa27681dfd45: Pushed
1052af976019: Layer already exists
77cae8ab23bf: Layer already exists
1.0.0: digest: sha256:e9e75476dac11c05cf31175b7342f21ab625e4341564d23b508adb68c5b4f991 size: 952

Откроем web-интерфейс Docker Hub по адресу и найдем загруженный image

docker pull sladkkov/calculator:1.0.0
1.0.0: Pulling from sladkkov/calculator
Digest: sha256:e9e75476dac11c05cf31175b7342f21ab625e4341564d23b508adb68c5b4f991
Status: Image is up to date for sladkkov/calculator:1.0.0
docker.io/sladkkov/calculator:1.0.0

Шаг 6

Запуск кластера

PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator> minikube start --embed-certs
😄  minikube v1.25.2 на Microsoft Windows 11 Home Single Language 10.0.22000 Build 22000
✨  Используется драйвер docker на основе существующего профиля
👍  Запускается control plane узел minikube в кластере minikube
🚜  Скачивается базовый образ ...
🔄  Перезагружается существующий docker container для "minikube" ...
❗  This container is having trouble accessing https://k8s.gcr.io
💡  To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
🐳  Подготавливается Kubernetes v1.23.3 на Docker 20.10.12 ...
    ▪ kubelet.housekeeping-interval=5m
🔎  Компоненты Kubernetes проверяются ...
    ▪ Используется образ gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Включенные дополнения: storage-provisioner, default-storageclass
🏄  Готово! kubectl настроен для использования кластера "minikube" и "default" пространства имён по умолчанию

Просмотрим статус кластера

PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator> minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

Посмотрим файл конфига kubeconfig

kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    extensions:
    - extension:
        last-update: Fri, 17 Jun 2022 07:45:32 +04
        provider: minikube.sigs.k8s.io
        version: v1.25.2
      name: cluster_info
    server: https://127.0.0.1:59245
  name: minikube
contexts:
- context:
    cluster: minikube
    extensions:
    - extension:
        last-update: Fri, 17 Jun 2022 07:45:32 +04
        provider: minikube.sigs.k8s.io
        version: v1.25.2
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

Проверка подключения к кластеру.

kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:59245
CoreDNS is running at https://127.0.0.1:59245/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

Создадим pod manifest

apiVersion: v1
kind: Pod
metadata:
  name: calculator
  labels:
    env: test
spec:
  containers:
    - name: calculator
      image: sladkkov/calculator:1.0.0
      imagePullPolicy: IfNotPresent

Применим manifest. Манифест ранее уже был создан

PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator> kubectl apply -f pod.yaml -n default
pod/calculator unchanged

Проверим установку манифеста

PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator> kubectl describe pod calculator -n default
Name:         calculator
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Fri, 17 Jun 2022 06:40:05 +0400
Labels:       env=test
Annotations:  <none>
Status:       Running
IP:           172.17.0.2
IPs:
  IP:  172.17.0.2
Containers:
  calculator:
    Container ID:   docker://8389d4f5f2a6032c584e3fad026da80b8af49f9c1314affc0a00a4e1628bde96
    Image:          sladkkov/calculator:1.0.0
    Image ID:       docker-pullable://sladkkov/calculator@sha256:d5fbbf62745a42c04b3b2008465bd835fcc44af54dbff369b1584feaa0d692a1
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Fri, 17 Jun 2022 07:45:36 +0400
    Last State:     Terminated
      Reason:       Error
      Exit Code:    143
      Started:      Fri, 17 Jun 2022 06:40:06 +0400
      Finished:     Fri, 17 Jun 2022 06:42:14 +0400
    Ready:          True
    Restart Count:  1
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-2j4fp (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-2j4fp:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason          Age    From               Message
  ----    ------          ----   ----               -------
  Normal  Scheduled       70m    default-scheduler  Successfully assigned default/calculator to minikube
  Normal  Pulled          70m    kubelet            Container image "sladkkov/calculator:1.0.0" already present on machine
  Normal  Created         70m    kubelet            Created container calculator
  Normal  Started         70m    kubelet            Started container calculator
  Normal  SandboxChanged  5m23s  kubelet            Pod sandbox changed, it will be killed and re-created.
  Normal  Pulled          5m18s  kubelet            Container image "sladkkov/calculator:1.0.0" already present on machine
  Normal  Created         5m18s  kubelet            Created container calculator
  Normal  Started         5m18s  kubelet            Started container calculator
PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator>

Пробросим наружу порт web-приложения.

port-forward pods/calculator 9090:9090
Forwarding from 127.0.0.1:9090 -> 9090
Forwarding from [::1]:9090 -> 9090
Handling connection for 9090
Handling connection for 9090
Handling connection for 9090

Удалим Pod с web-приложением

PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator>  kubectl delete po calculator
pod "calculator" deleted

Остановим minikube

PS C:\Users\sladk\Downloads\control-work-time-main\RestApiCalculator>
                                                                      minikube stop
✋  Узел "minikube" останавливается ...
🛑  Выключается "minikube" через SSH ...
🛑  Остановлено узлов: 1.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published