---
title: Kubernetes
description: Deployment, ClusterIP Service, 설정용 Secret, Unico 레지스트리용 풀 시크릿을 사용해 Kubernetes에서 Human Plugin을 실행합니다.
canonical: https://developer.unico.io/ko/human-plugin/self-hosting/kubernetes
locale: ko
generated_by: markdown-export
---

# Kubernetes

ClusterIP Service 뒤의 두 개 이상의 레플리카로, 고객의 백엔드에서만 접근할 수 있습니다.

## 사전 요구 사항

- Kubernetes 클러스터와 이에 대한 `kubectl` 접근 권한.
- 클러스터에서 접근할 수 있는, Human Plugin 전용 PostgreSQL 데이터베이스. [사전 요구 사항 및 액세스](/ko/human-plugin/get-started/prerequisites)를 참고하세요.
- Unico에서 받은 레지스트리 자격 증명과 액세스 키.

아래의 모든 리소스는 전용 네임스페이스에 만듭니다.

```bash
kubectl create namespace human-plugin
```

## 1. 레지스트리 풀 시크릿

```bash
kubectl -n human-plugin create secret docker-registry unico-registry \
  --docker-server=pkg.unico.run \
  --docker-username="<username>" \
  --docker-password="<token>"
```

## 2. 설정용 Secret

```bash
kubectl -n human-plugin create secret generic human-plugin \
  --from-literal=HUMAN_API_ACCESS_KEY='<your access key>' \
  --from-literal=POSTGRES_ADDRESS_HOST='<database host>' \
  --from-literal=POSTGRES_USER='human_plugin' \
  --from-literal=POSTGRES_PASSWORD='<database password>'
```

데이터베이스가 [구성](/ko/human-plugin/self-hosting/configuration)의 기본값과 다른 경우에만 `POSTGRES_ADDRESS_PORT`, `POSTGRES_DATABASE`, `POSTGRES_SSL_MODE`를 추가하세요. 다른 도구(External Secrets, Sealed Secrets, 볼트)로 시크릿을 관리한다면 해당 도구로 동일한 키를 만드세요. 값이 들어 있는 Secret 매니페스트는 절대 커밋하지 마세요.

## 3. Deployment와 Service

```yaml title="human-plugin.yaml"
apiVersion: apps/v1
kind: Deployment
metadata:
  name: human-plugin
  namespace: human-plugin
spec:
  replicas: 2
  selector:
    matchLabels: { app: human-plugin }
  template:
    metadata:
      labels: { app: human-plugin }
    spec:
      terminationGracePeriodSeconds: 60
      imagePullSecrets:
        - name: unico-registry
      containers:
        - name: human-plugin
          image: pkg.unico.run/human-plugin-api:latest
          imagePullPolicy: Always
          ports:
            - { name: http, containerPort: 8080 }
          envFrom:
            - secretRef: { name: human-plugin }
          resources:
            requests: { cpu: "1", memory: 1Gi }
            limits: { cpu: "1", memory: 1Gi }
          readinessProbe:
            httpGet: { path: /health/ready, port: http }
            timeoutSeconds: 5
          livenessProbe:
            httpGet: { path: /health/live, port: http }
            periodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  name: human-plugin
  namespace: human-plugin
spec:
  selector: { app: human-plugin }
  ports:
    - { name: http, port: 8080, targetPort: http }
```

```bash
kubectl apply -f human-plugin.yaml
```

```bash
kubectl -n human-plugin rollout status deployment/human-plugin
```

- **`replicas: 2`:** 레플리카는 데이터베이스를 공유하므로 필요한 만큼 실행할 수 있습니다. 두 개를 두면 하나가 재시작되는 동안에도 Human Plugin을 계속 사용할 수 있습니다.
- **`terminationGracePeriodSeconds: 60`:** Human Plugin은 중지될 때 처리 중인 요청을 최대 55초 동안 기다립니다. Kubernetes 기본값인 30초는 생성 요청을 중간에 끊을 수 있습니다.
- **`imagePullPolicy: Always`:** `latest` 태그를 사용하면 새 Pod마다 가장 최신 릴리스를 풀합니다.
- **프로브:** 레디니스는 데이터베이스가 응답할 때까지 해당 레플리카로 트래픽이 가지 않게 하고, `timeoutSeconds: 5`는 데이터베이스가 응답하지 않을 때 프로브가 실패하게 합니다. [상태 확인 및 모니터링](/ko/human-plugin/self-hosting/health-and-monitoring)을 참고하세요.
- **리소스:** 위 값은 각 레플리카의 최소값입니다. [하드웨어 요구 사항](/ko/human-plugin/self-hosting/overview#hardware-requirements)을 참고하세요.

## 4. 접근 제한

백엔드는 `http://human-plugin.human-plugin.svc:8080`으로 Human Plugin에 접근합니다. Human Plugin에는 자체 인증이 없으므로 다음을 지켜야 합니다.

- Ingress, `LoadBalancer`, `NodePort`로 Service를 노출하지 마세요.
- NetworkPolicy로 백엔드의 네임스페이스만 허용하세요.

```yaml title="network-policy.yaml"
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: human-plugin-allow-backend
  namespace: human-plugin
spec:
  podSelector:
    matchLabels: { app: human-plugin }
  policyTypes: [Ingress]
  ingress:
    - from:
        - namespaceSelector:
            matchLabels: { kubernetes.io/metadata.name: <your back-end namespace> }
      ports:
        - { port: 8080 }
```

Human Plugin 자체에는 Unico로 나가는 아웃바운드 HTTPS와 고객의 데이터베이스 접근이 필요합니다. [네트워킹 및 보안](/ko/human-plugin/self-hosting/networking-and-security)을 참고하세요.

## 5. 검증

```bash
kubectl -n human-plugin port-forward svc/human-plugin 8080:8080
```

다른 터미널에서 레디니스를 확인하고, `http://127.0.0.1:8080`에 대해 [빠른 시작](/ko/human-plugin/get-started/quickstart#3-create-a-process)의 생성 요청을 실행하세요.

```bash
curl --fail http://127.0.0.1:8080/health/ready
```

## 로그

```bash
kubectl -n human-plugin logs deploy/human-plugin --since=10m
```

## 업데이트

```bash
kubectl -n human-plugin rollout restart deployment/human-plugin
```

새 Pod는 최신 이미지를 풀하고, 준비가 되면 이전 Pod를 하나씩 교체합니다. [운영](/ko/human-plugin/self-hosting/operations)을 참고하세요.