我'm using Google'的容器引擎服务,并得到一个运行服务器的pod侦听端口3000.我设置服务将端口80连接到该容器's port 3000. I am able to curl the service using its local and public ip from within the node, but not from outside. I set up a firewall rule to allow port 80 and send it to the node, but I keep getting '连接被拒绝' from outside the network. I' m试图在没有转发规则的情况下执行此操作,因为只有一个容器它看起来像转发规则花钱并进行负载 balancer . 我认为防火墙规则有效,因为当我将 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
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
Edit (additional details): 创建此服务会添加这些在运行 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
我不知道't fully understand iptables, so I'我不确定目标端口如何与我的服务匹配 . 我发现 89.67.45.123.bc.googleusercontent.com
的DNS解析为 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
在/var/log/kube-proxy.log中没有显示外部IP的最新信息
3 回答
TL; DR:使用节点的内部IP作为服务定义中的公共IP .
如果在kube-proxy上启用详细日志记录,您将看到它似乎正在创建适当的IP表规则:
使用
-L -t
列出iptables条目显示公共IP变为反向DNS名称,如下所示:但添加
-n
选项会显示IP地址(默认情况下,-L
会对IP地址执行反向查找,这就是您查看DNS名称的原因):此时,您可以使用内部和外部IP从群集中访问服务:
在不添加防火墙规则的情况下,尝试远程连接到公共IP超时 . 如果添加防火墙规则,则可以可靠地拒绝连接:
如果启用一些iptables日志记录:
然后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网络外部访问您的应用程序 .如果添加节点's external IP address to the service' s
publicIPs
字段,则应该能够在节点's IP address. If your cluster has multiple nodes, you can put more than one of their IP addresses into the field if you'上访问它,以便能够访问任何节点上的窗格 .在即将发布的版本中,将有一个更简单的内置选项,用于在没有负载均衡器的情况下设置外部服务 . 如果您有兴趣或将来某个时候阅读此内容,请查看this doc的更新"External Services"部分,了解如何使用
NodePort
来更轻松地完成相同的操作 .回答@Robert Bailey是完全正确的 . publicIPs已在kubernetes 1.5.1中弃用,您可以使用externalIPs代替 .
获取节点的内部ip,
kubectl describe node | grep Address
Addresses: 10.119.244.130,101.192.150.200,gke-...
或者您可以在节点终端内运行
ifconfig eth0
以获取内部IP在服务中设置ip.yaml
spec: type: NodePort externalIPs: - 10.119.244.130
可以卷曲以决定测试
curl --resolve 'example.com:443:23.251.156.36' https://example.com -k