InfoGrab Docs

OpenShift Local (CRC)에서 n8n 호스팅

요약

이 가이드는 Red Hat의 로컬 OpenShift 클러스터 실행 도구인 OpenShift Local (CRC)에 n8n을 배포하는 과정을 안내합니다. OpenShift 자체가 많은 리소스를 소비하므로, 충분한 리소스를 갖춘 머신이 필요합니다.

이 가이드는 Red Hat의 로컬 OpenShift 클러스터 실행 도구인 OpenShift Local (CRC)에 n8n을 배포하는 과정을 안내합니다. AWS/EKS 배포와 동일한 방식으로 작동하지만, 로컬 머신에서만 실행됩니다. 클라우드 비용 없이 OpenShift 환경에서 n8n을 로컬로 테스트하기 위한 용도입니다.

OpenShift 자체가 많은 리소스를 소비하므로, 충분한 리소스를 갖춘 머신이 필요합니다.

OpenShift 개념과 표준 Kubernetes 비교#

OpenShift는 Kubernetes 기반으로 구축되었지만 다른 용어를 사용하며 더 엄격한 보안 기본값을 갖습니다. 표준 Kubernetes 또는 EKS 같은 관리형 Kubernetes 서비스를 대상으로 하는 가이드에 익숙한 경우, 아래 표에서 동등한 개념을 확인할 수 있습니다.

표준 Kubernetes / EKS OpenShift Local (CRC)
kubectl oc (OpenShift CLI; kubectl 명령어도 이해함)
Namespace Project (동일한 개념, 다른 명령어)
Ingress / LoadBalancer Route (OpenShift에 내장, 별도 컨트롤러 불필요)
EBS StorageClass (gp3) CRC 내장 스토리지 프로비저너 (설정 불필요)
RDS PostgreSQL Helm을 통한 클러스터 내 PostgreSQL (Bitnami)
ElastiCache Redis Helm을 통한 클러스터 내 Redis (Bitnami)
AWS S3 클러스터 내 MinIO (S3 호환)
Pod Identity / IRSA Kubernetes Secret을 통한 액세스 키
AWS Load Balancer Controller 불필요 (Route가 내장됨)
OIDC / IAM 불필요
월 $135–400 무료 (로컬 머신에서 실행)

사전 요구사항#

시작하기 전에 머신이 다음 사항을 충족하는지 확인하세요:

  • CPU: 가상화 지원이 있는 물리적 코어 4개 이상 (스레드 제외)
  • RAM: 최소 32GB 이상 여유 (CRC가 VM에 9GB 예약)
  • 디스크: 100GB 이상 여유 공간
  • OS: Ubuntu (22.04 LTS 이상)

Ubuntu 준비#

터미널 열기#

Ctrl+Alt+T를 누르거나 애플리케이션 메뉴에서 Terminal을 검색하세요.

이 가이드의 모든 명령어는 터미널에 입력하고 Enter를 눌러 실행합니다.

시스템 업데이트#

의존성 문제를 방지하기 위해 시스템 업데이트부터 시작합니다:

sudo apt update && sudo apt upgrade -y
sudo

sudo는 "관리자 권한으로 실행"을 의미합니다. 비밀번호를 입력하라는 메시지가 표시됩니다. 입력하는 문자는 화면에 표시되지 않으며, 이는 정상입니다.

CPU 가상화 지원 확인#

CRC는 가상 머신을 실행합니다. CPU가 하드웨어 가상화를 지원해야 합니다:

egrep -c '(vmx|svm)' /proc/cpuinfo
  • 출력 0: 가상화가 비활성화되어 있습니다. BIOS/UEFI 설정에 들어가서 VT-x(Intel) 또는 AMD-V(AMD)를 활성화한 후 재부팅하고 다시 시도하세요.
  • 출력 1 이상: 계속 진행할 수 있습니다.

KVM 및 libvirt 설치#

KVM은 Linux의 내장 하이퍼바이저입니다. CRC는 이를 사용하여 OpenShift 클러스터 VM을 실행합니다:

sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils

CRC가 클러스터 VM과 파일시스템을 공유하는 데 필요한 virtiofsd를 설치합니다:

sudo apt install -y virtiofsd

libvirt 서비스를 시작하고 부팅 시 자동으로 시작되도록 설정합니다:

sudo systemctl start libvirtd
sudo systemctl enable libvirtd

실행 중인지 확인합니다:

sudo systemctl status libvirtd

초록색으로 Active: active (running)이 표시되는지 확인하세요. q를 눌러 종료합니다.

사용자를 필요한 그룹에 추가#

이를 통해 모든 명령어에 sudo를 입력하지 않고도 KVM과 libvirt를 사용할 수 있습니다:

sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
경고

이 설정을 적용하려면 로그아웃 후 다시 로그인(또는 재부팅)해야 합니다. 이 단계를 건너뛰면 CRC가 "permission denied" 오류로 실패합니다.

지금 재부팅합니다:

sudo reboot

다시 로그인한 후 터미널을 열고 그룹 멤버십을 확인합니다:

groups

목록에 libvirtkvm이 표시되어야 합니다.

NetworkManager 설치#

CRC는 클러스터의 내부 도메인(*.apps-crc.testing, api.crc.testing)에 대한 DNS 항목을 관리하기 위해 NetworkManager가 필요합니다:

sudo apt install -y network-manager
sudo systemctl start NetworkManager
sudo systemctl enable NetworkManager

연결 상태를 확인합니다:

nmcli general status

STATE 컬럼에 connected가 표시되어야 합니다.

도구 설치#

Red Hat 계정 및 Pull Secret 가져오기#

CRC는 컨테이너 이미지를 가져오기 위해 무료 Red Hat 계정이 필요합니다.

  1. 계정이 없다면 무료 Red Hat 계정을 생성하세요.
  2. console.redhat.com/openshift/create/local에서 Download OpenShift Local을 클릭합니다.
  3. Linux를 선택하고 .tar.xz 파일을 ~/Downloads에 다운로드합니다.
  4. Red Hat 콘솔의 동일한 페이지에서 Copy pull secret을 클릭합니다. 텍스트 파일에 붙여넣고 나중을 위해 저장합니다.

CRC 설치#

Downloads 폴더에서 터미널을 엽니다.

cd ~/Downloads

아카이브를 추출합니다.

tar xf crc-linux-amd64.tar.xz

어느 터미널에서든 사용할 수 있도록 crc 바이너리를 시스템 전역 위치로 이동합니다:

sudo mv crc-*-linux-amd64/crc /usr/local/bin/

설치를 확인합니다:

crc version

터미널에 버전 번호가 출력되어야 합니다.

Helm 설치#

Helm은 n8n과 지원 서비스를 클러스터에 설치합니다:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

확인:

helm version

환경 변수 설정#

export NAMESPACE=n8n-$(date +%Y%m%d)
echo "Namespace:$NAMESPACE"
변수 지속성

이 변수는 현재 터미널 세션에서만 유효합니다. 계속 진행하기 전에 새 터미널을 열 때마다 이 줄을 다시 실행하세요.

OpenShift Local 시작#

CRC setup 실행#

한 번만 실행하면 됩니다. KVM 네트워킹을 구성하고, 시스템 요구사항을 확인하며, CRC 번들(~2.5GB)을 다운로드합니다:

crc setup

몇 분이 소요됩니다. 누락된 패키지가 보고되면 sudo apt install -y <package-name>으로 설치한 후 다시 실행하세요.

CRC 메모리 구성 및 클러스터 시작#

CRC는 VM에 기본적으로 9GB의 RAM을 할당합니다. n8n과 지원 서비스에는 더 많은 여유 공간이 필요합니다. 시작하기 전에 메모리를 14GB로 설정합니다:

crc config set memory 14336

한 번만 실행하면 됩니다. 이 설정은 crc stop / crc start 사이클에 걸쳐 유지됩니다.

권장사항: 매번 붙여넣지 않아도 되도록 Pull Secret을 파일로 저장하세요:

# 파일을 열고, Pull Secret을 붙여넣은 후(앞에서 저장한 것), Ctrl+O로 저장, Ctrl+X로 종료
nano ~/pull-secret.txt

