Tinyauth

Kubernetes

Kubernetes에 Tinyauth를 배포하는 방법

이 가이드는 Kubernetes에 tinyauth를 배포하는 방법을 설명해요. ConfigMap, Secret, Deployment, Service, Ingress 및 데이터 정리를 위한 CronJob 구성을 다뤄요.


사전 준비

  • Kubernetes 클러스터 (v1.25 이상 권장)
  • kubectl CLI 도구
  • Ingress 컨트롤러 (예: nginx-ingress, traefik)
  • TLS 인증서 관리 (예: cert-manager)

1. 네임스페이스 생성

apiVersion: v1
kind: Namespace
metadata:
  name: tinyauth

2. 설정 파일 (ConfigMap)

민감하지 않은 설정은 ConfigMap으로 관리해요.

apiVersion: v1
kind: ConfigMap
metadata:
  name: tinyauth-config
  namespace: tinyauth
data:
  config.yaml: |
    server:
      public_origin: https://auth.example.com
      listen_port: 8080
      trust_proxy: true

    security:
      session_secret: ${SESSION_SECRET}
      hash_secret: ${HASH_SECRET}

    registration:
      enabled: false

    database:
      type: postgres
      host: ${DATABASE_HOST}
      port: ${DATABASE_PORT}
      name: ${DATABASE_NAME}
      user: ${DATABASE_USER}
      password: ${DATABASE_PASSWORD}

    email:
      transport: smtp
      host: smtp.example.com
      port: 465
      secure: true
      user: ${SMTP_USER}
      password: ${SMTP_PASSWORD}
      from: "TinyAuth <noreply@example.com>"

    scheduler:
      enabled: false

이 예시는 자체 회원가입을 닫아 둔 기본 배포 예시예요. 공개 회원가입이 필요하면 registration.enabled: true를 명시하고, 비밀번호 가입을 사용할 경우 이메일 전송 설정도 함께 점검하세요.

Note

Kubernetes 환경에서는 내장 스케줄러를 비활성화(scheduler.enabled: false)하고, 대신 CronJob으로 정리 작업을 실행하는 것을 권장해요. 이렇게 하면 여러 파드가 동시에 정리 작업을 실행하는 것을 방지할 수 있어요.


3. 민감 정보 (Secret)

비밀번호, 시크릿 등 민감한 정보는 Secret으로 관리해요.

apiVersion: v1
kind: Secret
metadata:
  name: tinyauth-secrets
  namespace: tinyauth
type: Opaque
stringData:
  SESSION_SECRET: "your-32-byte-random-session-secret"
  HASH_SECRET: "your-base64url-hash-secret"
  DATABASE_HOST: "postgres-host"
  DATABASE_PORT: "5432"
  DATABASE_NAME: "tinyauth"
  DATABASE_USER: "tinyauth"
  DATABASE_PASSWORD: "your-database-password"
  SMTP_USER: "smtp-user@example.com"
  SMTP_PASSWORD: "your-smtp-password"
Caution

프로덕션 환경에서는 stringData 대신 외부 비밀 관리 도구(Vault, AWS Secrets Manager, Sealed Secrets 등)를 사용하는 것을 권장해요.


4. Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tinyauth
  namespace: tinyauth
  labels:
    app: tinyauth
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tinyauth
  template:
    metadata:
      labels:
        app: tinyauth
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
      containers:
        - name: tinyauth
          image: ghcr.io/tinyrack-net/tinyauth:latest
          ports:
            - containerPort: 8080
              protocol: TCP
          envFrom:
            - secretRef:
                name: tinyauth-secrets
          volumeMounts:
            - name: config
              mountPath: /opt/config.yaml
              subPath: config.yaml
              readOnly: true
            - name: tmp
              mountPath: /tmp
          securityContext:
            readOnlyRootFilesystem: true
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 256Mi
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
      volumes:
        - name: config
          configMap:
            name: tinyauth-config
        - name: tmp
          emptyDir: {}

5. Service

apiVersion: v1
kind: Service
metadata:
  name: tinyauth
  namespace: tinyauth
spec:
  selector:
    app: tinyauth
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP

6. Ingress

nginx-ingress를 사용하는 예시예요. cert-manager로 TLS 인증서를 자동 발급한다고 가정해요.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tinyauth
  namespace: tinyauth
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - auth.example.com
      secretName: tinyauth-tls
  rules:
    - host: auth.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tinyauth
                port:
                  number: 80

7. CronJob (데이터 정리)

내장 스케줄러 대신 Kubernetes CronJob으로 정리 작업을 실행해요.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: tinyauth-cleanup
  namespace: tinyauth
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          securityContext:
            runAsNonRoot: true
            runAsUser: 1000
          containers:
            - name: cleanup
              image: ghcr.io/tinyrack-net/tinyauth:latest
              command: ["tinyauth", "cleanup"]
              envFrom:
                - secretRef:
                    name: tinyauth-secrets
              volumeMounts:
                - name: config
                  mountPath: /opt/config.yaml
                  subPath: config.yaml
                  readOnly: true
              resources:
                requests:
                  cpu: 50m
                  memory: 64Mi
                limits:
                  cpu: 200m
                  memory: 128Mi
          restartPolicy: OnFailure
          volumes:
            - name: config
              configMap:
                name: tinyauth-config
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3

PostgreSQL 참고

Kubernetes에서 tinyauth를 운영할 때는 PostgreSQL 사용을 권장해요.

  • SQLite는 단일 파드에서만 사용 가능해요 (파일 기반이므로 여러 파드에서 공유 불가).
  • PostgreSQL을 사용하면 수평 확장(replicas > 1)이 가능해요.
  • 기존 PostgreSQL 클러스터가 있다면 그것을 사용하거나, CloudNativePG와 같은 Kubernetes 네이티브 PostgreSQL 오퍼레이터를 고려해 보세요.

보안 권장 사항

  • readOnlyRootFilesystem: 컨테이너의 파일 시스템을 읽기 전용으로 설정해요.
  • runAsNonRoot: root가 아닌 사용자로 실행해요.
  • allowPrivilegeEscalation: false: 권한 상승을 방지해요.
  • capabilities.drop: ALL: 불필요한 Linux 커널 capabilities를 모두 제거해요.
  • trust_proxy: true: Ingress 컨트롤러를 통해 들어오는 X-Forwarded-* 헤더를 신뢰하도록 설정해요.
  • 민감 정보는 반드시 Secret 또는 외부 비밀 관리 도구로 관리해요.