Файлы, упомянутые в главе

  • .helm/templates/deployment.yaml
  • .helm/secret-values.yaml
  • .helm/values.yaml
  • src/main/resources/application.properties
  • pom.xml

В этой главе мы настроим в нашем базовом приложении работу с пользовательскими файлами. Для этого потребуется персистентное (постоянное) хранилище.

В идеале — нужно добиться, чтобы приложение было stateless, а данные хранились в S3-совместимом хранилище — например, MinIO или AWS S3. Это обеспечивает простое масштабирование, работу в HA-режиме и высокую доступность.

А есть какие-то способы кроме S3?

Первый и более общий способ — это использовать как volume хранилище NFS, CephFS или hostPath.

Мы не рекомендуем этот способ, потому что при возникновении неполадок с такими типами volume’ов они влияют на работоспособность контейнера и всего демона Docker в целом. Тогда могут пострадать приложения, не имеющие никакого отношения к вашему.

Более надёжный путь — пользоваться S3. Так мы используем отдельный сервис, который имеет возможность масштабироваться, работать в HA-режиме и иметь высокую доступность. Можно воспользоваться облачным решением вроде AWS S3, Google Cloud Storage, Microsoft Blobs Storage и т.д.

Природа Kubernetes (и оркестровки контейнеров в целом) такова, что если мы будем сохранять файлы в какой-либо директории у приложения (запущенного в Kubernetes), то после перезапуска контейнера все изменения пропадут.

Данная настройка производится полностью в рамках приложения. Нужно подключить aws-java-sdk, сконфигурировать его и начать использовать.

Пропишем использование aws-java-sdk как зависимость:

		<dependency>
				<groupId>com.amazonaws</groupId>
				<artifactId>aws-java-sdk</artifactId>
				<version>1.11.163</version>
		</dependency>
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk</artifactId> <version>1.11.163</version> </dependency>

И сконфигурируем:

amazonProperties.endpointUrl=${S3ENDPOINT}
amazonProperties.login=${S3LOGIN}
amazonProperties.password=${S3PASSWORD}
amazonProperties.bucketName=${S3BUCKET}
amazonProperties.zone=${S3ZONE}
amazonProperties.endpointUrl=${S3ENDPOINT} amazonProperties.login=${S3LOGIN} amazonProperties.password=${S3PASSWORD} amazonProperties.bucketName=${S3BUCKET} amazonProperties.zone=${S3ZONE}

Для работы с S3 необходимо пробросить ключи доступа в приложение. Для этого стоит использовать механизм секретных переменных. Вопрос работы с секретными переменными рассматривался подробнее, когда мы делали базовое приложение.

.helm/secret-values.yaml (расшифрованный) копировать имя копировать текст
app:
  s3:
    login:
      _default: mys3keyidstage
    password:
      _default: mys3keysecretstage
app: s3: login: _default: mys3keyidstage password: _default: mys3keysecretstage

Несекретные значения — храним в values.yaml:

app:
<...>
  s3:
    endpoint:
      _default: "https://s3.selcdn.ru"
    bucket:
      _default: "test-container"
    zone:
      _default: "ru-1a"
app: <...> s3: endpoint: _default: "https://s3.selcdn.ru" bucket: _default: "test-container" zone: _default: "ru-1a"

После того, как значения корректно прописаны и зашифрованы, можно пробросить соответствующие значения в Deployment:

        env:
<...>
        - name: S3ENDPOINT
          value: {{ pluck .Values.global.env .Values.app.s3.endpoint | first | default .Values.app.s3.endpoint._default | quote }}
        - name: S3LOGIN
          value: {{ pluck .Values.global.env .Values.app.s3.login | first | default .Values.app.s3.login._default | quote }}
        - name: S3PASSWORD
          value: {{ pluck .Values.global.env .Values.app.s3.password | first | default .Values.app.s3.password._default | quote }}
        - name: S3BUCKET
          value: {{ pluck .Values.global.env .Values.app.s3.bucket | first | default .Values.app.s3.bucket._default | quote }}
        - name: S3ZONE
          value: {{ pluck .Values.global.env .Values.app.s3.zone | first | default .Values.app.s3.zone._default | quote }}
{{ tuple "basicapp" . | include "werf_container_env" | indent 8 }}
env: <...> - name: S3ENDPOINT value: {{ pluck .Values.global.env .Values.app.s3.endpoint | first | default .Values.app.s3.endpoint._default | quote }} - name: S3LOGIN value: {{ pluck .Values.global.env .Values.app.s3.login | first | default .Values.app.s3.login._default | quote }} - name: S3PASSWORD value: {{ pluck .Values.global.env .Values.app.s3.password | first | default .Values.app.s3.password._default | quote }} - name: S3BUCKET value: {{ pluck .Values.global.env .Values.app.s3.bucket | first | default .Values.app.s3.bucket._default | quote }} - name: S3ZONE value: {{ pluck .Values.global.env .Values.app.s3.zone | first | default .Values.app.s3.zone._default | quote }} {{ tuple "basicapp" . | include "werf_container_env" | indent 8 }}

Об особенностях использования aws-java-sdk можно подробно почитать в документации