# 본인만 읽을 수 있도록 권한 제한
chmod 600 ~/pull-secret.txt

파일을 사용하여 CRC를 시작합니다:

crc start --pull-secret-file ~/pull-secret.txt

또는 플래그 없이 crc start를 실행하고 메시지가 표시될 때 Secret을 붙여넣을 수 있습니다.

10~15분이 소요됩니다. 완료되면 다음과 같은 내용이 표시됩니다:

Started the OpenShift cluster.

The server is accessible via web console at:
  https://console-openshift-console.apps-crc.testing

Log in as administrator:
  Username: kubeadmin
  Password: <generated-password>

Log in as user:
  Username: developer
  Password: developer

지금 kubeadmin 비밀번호를 저장하세요. 다음 단계에서 필요합니다. 나중에 crc console --credentials를 사용하여 검색할 수 있습니다.

DNS 확인 검증#

Ubuntu에서 CRC는 NetworkManager와 systemd-resolved를 통해 시스템 리졸버를 자동으로 구성합니다. 수동 /etc/hosts 항목은 필요 없습니다.

API에 접근 가능한지 확인합니다:

sudo ss -tlnp | grep 6443

127.0.0.1:6443에 바인딩된 프로세스가 표시되어야 합니다. 아무것도 표시되지 않으면 crc start를 다시 실행하세요. DNS가 *.apps-crc.testing을 확인하지 못하는 경우 문제 해결 섹션을 참조하세요.

셸 구성#

CRC는 VM 내부에 oc CLI를 번들로 제공합니다. 다음 명령어로 터미널에서 사용할 수 있게 합니다:

eval $(crc oc-env)

터미널을 열 때마다 실행하지 않아도 되도록 영구적으로 설정하려면:

echo 'eval $(crc oc-env)' >> ~/.bashrc
source ~/.bashrc

oc가 작동하는지 확인합니다:

oc version

클러스터 로그인#

oc login -u kubeadmin -p <your-kubeadmin-password> https://api.crc.testing:6443

<your-kubeadmin-password>CRC 메모리 구성 및 클러스터 시작 시 출력된 비밀번호로 교체하세요.

로그인되었는지 확인합니다:

oc whoami

kubeadmin이 화면에 출력되어야 합니다.

단독 배포#

단독 모드는 SQLite를 사용하여 n8n을 단일 Pod로 실행합니다. 외부 데이터베이스나 Redis가 필요 없습니다. n8n을 탐색하고 로컬에서 워크플로우를 테스트하기에 이상적입니다.

프로젝트 생성#

OpenShift에서 project는 Kubernetes namespace와 동일합니다: 리소스를 위한 격리된 공간입니다:

oc new-project $NAMESPACE

필요한 보안 권한 부여#

OpenShift는 **Security Context Constraints (SCCs)**라고 하는 엄격한 보안 정책을 적용합니다. 기본적으로 Pod는 특정 사용자 ID로 실행될 수 없습니다. n8n 차트는 사용자 ID 1000으로 실행되므로 명시적으로 허용해야 합니다.

완전한 명시적 형식을 사용하세요. -z 약식 플래그는 일부 OpenShift 버전에서 자동으로 실패할 수 있습니다:

oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n

바인딩이 생성되었는지 확인합니다:

oc get rolebindings -n $NAMESPACE

system:openshift:scc:anyuid를 참조하는 바인딩이 표시되어야 합니다.

필요한 Secret 생성#

oc create secret generic n8n-secrets \
  --namespace $NAMESPACE \
  --from-literal=N8N_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
  --from-literal=N8N_HOST="localhost" \
  --from-literal=N8N_PORT="5678" \
  --from-literal=N8N_PROTOCOL="http"

즉시 암호화 키를 백업하세요:

oc get secret n8n-secrets -n $NAMESPACE \
  -o jsonpath='{.data.N8N_ENCRYPTION_KEY}' | base64 --decode

해당 출력을 복사하여 안전한 곳에 저장하세요. 잃어버리면 워크플로우에 저장된 모든 자격 증명이 영구적으로 읽을 수 없게 됩니다.

Values 파일 생성#

n8n-standalone-values.yaml이라는 파일을 만듭니다. 간단한 텍스트 편집기인 nano를 사용할 수 있습니다:

nano n8n-standalone-values.yaml

다음 내용을 붙여넣고 Ctrl+O를 눌러 저장한 후 Ctrl+X를 눌러 종료합니다:

# n8n-standalone-values.yaml
# 단일 Pod, SQLite 데이터베이스, 외부 의존성 없음.

queueMode:
  enabled: false

database:
  type: sqlite
  useExternal: false

redis:
  enabled: false

# PVC는 SQLite 데이터베이스 파일을 저장합니다.
persistence:
  enabled: true
  size: 5Gi
  # storageClassName 불필요 — CRC가 기본 스토리지 프로비저너를 제공합니다.

secretRefs:
  existingSecret: "n8n-secrets"

service:
  type: ClusterIP
  port: 5678

# OpenShift: securityContext를 활성화하여 Pod가 UID 1000 (node 사용자)으로
# fsGroup 1000 (PVC를 쓰기 가능하게)으로 실행되도록 해야 합니다. 위에서 부여한
# anyuid SCC가 이를 허용합니다. seccompProfile 줄은 OpenShift 4.14+에서
# anyuid 포함에도 거부되므로 "Deploy n8n"에서 차트 템플릿에서 제거됩니다.
securityContext:
  enabled: true

resources:
  main:
    requests:
      cpu: 100m
      memory: 256Mi
    limits:
      cpu: "1"
      memory: 1Gi

config:
  timezone: UTC

n8n 배포#

n8n Helm 차트는 Pod 스펙에 seccompProfile: RuntimeDefault를 하드코딩합니다. OpenShift 4.14+는 이를 deprecated alpha 어노테이션으로 변환하여 anyuid SCC가 부여된 경우에도 admission에서 거부됩니다. 해결 방법은 차트를 로컬로 가져와서 해당 두 줄을 제거하고 패치된 복사본에서 설치하는 것입니다.

차트 가져오기 및 패치:

helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version 1.0.3 --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml

# 줄이 사라졌는지 확인 (출력이 없어야 함)
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml

패치된 차트에서 설치:

helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml \
  --wait \
  --timeout 10m

Port Forward를 사용하여 n8n 접근#

OpenShift Route는 호스트명이 필요하여 단독 로컬 접근에는 복잡성이 추가됩니다. Port-forward가 더 간단합니다:

oc port-forward service/n8n-main --namespace $NAMESPACE 5678:5678

이 상태로 두고 브라우저에서 다음 주소로 이동합니다:

http://localhost:5678

n8n이 소유자 계정 생성을 요청합니다.

터널 중지

Ctrl+C를 눌러 터널을 중지합니다. 나중에 n8n에 다시 접근하려면 port-forward 명령어를 다시 실행하세요.

배포 상태 확인#

oc get pods -n $NAMESPACE

예상 결과:

NAME                       READY   STATUS    RESTARTS   AGE
n8n-main-7d9f8b-xxxx       1/1     Running   0          3m

단독 배포 완료.

멀티 인스턴스 큐 모드#

멀티 인스턴스 큐 모드는 공유 데이터베이스, 메시지 큐, 오브젝트 스토리지를 사용하여 여러 n8n Pod를 실행합니다. n8n Enterprise 라이선스가 필요합니다.

AWS 관리형 서비스 대신 이 가이드는 온프레미스 또는 고객 OpenShift 환경에서 찾을 수 있는 것을 반영하는 클러스터 내 동등물을 사용합니다:

AWS 서비스 로컬 동등물
RDS PostgreSQL PostgreSQL (Bitnami Helm 차트)
ElastiCache Redis Redis (Bitnami Helm 차트)
S3 MinIO (S3 호환, Bitnami Helm 차트)

클러스터 내 서비스 설치#

프로젝트 생성 및 Bitnami Helm 저장소 추가#

oc new-project $NAMESPACE

Bitnami 차트 저장소를 추가합니다 (한 번만 필요):

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

PostgreSQL 설치#

아래 명령어에서 YourStrongPassword123을 적절한 복잡한 비밀번호로 교체하세요.

