rwi*_*n04 4 firewall kubernetes google-kubernetes-engine
我正在使用谷歌的容器引擎服务,并获得一个运行服务器的pod在端口3000上侦听.我设置了服务以将端口80连接到该容器的端口3000.我能够使用其本地和公共IP来卷曲服务在节点内,但不是从外部.我设置了防火墙规则以允许端口80并将其发送到节点,但我不断从网络外部获得"连接被拒绝".我试图在没有转发规则的情况下这样做,因为只有一个pod,看起来转发规则需要花钱并进行负载平衡.我认为防火墙规则有效,因为当我添加createExternalLoadBalancer: true到服务的规范时,转发规则创建的外部IP按预期工作.我还需要做点什么吗?设置路线或什么?
controller.yaml
kind: ReplicationController
apiVersion: v1beta3
metadata:
name: app-frontend
labels:
name: app-frontend
app: app
role: frontend
spec:
replicas: 1
selector:
name: app-frontend
template:
metadata:
labels:
name: app-frontend
app: app
role: frontend
spec:
containers:
- name: node-frontend
image: gcr.io/project_id/app-frontend
ports:
- name: app-frontend-port
containerPort: 3000
targetPort: 3000
protocol: TCP
Run Code Online (Sandbox Code Playgroud)
service.yaml
kind: Service
apiVersion: v1beta3
metadata:
name: app-frontend-service
labels:
name: app-frontend-service
app: app
role: frontend
spec:
ports:
- port: 80
targetPort: app-frontend-port
protocol: TCP
publicIPs:
- 123.45.67.89
selector:
name: app-frontend
Run Code Online (Sandbox Code Playgroud)
编辑(其他详细信息):
创建此服务会添加这些在运行时找到的附加规则iptables -L -t nat
Chain KUBE-PORTALS-CONTAINER (1 references)
target prot opt source destination
REDIRECT tcp -- anywhere 10.247.247.206 /* default/app-frontend-service: */ tcp dpt:http redir ports 56859
REDIRECT tcp -- anywhere 89.67.45.123.bc.googleusercontent.com /* default/app-frontend-service: */ tcp dpt:http redir ports 56859
Chain KUBE-PORTALS-HOST (1 references)
target prot opt source destination
DNAT tcp -- anywhere 10.247.247.206 /* default/app-frontend-service: */ tcp dpt:http to:10.241.69.28:56859
DNAT tcp -- anywhere 89.67.45.123.bc.googleusercontent.com /* default/app-frontend-service: */ tcp dpt:http to:10.241.69.28:56859
Run Code Online (Sandbox Code Playgroud)
我不完全了解iptables,所以我不确定目标端口如何匹配我的服务.我发现DNS的89.67.45.123.bc.googleusercontent.com解析为123.45.67.89.
kubectl get services显示我指定的IP地址和端口:
NAME IP(S) PORT(S)
app-frontend-service 10.247.243.151 80/TCP
123.45.67.89
Run Code Online (Sandbox Code Playgroud)
在/var/log/kube-proxy.log中没有显示外部IP的最新信息
TL; DR:使用节点的内部IP作为服务定义中的公共IP.
如果在kube-proxy上启用详细日志记录,您将看到它似乎正在创建适当的IP表规则:
I0602 04:07:32.046823 24360 roundrobin.go:98] LoadBalancerRR service "default/app-frontend-service:" did not exist, created
I0602 04:07:32.047153 24360 iptables.go:186] running iptables -A [KUBE-PORTALS-HOST -t nat -m comment --comment default/app-frontend-service: -p tcp -m tcp -d 10.119.244.130/32 --dport 80 -j DNAT --to-destination 10.240.121.42:36970]
I0602 04:07:32.048446 24360 proxier.go:606] Opened iptables from-host portal for service "default/app-frontend-service:" on TCP 10.119.244.130:80
I0602 04:07:32.049525 24360 iptables.go:186] running iptables -C [KUBE-PORTALS-CONTAINER -t nat -m comment --comment default/app-frontend-service: -p tcp -m tcp -d 23.251.156.36/32 --dport 80 -j REDIRECT --to-ports 36970]
I0602 04:07:32.050872 24360 iptables.go:186] running iptables -A [KUBE-PORTALS-CONTAINER -t nat -m comment --comment default/app-frontend-service: -p tcp -m tcp -d 23.251.156.36/32 --dport 80 -j REDIRECT --to-ports 36970]
I0602 04:07:32.052247 24360 proxier.go:595] Opened iptables from-containers portal for service "default/app-frontend-service:" on TCP 23.251.156.36:80
I0602 04:07:32.053222 24360 iptables.go:186] running iptables -C [KUBE-PORTALS-HOST -t nat -m comment --comment default/app-frontend-service: -p tcp -m tcp -d 23.251.156.36/32 --dport 80 -j DNAT --to-destination 10.240.121.42:36970]
I0602 04:07:32.054491 24360 iptables.go:186] running iptables -A [KUBE-PORTALS-HOST -t nat -m comment --comment default/app-frontend-service: -p tcp -m tcp -d 23.251.156.36/32 --dport 80 -j DNAT --to-destination 10.240.121.42:36970]
I0602 04:07:32.055848 24360 proxier.go:606] Opened iptables from-host portal for service "default/app-frontend-service:" on TCP 23.251.156.36:80
Run Code Online (Sandbox Code Playgroud)
列出iptables条目使用-L -t显示公共IP转换为反向DNS名称,如下所示:
Chain KUBE-PORTALS-CONTAINER (1 references)
target prot opt source destination
REDIRECT tcp -- anywhere 10.119.240.2 /* default/kubernetes: */ tcp dpt:https redir ports 50353
REDIRECT tcp -- anywhere 10.119.240.1 /* default/kubernetes-ro: */ tcp dpt:http redir ports 54605
REDIRECT udp -- anywhere 10.119.240.10 /* default/kube-dns:dns */ udp dpt:domain redir ports 37723
REDIRECT tcp -- anywhere 10.119.240.10 /* default/kube-dns:dns-tcp */ tcp dpt:domain redir ports 50126
REDIRECT tcp -- anywhere 10.119.244.130 /* default/app-frontend-service: */ tcp dpt:http redir ports 36970
REDIRECT tcp -- anywhere 36.156.251.23.bc.googleusercontent.com /* default/app-frontend-service: */ tcp dpt:http redir ports 36970
Run Code Online (Sandbox Code Playgroud)
但添加该-n选项会显示IP地址(默认情况下,-L会对IP地址执行反向查找,这就是您查看DNS名称的原因):
Chain KUBE-PORTALS-CONTAINER (1 references)
target prot opt source destination
REDIRECT tcp -- 0.0.0.0/0 10.119.240.2 /* default/kubernetes: */ tcp dpt:443 redir ports 50353
REDIRECT tcp -- 0.0.0.0/0 10.119.240.1 /* default/kubernetes-ro: */ tcp dpt:80 redir ports 54605
REDIRECT udp -- 0.0.0.0/0 10.119.240.10 /* default/kube-dns:dns */ udp dpt:53 redir ports 37723
REDIRECT tcp -- 0.0.0.0/0 10.119.240.10 /* default/kube-dns:dns-tcp */ tcp dpt:53 redir ports 50126
REDIRECT tcp -- 0.0.0.0/0 10.119.244.130 /* default/app-frontend-service: */ tcp dpt:80 redir ports 36970
REDIRECT tcp -- 0.0.0.0/0 23.251.156.36 /* default/app-frontend-service: */ tcp dpt:80 redir ports 36970
Run Code Online (Sandbox Code Playgroud)
此时,您可以使用内部和外部IP从群集中访问服务:
$ curl 10.119.244.130:80
app-frontend-5pl5s
$ curl 23.251.156.36:80
app-frontend-5pl5s
Run Code Online (Sandbox Code Playgroud)
在不添加防火墙规则的情况下,尝试远程连接到公共IP超时.如果添加防火墙规则,则可以可靠地拒绝连接:
$ curl 23.251.156.36
curl: (7) Failed to connect to 23.251.156.36 port 80: Connection refused
Run Code Online (Sandbox Code Playgroud)
如果启用一些iptables日志记录:
sudo iptables -t nat -I KUBE-PORTALS-CONTAINER -m tcp -p tcp --dport
80 -j LOG --log-prefix "WTF: "
Run Code Online (Sandbox Code Playgroud)
然后grep输出,dmesg因为WTF它清楚地表明数据包到达VM的IP地址,而不是在服务上设置为公共IP的短暂外部IP地址.
事实证明,问题在于GCE有两种类型的外部IP:ForwardingRules(在DSTIP完整的情况下转发)和1对1 NAT(实际上将DSTIP重写为内部IP).VM的外部IP是后一种类型,因此当节点收到数据包时,IP表规则不匹配.
修复实际上非常简单(但不直观):使用节点的内部IP作为服务定义中的公共IP.更新service.yaml文件以将publicIP设置为内部IP(例如10.240.121.42)后,您将能够从GCE网络外部访问您的应用程序.
| 归档时间: |
|
| 查看次数: |
11390 次 |
| 最近记录: |