Гарячі перезавантаження на Kubernetes за допомогою Git-Sync

pic

Git-sync гаряча перезавантаження на Kubernetes

Kubernetes (K8s) — потужна платформа оркестрації контейнерів, яка спрощує розгортання програмного забезпечення, масштабування та керування. Вона дозволяє ефективно запускати та керувати контейнеризованими програмами, мінімізуючи час простою та оптимізуючи цикл розробки.

Традиційно контейнеризовані програми будуються як Docker-образи та розгортаються на Kubernetes за допомогою таких ресурсів, як deployments, replicasets або statefulsets. Хоча цей робочий процес ефективний для виробничих середовищ, він може бути неефективним для швидкоплинної, спільної розробки, особливо в розподілених командах.

Проблема: Повільні цикли розробки на Kubernetes

Уявіть, що ви працюєте в великій, розподіленій команді, яка використовує Kubernetes як свою платформу розробки. Якщо кожна зміна коду ініціює CI/CD pipeline для перевірки, тестування, створення Docker-образу і його повторного розгортання, цей процес може значно сповільнити цикл зворотного зв'язку. Це затримка, яка стає вузьким місцем для ітеративної розробки, ускладнюючи підтримку швидкості роботи команд розробників і QA-інженерів.

Рішення: Гаряче перезавантаження на Kubernetes

Гаряче перезавантаження дозволяє розробникам бачити свої зміни в запущених програмах без необхідності перебудовувати і повторно розгортати контейнери. Цей процес:

  1. Створює і розгортає програму один раз під час першого коміту.
  2. Підтягує та застосовує наступні зміни коду безпосередньо до запущеного контейнера.

Це значно зменшує час простою, пришвидшує ітерації та покращує співпрацю.

Проблеми з традиційною контейнеризацією

Щоб реалізувати гаряче перезавантаження, ми повинні вирішити дві основні проблеми:

  1. Незмінність Docker-образів: Після створення Docker-образи не можна змінити, щоб додати новий код.
  2. Динамічні оновлення коду на Kubernetes: Kubernetes не має вбудованої підтримки для синхронізації змін коду з Git-репозиторія в працюючий контейнер.

Подолання цих проблем за допомогою Git-Sync

Git-Sync — легкий інструмент, який постійно синхронізує Git-репозиторій з локальним томом. У поєднанні з патерном sidecar в Kubernetes, Git-Sync дозволяє реалізувати гаряче перезавантаження шляхом:

  • Підтягування останніх змін коду з Git-репозиторія в спільний том.
  • Спільного використання цього тому з контейнером програми, що запускає оновлений код.

Архітектура Git-Sync:

  • Git-Sync працює періодично (визначено за допомогою параметра --period), перевіряючи нові коміти.
  • Коли виявляється новий коміт, він створює каталог у .worktrees, використовуючи хеш коміту, і оновлює символьне посилання (налаштовується за допомогою параметра --link), щоб вказати на каталог останнього коміту.
  • Символьне посилання слугує «контрактом» між Git-Sync і програмою, дозволяючи програмі завжди використовувати найостанніший код.

Кроки реалізації

Необхідні вимоги

  1. Базові знання: Ресурси Kubernetes (deployments, services, persistent volumes, ingress), Git та shell-скрипти.
  2. Середовище: Kubernetes кластер або Minikube, встановлений локально.
    3.
    Git Repository: Репозиторій, що містить код вашої програми.

Приклад програми

Ми використаємо просту Python Flask програму:

# app.py  
from flask import Flask  

app = Flask(__name__)  

@app.route('/')  
def hello_world():  
 return "Hello, World!"  

if __name__ == '__main__':  
 app.run(debug=True)

Dockerfile для тільки залежностей

Dockerfile буде містити тільки залежності:

FROM python:3.9-slim  

# Встановлення Python залежностей  
RUN pip install flask  

ENV FLASK_APP=/app/latest/app.py  

CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]

Створення Persistent Volume Claim (PVC)

Persistent Volume Claim (PVC) потрібен для того, щоб ділитися оновленнями коду між контейнерами.

# pvc.yaml  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
 name: app-pvc  
 namespace: default  
spec:  
 accessModes:  
 - ReadWriteOnce  
 storageClassName: standard  
 resources:  
 requests:  
 storage: 1Gi

Застосування PVC:

kubectl apply -f pvc.yaml

