Skip to content

在 OpenShift Local (CRC) 上托管 n8n#

本指南将引导你在 OpenShift Local (CRC) 上部署 n8n。CRC 是 Red Hat 提供的本地 OpenShift 集群运行工具。它与 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 集群内 PostgreSQL(通过 Helm Bitnami 部署)
ElastiCache Redis 集群内 Redis(通过 Helm Bitnami 部署)
AWS S3 集群内 MinIO(S3 兼容)
Pod Identity / IRSA 通过 Kubernetes Secret 管理访问密钥
AWS Load Balancer Controller 不需要(Route 已内置)
OIDC / IAM 不需要
约 $135–400/月 免费(在你的机器上运行)

前提条件#

开始之前,请确认你的机器满足以下要求:

  • CPU:4 个或更多物理核心(不仅仅是线程),且支持虚拟化
  • 内存:至少 32 GB 可用空闲内存(CRC 为其虚拟机保留 9 GB)
  • 磁盘:100 GB 可用空间
  • 操作系统:Ubuntu(22.04 LTS 或更新版本)

准备 Ubuntu#

打开终端#

Ctrl+Alt+T 或在应用程序菜单中搜索 Terminal

本指南中的每个命令都在终端中输入,按 Enter 执行。

更新系统#

首先进行系统更新,以避免依赖问题:

1
sudo apt update && sudo apt upgrade -y

sudo

sudo 表示"以管理员身份运行"。系统会提示你输入密码。输入时屏幕上不会显示任何字符,这是正常现象。

检查 CPU 虚拟化支持#

CRC 运行在虚拟机上,你的 CPU 必须支持硬件虚拟化:

1
egrep -c '(vmx|svm)' /proc/cpuinfo
  • 输出 0:虚拟化未启用。进入 BIOS/UEFI 设置,启用 VT-x(Intel)或 AMD-V(AMD),然后重启再试。
  • 输出 1 或更高:可以继续。

安装 KVM 和 libvirt#

KVM 是 Linux 内置的虚拟化引擎。CRC 使用它来运行 OpenShift 集群虚拟机:

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

安装 virtiofsd,CRC 需要它来与集群虚拟机共享文件系统:

1
sudo apt install -y virtiofsd

启动 libvirt 服务并设置为开机自启:

1
2
sudo systemctl start libvirtd
sudo systemctl enable libvirtd

验证其是否正在运行:

1
sudo systemctl status libvirtd

查看是否显示绿色的 Active: active (running)。按 q 退出。

将用户添加到所需的用户组#

这样你就可以使用 KVM 和 libvirt,而无需每条命令都输入 sudo

1
2
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER

警告

你必须注销并重新登录(或重启)才能使此更改生效。 如果跳过此步骤,CRC 会报"permission denied"错误。

立即重启:

1
sudo reboot

重新登录后,打开终端并验证用户组成员身份:

1
groups

你应该能看到列出了 libvirtkvm

安装 NetworkManager#

CRC 需要 NetworkManager 来管理集群内部域名的 DNS 条目(*.apps-crc.testingapi.crc.testing):

1
2
3
sudo apt install -y network-manager
sudo systemctl start NetworkManager
sudo systemctl enable NetworkManager

验证连接状态:

1
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 文件夹中打开终端。

1
cd ~/Downloads

解压归档文件。

1
tar xf crc-linux-amd64.tar.xz

crc 二进制文件移动到系统级目录,以便在任何终端中使用:

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

验证安装:

1
crc version

终端应输出版本号。

安装 Helm#

Helm 用于将 n8n 及其支持服务安装到集群中:

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

验证:

1
helm version

设置环境变量#

1
2
export NAMESPACE=n8n-$(date +%Y%m%d)
echo "Namespace:$NAMESPACE"

变量持久性

这些变量仅在当前终端会话中有效。每次打开新终端后,需要重新运行此命令再继续操作。

启动 OpenShift Local#

