有时会遇到部分服务在集群外部,比如中间件和存储,想要通过k8s集群直接连接两种方式,一种就是直接通过IP地址连接;另外一种就是把外部地址映射到集群内部作为一个service来访问,这样优点很明显后期如果资源IP地址有变更直接在线更新。
看到这,我是想马上直接测试下,创建了一个service和endpoints 如下:
---
apiVersion: v1
kind: Service
metadata:
name: solr-cloud
namespace: yp-test
spec:
ports:
- protocol: TCP
name: solr-port
port: 9090
targetPort: 9090
type: ClusterIP
clusterIP:
---
apiVersion: v1
kind: Endpoints
metadata:
name: solr-cloud
namespace: yp-test
subsets:
- addresses:
- ip: 192.168.11.229
ports:
- port: 9090
kubectl apply -f solr-endpoint.yaml 执行成功了
然后通过集群内部pod来访问刚刚创建的service,发现拒绝,但是直接请求IP是通的。
再kubectl describe svc,ep solr-cloud -n yp-test查看如下:
Name: solr-cloud
Namespace: yp-test
Labels: <none>
Annotations: Selector: <none>
Type: ClusterIP
IP: 10.96.78.185
Port: solr-port 9090/TCP
TargetPort: 9090/TCP
Endpoints:
Session Affinity: None
Events: <none>
Name: solr-cloud
Namespace: yp-test
Labels: <none>
Annotations: Subsets:
Addresses: 192.168.11.229
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 9090 TCP
Events: <none>
可以发现Endpoints为空也就是endpoints 并没有绑定到内部service上。
为何会这样?
前面的配置貌似也没任何问题,经过和官方文档对比,细心的朋友可能会发现,service配置里spec.ports有个name(之前写service习惯会把port再定义个name).
先去掉这个name再重新创建试试
没问题,去掉name,请求service通了。
总结:
serivce和endpoints关联是通过metadata.name来关联的,官方文档也是这么说的。个人猜想,那么当有spec.ports.name时,endpoints中端口ports进行关联时匹配不了,为了再次验证我的猜想,在endpoints中也增加一个一样的name,结果真就关联上了。所以,我们创建时一定要注意些细节,一种就是去掉spec.ports.name,或者endpoints同样增加上ports.name。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。