helm install postgresql bitnami/postgresql \
  --namespace $NAMESPACE \
  --set auth.username=n8n \
  --set auth.password='YourStrongPassword123' \
  --set auth.database=n8n_enterprise \
  --set global.compatibility.openshift.adaptSecurityContext=auto \
  --wait
플래그

global.compatibility.openshift.adaptSecurityContext=auto 플래그는 Bitnami에 OpenShift가 올바른 사용자 ID를 자동으로 할당하도록 지시합니다 (SCC 오류 방지).

엔드포인트를 저장하세요. 클러스터 내 서비스의 경우 고정입니다:

postgresql.YOUR_NAMESPACE.svc.cluster.local

YOUR_NAMESPACE를 실제 $NAMESPACE 값으로 교체하세요 (예: n8n-20260306).

Redis 설치#

helm install redis bitnami/redis \
  --namespace $NAMESPACE \
  --set auth.enabled=false \
  --set architecture=standalone \
  --set global.compatibility.openshift.adaptSecurityContext=auto \
  --wait

Redis 엔드포인트: redis-master.$NAMESPACE.svc.cluster.local

MinIO (S3 호환 스토리지) 설치#

아래 명령어에서 MinioStrongPassword123을 적절한 복잡한 비밀번호로 교체하세요.

helm install minio bitnami/minio \
  --namespace $NAMESPACE \
  --set auth.rootUser=minioadmin \
  --set auth.rootPassword='MinioStrongPassword123' \
  --set global.compatibility.openshift.adaptSecurityContext=auto \
  --wait

MinIO 엔드포인트: http://minio:9000 (동일한 네임스페이스 내에서는 서비스 이름만으로 작동)

MinIO에 n8n 스토리지 버킷 생성#

n8n이 사용하기 전에 MinIO에 버킷을 생성해야 합니다. MinIO 웹 콘솔을 사용합니다:

MinIO 콘솔 열기:

oc port-forward svc/minio 9001:9001 -n $NAMESPACE

이 상태로 두고 브라우저에서 http://localhost:9001로 이동합니다.

다음으로 로그인합니다:

  • 사용자명: minioadmin
  • 비밀번호: MinioStrongPassword123

콘솔에서:

  1. 왼쪽 사이드바의 Buckets 클릭 → Create Bucket
  2. Bucket Name: n8n-data
  3. Create Bucket 클릭

터미널로 돌아가서 Ctrl+C를 눌러 port-forward를 중지합니다.

n8n 배포#

n8n용 SCC 부여#

oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n-enterprise

oc get rolebindings -n $NAMESPACE에서 system:openshift:scc:anyuid에 대한 바인딩이 표시되는지 확인합니다.

필요한 Secret 생성#

# 핵심 n8n secret
oc create secret generic n8n-enterprise-secrets \
  --namespace $NAMESPACE \
  --from-literal=N8N_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
  --from-literal=N8N_HOST="localhost" \
  --from-literal=N8N_PORT="5678" \
  --from-literal=N8N_PROTOCOL="http"

즉시 암호화 키를 백업하세요:

oc get secret n8n-enterprise-secrets -n $NAMESPACE \
  -o jsonpath='{.data.N8N_ENCRYPTION_KEY}' | base64 --decode

해당 값을 안전한 곳에 저장하세요.

아래 명령어에서 YourStrongPassword123MinioStrongPassword123을 이전 단계의 비밀번호로 교체하세요.

# 데이터베이스 비밀번호 (PostgreSQL 설치 시 설정한 것과 일치해야 함)
oc create secret generic n8n-enterprise-db-secret \
  --namespace $NAMESPACE \
  --from-literal=password='YourStrongPassword123'

# MinIO 자격 증명
oc create secret generic n8n-minio-secret \
  --namespace $NAMESPACE \
  --from-literal=root-password='MinioStrongPassword123'

Values 파일 생성#

n8n-multimain-ocp-values.yaml을 만듭니다. # <-- REPLACE로 표시된 3개의 플레이스홀더 값을 교체하세요:

nano n8n-multimain-ocp-values.yaml
# n8n-multimain-ocp-values.yaml
# OpenShift Local (CRC)용 멀티 인스턴스 큐 모드.
# AWS 서비스 대신 클러스터 내 PostgreSQL, Redis, MinIO를 사용합니다.
# Enterprise 라이선스 필요.

# --- Enterprise 라이선스 ---
license:
  enabled: true
  activationKey: "your-enterprise-license-key-here"  # <-- REPLACE

# --- Multi-main: 로컬 리소스를 위해 2 replicas로 축소 ---
multiMain:
  enabled: true
  replicas: 2

# --- 큐 모드: 2개의 worker Pod ---
queueMode:
  enabled: true
  workerReplicaCount: 2
  workerConcurrency: 5

# --- Webhook 프로세서 ---
webhookProcessor:
  enabled: true
  replicaCount: 1
  disableProductionWebhooksOnMainProcess: true

# --- PostgreSQL (클러스터 내) ---
database:
  type: postgresdb
  useExternal: true
  host: "postgresql.YOUR_NAMESPACE.svc.cluster.local"   # <-- REPLACE YOUR_NAMESPACE
  port: 5432
  database: n8n_enterprise
  schema: "public"
  user: n8n
  passwordSecret:
    name: "n8n-enterprise-db-secret"
    key: "password"

# --- Redis (클러스터 내, TLS 없음) ---
redis:
  enabled: true
  useExternal: true
  host: "redis-master.YOUR_NAMESPACE.svc.cluster.local"  # <-- REPLACE YOUR_NAMESPACE
  port: 6379
  tls: false

# --- MinIO (S3 호환, 클러스터 내) ---
s3:
  enabled: true
  bucket:
    name: "n8n-data"
    region: "us-east-1"
  host: "http://minio:9000"
  auth:
    autoDetect: false
    accessKeyId: "minioadmin"
    secretAccessKeySecret:
      name: "n8n-minio-secret"
      key: "root-password"
  storage:
    mode: "s3"
    availableModes: "filesystem,s3"
  forcePathStyle: true

# --- Service account ---
serviceAccount:
  create: true
  name: n8n

nano를 저장하고 종료합니다 (Ctrl+O, Ctrl+X).

배포 전에 두 개의 YOUR_NAMESPACE 플레이스홀더를 실제 네임스페이스 값으로 교체합니다:

# 네임스페이스 값 확인
echo $NAMESPACE

# 파일에서 교체 (자동으로 편집됨)
sed -i "s/YOUR_NAMESPACE/$NAMESPACE/g" n8n-multimain-ocp-values.yaml

교체 결과를 확인합니다:

grep "svc.cluster.local" n8n-multimain-ocp-values.yaml

두 줄 모두 YOUR_NAMESPACE가 아닌 실제 네임스페이스 이름이 표시되어야 합니다.

n8n 배포#

이전에 차트를 패치하지 않았다면 지금 가져와서 패치합니다:

helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version 1.0.3 --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml  # 아무것도 반환되지 않아야 함

패치된 차트에서 설치합니다:

helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-multimain-ocp-values.yaml \
  --wait \
  --timeout 15m

외부 접근을 위한 Route 생성#

OpenShift에서 Route는 서비스를 외부에 노출합니다. Kubernetes Ingress 또는 LoadBalancer와 동일하며 추가 컨트롤러가 필요 없습니다:

oc expose svc/n8n-main -n $NAMESPACE

URL 가져오기:

export ROUTE=$(oc get route n8n-main -n $NAMESPACE -o jsonpath='{.spec.host}')
echo "n8n URL: http://$ROUTE"

URL은 다음과 같은 형태입니다: http://n8n-main-n8n-20260306.apps-crc.testing

호스트 Secret 업데이트#

n8n은 공개 URL을 알아야 합니다. Route 호스트명으로 Secret을 업데이트한 후 Pod를 재시작합니다:

ENCRYPTION_KEY=$(oc get secret n8n-enterprise-secrets -n $NAMESPACE \
  -o jsonpath='{.data.N8N_ENCRYPTION_KEY}' | base64 --decode)

