微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

未找到 k8s ExternalName 端点 - 但工作正常

如何解决未找到 k8s ExternalName 端点 - 但工作正常

我使用 ingress 部署了一个简单的测试 externalName一个 service kustomize。 部署有效,我得到了预期的结果,但是当 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>)

这是什么错误?为什么即使一切正常,我还是得到它?我在这里错过了什么?

解决方法

这就是 kubectl describe ingress 命令的工作原理。
kubectl describe ingress 命令调用 describeIngressV1beta1 函数,该函数调用 describeBackendV1beta1 函数来描述后端。

source code 中可以找到,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 服务没有选择器,也没有任何定义的端口或端点,因此,您可以使用 ExternalName 服务将流量定向到外部服务。

,

服务是一种 Kubernetes 抽象,它使用标签来选择要将流量路由到的 Pod。

端点跟踪服务向其发送流量的对象的 IP 地址。当服务选择器与 pod 标签匹配时。

这就是类型为 ClusterIP、NodePort 或 LoadBalancer 的 Kubernetes 服务的情况。

对于您的情况,您使用类型为 ExternalName 的 Kubernetes 服务,其中端点是集群外部或不同命名空间中的服务器,因此当您尝试描述入口时,kubernetes 会显示该错误消息。

通常我们不会创建指向 ExternalName 类型服务的入口,因为我们不应该向外部公开它已经公开的服务。 kubernetes 入口需要类型为 ClusterIP、NodePort 或 LoadBalancer 的服务,这就是您在描述入口时遇到意外错误的原因。

如果您在集群中浏览该 ExternalName,最好避免使用入口并使用服务 uri (test-external-service..svc.cluster.local:9200)

无论如何,如果您坚持使用 Ingress,您可以创建一个没有选择器的 Headless service,然后使用与服务相同的名称手动创建一个端点。按照示例 here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。