运行 CRC setup#

只需运行一次。它会配置 KVM 网络、检查系统要求,并下载 CRC 包(约 2.5 GB):

1
crc setup

这需要几分钟时间。如果提示缺少任何软件包,使用 sudo apt install -y <package-name> 安装后重新运行。

配置 CRC 内存并启动集群#

CRC 默认为虚拟机分配 9 GB 内存。n8n 及其支持服务需要更多资源。在启动前将内存设置为 14 GB:

1
crc config set memory 14336

此设置只需运行一次,会在 crc stop / crc start 周期中持久保留。

建议: 先将 pull secret 保存到文件,这样就不用每次都粘贴:

1
2
3
4
5
# Open the file, paste your pull secret (from earlier), then Ctrl+O to save, Ctrl+X to exit
nano ~/pull-secret.txt

# Restrict permissions so only you can read it
chmod 600 ~/pull-secret.txt

使用文件启动 CRC:

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

也可以不带参数直接运行 crc start,在提示时粘贴 secret。

这需要 10–15 分钟。 完成后你会看到类似以下输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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 是否可达:

1
sudo ss -tlnp | grep 6443

你应该能看到一个绑定在 127.0.0.1:6443 上的进程。如果没有输出,重新运行 crc start。如果 DNS 无法解析 *.apps-crc.testing,请参阅故障排除部分。

配置 Shell#

CRC 在虚拟机内打包了 oc CLI。以下命令使其在你的终端中可用:

1
eval $(crc oc-env)

要使此设置永久生效,避免每次打开终端都要重新运行:

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

验证 oc 是否正常工作:

1
oc version

登录集群#

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

<your-kubeadmin-password> 替换为配置 CRC 内存并启动集群时输出的密码。

验证是否已登录:

1
oc whoami

屏幕上应显示 kubeadmin

单实例部署#

单实例模式将 n8n 作为单个 Pod 运行,使用 SQLite 数据库。不需要外部数据库或 Redis。适合在本地探索 n8n 和测试工作流。

创建 Project#

在 OpenShift 中,Project 等同于 Kubernetes 的 Namespace:一个用于隔离资源的独立空间:

1
oc new-project $NAMESPACE

授予所需的安全权限#

OpenShift 强制执行名为 Security Context Constraints (SCCs) 的严格安全策略。默认情况下,Pod 不能以特定用户 ID 运行。n8n chart 以用户 ID 1000 运行,因此你必须显式允许此操作。

使用完整的显式形式。简写的 -z 标志在某些 OpenShift 版本中可能会静默失败:

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

验证绑定是否已创建:

1
oc get rolebindings -n $NAMESPACE

你应该能看到引用了 system:openshift:scc:anyuid 的绑定。

创建所需的 Secret#

1
2
3
4
5
6
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"

立即备份加密密钥:

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

复制输出并保存到安全的地方。丢失加密密钥意味着工作流中存储的所有凭据将永久不可读。

创建 values 文件#

创建名为 n8n-standalone-values.yaml 的文件。你可以使用 nano(一个简单的文本编辑器):

1
nano n8n-standalone-values.yaml

粘贴以下内容,然后按 Ctrl+O 保存,Ctrl+X 退出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# n8n-standalone-values.yaml
# Single pod, SQLite database, no external dependencies.

queueMode:
  enabled: false

database:
  type: sqlite
  useExternal: false

redis:
  enabled: false

# PVC stores the SQLite database file.
persistence:
  enabled: true
  size: 5Gi
  # No storageClassName needed — CRC provides a default storage provisioner.

secretRefs:
  existingSecret: "n8n-secrets"

service:
  type: ClusterIP
  port: 5678

# OpenShift: securityContext must be enabled so the pod runs as UID 1000 (node user)
# with fsGroup 1000 (so the PVC is writable). The anyuid SCC granted above
# allows this. The seccompProfile line is removed from the chart template in
# "Deploy n8n" because OpenShift 4.14+ rejects it even with anyuid.
securityContext:
  enabled: true

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