oc create secret generic n8n-enterprise-secrets \
  --namespace $NAMESPACE \
  --from-literal=N8N_ENCRYPTION_KEY="$ENCRYPTION_KEY" \
  --from-literal=N8N_HOST="$ROUTE" \
  --from-literal=N8N_PORT="5678" \
  --from-literal=N8N_PROTOCOL="http" \
  --dry-run=client -o yaml | oc apply -f -

oc rollout restart deployment -n $NAMESPACE

롤아웃 완료 대기:

oc rollout status deployment/n8n-main -n $NAMESPACE

모든 Pod가 실행 중인지 확인#

oc get pods -n $NAMESPACE

예상 결과 (모두 Running):

NAME                                    READY   STATUS    RESTARTS   AGE
n8n-main-xxxx-aaaa                      1/1     Running   0          5m
n8n-main-xxxx-bbbb                      1/1     Running   0          5m
n8n-worker-xxxx-aaaa                    1/1     Running   0          5m
n8n-worker-xxxx-bbbb                    1/1     Running   0          5m
n8n-webhook-processor-xxxx-aaaa         1/1     Running   0          5m
postgresql-0                            1/1     Running   0          15m
redis-master-0                          1/1     Running   0          15m
minio-xxxx-xxxx                         1/1     Running   0          15m

위에서 출력된 URL로 브라우저를 엽니다.

멀티 인스턴스 배포 완료.

n8n 업데이트#

구성을 변경하거나 차트 버전을 업그레이드하려면, 새 차트 버전을 가져와서 다시 패치한 후 업그레이드합니다:

# 이전 로컬 차트 복사본 제거
rm -rf ~/n8n/

# 새 버전 가져오기 및 패치
helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version <new-version> --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml

# 단독 모드
helm upgrade n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml

# 멀티 인스턴스
helm upgrade n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-multimain-ocp-values.yaml

CRC 중지 및 재개#

CRC는 세션 간에 삭제할 필요가 없습니다. 중지했다가 다시 시작할 수 있습니다:

# 클러스터 중지 (상태 저장)
crc stop

# 나중에 다시 시작
crc start

재시작 후 다시 실행합니다:

eval $(crc oc-env)
export NAMESPACE=n8n-YYYYMMDD   # 원래 날짜 사용
oc login -u kubeadmin -p <password> https://api.crc.testing:6443

문제 해결#

crc setup이 "libvirt not found"로 실패#

sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients
sudo systemctl start libvirtd

그런 다음 crc setup을 다시 실행합니다.

crc start가 "insufficient memory"로 실패#

CRC는 최소 9GB의 여유 RAM이 필요합니다. 다른 애플리케이션을 종료하고 다시 시도하세요. CRC 메모리 구성 지침을 따랐다면 CRC는 14GB를 사용하도록 구성됩니다.

n8n Pod가 Pending 상태에 멈추거나 SCC 오류로 생성되지 않음#

오류에 대한 이벤트를 확인합니다:

oc get events -n $NAMESPACE --sort-by='.lastTimestamp' | tail -20

unable to validate against any security context constraint 또는 seccomp may not be set이 표시되면, 차트의 하드코딩된 seccompProfile: RuntimeDefault가 거부되는 것입니다. OpenShift 4.14+는 이를 deprecated alpha 어노테이션으로 변환하여 anyuid SCC가 부여된 경우에도 admission에서 거부됩니다.

1. 명시적 형식으로 anyuid 부여 (-z 약식은 자동으로 실패할 수 있음):

# 단독 모드
oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n

# 멀티 인스턴스
oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n-enterprise

확인: oc get rolebindings -n $NAMESPACE를 실행합니다. system:openshift:scc:anyuid에 대한 바인딩이 표시되어야 합니다.

2. 차트를 로컬로 가져와서 seccompProfile 줄 제거:

helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version 1.0.3 --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml

# 사라졌는지 확인 (출력이 없어야 함)
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml

3. 제거 후 패치된 차트에서 재설치:

helm uninstall n8n -n $NAMESPACE
helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml \
  --wait \
  --timeout 10m

Route URL이 "Application not available" 반환#

Pod가 아직 시작 중일 수 있습니다. 확인합니다:

oc get pods -n $NAMESPACE
oc rollout status deployment/n8n-main -n $NAMESPACE

Route도 확인합니다:

oc get route -n $NAMESPACE

n8n Pod가 Insufficient memoryPending 상태에 멈춤#

CRC 노드에 Pod를 스케줄할 여유 메모리가 충분하지 않습니다.

해결: CRC의 VM 메모리를 늘리고 재시작합니다:

crc stop
crc config set memory 14336
crc start

CRC가 재시작되면 Pod가 자동으로 스케줄됩니다. 몇 분 후에도 Pod가 대기 중이면 강제 재스케줄을 위해 삭제합니다:

oc delete pod -n $NAMESPACE -l app.kubernetes.io/component=main

머신이 14GB를 확보할 수 없다면 n8n-standalone-values.yaml에서 Pod의 메모리 요청을 낮출 수도 있습니다:

resources:
  main:
    requests:
      memory: 256Mi

그런 다음 업그레이드합니다: helm upgrade n8n ~/n8n/ -n $NAMESPACE -f n8n-standalone-values.yaml

DNS가 .apps-crc.testing 또는 api.crc.testing을 확인하지 못함#

Ubuntu에서 CRC는 DNS를 자동으로 구성합니다. 실패하면 NetworkManager를 재시작합니다:

sudo systemctl restart NetworkManager

여전히 작동하지 않으면 수동으로 항목을 추가합니다 (CRC는 127.0.0.1을 통해 트래픽을 라우팅함):

sudo tee -a /etc/hosts <
서브도메인

멀티 인스턴스 섹션에서 Route를 노출하면 새로운 *.apps-crc.testing 서브도메인이 생성됩니다. 브라우저가 접근할 수 없다면 127.0.0.1을 가리키도록 /etc/hosts에 추가하세요.

n8n Pod가 /home/node/.n8n/에 쓸 때 EACCES: permission denied로 크래시#

이는 Pod가 UID 1000 (n8n 이미지가 기대하는 node 사용자) 대신 OpenShift가 임의로 할당한 UID로 실행되고 있음을 의미합니다. runAsUser: 1000fsGroup: 1000 없이 values에 securityContext.enabled: false가 설정된 경우 발생하며, OpenShift가 PVC에 쓸 수 없는 임의의 UID를 할당합니다.

해결: values 파일에 securityContext.enabled: true가 설정되어 있는지 확인하고, 차트에서 seccompProfile이 제거되도록 패치되었는지 확인합니다 (위의 SCC 오류 섹션 참조). 두 가지 모두 함께 필요합니다.

Pod 로그 확인#

# 메인 프로세스
oc logs -n $NAMESPACE -l app.kubernetes.io/component=main --tail=50

# 워커
oc logs -n $NAMESPACE -l app.kubernetes.io/component=worker --tail=50

# Webhook 프로세서
oc logs -n $NAMESPACE -l app.kubernetes.io/component=webhook-processor --tail=50

네임스페이스의 모든 이벤트#

oc get events -n $NAMESPACE --sort-by='.lastTimestamp'

빠른 참조#

터미널 재시작 후 변수 재내보내기#

eval $(crc oc-env)
export NAMESPACE=n8n-YYYYMMDD   # 원래 배포 날짜 사용
oc login -u kubeadmin -p <password> https://api.crc.testing:6443

클러스터 상태 확인#

crc status

OpenShift 웹 콘솔 열기#

crc console

kubeadmin / 비밀번호로 로그인하면 실행 중인 모든 것의 그래픽 뷰를 볼 수 있습니다.

저장해야 할 항목#

항목 중요한 이유
kubeadmin 비밀번호 클러스터 로그인
n8n 암호화 키 잃어버리면 저장된 모든 자격 증명을 읽을 수 없음
n8n-standalone-values.yaml helm upgrade에 필요
n8n-multimain-ocp-values.yaml helm upgrade에 필요
MinIO 루트 비밀번호 MinIO 콘솔 접근
PostgreSQL 비밀번호 데이터베이스 접근

다음 단계#

OpenShift Local (CRC)에서 n8n 호스팅

원문 보기
요약

