Files
k3s/009-基础设施/008-portainer/README.md
2026-02-05 00:11:05 +08:00

192 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Portainer 部署指南
## 概述
本文档记录了在 k3s 集群中部署 Portainer 的完整过程包括域名绑定、KEDA 自动缩放和 CSRF 校验问题的解决方案。
## 部署步骤
### 1. 使用 Helm 安装 Portainer
```bash
# 添加 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 的反向代理规则:
```yaml
# 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
```bash
kubectl patch configmap caddy-config -n default --type merge -p '{"data":{"Caddyfile":"..."}}'
```
#### 2.3 重启 Caddy Pod
```bash
kubectl delete pod -n default -l app=caddy
```
### 3. 配置 KEDA 自动缩放(可选)
如果需要实现访问时启动、空闲时缩容的功能,应用 KEDA 配置:
```bash
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 校验**
```bash
kubectl set env deployment/portainer -n portainer CONTROLLER_DISABLE_CSRF=true
```
**步骤 2添加环境变量配置 origins**
```bash
kubectl set env deployment/portainer -n portainer PORTAINER_ADMIN_ORIGINS="*"
```
**步骤 3重启 Portainer**
```bash
kubectl rollout restart deployment portainer -n portainer
```
**步骤 4修改 Caddy 配置(最关键)**
直接转发到 Portainer 的 HTTPS 端口,避免通过 Traefik 导致的协议转换问题:
```yaml
portainer.u6.net3w.com {
reverse_proxy https://portainer.portainer.svc.cluster.local:9443 {
transport http {
tls_insecure_skip_verify
}
}
}
```
## 配置文件
### portainer-server.yaml
记录 Portainer deployment 的环境变量配置:
```yaml
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 校验失败导致的。检查以下几点:
1. 确认已添加环境变量 `CONTROLLER_DISABLE_CSRF=true`
2. 确认 Caddy 配置直接转发到 Portainer HTTPS 端口
3. 检查 Portainer 日志中是否有 "origin invalid" 错误
4. 重启 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/