config:
  timezone: UTC

部署 n8n#

n8n Helm chart 在 Pod 规格中硬编码了 seccompProfile: RuntimeDefault。OpenShift 4.14+ 会将其转换为已弃用的 alpha 注解,即使授予了 anyuid SCC 也会在准入时被拒绝。解决方法是将 chart 拉取到本地,删除这两行,然后从修补后的副本进行安装。

拉取并修补 chart:

1
2
3
4
5
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

# Confirm the lines are gone (should return no output)
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml

从修补后的 chart 安装:

1
2
3
4
5
helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml \
  --wait \
  --timeout 10m

通过端口转发访问 n8n#

OpenShift Route 需要主机名,这会增加单实例本地访问的复杂性。端口转发更简单:

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

保持此命令运行,然后在浏览器中打开:

1
http://localhost:5678

n8n 会提示你创建一个管理员账号。

停止隧道

Ctrl+C 停止隧道。之后需要再次访问 n8n 时,重新运行 port-forward 命令即可。

检查部署状态#

1
oc get pods -n $NAMESPACE

预期输出:

1
2
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 chart)
ElastiCache Redis Redis(Bitnami Helm chart)
S3 MinIO(S3 兼容,Bitnami Helm chart)

安装集群内服务#

创建 Project 并添加 Bitnami Helm 仓库#

1
oc new-project $NAMESPACE

添加 Bitnami chart 仓库(只需执行一次):

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

安装 PostgreSQL#

在以下命令中,将 YourStrongPassword123 替换为一个合适的复杂密码。

1
2
3
4
5
6
7
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 错误)。

保存端点地址,集群内服务的地址是固定的:

1
postgresql.YOUR_NAMESPACE.svc.cluster.local

YOUR_NAMESPACE 替换为你的实际 $NAMESPACE 值(例如 n8n-20260306)。

安装 Redis#

1
2
3
4
5
6
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 替换为一个合适的复杂密码。

1
2
3
4
5
6
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(在同一 Namespace 内,直接使用服务名即可)

在 MinIO 中创建 n8n 存储桶#

n8n 使用前需要先在 MinIO 中创建存储桶。通过 MinIO 网页控制台操作:

打开 MinIO 控制台:

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

保持此命令运行,然后在浏览器中打开 http://localhost:9001

使用以下凭据登录: - 用户名: minioadmin - 密码: MinioStrongPassword123

在控制台中: 1. 点击左侧边栏的 BucketsCreate Bucket 2. Bucket Name: n8n-data 3. 点击 Create Bucket

回到终端,按 Ctrl+C 停止端口转发。

部署 n8n#

为 n8n 授予 SCC#

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

验证 oc get rolebindings -n $NAMESPACE 显示了 system:openshift:scc:anyuid 的绑定。

创建所需的 Secret#

1
2
3
4
5
6
7
# Core n8n secrets
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"

立即备份加密密钥:

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

将该值保存到安全的地方。

在以下命令中,将 YourStrongPassword123MinioStrongPassword123 替换为之前步骤中设置的密码。

1
2
3
4
5
6
7
8
9
# Database password (must match what you set when installing PostgreSQL)
oc create secret generic n8n-enterprise-db-secret \
  --namespace $NAMESPACE \
  --from-literal=password='YourStrongPassword123'

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

创建 values 文件#

创建 n8n-multimain-ocp-values.yaml。替换标记为 # <-- REPLACE3 个占位值

1
nano n8n-multimain-ocp-values.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# n8n-multimain-ocp-values.yaml
# Multi-instance queue mode for OpenShift Local (CRC).
# Uses in-cluster PostgreSQL, Redis, and MinIO instead of AWS services.
# Requires Enterprise license.

# --- Enterprise license ---
license:
  enabled: true
  activationKey: "your-enterprise-license-key-here"  # <-- REPLACE