이 가이드는 Red Hat의 로컬 OpenShift 클러스터 실행 도구인 OpenShift Local (CRC)에 n8n을 배포하는 과정을 안내합니다. OpenShift 자체가 많은 리소스를 소비하므로, 충분한 리소스를 갖춘 머신이 필요합니다.

이 가이드는 Red Hat의 로컬 OpenShift 클러스터 실행 도구인 OpenShift Local (CRC)에 n8n을 배포하는 과정을 안내합니다. AWS/EKS 배포와 동일한 방식으로 작동하지만, 로컬 머신에서만 실행됩니다. 클라우드 비용 없이 OpenShift 환경에서 n8n을 로컬로 테스트하기 위한 용도입니다.

OpenShift 자체가 많은 리소스를 소비하므로, 충분한 리소스를 갖춘 머신이 필요합니다.

OpenShift 개념과 표준 Kubernetes 비교#

OpenShift는 Kubernetes 기반으로 구축되었지만 다른 용어를 사용하며 더 엄격한 보안 기본값을 갖습니다. 표준 Kubernetes 또는 EKS 같은 관리형 Kubernetes 서비스를 대상으로 하는 가이드에 익숙한 경우, 아래 표에서 동등한 개념을 확인할 수 있습니다.

표준 Kubernetes / EKS OpenShift Local (CRC)
kubectl oc (OpenShift CLI; kubectl 명령어도 이해함)
Namespace Project (동일한 개념, 다른 명령어)
Ingress / LoadBalancer Route (OpenShift에 내장, 별도 컨트롤러 불필요)
EBS StorageClass (gp3) CRC 내장 스토리지 프로비저너 (설정 불필요)
RDS PostgreSQL Helm을 통한 클러스터 내 PostgreSQL (Bitnami)
ElastiCache Redis Helm을 통한 클러스터 내 Redis (Bitnami)
AWS S3 클러스터 내 MinIO (S3 호환)
Pod Identity / IRSA Kubernetes Secret을 통한 액세스 키
AWS Load Balancer Controller 불필요 (Route가 내장됨)
OIDC / IAM 불필요
월 $135–400 무료 (로컬 머신에서 실행)

사전 요구사항#

시작하기 전에 머신이 다음 사항을 충족하는지 확인하세요:

  • CPU: 가상화 지원이 있는 물리적 코어 4개 이상 (스레드 제외)
  • RAM: 최소 32GB 이상 여유 (CRC가 VM에 9GB 예약)
  • 디스크: 100GB 이상 여유 공간
  • OS: Ubuntu (22.04 LTS 이상)

Ubuntu 준비#

터미널 열기#

Ctrl+Alt+T를 누르거나 애플리케이션 메뉴에서 Terminal을 검색하세요.

이 가이드의 모든 명령어는 터미널에 입력하고 Enter를 눌러 실행합니다.

시스템 업데이트#

의존성 문제를 방지하기 위해 시스템 업데이트부터 시작합니다:

sudo apt update && sudo apt upgrade -y
sudo

sudo는 "관리자 권한으로 실행"을 의미합니다. 비밀번호를 입력하라는 메시지가 표시됩니다. 입력하는 문자는 화면에 표시되지 않으며, 이는 정상입니다.

CPU 가상화 지원 확인#

CRC는 가상 머신을 실행합니다. CPU가 하드웨어 가상화를 지원해야 합니다:

egrep -c '(vmx|svm)' /proc/cpuinfo
  • 출력 0: 가상화가 비활성화되어 있습니다. BIOS/UEFI 설정에 들어가서 VT-x(Intel) 또는 AMD-V(AMD)를 활성화한 후 재부팅하고 다시 시도하세요.
  • 출력 1 이상: 계속 진행할 수 있습니다.

KVM 및 libvirt 설치#

KVM은 Linux의 내장 하이퍼바이저입니다. CRC는 이를 사용하여 OpenShift 클러스터 VM을 실행합니다:

sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils

CRC가 클러스터 VM과 파일시스템을 공유하는 데 필요한 virtiofsd를 설치합니다:

sudo apt install -y virtiofsd

libvirt 서비스를 시작하고 부팅 시 자동으로 시작되도록 설정합니다:

sudo systemctl start libvirtd
sudo systemctl enable libvirtd

실행 중인지 확인합니다:

sudo systemctl status libvirtd

초록색으로 Active: active (running)이 표시되는지 확인하세요. q를 눌러 종료합니다.

사용자를 필요한 그룹에 추가#

이를 통해 모든 명령어에 sudo를 입력하지 않고도 KVM과 libvirt를 사용할 수 있습니다:

sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
경고

이 설정을 적용하려면 로그아웃 후 다시 로그인(또는 재부팅)해야 합니다. 이 단계를 건너뛰면 CRC가 "permission denied" 오류로 실패합니다.

지금 재부팅합니다:

sudo reboot

다시 로그인한 후 터미널을 열고 그룹 멤버십을 확인합니다:

groups

목록에 libvirtkvm이 표시되어야 합니다.

NetworkManager 설치#

CRC는 클러스터의 내부 도메인(*.apps-crc.testing, api.crc.testing)에 대한 DNS 항목을 관리하기 위해 NetworkManager가 필요합니다:

sudo apt install -y network-manager
sudo systemctl start NetworkManager
sudo systemctl enable NetworkManager

연결 상태를 확인합니다:

nmcli general status

STATE 컬럼에 connected가 표시되어야 합니다.

도구 설치#

Red Hat 계정 및 Pull Secret 가져오기#

CRC는 컨테이너 이미지를 가져오기 위해 무료 Red Hat 계정이 필요합니다.

  1. 계정이 없다면 무료 Red Hat 계정을 생성하세요.
  2. console.redhat.com/openshift/create/local에서 Download OpenShift Local을 클릭합니다.
  3. Linux를 선택하고 .tar.xz 파일을 ~/Downloads에 다운로드합니다.
  4. Red Hat 콘솔의 동일한 페이지에서 Copy pull secret을 클릭합니다. 텍스트 파일에 붙여넣고 나중을 위해 저장합니다.

CRC 설치#

Downloads 폴더에서 터미널을 엽니다.

cd ~/Downloads

아카이브를 추출합니다.

tar xf crc-linux-amd64.tar.xz

어느 터미널에서든 사용할 수 있도록 crc 바이너리를 시스템 전역 위치로 이동합니다:

sudo mv crc-*-linux-amd64/crc /usr/local/bin/

설치를 확인합니다:

crc version

터미널에 버전 번호가 출력되어야 합니다.

Helm 설치#

Helm은 n8n과 지원 서비스를 클러스터에 설치합니다:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

확인:

helm version

환경 변수 설정#

export NAMESPACE=n8n-$(date +%Y%m%d)
echo "Namespace:$NAMESPACE"
변수 지속성

이 변수는 현재 터미널 세션에서만 유효합니다. 계속 진행하기 전에 새 터미널을 열 때마다 이 줄을 다시 실행하세요.

OpenShift Local 시작#

CRC setup 실행#

한 번만 실행하면 됩니다. KVM 네트워킹을 구성하고, 시스템 요구사항을 확인하며, CRC 번들(~2.5GB)을 다운로드합니다:

crc setup

몇 분이 소요됩니다. 누락된 패키지가 보고되면 sudo apt install -y <package-name>으로 설치한 후 다시 실행하세요.

CRC 메모리 구성 및 클러스터 시작#

CRC는 VM에 기본적으로 9GB의 RAM을 할당합니다. n8n과 지원 서비스에는 더 많은 여유 공간이 필요합니다. 시작하기 전에 메모리를 14GB로 설정합니다:

crc config set memory 14336

한 번만 실행하면 됩니다. 이 설정은 crc stop / crc start 사이클에 걸쳐 유지됩니다.

권장사항: 매번 붙여넣지 않아도 되도록 Pull Secret을 파일로 저장하세요:

# 파일을 열고, Pull Secret을 붙여넣은 후(앞에서 저장한 것), Ctrl+O로 저장, Ctrl+X로 종료
nano ~/pull-secret.txt

# 본인만 읽을 수 있도록 권한 제한
chmod 600 ~/pull-secret.txt

파일을 사용하여 CRC를 시작합니다:

crc start --pull-secret-file ~/pull-secret.txt

또는 플래그 없이 crc start를 실행하고 메시지가 표시될 때 Secret을 붙여넣을 수 있습니다.

10~15분이 소요됩니다. 완료되면 다음과 같은 내용이 표시됩니다:

Started the OpenShift cluster.

The server is accessible via web console at:
  https://console-openshift-console.apps-crc.testing

Log in as administrator:
  Username: kubeadmin
  Password: <generated-password>

Log in as user:
  Username: developer
  Password: developer

지금 kubeadmin 비밀번호를 저장하세요. 다음 단계에서 필요합니다. 나중에 crc console --credentials를 사용하여 검색할 수 있습니다.

DNS 확인 검증#

Ubuntu에서 CRC는 NetworkManager와 systemd-resolved를 통해 시스템 리졸버를 자동으로 구성합니다. 수동 /etc/hosts 항목은 필요 없습니다.

API에 접근 가능한지 확인합니다:

sudo ss -tlnp | grep 6443

127.0.0.1:6443에 바인딩된 프로세스가 표시되어야 합니다. 아무것도 표시되지 않으면 crc start를 다시 실행하세요. DNS가 *.apps-crc.testing을 확인하지 못하는 경우 문제 해결 섹션을 참조하세요.

셸 구성#

CRC는 VM 내부에 oc CLI를 번들로 제공합니다. 다음 명령어로 터미널에서 사용할 수 있게 합니다:

eval $(crc oc-env)

터미널을 열 때마다 실행하지 않아도 되도록 영구적으로 설정하려면:

echo 'eval $(crc oc-env)' >> ~/.bashrc
source ~/.bashrc

oc가 작동하는지 확인합니다:

oc version

클러스터 로그인#

oc login -u kubeadmin -p <your-kubeadmin-password> https://api.crc.testing:6443

<your-kubeadmin-password>CRC 메모리 구성 및 클러스터 시작 시 출력된 비밀번호로 교체하세요.

로그인되었는지 확인합니다:

oc whoami

kubeadmin이 화면에 출력되어야 합니다.

단독 배포#

단독 모드는 SQLite를 사용하여 n8n을 단일 Pod로 실행합니다. 외부 데이터베이스나 Redis가 필요 없습니다. n8n을 탐색하고 로컬에서 워크플로우를 테스트하기에 이상적입니다.

프로젝트 생성#

OpenShift에서 project는 Kubernetes namespace와 동일합니다: 리소스를 위한 격리된 공간입니다:

oc new-project $NAMESPACE

필요한 보안 권한 부여#

OpenShift는 **Security Context Constraints (SCCs)**라고 하는 엄격한 보안 정책을 적용합니다. 기본적으로 Pod는 특정 사용자 ID로 실행될 수 없습니다. n8n 차트는 사용자 ID 1000으로 실행되므로 명시적으로 허용해야 합니다.

완전한 명시적 형식을 사용하세요. -z 약식 플래그는 일부 OpenShift 버전에서 자동으로 실패할 수 있습니다:

oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n

바인딩이 생성되었는지 확인합니다:

oc get rolebindings -n $NAMESPACE

system:openshift:scc:anyuid를 참조하는 바인딩이 표시되어야 합니다.

필요한 Secret 생성#

oc create secret generic n8n-secrets \
  --namespace $NAMESPACE \
  --from-literal=N8N_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
  --from-literal=N8N_HOST="localhost" \
  --from-literal=N8N_PORT="5678" \
  --from-literal=N8N_PROTOCOL="http"

즉시 암호화 키를 백업하세요:

oc get secret n8n-secrets -n $NAMESPACE \
  -o jsonpath='{.data.N8N_ENCRYPTION_KEY}' | base64 --decode

해당 출력을 복사하여 안전한 곳에 저장하세요. 잃어버리면 워크플로우에 저장된 모든 자격 증명이 영구적으로 읽을 수 없게 됩니다.

Values 파일 생성#

n8n-standalone-values.yaml이라는 파일을 만듭니다. 간단한 텍스트 편집기인 nano를 사용할 수 있습니다:

nano n8n-standalone-values.yaml

다음 내용을 붙여넣고 Ctrl+O를 눌러 저장한 후 Ctrl+X를 눌러 종료합니다:

# n8n-standalone-values.yaml
# 단일 Pod, SQLite 데이터베이스, 외부 의존성 없음.

queueMode:
  enabled: false

database:
  type: sqlite
  useExternal: false

redis:
  enabled: false

# PVC는 SQLite 데이터베이스 파일을 저장합니다.
persistence:
  enabled: true
  size: 5Gi
  # storageClassName 불필요 — CRC가 기본 스토리지 프로비저너를 제공합니다.

secretRefs:
  existingSecret: "n8n-secrets"

service:
  type: ClusterIP
  port: 5678

# OpenShift: securityContext를 활성화하여 Pod가 UID 1000 (node 사용자)으로
# fsGroup 1000 (PVC를 쓰기 가능하게)으로 실행되도록 해야 합니다. 위에서 부여한
# anyuid SCC가 이를 허용합니다. seccompProfile 줄은 OpenShift 4.14+에서
# anyuid 포함에도 거부되므로 "Deploy n8n"에서 차트 템플릿에서 제거됩니다.
securityContext:
  enabled: true

resources:
  main:
    requests:
      cpu: 100m
      memory: 256Mi
    limits:
      cpu: "1"
      memory: 1Gi

config:
  timezone: UTC

n8n 배포#

n8n Helm 차트는 Pod 스펙에 seccompProfile: RuntimeDefault를 하드코딩합니다. OpenShift 4.14+는 이를 deprecated alpha 어노테이션으로 변환하여 anyuid SCC가 부여된 경우에도 admission에서 거부됩니다. 해결 방법은 차트를 로컬로 가져와서 해당 두 줄을 제거하고 패치된 복사본에서 설치하는 것입니다.

차트 가져오기 및 패치:

helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version 1.0.3 --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml

# 줄이 사라졌는지 확인 (출력이 없어야 함)
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml

패치된 차트에서 설치:

helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml \
  --wait \
  --timeout 10m

Port Forward를 사용하여 n8n 접근#

OpenShift Route는 호스트명이 필요하여 단독 로컬 접근에는 복잡성이 추가됩니다. Port-forward가 더 간단합니다:

oc port-forward service/n8n-main --namespace $NAMESPACE 5678:5678

이 상태로 두고 브라우저에서 다음 주소로 이동합니다:

http://localhost:5678

n8n이 소유자 계정 생성을 요청합니다.

터널 중지

Ctrl+C를 눌러 터널을 중지합니다. 나중에 n8n에 다시 접근하려면 port-forward 명령어를 다시 실행하세요.

배포 상태 확인#

oc get pods -n $NAMESPACE

예상 결과:

NAME                       READY   STATUS    RESTARTS   AGE
n8n-main-7d9f8b-xxxx       1/1     Running   0          3m

단독 배포 완료.

멀티 인스턴스 큐 모드#

멀티 인스턴스 큐 모드는 공유 데이터베이스, 메시지 큐, 오브젝트 스토리지를 사용하여 여러 n8n Pod를 실행합니다. n8n Enterprise 라이선스가 필요합니다.

AWS 관리형 서비스 대신 이 가이드는 온프레미스 또는 고객 OpenShift 환경에서 찾을 수 있는 것을 반영하는 클러스터 내 동등물을 사용합니다:

AWS 서비스 로컬 동등물
RDS PostgreSQL PostgreSQL (Bitnami Helm 차트)
ElastiCache Redis Redis (Bitnami Helm 차트)
S3 MinIO (S3 호환, Bitnami Helm 차트)

클러스터 내 서비스 설치#

프로젝트 생성 및 Bitnami Helm 저장소 추가#

oc new-project $NAMESPACE

Bitnami 차트 저장소를 추가합니다 (한 번만 필요):

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

PostgreSQL 설치#

아래 명령어에서 YourStrongPassword123을 적절한 복잡한 비밀번호로 교체하세요.

