此处介绍的IP白名单/黑名单示例 https://kubernetes.io/docs/tutorials/services/source-ip/使用source.ip属性。但是,在 kubernetes(运行在 docker-for-desktop 上的 kubernetes 集群)中,source.ip 返回 kube-proxy 的 IP。建议的解决方法是使用request.headers["X-Real-IP"]
,但它似乎不起作用,并在 mac 的 docker-for-desktop 中返回 kube-proxy IP。
https://github.com/istio/istio/issues/7328 提到了这个问题,并指出:
使用代理终止客户端连接并打开与节点/端点的新连接。在这种情况下,源 IP 将始终是云 LB 的 IP,而不是客户端的 IP。
使用数据包转发器,这样,来自客户端发送到负载均衡器 VIP 的请求最终会到达具有客户端源 IP 的节点,而不是中间代理。
第一类负载均衡器必须在负载均衡器和后端之间使用商定的协议来通信真正的客户端 IP,例如 HTTP X-FORWARDED-FOR 标头或代理协议。
有人可以帮忙,我们如何定义一个协议来从负载均衡器获取客户端 IP?
也许你对 kube-proxy 和 istio 感到困惑,默认情况下 Kubernetes 使用 kube-proxy,但你可以安装 istio,为每个 pod 注入一个新的代理来控制 pod 内服务的双向流量。
话虽如此,您可以在集群上安装 istio 并仅为您需要的服务启用它,并使用 istio 机制应用黑名单
https://istio.io/docs/tasks/policy-enforcement/denial-and-list/
要使用源 IP 制作黑名单,我们必须让 istio 管理如何获取源 IP 地址并使用从文档中获取的 som 配置:
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: whitelistip
spec:
compiledAdapter: listchecker
params:
# providerUrl: ordinarily black and white lists are maintained
# externally and fetched asynchronously using the providerUrl.
overrides: ["10.57.0.0/16"] # overrides provide a static list
blacklist: false
entryType: IP_ADDRESSES
---
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: sourceip
spec:
compiledTemplate: listentry
params:
value: source.ip | ip("0.0.0.0")
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: checkip
spec:
match: source.labels["istio"] == "ingressgateway"
actions:
- handler: whitelistip
instances: [ sourceip ]
---
您可以使用参数providerURL
来维护外部列表。
还要检查在 istio 的入口网关服务上使用externalTrafficPolicy: Local
。
根据评论,我最后的建议是使用不同的入口控制器来避免使用 kube-proxy,我的建议是使用 nginx 控制器
https://github.com/kubernetes/ingress-nginx
您可以将此入口配置为充当代理的常规nginx。