# --- Multi-main: 2 replicas (reduced for local resources) ---
multiMain:
  enabled: true
  replicas: 2

# --- Queue mode: 2 worker pods ---
queueMode:
  enabled: true
  workerReplicaCount: 2
  workerConcurrency: 5

# --- Webhook processors ---
webhookProcessor:
  enabled: true
  replicaCount: 1
  disableProductionWebhooksOnMainProcess: true

# --- PostgreSQL (in-cluster) ---
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 (in-cluster, no TLS) ---
redis:
  enabled: true
  useExternal: true
  host: "redis-master.YOUR_NAMESPACE.svc.cluster.local"  # <-- REPLACE YOUR_NAMESPACE
  port: 6379
  tls: false

# --- MinIO (S3-compatible, in-cluster) ---
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+OCtrl+X)。

在部署之前,将两个 YOUR_NAMESPACE 占位符替换为你的实际 Namespace 值:

1
2
3
4
5
# Check your namespace value
echo $NAMESPACE

# Replace in the file (this edits it automatically)
sed -i "s/YOUR_NAMESPACE/$NAMESPACE/g" n8n-multimain-ocp-values.yaml

验证替换结果:

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

两行都应显示你的实际 Namespace 名称,而不是 YOUR_NAMESPACE

部署 n8n#

如果之前没有修补过 chart,现在拉取并修补:

1
2
3
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  # should return nothing

从修补后的 chart 安装:

1
2
3
4
5
helm install n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-multimain-ocp-values.yaml \
  --wait \
  --timeout 15m

创建 Route 以进行外部访问#

在 OpenShift 中,Route 将服务暴露给外部访问。它等同于 Kubernetes 的 Ingress 或 LoadBalancer,且无需额外的控制器:

1
oc expose svc/n8n-main -n $NAMESPACE

获取 URL:

1
2
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

更新 host Secret#

n8n 需要知道其公开 URL。使用 Route 主机名更新 Secret,然后重启 Pod:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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

等待滚动更新完成:

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

验证所有 Pod 是否正在运行#

1
oc get pods -n $NAMESPACE

预期输出(全部 Running):

1
2
3
4
5
6
7
8
9
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#

要更改配置或升级 chart 版本,请拉取并重新修补新版本的 chart,然后升级:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Remove the old local chart copy
rm -rf ~/n8n/

# Pull and patch the new version
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

# Standalone
helm upgrade n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-standalone-values.yaml

# Multi-instance
helm upgrade n8n ~/n8n/ \
  --namespace $NAMESPACE \
  --values n8n-multimain-ocp-values.yaml

停止和恢复 CRC#

CRC 无需在两次使用之间删除。你可以停止并重新启动:

1
2
3
4
5
# Stop the cluster (saves state)
crc stop

# Start it again later
crc start

重新启动后,重新运行:

1
2
3
eval $(crc oc-env)
export NAMESPACE=n8n-YYYYMMDD   # use your original date
oc login -u kubeadmin -p <password> https://api.crc.testing:6443

故障排除#

crc setup 报错"libvirt not found"#

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

然后重新运行 crc setup

crc start 报错"insufficient memory"#

CRC 至少需要 9 GB 可用内存。关闭其他应用程序后重试。如果你已按照配置 CRC 内存的说明操作,CRC 配置为使用 14 GB。

n8n Pod 卡在 Pending 状态或从未创建(SCC 错误)#

检查事件以查找错误:

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

如果你看到 unable to validate against any security context constraintseccomp may not be set,说明 chart 中硬编码的 seccompProfile: RuntimeDefault 被拒绝了。OpenShift 4.14+ 将其转换为已弃用的 alpha 注解,即使授予了 anyuid SCC,准入控制也会拒绝。

1. 使用显式形式授予 anyuid(简写的 -z 可能会静默失败):

1
2
3
4
5
6
7
# For standalone
oc adm policy add-scc-to-user anyuid \
  system:serviceaccount:$NAMESPACE:n8n

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