helm install postgresql bitnami/postgresql \
  --namespace $NAMESPACE \
  --set auth.username=n8n \
  --set auth.password='YourStrongPassword123' \
  --set auth.database=n8n_enterprise \
  --set global.compatibility.openshift.adaptSecurityContext=auto \
  --wait
플래그

global.compatibility.openshift.adaptSecurityContext=auto 플래그는 Bitnami에 OpenShift가 올바른 사용자 ID를 자동으로 할당하도록 지시합니다 (SCC 오류 방지).

엔드포인트를 저장하세요. 클러스터 내 서비스의 경우 고정입니다:

postgresql.YOUR_NAMESPACE.svc.cluster.local

YOUR_NAMESPACE를 실제 $NAMESPACE 값으로 교체하세요 (예: n8n-20260306).

Redis 설치#

helm install redis bitnami/redis \
  --namespace $NAMESPACE \
  --set auth.enabled=false \
  --set architecture=standalone \
  --set global.compatibility.openshift.adaptSecurityContext=auto \
  --wait

Redis 엔드포인트: redis-master.$NAMESPACE.svc.cluster.local

MinIO (S3 호환 스토리지) 설치#

아래 명령어에서 MinioStrongPassword123을 적절한 복잡한 비밀번호로 교체하세요.

helm install minio bitnami/minio \
  --namespace $NAMESPACE \
  --set auth.rootUser=minioadmin \
  --set auth.rootPassword='MinioStrongPassword123' \
  --set global.compatibility.openshift.adaptSecurityContext=auto \
  --wait

MinIO 엔드포인트: http://minio:9000 (동일한 네임스페이스 내에서는 서비스 이름만으로 작동)

MinIO에 n8n 스토리지 버킷 생성#

n8n이 사용하기 전에 MinIO에 버킷을 생성해야 합니다. MinIO 웹 콘솔을 사용합니다:

MinIO 콘솔 열기:

oc port-forward svc/minio 9001:9001 -n $NAMESPACE

이 상태로 두고 브라우저에서 http://localhost:9001로 이동합니다.

다음으로 로그인합니다:

  • 사용자명: minioadmin
  • 비밀번호: MinioStrongPassword123

콘솔에서:

  1. 왼쪽 사이드바의 Buckets 클릭 → Create Bucket
  2. Bucket Name: n8n-data
  3. Create Bucket 클릭

터미널로 돌아가서 Ctrl+C를 눌러 port-forward를 중지합니다.

n8n 배포#

n8n용 SCC 부여#

oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n-enterprise

oc get rolebindings -n $NAMESPACE에서 system:openshift:scc:anyuid에 대한 바인딩이 표시되는지 확인합니다.

필요한 Secret 생성#

# 핵심 n8n secret
oc create secret generic n8n-enterprise-secrets \
  --namespace $NAMESPACE \
  --from-literal=N8N_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
  --from-literal=N8N_HOST="localhost" \
  --from-literal=N8N_PORT="5678" \
  --from-literal=N8N_PROTOCOL="http"

즉시 암호화 키를 백업하세요:

oc get secret n8n-enterprise-secrets -n $NAMESPACE \
  -o jsonpath='{.data.N8N_ENCRYPTION_KEY}' | base64 --decode

해당 값을 안전한 곳에 저장하세요.

아래 명령어에서 YourStrongPassword123MinioStrongPassword123을 이전 단계의 비밀번호로 교체하세요.

# 데이터베이스 비밀번호 (PostgreSQL 설치 시 설정한 것과 일치해야 함)
oc create secret generic n8n-enterprise-db-secret \
  --namespace $NAMESPACE \
  --from-literal=password='YourStrongPassword123'

# MinIO 자격 증명
oc create secret generic n8n-minio-secret \
  --namespace $NAMESPACE \
  --from-literal=root-password='MinioStrongPassword123'

Values 파일 생성#

n8n-multimain-ocp-values.yaml을 만듭니다. # <-- REPLACE로 표시된 3개의 플레이스홀더 값을 교체하세요:

nano n8n-multimain-ocp-values.yaml
# n8n-multimain-ocp-values.yaml
# OpenShift Local (CRC)용 멀티 인스턴스 큐 모드.
# AWS 서비스 대신 클러스터 내 PostgreSQL, Redis, MinIO를 사용합니다.
# Enterprise 라이선스 필요.

# --- Enterprise 라이선스 ---
license:
  enabled: true
  activationKey: "your-enterprise-license-key-here"  # <-- REPLACE

# --- Multi-main: 로컬 리소스를 위해 2 replicas로 축소 ---
multiMain:
  enabled: true
  replicas: 2

# --- 큐 모드: 2개의 worker Pod ---
queueMode:
  enabled: true
  workerReplicaCount: 2
  workerConcurrency: 5

# --- Webhook 프로세서 ---
webhookProcessor:
  enabled: true
  replicaCount: 1
  disableProductionWebhooksOnMainProcess: true

# --- PostgreSQL (클러스터 내) ---
database:
  type: postgresdb
  useExternal: true
  host: "postgresql.YOUR_NAMESPACE.svc.cluster.local"   # <-- REPLACE YOUR_NAMESPACE
  port: 5432
  database: n8n_enterprise
  schema: "public"
  user: n8n
  passwordSecret:
    name: "n8n-enterprise-db-secret"
    key: "password"

# --- Redis (클러스터 내, TLS 없음) ---
redis:
  enabled: true
  useExternal: true
  host: "redis-master.YOUR_NAMESPACE.svc.cluster.local"  # <-- REPLACE YOUR_NAMESPACE
  port: 6379
  tls: false

# --- MinIO (S3 호환, 클러스터 내) ---
s3:
  enabled: true
  bucket:
    name: "n8n-data"
    region: "us-east-1"
  host: "http://minio:9000"
  auth:
    autoDetect: false
    accessKeyId: "minioadmin"
    secretAccessKeySecret:
      name: "n8n-minio-secret"
      key: "root-password"
  storage:
    mode: "s3"
    availableModes: "filesystem,s3"
  forcePathStyle: true

# --- Service account ---
serviceAccount:
  create: true
  name: n8n

nano를 저장하고 종료합니다 (Ctrl+O, Ctrl+X).

배포 전에 두 개의 YOUR_NAMESPACE 플레이스홀더를 실제 네임스페이스 값으로 교체합니다:

# 네임스페이스 값 확인
echo $NAMESPACE

# 파일에서 교체 (자동으로 편집됨)
sed -i "s/YOUR_NAMESPACE/$NAMESPACE/g" n8n-multimain-ocp-values.yaml

교체 결과를 확인합니다:

grep "svc.cluster.local" n8n-multimain-ocp-values.yaml

두 줄 모두 YOUR_NAMESPACE가 아닌 실제 네임스페이스 이름이 표시되어야 합니다.

n8n 배포#

이전에 차트를 패치하지 않았다면 지금 가져와서 패치합니다:

helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version 1.0.3 --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml  # 아무것도 반환되지 않아야 함

패치된 차트에서 설치합니다:

helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-multimain-ocp-values.yaml \
  --wait \
  --timeout 15m

외부 접근을 위한 Route 생성#

OpenShift에서 Route는 서비스를 외부에 노출합니다. Kubernetes Ingress 또는 LoadBalancer와 동일하며 추가 컨트롤러가 필요 없습니다:

oc expose svc/n8n-main -n $NAMESPACE

URL 가져오기:

export ROUTE=$(oc get route n8n-main -n $NAMESPACE -o jsonpath='{.spec.host}')
echo "n8n URL: http://$ROUTE"

URL은 다음과 같은 형태입니다: http://n8n-main-n8n-20260306.apps-crc.testing

호스트 Secret 업데이트#

n8n은 공개 URL을 알아야 합니다. Route 호스트명으로 Secret을 업데이트한 후 Pod를 재시작합니다:

ENCRYPTION_KEY=$(oc get secret n8n-enterprise-secrets -n $NAMESPACE \
  -o jsonpath='{.data.N8N_ENCRYPTION_KEY}' | base64 --decode)

