Пример Kubernetes-манифеста для Hermes Agent
Опубликовано:
Используемые термины: Kubernetes, Hermes AI.
В этой инструкции разберем готовый манифест для развертывания Hermes Agent в Kubernetes — с дашбордом управления, постоянным хранилищем и доступом по HTTPS через Ingress.
Предварительная настройка
Примеры манифестов
Deployment
PersistentVolumeClaim
Service
Ingress
Secret
Запуск контейнера Hermes
Подготовка каталога и namespace
Создадим каталог для файлов манифеста и перейдем в него:
mkdir -p /opt/hermes && cd /opt/hermes
Заведем для Hermes Agent отдельный namespace, чтобы не смешивать ресурсы с другими приложениями в кластере:
kubectl create namespace hermes
* все манифесты ниже уже указывают namespace: hermes в metadata — отдельно указывать пространство имен флагом -n при apply не потребуется.
Примеры манифестов
По отдельности, рассмотрим минимально необходимый набор манифестов для запуска и работы Hermes.
Deployment для Hermes Agent
Опишем деплоймент — он запускает контейнер с образом hermes-agent и поднимает дашборд управления:
vi deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hermes
labels:
app: hermes
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: hermes
template:
metadata:
labels:
app: hermes
spec:
containers:
- name: hermes
image: nousresearch/hermes-agent:v2026.7.30
imagePullPolicy: Always
args: ['gateway', 'run']
env:
- name: HERMES_DASHBOARD
value: '1'
- name: HERMES_DASHBOARD_PUBLIC_URL
value: https://ai.dmosk.ru
- name: HERMES_DASHBOARD_BASIC_AUTH_USERNAME
valueFrom:
secretKeyRef:
name: hermes-dashboard-auth
key: HERMES_DASHBOARD_BASIC_AUTH_USERNAME
- name: HERMES_DASHBOARD_BASIC_AUTH_PASSWORD
valueFrom:
secretKeyRef:
name: hermes-dashboard-auth
key: HERMES_DASHBOARD_BASIC_AUTH_PASSWORD
- name: HERMES_DASHBOARD_BASIC_AUTH_SECRET
valueFrom:
secretKeyRef:
name: hermes-dashboard-auth
key: HERMES_DASHBOARD_BASIC_AUTH_SECRET
ports:
- name: dashboard
containerPort: 9119
volumeMounts:
- name: hermes-data
mountPath: /opt/data
readinessProbe:
tcpSocket:
port: dashboard
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 12
livenessProbe:
tcpSocket:
port: dashboard
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
memory: '1Gi'
limits:
memory: '2Gi'
volumes:
- name: hermes-data
persistentVolumeClaim:
claimName: hermes-data
* дашборд включается переменной HERMES_DASHBOARD, а его публичный адрес задается через HERMES_DASHBOARD_PUBLIC_URL; логин, пароль и секрет подписи сессий подтягиваются из Secret hermes-dashboard-auth, который создадим ниже; readinessProbe проверяет порт dashboard и допускает до 12 неудачных попыток, прежде чем считать под неготовым.
** обратите внимание, что указанную версию v2026.7.30 необходимо заменить на актуальную.
PersistentVolumeClaim для данных
Под данные Hermes Agent выделим отдельный том на 10 Гб:
vi pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hermes-data
namespace: hermes
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
* том подключается в деплойменте по пути /opt/data — там Hermes Agent хранит свои рабочие файлы.
Service для дашборда
Добавим сервис, который свяжет под с портом дашборда:
vi service.yml
apiVersion: v1
kind: Service
metadata:
name: hermes-service
namespace: hermes
spec:
selector:
app: hermes
ports:
- name: dashboard
protocol: TCP
port: 9119
targetPort: dashboard
* targetPort: dashboard — это ссылка не на номер порта, а на его имя dashboard, заданное в контейнере деплоймента; Kubernetes сам сопоставит его с containerPort 9119.
Ingress с TLS-сертификатом
Настроим Ingress для traefik, чтобы дашборд Hermes Agent был доступен снаружи по HTTPS:
vi ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hermes-ingress
namespace: hermes
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
traefik.ingress.kubernetes.io/router.tls.certresolver: default
spec:
ingressClassName: "traefik"
tls:
- hosts:
- ai.dmosk.ru
secretName: hermes-tls-cert
rules:
- host: ai.dmosk.ru
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hermes-service
port:
name: dashboard
* certresolver default должен быть уже настроен в traefik заранее — иначе сертификат для домена не выпустится; вместо ai.dmosk.ru подставляем свой домен; аннотацию router.tls: "true" отдельно не указываем — наличие certresolver уже включает TLS.
** если в кластере установлены Traefik CRD и нужен принудительный редирект с HTTP на HTTPS, в annotations можно добавить traefik.ingress.kubernetes.io/router.middlewares: hermes-redirect-https@kubernetescrd вместе с отдельным ресурсом Middleware — это опционально и зависит от того, как настроен конкретный кластер.
Secret с учетными данными дашборда
Дашборд Hermes Agent защищен базовой авторизацией, а секрет подписи сессий и пароль нельзя оставлять в манифесте по умолчанию. Сгенерируем оба значения перед созданием Secret:
openssl rand -base64 24
Мы должны увидеть случайную строку — используем ее как значение для HERMES_DASHBOARD_BASIC_AUTH_PASSWORD. Повторим команду еще раз, чтобы получить отдельное значение для HERMES_DASHBOARD_BASIC_AUTH_SECRET.
Создадим Secret с логином, паролем и ключом подписи сессий:
vi secret.yml
apiVersion: v1
kind: Secret
metadata:
name: hermes-dashboard-auth
namespace: hermes
type: Opaque
stringData:
HERMES_DASHBOARD_BASIC_AUTH_USERNAME: admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD: "вставить-сюда-сгенерированный-пароль"
# Стабильный ключ подписи сессий (не менять без необходимости — иначе разлогинит всех)
HERMES_DASHBOARD_BASIC_AUTH_SECRET: "вставить-сюда-сгенерированный-секрет"
* оба значения берем из вывода openssl rand выше, а не из примера — готовый пароль из статьи использовать нельзя, он попадет в поисковую выдачу и станет известен всем.
Причина: файл secret.yml с реальными значениями пароля и секрета, попавший в Git-репозиторий, раскрывает учетные данные всем, у кого есть доступ к репозиторию — кодирование Secret внутри Kubernetes от этого не защищает. Решение: добавляем secret.yml в .gitignore и применяем его вручную либо через отдельный защищенный пайплайн (CI/CD с секретами в переменных окружения, Sealed Secrets, External Secrets Operator, HashiCorp Vault) — в репозитории должен остаться только шаблон без реальных значений.
Применение манифестов
Сначала применим том и секрет — они нужны деплойменту сразу при старте:
kubectl apply -f pvc.yml,secret.yml
Затем применим оставшиеся манифесты из каталога:
kubectl apply -f ./
Проверим, что под поднялся:
kubectl get pod -n hermes
Мы должны увидеть под hermes в статусе Running.
Развертывание Hermes Kubernetes-стека завершено. Дашборд доступен по адресу с указанным доменом. В нашем примере — https://ai.dmosk.ru.