云容器引擎 CCE-服务概述:集群内无法访问Service的说明
集群内无法访问Service的说明
upstream connect error or disconnect/reset before headers. reset reason: connection failure 或: curl: (7) Failed to connect to 192.168.10.36 port 900: Connection refused
在集群中访问ELB地址时出现无法访问的场景较为常见,这是由于Kubernetes在创建Service时,kube-proxy会把ELB的访问地址作为外部IP(即External-IP,如下方回显所示)添加到iptables或IPVS中。如果客户端从集群内部发起访问ELB地址的请求,该地址会被认为是服务的外部IP,被kube-proxy直接转发,而不再经过集群外部的ELB。
# kubectl get svc nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx LoadBalancer 10.247.76.156 123.**.**.**,192.168.0.133 80:32146/TCP 37s
- 多实例的工作负载需要保证所有实例均可正常访问,否则可能出现概率性访问不通的情况。
- CCE Turbo 集群(云原生2.0网络模型)中,仅当Service的后端对接使用主机网络(HostNetwork)的Pod时,亲和级别支持配置为节点级别。
- 表格中仅列举了可能存在访问不通的场景,其他不在表格中的场景即表示可以正常访问。
服务端发布服务类型 |
访问类型 |
客户端请求发起位置 |
容器隧道集群(IPVS) |
VPC集群(IPVS) |
容器隧道集群(IPTABLES) |
VPC集群(IPTABLES) |
---|---|---|---|---|---|---|
节点访问类型Service |
公网/私网 |
与服务Pod同节点 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
与服务Pod不同节点 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
正常访问 |
正常访问 |
||
与服务Pod同节点的其他容器 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
无法访问 |
||
与服务Pod不同节点的其他容器 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
访问服务端所在节点IP+NodePort — 正常访问 访问非服务端所在节点IP+NodePort — 无法访问 |
||
独享型负载均衡类型Service |
私网 |
与服务Pod同节点 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
与服务Pod同节点的其他容器 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
||
DNAT网关类型Service |
公网 |
与服务Pod同节点 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
与服务Pod不同节点 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
||
与服务Pod同节点的其他容器 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
||
与服务Pod不同节点的其他容器 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
||
nginx-ingress插件对接独享型ELB(Local) |
私网 |
与cceaddon-nginx-ingress-controller Pod同节点 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
与cceaddon-nginx-ingress-controller Pod同节点的其他容器 |
无法访问 |
无法访问 |
无法访问 |
无法访问 |
解决这个问题通常有如下办法:
- (推荐)在集群内部访问使用Service的ClusterIP或服务 域名 访问。
- 将Service的externalTrafficPolicy设置为Cluster,即集群级别服务亲和。不过需要注意这会影响源地址保持。
apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Cluster ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer
- 使用Service的pass-through特性,使用ELB地址访问时绕过kube-proxy,先访问ELB,经过ELB再访问到负载。具体请参见LoadBalancer类型Service使用pass-through能力。
- 独享型负载均衡配置pass-through后,CCE Standard集群在工作负载同节点和同节点容器内无法通过Service访问。
- 1.15及以下老版本集群暂不支持该能力。
- IPVS网络模式下,对接同一个ELB的Service需保持pass-through设置情况一致。
- 使用节点级别(Local)的服务亲和的场景下,会自动设置kubernetes.io/elb.pass-through为onlyLocal,开启pass-through能力。
apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.pass-through: "true" kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Local ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer