Git-sync гаряча перезавантаження на Kubernetes
Kubernetes (K8s) — потужна платформа оркестрації контейнерів, яка спрощує розгортання програмного забезпечення, масштабування та керування. Вона дозволяє ефективно запускати та керувати контейнеризованими програмами, мінімізуючи час простою та оптимізуючи цикл розробки.
Традиційно контейнеризовані програми будуються як Docker-образи та розгортаються на Kubernetes за допомогою таких ресурсів, як deployments, replicasets або statefulsets. Хоча цей робочий процес ефективний для виробничих середовищ, він може бути неефективним для швидкоплинної, спільної розробки, особливо в розподілених командах.
Проблема: Повільні цикли розробки на Kubernetes
Уявіть, що ви працюєте в великій, розподіленій команді, яка використовує Kubernetes як свою платформу розробки. Якщо кожна зміна коду ініціює CI/CD pipeline для перевірки, тестування, створення Docker-образу і його повторного розгортання, цей процес може значно сповільнити цикл зворотного зв'язку. Це затримка, яка стає вузьким місцем для ітеративної розробки, ускладнюючи підтримку швидкості роботи команд розробників і QA-інженерів.
Рішення: Гаряче перезавантаження на Kubernetes
Гаряче перезавантаження дозволяє розробникам бачити свої зміни в запущених програмах без необхідності перебудовувати і повторно розгортати контейнери. Цей процес:
- Створює і розгортає програму один раз під час першого коміту.
- Підтягує та застосовує наступні зміни коду безпосередньо до запущеного контейнера.
Це значно зменшує час простою, пришвидшує ітерації та покращує співпрацю.
Проблеми з традиційною контейнеризацією
Щоб реалізувати гаряче перезавантаження, ми повинні вирішити дві основні проблеми:
- Незмінність Docker-образів: Після створення Docker-образи не можна змінити, щоб додати новий код.
- Динамічні оновлення коду на Kubernetes: Kubernetes не має вбудованої підтримки для синхронізації змін коду з Git-репозиторія в працюючий контейнер.
Подолання цих проблем за допомогою Git-Sync
Git-Sync — легкий інструмент, який постійно синхронізує Git-репозиторій з локальним томом. У поєднанні з патерном sidecar в Kubernetes, Git-Sync дозволяє реалізувати гаряче перезавантаження шляхом:
- Підтягування останніх змін коду з Git-репозиторія в спільний том.
- Спільного використання цього тому з контейнером програми, що запускає оновлений код.
Архітектура Git-Sync:
- Git-Sync працює періодично (визначено за допомогою параметра
--period
), перевіряючи нові коміти. - Коли виявляється новий коміт, він створює каталог у
.worktrees
, використовуючи хеш коміту, і оновлює символьне посилання (налаштовується за допомогою параметра--link
), щоб вказати на каталог останнього коміту. - Символьне посилання слугує «контрактом» між Git-Sync і програмою, дозволяючи програмі завжди використовувати найостанніший код.
Кроки реалізації
Необхідні вимоги
- Базові знання: Ресурси Kubernetes (deployments, services, persistent volumes, ingress), Git та shell-скрипти.
- Середовище: 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
Пояснення:
- Скрипт моніторить символьне посилання
LATEST_LINK
, створене Git-Sync. - Коли символьне посилання оновлюється, щоб вказати на новий коміт, скрипт перезавантажує 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