未找到 k8s ExternalName 端点 - 但工作正常
k8s ExternalName endpoint not found - but working
我使用 kustomize
部署了一个简单的测试 ingress
和一个 externalName
service
。
部署有效,我得到了预期的结果,但是当 describing
和 test-ingress
时,它显示错误:<error: endpoints "test-external-service" not found>
。
这似乎是一个 k8s 错误。它显示此错误,但一切正常。
这是我的部署:
kustomization.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: platform
resources:
- test-ingress.yaml
- test-service.yaml
generatorOptions:
disableNameSuffixHash: true
test-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: test-external-service
namespace: platform
spec:
type: ExternalName
externalName: "some-working-external-elasticsearch-service"
test-ingress.yaml
:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: nginx-external
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_cache_bypass $http_upgrade;
spec:
rules:
- host: testapi.mydomain.com
http:
paths:
- path: /
backend:
serviceName: test-external-service
servicePort: 9200
在这里,我将外部服务连接到工作中的 elasticsearch
服务器。当浏览到 testapi.mydomain.com
(“mydomain”当然被我们的真实域替换)时,我得到了众所周知的预期 elasticsearch
结果:
{
"name" : "73b40a031651",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "Xck-u_EFQ0uDHJ1MAho4mQ",
"version" : {
"number" : "7.10.1",
"build_flavor" : "oss",
"build_type" : "docker",
"build_hash" : "1c34507e66d7db1211f66f3513706fdf548736aa",
"build_date" : "2020-12-05T01:00:33.671820Z",
"build_snapshot" : false,
"lucene_version" : "8.7.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
所以一切正常。但是在描述test-ingress
的时候出现如下错误:
test-external-service:9200 (<error: endpoints "test-external-service" not found>)
这是什么错误?为什么我得到它,即使一切正常?我在这里错过了什么?
服务是一种 Kubernetes 抽象,它使用标签来选择 pods 将流量路由到。
端点跟踪服务向其发送流量的对象的 IP 地址。当服务选择器匹配 pod 标签时。
这是类型为 ClusterIP、NodePort 或 LoadBalancer 的 Kubernetes 服务的情况。
对于您的情况,您使用类型为 ExternalName 的 Kubernetes 服务,其中端点是集群外部或不同命名空间中的服务器,因此当您尝试描述入口时,kubernetes 会显示该错误消息。
通常我们不会创建指向 ExternalName 类型服务的入口,因为我们不应该向外部公开已经公开的服务。 kubernetes ingress 需要 ClusterIP、NodePort 或 LoadBalancer 类型的服务,这就是为什么您在描述 ingress 时遇到意外错误的原因。
如果您在集群内浏览该 ExternalName,最好避免使用入口并改用服务 uri (test-external-service..svc.cluster.local:9200)
总之如果你坚持使用Ingress,你可以创建一个Headless service without selector and then manually create an endpoint using the same name as of the service. Follow the example here
这就是 kubectl describe ingress
命令的工作原理。
kubectl describe ingress
命令调用describeIngressV1beta1 function, which calls the describeBackendV1beta1函数描述后端。
在 source code, the describeBackendV1beta1 函数中可以找到查找与后端服务关联的端点,如果找不到合适的端点,则会生成一条错误消息(如您的示例所示):
func (i *IngressDescriber) describeBackendV1beta1(ns string, backend *networkingv1beta1.IngressBackend) string {
endpoints, err := i.client.CoreV1().Endpoints(ns).Get(context.TODO(), backend.ServiceName, metav1.GetOptions{})
if err != nil {
return fmt.Sprintf("<error: %v>", err)
}
...
在 Integrating External Services 文档中,您可以发现 ExternalName
服务没有任何已定义的端点:
ExternalName services do not have selectors, or any defined ports or endpoints, therefore, you can use an ExternalName service to direct traffic to an external service.
我使用 kustomize
部署了一个简单的测试 ingress
和一个 externalName
service
。
部署有效,我得到了预期的结果,但是当 describing
和 test-ingress
时,它显示错误:<error: endpoints "test-external-service" not found>
。
这似乎是一个 k8s 错误。它显示此错误,但一切正常。
这是我的部署:
kustomization.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: platform
resources:
- test-ingress.yaml
- test-service.yaml
generatorOptions:
disableNameSuffixHash: true
test-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: test-external-service
namespace: platform
spec:
type: ExternalName
externalName: "some-working-external-elasticsearch-service"
test-ingress.yaml
:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: nginx-external
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_cache_bypass $http_upgrade;
spec:
rules:
- host: testapi.mydomain.com
http:
paths:
- path: /
backend:
serviceName: test-external-service
servicePort: 9200
在这里,我将外部服务连接到工作中的 elasticsearch
服务器。当浏览到 testapi.mydomain.com
(“mydomain”当然被我们的真实域替换)时,我得到了众所周知的预期 elasticsearch
结果:
{
"name" : "73b40a031651",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "Xck-u_EFQ0uDHJ1MAho4mQ",
"version" : {
"number" : "7.10.1",
"build_flavor" : "oss",
"build_type" : "docker",
"build_hash" : "1c34507e66d7db1211f66f3513706fdf548736aa",
"build_date" : "2020-12-05T01:00:33.671820Z",
"build_snapshot" : false,
"lucene_version" : "8.7.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
所以一切正常。但是在描述test-ingress
的时候出现如下错误:
test-external-service:9200 (<error: endpoints "test-external-service" not found>)
这是什么错误?为什么我得到它,即使一切正常?我在这里错过了什么?
服务是一种 Kubernetes 抽象,它使用标签来选择 pods 将流量路由到。
端点跟踪服务向其发送流量的对象的 IP 地址。当服务选择器匹配 pod 标签时。
这是类型为 ClusterIP、NodePort 或 LoadBalancer 的 Kubernetes 服务的情况。
对于您的情况,您使用类型为 ExternalName 的 Kubernetes 服务,其中端点是集群外部或不同命名空间中的服务器,因此当您尝试描述入口时,kubernetes 会显示该错误消息。
通常我们不会创建指向 ExternalName 类型服务的入口,因为我们不应该向外部公开已经公开的服务。 kubernetes ingress 需要 ClusterIP、NodePort 或 LoadBalancer 类型的服务,这就是为什么您在描述 ingress 时遇到意外错误的原因。
如果您在集群内浏览该 ExternalName,最好避免使用入口并改用服务 uri (test-external-service.
总之如果你坚持使用Ingress,你可以创建一个Headless service without selector and then manually create an endpoint using the same name as of the service. Follow the example here
这就是 kubectl describe ingress
命令的工作原理。
kubectl describe ingress
命令调用describeIngressV1beta1 function, which calls the describeBackendV1beta1函数描述后端。
在 source code, the describeBackendV1beta1 函数中可以找到查找与后端服务关联的端点,如果找不到合适的端点,则会生成一条错误消息(如您的示例所示):
func (i *IngressDescriber) describeBackendV1beta1(ns string, backend *networkingv1beta1.IngressBackend) string {
endpoints, err := i.client.CoreV1().Endpoints(ns).Get(context.TODO(), backend.ServiceName, metav1.GetOptions{})
if err != nil {
return fmt.Sprintf("<error: %v>", err)
}
...
在 Integrating External Services 文档中,您可以发现 ExternalName
服务没有任何已定义的端点:
ExternalName services do not have selectors, or any defined ports or endpoints, therefore, you can use an ExternalName service to direct traffic to an external service.