由人肉运维------>脚本运维------>自动化运维------>智能化运维靠拢
先基础n8n实现工作流
一、在k8s集群中安装n8n
1、克隆官方仓库的n8n
git clone https://github.com/n8n-io/n8n-hosting.git
进入n8n-hosting/kubernetes目录

创建集群的默认StorageClass,我这集群没有所以要创建
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
EOF

需要先确认你的 worker 节点名称,用来配置 PV 的节点亲和性:
2、创建 PV(绑定到 k8s-node1)
创建 PostgreSQL 的 PV
[root@k8s-master ~]# cat PostgreSQL-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
storageClassName: standard
hostPath:
path: /mnt/data/postgres
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node-1
[root@k8s-master ~]#
创建 n8n 的 PV
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: n8n-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
storageClassName: standard
hostPath:
path: /mnt/data/n8n
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node-1 # ⚠️ 替换成你的 worker 节点名
EOF
验证 PV 是否创建成功:
kubectl get pv
在 worker 节点上创建数据目录
mkdir -p /mnt/data/postgres
mkdir -p /mnt/data/n8n
chmod 777 /mnt/data/postgres
chmod 777 /mnt/data/n8n
修改数据库密码
postgres-secret.yaml
apiVersion: v1
kind: Secret
metadata:
namespace: n8n
name: postgres-secret
type: Opaque
stringData:
POSTGRES_USER: changeUser
POSTGRES_PASSWORD: changePassword
POSTGRES_DB: n8n
POSTGRES_NON_ROOT_USER: changeUser
POSTGRES_NON_ROOT_PASSWORD: changePassword
3、按顺序部署所有资源
# 1. 创建命名空间
kubectl apply -f namespace.yaml
# 2. 创建 secret 和 configmap
kubectl apply -f postgres-secret.yaml
kubectl apply -f postgres-configmap.yaml
# 3. 创建 PVC
kubectl apply -f postgres-claim0-persistentvolumeclaim.yaml
kubectl apply -f n8n-claim0-persistentvolumeclaim.yaml
# 4. 部署 PostgreSQL
kubectl apply -f postgres-deployment.yaml
kubectl apply -f postgres-service.yaml
# 5. 部署 n8n
kubectl apply -f n8n-deployment.yaml
kubectl apply -f n8n-service.yaml
文件内容
[root@k8s-master kubernetes]# cat namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: n8n
[root@k8s-master kubernetes]# cat postgres-secret.yaml
apiVersion: v1
kind: Secret
metadata:
namespace: n8n
name: postgres-secret
type: Opaque
stringData:
POSTGRES_USER: changeUser
POSTGRES_PASSWORD: changePassword
POSTGRES_DB: n8n
POSTGRES_NON_ROOT_USER: changeUser
POSTGRES_NON_ROOT_PASSWORD: changePassword
[root@k8s-master kubernetes]# cat postgres-secret.yaml
apiVersion: v1
kind: Secret
metadata:
namespace: n8n
name: postgres-secret
type: Opaque
stringData:
POSTGRES_USER: changeUser
POSTGRES_PASSWORD: changePassword
POSTGRES_DB: n8n
POSTGRES_NON_ROOT_USER: changeUser
POSTGRES_NON_ROOT_PASSWORD: changePassword[root@k8s-master kubernetes]# ^C
[root@k8s-master kubernetes]# ^C
[root@k8s-master kubernetes]# cat postgres-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: init-data
namespace: n8n
data:
init-data.sh: |
#!/bin/bash
set -e;
if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER "${POSTGRES_NON_ROOT_USER}" WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO "${POSTGRES_NON_ROOT_USER}";
GRANT ALL ON SCHEMA public TO "${POSTGRES_NON_ROOT_USER}";
EOSQL
else
echo "SETUP INFO: No Environment variables given!"
fi
[root@k8s-master kubernetes]# cat postgres-claim0-persistentvolumeclaim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgresql-pv
namespace: n8n
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
[root@k8s-master kubernetes]# cat n8n-claim0-persistentvolumeclaim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
service: n8n-claim0
name: n8n-claim0
namespace: n8n
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
[root@k8s-master kubernetes]# cat postgres-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: postgres-n8n
name: postgres
namespace: n8n
spec:
replicas: 1
selector:
matchLabels:
service: postgres-n8n
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
service: postgres-n8n
spec:
containers:
- image: postgres:16
name: postgres
resources:
limits:
cpu: "4"
memory: 4Gi
requests:
cpu: "1"
memory: 2Gi
ports:
- containerPort: 5432
volumeMounts:
- name: postgresql-pv
mountPath: /var/lib/postgresql/data
- name: init-data
mountPath: /docker-entrypoint-initdb.d/init-n8n-user.sh
subPath: init-data.sh
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_PASSWORD
- name: POSTGRES_DB
value: n8n
- name: POSTGRES_NON_ROOT_USER
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_NON_ROOT_USER
- name: POSTGRES_NON_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_NON_ROOT_PASSWORD
- name: POSTGRES_HOST
value: postgres-service
- name: POSTGRES_PORT
value: '5432'
restartPolicy: Always
volumes:
- name: postgresql-pv
persistentVolumeClaim:
claimName: postgresql-pv
- name: postgres-secret
secret:
secretName: postgres-secret
- name: init-data
configMap:
name: init-data
defaultMode: 0744
[root@k8s-master kubernetes]# cat postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
service: postgres-n8n
name: postgres-service
namespace: n8n
spec:
clusterIP: None
ports:
- name: "5432"
port: 5432
targetPort: 5432
protocol: TCP
selector:
service: postgres-n8n
[root@k8s-master kubernetes]# cat n8n-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: n8n
name: n8n
namespace: n8n
spec:
replicas: 1
selector:
matchLabels:
service: n8n
strategy:
type: Recreate
template:
metadata:
labels:
service: n8n
spec:
initContainers:
- name: volume-permissions
image: busybox:1.36
command: ["sh", "-c", "chown 1000:1000 /data"]
volumeMounts:
- name: n8n-claim0
mountPath: /data
containers:
- command:
- /bin/sh
args:
- -c
- sleep 5; n8n start
env:
- name: DB_TYPE
value: postgresdb
- name: DB_POSTGRESDB_HOST
value: postgres-service.n8n.svc.cluster.local
- name: DB_POSTGRESDB_PORT
value: "5432"
- name: DB_POSTGRESDB_DATABASE
value: n8n
- name: DB_POSTGRESDB_USER
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_NON_ROOT_USER
- name: DB_POSTGRESDB_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_NON_ROOT_PASSWORD
- name: N8N_PROTOCOL
value: http
- name: N8N_PORT
value: "5678"
image: n8nio/n8n
name: n8n
ports:
- containerPort: 5678
resources:
requests:
memory: "250Mi"
limits:
memory: "500Mi"
volumeMounts:
- mountPath: /home/node/.n8n
name: n8n-claim0
restartPolicy: Always
volumes:
- name: n8n-claim0
persistentVolumeClaim:
claimName: n8n-claim0
- name: n8n-secret
secret:
secretName: n8n-secret
- name: postgres-secret
secret:
secretName: postgres-secret
[root@k8s-master kubernetes]# cat n8n-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
service: n8n
name: n8n
namespace: n8n
spec:
type: ClusterIP
ports:
- name: "5678"
port: 5678
targetPort: 5678
protocol: TCP
selector:
service: n8n
如果容器拉不下来镜像就手动拉取一下并改名字
# 1. busybox(已经拉取,只需要打标签)
sudo ctr image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox:1.36.1-1 docker.io/library/busybox:1.36
# 2. postgres
sudo ctr image pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/postgres:16
sudo ctr image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/postgres:16 docker.io/library/postgres:16
# 3. n8n
sudo ctr image pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/n8n-io/n8n:latest
sudo ctr image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/n8n-io/n8n:latest docker.io/n8nio/n8n:latest
# 4. 查看已拉取的镜像
sudo ctr image list | grep -E "busybox|postgres|n8n"
二、验证部署状态
# 查看 PVC 状态(应该是 Bound)
kubectl get pvc -n n8n
# 查看 Pod 状态(应该是 Running)
kubectl get pods -n n8n
# 查看服务
kubectl get svc -n n8n
三、访问 n8n
部署成功后,先用端口转发临时访问
k8s的master执行
kubectl port-forward -n n8n svc/n8n 5678:5678
宿主机执行
ssh -L 5678:localhost:5678 root@192.168.158.131
这个时候就能用http://localhost:5678/setup访问了

设置好就能登陆了

本篇文章先到这里
