问题描述
当您在 Ingress Nginx 中使用 configuration-snippet 注解时,可能会遇到以下错误:
1
2
3
Error from server (BadRequest): error when creating "ingress-nginx-proxy-complete.yaml":
admission webhook "validate.nginx.ingress.kubernetes.io" denied the request:
annotation group ConfigurationSnippet contains risky annotation based on ingress configuration
原因分析
这个错误是由于 Ingress Nginx 的安全验证机制导致的。从 Ingress Nginx Controller v1.9.0 开始,引入了更严格的安全验证,会阻止包含潜在风险配置的注解。
被阻止的配置包括:
location 块配置 :如 location ~* \.(blob|manifest)$ { ... }复杂的重写规则 :可能包含恶意代码不安全的头设置 :可能被用于注入攻击文件路径操作 :如日志文件路径解决方案
方案1:使用安全的标准注解(推荐)
使用 Ingress Nginx 提供的标准注解替代 configuration-snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
name : docker-hub-proxy-safe
annotations :
# 使用 proxy-set-headers 替代 configuration-snippet
nginx.ingress.kubernetes.io/proxy-set-headers : "default/proxy-set-headers"
# 使用 custom-headers 替代 add_header
nginx.ingress.kubernetes.io/custom-headers : "default/custom-headers"
# 标准代理配置
nginx.ingress.kubernetes.io/backend-protocol : "HTTPS"
nginx.ingress.kubernetes.io/proxy-body-size : "0"
nginx.ingress.kubernetes.io/proxy-read-timeout : "600"
nginx.ingress.kubernetes.io/proxy-send-timeout : "600"
nginx.ingress.kubernetes.io/proxy-connect-timeout : "600"
# 缓冲区配置
nginx.ingress.kubernetes.io/proxy-buffer-size : "16k"
nginx.ingress.kubernetes.io/proxy-buffers-number : "8"
nginx.ingress.kubernetes.io/proxy-max-temp-file-size : "1024m"
nginx.ingress.kubernetes.io/proxy-request-buffering : "off"
对应的 ConfigMap:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion : v1
kind : ConfigMap
metadata :
name : proxy-set-headers
namespace : default
data :
# 设置 Host 头
Host : "registry-1.docker.io"
# Docker Registry API 版本
Docker-Distribution-Api-Version : "registry/2.0"
---
apiVersion : v1
kind : ConfigMap
metadata :
name : custom-headers
namespace : default
data :
# 安全头
X-Content-Type-Options : "nosniff"
X-Frame-Options : "DENY"
X-XSS-Protection : "1; mode=block"
方案2:使用 ConfigMap 全局配置
修改 Ingress Nginx Controller 的 ConfigMap 来应用全局配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion : v1
kind : ConfigMap
metadata :
name : nginx-configuration
namespace : ingress-nginx
data :
# 全局代理配置
proxy-connect-timeout : "600"
proxy-send-timeout : "600"
proxy-read-timeout : "600"
proxy-buffer-size : "16k"
proxy-buffers-number : "8"
proxy-max-temp-file-size : "1024m"
proxy-body-size : "0"
# 全局头配置
add-headers : "ingress-nginx/custom-headers"
proxy-set-headers : "ingress-nginx/proxy-set-headers"
# 启用压缩
use-gzip : "true"
gzip-level : "6"
gzip-min-length : "1024"
方案3:禁用安全验证(不推荐)
如果您确实需要使用 configuration-snippet,可以禁用安全验证,但这会降低安全性:
1
2
# 编辑 Ingress Nginx Controller 的部署
kubectl edit deployment ingress-nginx-controller -n ingress-nginx
在容器参数中添加:
1
2
3
4
5
args :
- /nginx-ingress-controller
- --enable-annotation-validation=false # 禁用安全验证
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --annotations-prefix=nginx.ingress.kubernetes.io
⚠️ 警告 :禁用安全验证会使您的集群面临安全风险,不建议在生产环境中使用。
验证配置
1. 检查 Ingress 状态
1
2
3
4
5
# 查看 Ingress 状态
kubectl get ingress docker-hub-proxy-safe
# 查看详细事件
kubectl describe ingress docker-hub-proxy-safe
2. 测试代理功能
1
2
3
4
5
# 测试 Docker Hub 代理
docker pull dockerhub.yourdomain.com/library/nginx:latest
# 查看 Nginx 日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller | grep dockerhub
3. 检查配置是否生效
1
2
3
4
5
# 进入 Ingress Controller Pod
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller -- cat /etc/nginx/nginx.conf | grep -A 10 -B 10 dockerhub
# 检查 Nginx 配置是否正确
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller -- nginx -t
最佳实践
1. 使用安全的替代方案
原始配置 安全替代方案 configuration-snippet 中的 add_headernginx.ingress.kubernetes.io/custom-headersconfiguration-snippet 中的 proxy_set_headernginx.ingress.kubernetes.io/proxy-set-headersconfiguration-snippet 中的 location 块使用多个 Ingress 规则 configuration-snippet 中的重写规则nginx.ingress.kubernetes.io/rewrite-target
2. 配置示例对比
❌ 不安全的配置:
1
2
3
4
5
6
7
annotations :
nginx.ingress.kubernetes.io/configuration-snippet : |
location ~* \.(blob|manifest|config)$ {
proxy_cache_valid 200 302 10m;
add_header X-Cache-Status $upstream_cache_status;
}
add_header X-Content-Type-Options nosniff;
✅ 安全的配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
annotations :
nginx.ingress.kubernetes.io/proxy-set-headers : "default/proxy-headers"
nginx.ingress.kubernetes.io/custom-headers : "default/custom-headers"
nginx.ingress.kubernetes.io/proxy-buffering : "on"
---
apiVersion : v1
kind : ConfigMap
metadata :
name : custom-headers
namespace : default
data :
X-Content-Type-Options : "nosniff"
X-Frame-Options : "DENY"
3. 监控和告警
设置监控来跟踪代理性能和错误:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion : v1
kind : ServiceMonitor
metadata :
name : ingress-nginx-registry-proxy
namespace : monitoring
spec :
selector :
matchLabels :
app.kubernetes.io/name : ingress-nginx
app.kubernetes.io/component : controller
endpoints :
- port : metrics
interval : 30s
path : /metrics
常见问题
Q1: 为什么我的配置被阻止了?
A: Ingress Nginx 的安全验证机制检测到您的配置包含潜在风险。这是为了保护您的集群安全。
Q2: 如何知道哪些配置是安全的?
A: 参考 Ingress Nginx 官方文档中的安全注解列表 。
Q3: 我可以在测试环境中禁用安全验证吗?
A: 技术上可以,但不推荐。更好的做法是找到安全的替代方案。
Q4: 配置更改后没有生效?
A: 检查以下几点:
ConfigMap 是否在正确的命名空间 Ingress Controller 是否重启以加载新配置 使用 kubectl describe ingress 查看事件 Q5: 如何调试配置问题?
A: 使用以下命令:
1
2
3
4
5
6
7
8
# 查看 Nginx 配置
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller -- cat /etc/nginx/nginx.conf
# 测试配置
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller -- nginx -t
# 查看日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
总结
使用 configuration-snippet 被拒绝时,应该:
首选方案 :使用标准注解和 ConfigMap 替代次选方案 :通过 ConfigMap 进行全局配置避免 :禁用安全验证这样既能保证功能实现,又能维护集群的安全性。