4.8 KiB
4.8 KiB
Portainer 部署指南
概述
本文档记录了在 k3s 集群中部署 Portainer 的完整过程,包括域名绑定、KEDA 自动缩放和 CSRF 校验问题的解决方案。
部署步骤
1. 使用 Helm 安装 Portainer
# 添加 Helm 仓库
helm repo add portainer https://portainer.github.io/k8s/
helm repo update
# 安装 Portainer(使用 Longhorn 作为存储类)
helm install --create-namespace -n portainer portainer portainer/portainer \
--set persistence.enabled=true \
--set persistence.storageClass=longhorn \
--set service.type=NodePort
2. 配置域名访问
2.1 Caddy 反向代理配置
修改 Caddy ConfigMap,添加 Portainer 的反向代理规则:
# Portainer 容器管理 - 直接转发到 Portainer HTTPS 端口
portainer.u6.net3w.com {
reverse_proxy https://portainer.portainer.svc.cluster.local:9443 {
transport http {
tls_insecure_skip_verify
}
}
}
关键点:
- 直接转发到 Portainer 的 HTTPS 端口(9443),而不是通过 Traefik
- 这样可以避免协议不匹配导致的 CSRF 校验失败
2.2 更新 Caddy ConfigMap
kubectl patch configmap caddy-config -n default --type merge -p '{"data":{"Caddyfile":"..."}}'
2.3 重启 Caddy Pod
kubectl delete pod -n default -l app=caddy
3. 配置 KEDA 自动缩放(可选)
如果需要实现访问时启动、空闲时缩容的功能,应用 KEDA 配置:
kubectl apply -f keda-scaler.yaml
配置说明:
- 最小副本数:0(空闲时缩容到 0)
- 最大副本数:3
- 缩容延迟:5 分钟无流量后缩容
4. 解决 CSRF 校验问题
问题描述
登录时提示 "Unable to login",日志显示:
Failed to validate Origin or Referer | error="origin invalid"
问题原因
Portainer 新版本对 CSRF 校验非常严格。当通过域名访问时,协议不匹配导致校验失败:
- 客户端发送:HTTPS 请求
- Portainer 接收:x_forwarded_proto=http
解决方案
步骤 1:添加环境变量禁用 CSRF 校验
kubectl set env deployment/portainer -n portainer CONTROLLER_DISABLE_CSRF=true
步骤 2:添加环境变量配置 origins
kubectl set env deployment/portainer -n portainer PORTAINER_ADMIN_ORIGINS="*"
步骤 3:重启 Portainer
kubectl rollout restart deployment portainer -n portainer
步骤 4:修改 Caddy 配置(最关键)
直接转发到 Portainer 的 HTTPS 端口,避免通过 Traefik 导致的协议转换问题:
portainer.u6.net3w.com {
reverse_proxy https://portainer.portainer.svc.cluster.local:9443 {
transport http {
tls_insecure_skip_verify
}
}
}
配置文件
portainer-server.yaml
记录 Portainer deployment 的环境变量配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: portainer
namespace: portainer
spec:
template:
spec:
containers:
- name: portainer
env:
- name: CONTROLLER_DISABLE_CSRF
value: "true"
- name: PORTAINER_ADMIN_ORIGINS
value: "*"
keda-scaler.yaml
KEDA 自动缩放配置,实现访问时启动、空闲时缩容。
访问 Portainer
部署完成后,访问:
https://portainer.u6.net3w.com
常见问题
Q: 登录时提示 "Unable to login"
A: 这通常是 CSRF 校验失败导致的。检查以下几点:
- 确认已添加环境变量
CONTROLLER_DISABLE_CSRF=true - 确认 Caddy 配置直接转发到 Portainer HTTPS 端口
- 检查 Portainer 日志中是否有 "origin invalid" 错误
- 重启 Portainer pod 使配置生效
Q: 为什么要直接转发到 HTTPS 端口而不是通过 Traefik?
A: 因为通过 Traefik 转发时,协议头会被转换为 HTTP,导致 Portainer 接收到的协议与客户端发送的协议不匹配,从而 CSRF 校验失败。直接转发到 HTTPS 端口可以保持协议一致。
Q: KEDA 自动缩放是否必须配置?
A: 不是必须的。KEDA 自动缩放是可选功能,用于节省资源。如果不需要自动缩放,可以跳过这一步。
相关文件
portainer-server.yaml- Portainer deployment 环境变量配置keda-scaler.yaml- KEDA 自动缩放配置ingress.yaml- 原始 Ingress 配置(已弃用,改用 Caddy 直接转发)
下次部署检查清单
- 使用 Helm 安装 Portainer
- 修改 Caddy 配置,直接转发到 Portainer HTTPS 端口
- 添加 Portainer 环境变量(CONTROLLER_DISABLE_CSRF、PORTAINER_ADMIN_ORIGINS)
- 重启 Caddy 和 Portainer pods
- 测试登录功能
- (可选)配置 KEDA 自动缩放
参考资源
- Portainer 官方文档:https://docs.portainer.io/
- k3s 官方文档:https://docs.k3s.io/
- KEDA 官方文档:https://keda.sh/