验证:运行 oc get rolebindings -n $NAMESPACE,应能看到 system:openshift:scc:anyuid 的绑定。

2. 将 chart 拉取到本地并删除 seccompProfile 相关行:

1
2
3
4
5
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

# Confirm they're gone (should return no output)
grep -n "seccomp\|RuntimeDefault" ~/n8n/templates/deployment-main.yaml

3. 卸载并从修补后的 chart 重新安装:

1
2
3
4
5
6
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 可能仍在启动中。检查:

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

同时确认 Route 是否存在:

1
oc get route -n $NAMESPACE

n8n Pod 卡在 Pending 状态,提示 Insufficient memory#

CRC 节点没有足够的空闲内存来调度 Pod。

解决方法: 增加 CRC 虚拟机的内存并重启:

1
2
3
crc stop
crc config set memory 14336
crc start

CRC 重启后,Pod 应会自动调度。如果几分钟后 Pod 仍处于 Pending 状态,可以删除它以强制重新调度:

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

如果你的机器无法分配 14 GB,也可以在 n8n-standalone-values.yaml 中降低 Pod 的内存请求:

1
2
3
4
resources:
  main:
    requests:
      memory: 256Mi

然后升级:helm upgrade n8n ~/n8n/ -n $NAMESPACE -f n8n-standalone-values.yaml

DNS 无法解析 .apps-crc.testingapi.crc.testing#

在 Ubuntu 上,CRC 会自动配置 DNS。如果失败,请重启 NetworkManager:

1
sudo systemctl restart NetworkManager

如果仍然无法解析,手动添加条目(CRC 通过 127.0.0.1 路由流量):

1
2
3
4
5
6
sudo tee -a /etc/hosts <<EOF
127.0.0.1 api.crc.testing
127.0.0.1 console-openshift-console.apps-crc.testing
127.0.0.1 oauth-openshift.apps-crc.testing
127.0.0.1 default-route-openshift-image-registry.apps-crc.testing
EOF

子域名

当你在多实例部分暴露 Route 时,会创建新的 *.apps-crc.testing 子域名。如果浏览器无法访问,将它们添加到 /etc/hosts 中指向 127.0.0.1

n8n Pod 崩溃,报错 EACCES: permission denied 无法写入 /home/node/.n8n/#

这表示 Pod 以 OpenShift 随机分配的 UID 运行,而非 UID 1000(n8n 镜像期望的 node 用户)。当 values 文件中设置了 securityContext.enabled: false 而没有指定 runAsUser: 1000fsGroup: 1000 时,OpenShift 会分配一个无法写入 PVC 的随机 UID。

解决方法: 确保 values 文件中设置了 securityContext.enabled: true,并且 chart 已修补删除了 seccompProfile(参见上方 SCC 错误部分)。两者都必须同时满足。

查看 Pod 日志#

1
2
3
4
5
6
7
8
# Main process
oc logs -n $NAMESPACE -l app.kubernetes.io/component=main --tail=50

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

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

查看 Namespace 中的所有事件#

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

快速参考#

重新打开终端后重新导出变量#

1
2
3
eval $(crc oc-env)
export NAMESPACE=n8n-YYYYMMDD   # use the date from your original deployment
oc login -u kubeadmin -p <password> https://api.crc.testing:6443

检查集群状态#

1
crc status

打开 OpenShift 网页控制台#

1
crc console

使用 kubeadmin / 你的密码登录,即可查看所有运行中资源的图形化界面。

需要保存的内容#

项目 重要原因
kubeadmin 密码 登录集群
n8n 加密密钥 丢失后所有存储的凭据将不可读
n8n-standalone-values.yaml helm upgrade 时需要
n8n-multimain-ocp-values.yaml helm upgrade 时需要
MinIO root 密码 访问 MinIO 控制台
PostgreSQL 密码 数据库访问

后续步骤#