Skip to content

Kubernetes

Ongrid 는 Kubernetes 에서도 실행되지만, 일급 배포 대상은 아닙니다. 기본 설치 경로는 단일 Linux 호스트에서의 docker compose 인데, git clone 부터 동작하는 https://your-host/ 까지 가장 빠른 길이기 때문입니다. K8s 는 이미 Kubernetes 플랫폼을 운영 중이고 거기에 Ongrid 를 끼워 넣고 싶은 운영자를 위한 것입니다.

Helm 차트 현황

아직 공식 Helm 차트는 없습니다. 릴리스 tarball 은 deploy/docker-compose.yml 과 그것을 감싸는 설치 스크립트를 제공합니다 — deploy/charts/ 도, kustomize/ 도 없습니다. 오늘 K8s 에 배포해야 한다면 compose 파일을 직접 손으로 옮겨야 합니다. 커뮤니티 차트는 로드맵에 있습니다 — GitHub 이슈 트래커에서 진척을 확인하세요.

compose 파일이 주는 것과 K8s 에서 필요한 등가물:

Compose 서비스K8s 등가물
mysqlStatefulSet (replica 1) + headless Service + PVC
ongridDeployment (replica 1) + :8080 (/api) 와 :9100 (/metrics) 용 ClusterIP Service
nginx (front door)Deployment + :443:80 용 LoadBalancer/Ingress
frontierDeployment + 터널 포트 :40012 용 LoadBalancer/NodePort
prometheusStatefulSet + PVC, 또는 기존 kube-prom-stack
lokiStatefulSet + PVC, 또는 기존 loki-distributed
tempoStatefulSet + PVC
grafanaDeployment + PVC, 또는 기존 grafana
searxngDeployment + ClusterIP

ONGRID_* 환경 변수는 ConfigMap + Secret 으로 다루세요. compose 스택에서 마운트하는 것과 동일한 TLS 인증서를 nginx 파드에 마운트하세요.

매니저를 K8s 에서 돌려야 할까요?

솔직한 답: 동작하긴 하지만 크게 얻는 것이 없습니다. 매니저는 영속 상태 (MySQL) 를 가진 단일 프로세스이며 수평 확장이 불가능합니다 — Service 뒤에 두 개의 파드를 두면 in-process 알림 evaluator, 채팅 세션 라우터, 에이전트 커널의 도구 레지스트리 캐시가 모두 깨집니다. 따라서 PVC 가 붙은 1-replica Deployment 를 굴리게 되는데, 이는 본질적으로 Docker 를 쓰는 VM 과 같은 모양에 YAML 만 더 많은 형태입니다.

K8s 가 의미를 갖는 지점:

  • 이미 ingress / cert-manager / external-DNS 가 갖춰져 있다 — 매니저 front door 에 그것을 재사용하세요.
  • 이미 매니지드 MySQL (RDS / CloudSQL / Vitess) 이 있다 — ONGRID_DB_DSN 을 그쪽으로 가리키고 StatefulSet 을 빼세요.
  • 이미 Prometheus / Loki / Tempo 스택이 있다 — ONGRID_PROM_URL, ONGRID_LOG_QUERY_URL, ONGRID_TRACE_QUERY_URL 을 그쪽으로 가리키고 해당 StatefulSet 들을 빼세요.

이러한 치환을 거치면 "K8s 위의 매니저" 는 결국 두 개의 Deployment (매니저 + nginx) 와 재사용한 업스트림 하나당 하나의 Service 로 줄어듭니다.

K8s 위의 edge — daemonset 패턴

당신의 워크로드 가 K8s 에서 돌고 노드별 가관측성을 원한다면, edge 에이전트를 DaemonSet 으로 실행하세요. 노드당 하나의 에이전트 파드, hostPath 로 /proc, /sys, 노드의 journal, 노드의 syslog 에 연결합니다.

스케치:

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ongrid-edge
  namespace: ongrid
