diff --git a/readme.md b/readme.md index 8991b92..1ef232d 100644 --- a/readme.md +++ b/readme.md @@ -63,3 +63,4 @@ * [12.4. Развертывание кластера на собственных серверах, лекция 2](/src/homework/12-kubernetes/12.4) * [12.5. Сетевые решения CNI](/src/homework/12-kubernetes/12.5) * [13.1. контейнеры, поды, deployment, statefulset, services, endpoints](/src/homework/13-kubernates-config/13.1) +* [13.2. разделы и монтирование](/src/homework/13-kubernates-config/13.2) diff --git a/src/homework/13-kubernates-config/13.2/config/production/backend.yml b/src/homework/13-kubernates-config/13.2/config/production/backend.yml new file mode 100644 index 0000000..282726e --- /dev/null +++ b/src/homework/13-kubernates-config/13.2/config/production/backend.yml @@ -0,0 +1,49 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: prod-app + service: backend + name: prod-app-backend + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: prod-app + service: backend + template: + metadata: + labels: + app: prod-app + service: backend + spec: + terminationGracePeriodSeconds: 30 + containers: + - image: dannecron/netology-devops-k8s-app:backend-latest + imagePullPolicy: Always + name: netology-backend + env: + - name: DATABASE_URL + value: "postgres://pg_user:pg_passwd@postgres:5432/news" + volumeMounts: + - mountPath: "/shared" + name: shared-volume + volumes: + - name: shared-volume + persistentVolumeClaim: + claimName: pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: prod-backend + namespace: default +spec: + ports: + - name: web + port: 9000 + selector: + app: prod-app + service: backend diff --git a/src/homework/13-kubernates-config/13.2/config/production/database.yml b/src/homework/13-kubernates-config/13.2/config/production/database.yml new file mode 100644 index 0000000..5acd561 --- /dev/null +++ b/src/homework/13-kubernates-config/13.2/config/production/database.yml @@ -0,0 +1,87 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-config + labels: + app: postgres +data: + POSTGRES_DB: news + POSTGRES_USER: db_user + POSTGRES_PASSWORD: db_passwd + PGDATA: /var/lib/postgresql/data +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: postgres-pv-volume # Sets PV's name + labels: + type: local # Sets PV's type to local + app: postgres +spec: + storageClassName: manual + capacity: + storage: 1Gi # Sets PV Volume + accessModes: + - ReadWriteMany + hostPath: + path: "/mnt/pgsql_data" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-pv-claim # Sets name of PVC + labels: + app: postgres +spec: + storageClassName: manual + accessModes: + - ReadWriteMany # Sets read and write access + resources: + requests: + storage: 1Gi # Sets volume size +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: prod-app + service: database + db-kind: postgresql + name: testing-db + namespace: default +spec: + selector: + matchLabels: + app: prod-app + service: database + db-kind: postgresql + serviceName: postgres + replicas: 1 + podManagementPolicy: "Parallel" + updateStrategy: + type: "RollingUpdate" + template: + metadata: + labels: + app: prod-app + service: database + db-kind: postgresql + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: postgres + image: postgres:13-alpine # Sets Image + imagePullPolicy: "IfNotPresent" + ports: + - containerPort: 5432 # Exposes container port + envFrom: + - configMapRef: + name: postgres-config + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: postgredb + volumes: + - name: postgredb + persistentVolumeClaim: + claimName: postgres-pv-claim diff --git a/src/homework/13-kubernates-config/13.2/config/production/frontend.yml b/src/homework/13-kubernates-config/13.2/config/production/frontend.yml new file mode 100644 index 0000000..2f2759f --- /dev/null +++ b/src/homework/13-kubernates-config/13.2/config/production/frontend.yml @@ -0,0 +1,49 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: prod-app + service: frontend + name: prod-app-frontend + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: prod-app + service: frontend + template: + metadata: + labels: + app: prod-app + service: frontend + spec: + terminationGracePeriodSeconds: 30 + containers: + - image: dannecron/netology-devops-k8s-app:frontend-latest + imagePullPolicy: Always + name: netology-frontend + env: + - name: BASE_URL + value: "http://prod-backend:9000" + volumeMounts: + - mountPath: "/shared" + name: shared-volume + volumes: + - name: shared-volume + persistentVolumeClaim: + claimName: pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: prod-frontend + namespace: default +spec: + ports: + - name: web + port: 80 + selector: + app: prod-app + service: frontend diff --git a/src/homework/13-kubernates-config/13.2/config/production/volume.yml b/src/homework/13-kubernates-config/13.2/config/production/volume.yml new file mode 100644 index 0000000..6b964af --- /dev/null +++ b/src/homework/13-kubernates-config/13.2/config/production/volume.yml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pvc +spec: + storageClassName: "nfs" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi diff --git a/src/homework/13-kubernates-config/13.2/config/testing/deployment.yml b/src/homework/13-kubernates-config/13.2/config/testing/deployment.yml new file mode 100644 index 0000000..20e5313 --- /dev/null +++ b/src/homework/13-kubernates-config/13.2/config/testing/deployment.yml @@ -0,0 +1,120 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-config + labels: + app: postgres +data: + POSTGRES_DB: news + POSTGRES_USER: db_user + POSTGRES_PASSWORD: db_passwd + PGDATA: /var/lib/postgresql/data +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: postgres-pv-volume # Sets PV's name + labels: + type: local # Sets PV's type to local + app: postgres +spec: + storageClassName: manual + capacity: + storage: 1Gi # Sets PV Volume + accessModes: + - ReadWriteMany + hostPath: + path: "/mnt/pgsql_data" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-pv-claim # Sets name of PVC + labels: + app: postgres +spec: + storageClassName: manual + accessModes: + - ReadWriteMany # Sets read and write access + resources: + requests: + storage: 1Gi # Sets volume size +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: testing-app + db-kind: postgresql + name: testing-db + namespace: default +spec: + selector: + matchLabels: + db-kind: postgresql + serviceName: postgres + replicas: 1 + podManagementPolicy: "Parallel" + updateStrategy: + type: "RollingUpdate" + template: + metadata: + labels: + db-kind: postgresql + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: postgres + image: postgres:13-alpine # Sets Image + imagePullPolicy: "IfNotPresent" + ports: + - containerPort: 5432 # Exposes container port + envFrom: + - configMapRef: + name: postgres-config + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: postgredb + volumes: + - name: postgredb + persistentVolumeClaim: + claimName: postgres-pv-claim +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: testing-app + name: testing-app + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: testing-app + template: + metadata: + labels: + app: testing-app + spec: + terminationGracePeriodSeconds: 30 + containers: + - image: dannecron/netology-devops-k8s-app:frontend-latest + imagePullPolicy: Always + name: netology-frontend + volumeMounts: + - mountPath: "/static" + name: test-shared-volume + - image: dannecron/netology-devops-k8s-app:backend-latest + imagePullPolicy: Always + name: netology-backend + env: + - name: DATABASE_URL + value: "postgres://db_user:db_passwd@postgres:5432/news" + volumeMounts: + - mountPath: "/static" + name: test-shared-volume + volumes: + - name: test-shared-volume + emptyDir: {} diff --git a/src/homework/13-kubernates-config/13.2/readme.md b/src/homework/13-kubernates-config/13.2/readme.md new file mode 100644 index 0000000..858825f --- /dev/null +++ b/src/homework/13-kubernates-config/13.2/readme.md @@ -0,0 +1,176 @@ +Выполнение [домашнего задания](https://github.com/netology-code/devkub-homeworks/blob/main/13-kubernetes-config-02-mounts.md) +по теме "13.2. разделы и монтирование" + +## Q/A + +> Приложение запущено и работает, но время от времени появляется необходимость передавать между бекендами данные. +> А сам бекенд генерирует статику для фронта. Нужно оптимизировать это. +> Для настройки NFS сервера можно воспользоваться следующей инструкцией (производить под пользователем на сервере, у которого есть доступ до kubectl): +> +> * установить helm: curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash +> * добавить репозиторий чартов: helm repo add stable https://charts.helm.sh/stable && helm repo update +> * установить nfs-server через helm: helm install nfs-server stable/nfs-server-provisioner +> +> В конце установки будет выдан пример создания PVC для этого сервера. + +### Задание 1 + +> В stage окружении часто возникает необходимость отдавать статику бекенда сразу фронтом. Проще всего сделать это через общую папку. Требования: +> * в поде подключена общая папка между контейнерами (например, /static); +> * после записи чего-либо в контейнере с беком файлы можно получить из контейнера с фронтом. + +Для деплоя приложения будет использована [спецификация из предыдущего домашнего задания](/src/homework/13-kubernates-config/13.1/config/testing) с некоторыми отличиями: + +1. В deployment `testing-app` добавлен том `emptyDir` с названием `shared-volume` + + ```yaml + volumes: + - name: test-shared-volume + emptyDir: {} + ``` + +2. В контейнеры `netology-frontend` и `netology-backend` добавлена точка монтирования в `/static` для данного тома + + ```yaml + volumeMounts: + - mountPath: "/static" + name: test-shared-volume + ``` + +Итоговая конфигурация расположена в файле [testing/deployment.yml](./config/testing/deployment.yml). + +Применение конфигурации: + +```shell +kubectl apply -f testing/deployment.yml +``` + +Чтобы проверить, что файлы, созданные в одном контейнере будут видны в другом, нужно выполнить следующие шаги: + +* Записать данные в новый файл `/static/42.txt` + + ```shell + kubectl exec testing-app-85d8f9d7bc-x5cbm -c netology-backend -- sh -c "echo '42' > /static/42.txt" + ``` + +* Проверить, что файл доступен из данного контейнера + + ```shell + kubectl exec testing-app-85d8f9d7bc-x5cbm -c netology-backend -- sh -c "cat /static/42.txt" + ``` + + ```text + 42 + ``` + +* Проверить, что файл доступен из другого контейнера + + ```shell + kubectl exec testing-app-85d8f9d7bc-x5cbm -c netology-frontend -- sh -c "cat /static/42.txt" + ``` + + ```text + 42 + ``` + +### Задание 2 + +> Поработав на stage, доработки нужно отправить на прод. В продуктиве у нас контейнеры крутятся в разных подах, поэтому потребуется PV и связь через PVC. Сам PV должен быть связан с NFS сервером. Требования: +> * все бекенды подключаются к одному PV в режиме ReadWriteMany; +> * фронтенды тоже подключаются к этому же PV с таким же режимом; +> * файлы, созданные бекендом, должны быть доступны фронту. + +Перед выполнением задания необходимо установить плагин `nfs`, для этого: + +* Необходимо установить `helm`: + + ```shell + curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash + helm version + ``` + + ```text + version.BuildInfo{Version:"v3.10.2", GitCommit:"50f003e5ee8704ec937a756c646870227d7c8b58", GitTreeState:"clean", GoVersion:"go1.18.8"} + ``` + +* Добавить основной репозиторий `helm` + + ```shell + helm repo add stable https://charts.helm.sh/stable && helm repo update + ``` + +* Установить `nfs`-сервер + + ```shell + helm install nfs-server stable/nfs-server-provisioner + ``` + +* Установить на всех нодах необходимую утилиту: + + ```shell + sudo apt install nfs-common + ``` + +Для деплоя приложения будет использована [спецификация из предыдущего домашнего задания](/src/homework/13-kubernates-config/13.1/config/production) с некоторыми отличиями: + +1. Создан отдельный манифест для создания общего динамичного хранилища: [production/volume.yml](./config/production/volume.yml) +2. В deployment для `backend` и `frontend` добавлен том `shared-volume` и точка его монтирования в `/shared` + +Порядок деплоя: + +* Создание динамичного `pvc` + + ```shell + kubectl apply -f production/volume.yml + kubectl get pvc + ``` + + ```text + NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE + pvc Bound pvc-fd56d76a-a856-41e6-90a6-8ee4ca1a6439 1Gi RWO nfs 7s + ``` + +* Деплой БД: `kubectl apply -f production/database.yml` +* Деплой backend: `kubectl apply -f production/backend.yml` +* Деплой frontend: `kubectl apply -f production/frontend.yml` +* Проверка, что всё работает: + + ```shell + kubectl get pods + ``` + + ```text + NAME READY STATUS RESTARTS AGE + nfs-server-nfs-server-provisioner-0 1/1 Running 0 10m + prod-app-backend-755859df77-lcst2 1/1 Running 0 26s + prod-app-frontend-5967548577-dvzxc 1/1 Running 0 18s + testing-db-0 1/1 Running 0 5m58s + ``` + +Чтобы проверить, что файлы, созданные в одном поде будут видны в другом, нужно выполнить следующие шаги: + +* Записать данные в новый файл `/shared/42.txt` + + ```shell + kubectl exec prod-app-backend-755859df77-lcst2 -c netology-backend -- sh -c "echo '42' > /shared/42.txt" + ``` + +* Проверить, что файл доступен из данного пода + + ```shell + kubectl exec prod-app-backend-755859df77-lcst2 -c netology-backend -- sh -c "cat /shared/42.txt" + ``` + + ```text + 42 + ``` + +* Проверить, что файл доступен из другого пода + + ```shell + kubectl exec prod-app-frontend-5967548577-dvzxc -c netology-frontend -- sh -c "cat /shared/42.txt" + ``` + + ```text + 42 + ```