oc create secret generic n8n-enterprise-secrets \
  --namespace $NAMESPACE \
  --from-literal=N8N_ENCRYPTION_KEY="$ENCRYPTION_KEY" \
  --from-literal=N8N_HOST="$ROUTE" \
  --from-literal=N8N_PORT="5678" \
  --from-literal=N8N_PROTOCOL="http" \
  --dry-run=client -o yaml | oc apply -f -

oc rollout restart deployment -n $NAMESPACE

롤아웃 완료 대기:

oc rollout status deployment/n8n-main -n $NAMESPACE

모든 Pod가 실행 중인지 확인#

oc get pods -n $NAMESPACE

예상 결과 (모두 Running):

NAME                                    READY   STATUS    RESTARTS   AGE
n8n-main-xxxx-aaaa                      1/1     Running   0          5m
n8n-main-xxxx-bbbb                      1/1     Running   0          5m
n8n-worker-xxxx-aaaa                    1/1     Running   0          5m
n8n-worker-xxxx-bbbb                    1/1     Running   0          5m
n8n-webhook-processor-xxxx-aaaa         1/1     Running   0          5m
postgresql-0                            1/1     Running   0          15m
redis-master-0                          1/1     Running   0          15m
minio-xxxx-xxxx                         1/1     Running   0          15m

위에서 출력된 URL로 브라우저를 엽니다.

멀티 인스턴스 배포 완료.

n8n 업데이트#

구성을 변경하거나 차트 버전을 업그레이드하려면, 새 차트 버전을 가져와서 다시 패치한 후 업그레이드합니다:

# 이전 로컬 차트 복사본 제거
rm -rf ~/n8n/

# 새 버전 가져오기 및 패치
helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version <new-version> --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml

# 단독 모드
helm upgrade n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml

# 멀티 인스턴스
helm upgrade n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-multimain-ocp-values.yaml

CRC 중지 및 재개#

CRC는 세션 간에 삭제할 필요가 없습니다. 중지했다가 다시 시작할 수 있습니다:

# 클러스터 중지 (상태 저장)
crc stop

# 나중에 다시 시작
crc start

재시작 후 다시 실행합니다:

eval $(crc oc-env)
export NAMESPACE=n8n-YYYYMMDD   # 원래 날짜 사용
oc login -u kubeadmin -p <password> https://api.crc.testing:6443

문제 해결#

crc setup이 "libvirt not found"로 실패#

sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients
sudo systemctl start libvirtd

그런 다음 crc setup을 다시 실행합니다.

crc start가 "insufficient memory"로 실패#

CRC는 최소 9GB의 여유 RAM이 필요합니다. 다른 애플리케이션을 종료하고 다시 시도하세요. CRC 메모리 구성 지침을 따랐다면 CRC는 14GB를 사용하도록 구성됩니다.

n8n Pod가 Pending 상태에 멈추거나 SCC 오류로 생성되지 않음#

오류에 대한 이벤트를 확인합니다:

oc get events -n $NAMESPACE --sort-by='.lastTimestamp' | tail -20

unable to validate against any security context constraint 또는 seccomp may not be set이 표시되면, 차트의 하드코딩된 seccompProfile: RuntimeDefault가 거부되는 것입니다. OpenShift 4.14+는 이를 deprecated alpha 어노테이션으로 변환하여 anyuid SCC가 부여된 경우에도 admission에서 거부됩니다.

1. 명시적 형식으로 anyuid 부여 (-z 약식은 자동으로 실패할 수 있음):

# 단독 모드
oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n

# 멀티 인스턴스
oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n-enterprise

확인: oc get rolebindings -n $NAMESPACE를 실행합니다. system:openshift:scc:anyuid에 대한 바인딩이 표시되어야 합니다.

2. 차트를 로컬로 가져와서 seccompProfile 줄 제거:

helm pull oci://ghcr.io/n8n-io/n8n-helm-chart/n8n --version 1.0.3 --untar
sed -i '/seccompProfile:/d; /type: RuntimeDefault/d' ~/n8n/templates/deployment-main.yaml

# 사라졌는지 확인 (출력이 없어야 함)
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml

3. 제거 후 패치된 차트에서 재설치:

helm uninstall n8n -n $NAMESPACE
helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml \
  --wait \
  --timeout 10m

Route URL이 "Application not available" 반환#

Pod가 아직 시작 중일 수 있습니다. 확인합니다:

oc get pods -n $NAMESPACE
oc rollout status deployment/n8n-main -n $NAMESPACE

Route도 확인합니다:

oc get route -n $NAMESPACE

n8n Pod가 Insufficient memoryPending 상태에 멈춤#

CRC 노드에 Pod를 스케줄할 여유 메모리가 충분하지 않습니다.

해결: CRC의 VM 메모리를 늘리고 재시작합니다:

crc stop
crc config set memory 14336
crc start

CRC가 재시작되면 Pod가 자동으로 스케줄됩니다. 몇 분 후에도 Pod가 대기 중이면 강제 재스케줄을 위해 삭제합니다:

oc delete pod -n $NAMESPACE -l app.kubernetes.io/component=main

머신이 14GB를 확보할 수 없다면 n8n-standalone-values.yaml에서 Pod의 메모리 요청을 낮출 수도 있습니다:

resources:
  main:
    requests:
      memory: 256Mi

그런 다음 업그레이드합니다: helm upgrade n8n ~/n8n/ -n $NAMESPACE -f n8n-standalone-values.yaml

DNS가 .apps-crc.testing 또는 api.crc.testing을 확인하지 못함#

Ubuntu에서 CRC는 DNS를 자동으로 구성합니다. 실패하면 NetworkManager를 재시작합니다:

sudo systemctl restart NetworkManager

여전히 작동하지 않으면 수동으로 항목을 추가합니다 (CRC는 127.0.0.1을 통해 트래픽을 라우팅함):

sudo tee -a /etc/hosts <
서브도메인

멀티 인스턴스 섹션에서 Route를 노출하면 새로운 *.apps-crc.testing 서브도메인이 생성됩니다. 브라우저가 접근할 수 없다면 127.0.0.1을 가리키도록 /etc/hosts에 추가하세요.

n8n Pod가 /home/node/.n8n/에 쓸 때 EACCES: permission denied로 크래시#

이는 Pod가 UID 1000 (n8n 이미지가 기대하는 node 사용자) 대신 OpenShift가 임의로 할당한 UID로 실행되고 있음을 의미합니다. runAsUser: 1000fsGroup: 1000 없이 values에 securityContext.enabled: false가 설정된 경우 발생하며, OpenShift가 PVC에 쓸 수 없는 임의의 UID를 할당합니다.

해결: values 파일에 securityContext.enabled: true가 설정되어 있는지 확인하고, 차트에서 seccompProfile이 제거되도록 패치되었는지 확인합니다 (위의 SCC 오류 섹션 참조). 두 가지 모두 함께 필요합니다.

Pod 로그 확인#

# 메인 프로세스
oc logs -n $NAMESPACE -l app.kubernetes.io/component=main --tail=50

# 워커
oc logs -n $NAMESPACE -l app.kubernetes.io/component=worker --tail=50

# Webhook 프로세서
oc logs -n $NAMESPACE -l app.kubernetes.io/component=webhook-processor --tail=50

네임스페이스의 모든 이벤트#

oc get events -n $NAMESPACE --sort-by='.lastTimestamp'

빠른 참조#

터미널 재시작 후 변수 재내보내기#

eval $(crc oc-env)
export NAMESPACE=n8n-YYYYMMDD   # 원래 배포 날짜 사용
oc login -u kubeadmin -p <password> https://api.crc.testing:6443

클러스터 상태 확인#

crc status

OpenShift 웹 콘솔 열기#

crc console

kubeadmin / 비밀번호로 로그인하면 실행 중인 모든 것의 그래픽 뷰를 볼 수 있습니다.

저장해야 할 항목#

항목 중요한 이유
kubeadmin 비밀번호 클러스터 로그인
n8n 암호화 키 잃어버리면 저장된 모든 자격 증명을 읽을 수 없음
n8n-standalone-values.yaml helm upgrade에 필요
n8n-multimain-ocp-values.yaml helm upgrade에 필요
MinIO 루트 비밀번호 MinIO 콘솔 접근
PostgreSQL 비밀번호 데이터베이스 접근

다음 단계#