Створення ConfigMap для shell скрипту

Ми використаємо наступний shell скрипт для моніторингу змін і перезавантаження програми при отриманні нового коду:

#!/bin/bash  

LATEST_LINK="/app/latest"  
FLASK_PID=0  
LAST_TARGET=""  
start_flask_app_and_monitor() {  
 echo "Запуск Flask програми..."  
 python -m flask run --host=0.0.0.0 &  
 FLASK_PID=$!  
 echo "Моніторинг $LATEST_LINK для змін..."  
 while true; do  
 CURRENT_TARGET=$(readlink "$LATEST_LINK")  
 if ["$CURRENT_TARGET" != "$LAST_TARGET"]; then  
 echo "Виявлені зміни. Останній вказує на $CURRENT_TARGET"  
 LAST_TARGET=$CURRENT_TARGET  
 reload_flask_app  
 fi  
 sleep 2  
 done  
}  
reload_flask_app() {  
 echo "Зміни виявлено. Перезавантаження Flask програми..."  
 if [$FLASK_PID -ne 0]; then  
 kill -HUP $FLASK_PID  
 wait $FLASK_PID  
 fi  
 start_flask_app_and_monitor  
}  
echo "Чекати на $LATEST_LINK..."  
while [! -L "$LATEST_LINK"]; do  
 sleep 2  
done  
LAST_TARGET=$(readlink "$LATEST_LINK")  
start_flask_app_and_monitor

Пояснення:

  1. Скрипт моніторить символьне посилання LATEST_LINK, створене Git-Sync.
  2. Коли символьне посилання оновлюється, щоб вказати на новий коміт, скрипт перезавантажує Flask програму.

Створення ConfigMap:

kubectl create configmap script-configmap --from-file=watch_and_reload.sh

Kubernetes Deployment

Ось манифест для розгортання:

apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: flask-app  
 namespace: default  
spec:  
 replicas: 1  
 selector:  
 matchLabels:  
 app: flask-app  
 template:  
 metadata:  
 labels:  
 app: flask-app  
 spec:  
 volumes:  
 - name: app-volume  
 persistentVolumeClaim:  
 claimName: app-pvc  
 - name: script-volume  
 configMap:  
 name: script-configmap  
 containers:  
 - name: flask-app  
 image: flask-app:latest  
 command: ["/bin/sh", "-c", "/scripts/watch_and_reload.sh"]  
 volumeMounts:  
 - name: app-volume  
 mountPath: /app  
 - name: script-volume  
 mountPath: /scripts  
 - name: git-sync  
 image: registry.k8s.io/git-sync/git-sync:v4.2.3  
 args:  
 - --repo=https://github.com/your-username/your-repo  
 - --root=/git  
 - --link=/app/latest  
 - --period=30s  
 volumeMounts:  
 - name: app-volume  
 mountPath: /git

Застосування розгортання:

kubectl apply -f deployment.yaml

Перевірка налаштувань

  • Переконайтесь, що поди працюють:
kubectl get pods
  • Приклад виводу:
NAME READY STATUS RESTARTS AGE  
flask-app-xxxxx 2/2 Running 0 1m
  • Перевірте логи контейнера flask-app:
kubectl logs  -c flask-app
  • Ви повинні побачити логи, що свідчать про запуск програми та моніторинг змін.
  • Запуште новий коміт у репозиторій. Перевірте логи знову, і ви побачите:
Виявлені зміни. Останній вказує на 
  • Доступ до програми через сервіс або інтерфейс для перевірки, чи зміни відображаються.

Обмеження

1.
Тільки одна репліка: Налаштування з кількома репліками можуть призвести до непослідовної поведінки.
2. Не готово для виробництва: Підходить для використання в розробці або в якості концепції для доказів.

Висновок

Цей посібник демонструє, як реалізувати гаряче перезавантаження для динамічних програм на Kubernetes за допомогою Git-Sync. Використовуючи гнучкість Kubernetes, архітектуру Git-Sync та патерн розгортання з бічним контейнером, ви можете створити швидше та більш спільне середовище для розробки.

Перевірте повний робочий репозиторій:
GitHub Репозиторій: k8s-auto-reloader

Успішного кодування!

Перекладено з: Hot-Reloading on Kubernetes Using Git-Sync

Leave a Reply

Your email address will not be published. Required fields are marked *