spec:
  selector: { matchLabels: { app: ongrid-edge } }
  template:
    metadata: { labels: { app: ongrid-edge } }
    spec:
      hostPID: true
      hostNetwork: false      # tunnel is outbound; no need for hostNetwork
      containers:
      - name: edge
        image: your-registry/ongrid-edge:vX.Y.Z
        env:
        - name: ONGRID_EDGE_CLOUD_ADDR
          value: ongrid.example.com:40012
        - name: ONGRID_EDGE_ACCESS_KEY
          valueFrom: { secretKeyRef: { name: ongrid-edge, key: access_key } }
        - name: ONGRID_EDGE_SECRET_KEY
          valueFrom: { secretKeyRef: { name: ongrid-edge, key: secret_key } }
        # rare cases (read-only network introspection skills)
        securityContext:
          capabilities: { add: ["NET_ADMIN"] }
        volumeMounts:
        - { name: proc,   mountPath: /host/proc, readOnly: true }
        - { name: sys,    mountPath: /host/sys,  readOnly: true }
        - { name: jrnl,   mountPath: /var/log/journal, readOnly: true }
      volumes:
      - { name: proc,   hostPath: { path: /proc } }
      - { name: sys,    hostPath: { path: /sys } }
      - { name: jrnl,   hostPath: { path: /var/log/journal } }

ongrid-edge 의 Docker 이미지가 필요합니다 — make docker-ongrid-edge 가 이를 생성합니다 (ongrid-edge:<version>). 자체 사설 레지스트리에 푸시하세요.

같은 access/secret 쌍이 모든 노드에서 재사용됩니다. 매니저의 Edges 페이지에는 호스트명으로 중복 제거된 노드당 한 행이 표시됩니다.

K8s 위의 edge — sidecar 패턴

노드 전체가 아니라 단일 앱만 관측하고 싶다면, 그 앱의 파드 안에 sidecar 로 edge 에이전트를 실행하세요. 같은 이미지, 같은 환경 변수, hostPath 없음. 호스트 메트릭은 잃지만 (gopsutil 컬렉터가 노드가 아니라 파드의 시야를 반환합니다) 범위는 좁아집니다.

다음과 같은 상황에 맞는 모양입니다:

  • 여러 팀이 클러스터를 공유하고 각 팀이 자체 Ongrid 매니저 / 테넌트를 원할 때.
  • 특권 DaemonSet 을 띄울 권한이 없을 때.
  • 워크로드 하나의 로그와 트레이스만 관심 있을 때.

동작하지 않는 것들

  • ongrid 의 다중 replica. 매니저는 in-process 상태를 갖습니다: 알림 evaluator 상태, 채팅 세션 라우터, 에이전트 커널 캐시 모두 단일 인스턴스용입니다. 2-replica Deployment 는 알림 중복 발송, 알림 evaluator 의 경쟁, 채팅 세션 분리를 일으킵니다. replica 는 하나로 운영하세요.
  • 파드 안에서의 curl-pipe 설치 스크립트. systemd 없이는 hard-fail 합니다. 이미지를 쓰세요.
  • ADR-024 staged-bundle 업그레이드. 해당 훅은 systemd 에 연결된 Linux 셸 스크립트입니다. K8s 에서는 이미지 태그를 바꿔 DaemonSet 을 롤링 업데이트하는 방식으로 업그레이드 — in-place swap 경로는 우회됩니다.
  • 포트 40012 의 NodePort. 동작은 하지만, NodePort 뒤의 노드가 바뀔 때마다 모든 edge 연결이 재해시 됩니다. 터널 listener 에는 LoadBalancer 를 선호하거나, frontier 브로커를 전용 노드에 노출하세요.

로드맵

  • 합리적 기본값을 갖춘 Helm 차트 (1-replica 매니저, 선택적 번들 MySQL / Prom / Loki / Tempo).
  • ManagerEdgePool 리소스를 받는 CRD 기반 오퍼레이터 — access/secret 쌍을 자동 발급하고 업그레이드를 롤링합니다.
  • journald 대신 kubelet API 를 통해 파드 로그를 읽는 k8s 네이티브 edge 플러그인 — 클러스터 내부 로그에 hostPath 가 필요 없게 됩니다.

이 중 어느 것도 릴리스에 커밋되어 있지 않습니다. 함께 추진하고 싶다면 GitHub 이슈를 보세요.