EKS:如何在 eks cloudmap 中注册动态生成的 eks loadbalancer dns?

EKS: how to register dynamic generated eks loadbalancer dns in eks cloudmap?

我有一个我使用过的kafka外部服务type: Loadbalancer

问题:此服务将始终在 uninstall/delete 之后创建新的负载均衡器。

用例:我想在aws cloud-map中针对一个静态DNS注册负载均衡器的dns。

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
    service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-internal: "true"
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
  name: kafka-test-3-1-external
  labels:
    helm.sh/chart: kafka-0.21.5
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: kafka-broker
    app.kubernetes.io/name: kafka
    app.kubernetes.io/instance: kafka-test-3
    pod: "kafka-test-3-1"
spec:
  type: LoadBalancer
  ports:
    - name: external-broker
      port: 19092
      targetPort: 19092
      protocol: TCP
#
  selector:
    app.kubernetes.io/component: kafka-broker
    app.kubernetes.io/name: kafka
    app.kubernetes.io/instance: kafka-test-3
    statefulset.kubernetes.io/pod-name: "kafka-test-3-1"

我该怎么做?

您可以在您的服务中使用以下注释

external-dns.alpha.kubernetes.io/hostname: "kafka-test-3-1.kafka.internal"
external-dns.alpha.kubernetes.io/ttl: "60"

其中 kafka.internal 是我的云地图命名空间。

所以服务看起来像下面的片段。

apiVersion: v1
kind: Service
metadata:
  annotations:
    external-dns.alpha.kubernetes.io/hostname: "kafka-test-3-1.kafka.internal"
    external-dns.alpha.kubernetes.io/ttl: "60"
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
    service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-internal: "true"
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
  name: kafka-test-3-1-external
  labels:
    helm.sh/chart: kafka-0.21.5
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: kafka-broker
    app.kubernetes.io/name: kafka
    app.kubernetes.io/instance: kafka-test-3
    pod: "kafka-test-3-1"
spec:
  type: LoadBalancer
  ports:
    - name: external-broker
      port: 19092
      targetPort: 19092
      protocol: TCP
#
  selector:
    app.kubernetes.io/component: kafka-broker
    app.kubernetes.io/name: kafka
    app.kubernetes.io/instance: kafka-test-3
    statefulset.kubernetes.io/pod-name: "kafka-test-3-1"

要将服务loadbalancer的dns注册到cloud-map,我们需要使用external-dns服务。

注意:您必须在 cloudmap 中创建命名空间。并为您的 kubernetes 用户提供足够的访问权限。

要使用 AWS Cloud Map API,用户必须有权创建 DNS 命名空间。此外,您需要确保您的节点(运行外部 DNS 的节点)具有附加了 AWSCloudMapFullAccess 托管策略的 IAM 实例配置文件,该策略提供以下权限:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "route53:GetHostedZone",
        "route53:ListHostedZonesByName",
        "route53:CreateHostedZone",
        "route53:DeleteHostedZone",
        "route53:ChangeResourceRecordSets",
        "route53:CreateHealthCheck",
        "route53:GetHealthCheck",
        "route53:DeleteHealthCheck",
        "route53:UpdateHealthCheck",
        "ec2:DescribeVpcs",
        "ec2:DescribeRegions",
        "servicediscovery:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

在应用下面的代码片段之前,替换占位符

  • YOUR_NAMESPACE:使用您的 kubernetes 集群命名空间,如默认值
  • AWS_REGION_VALUE: ap-south-1
  • DOMAIN_FILTER: 必须是你的cloudmap命名空间的名称。在我的例子中是 kafka.internal

片段: external-dns

apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: external-dns
rules:
- apiGroups: [""]
  resources: ["services","endpoints","pods"]
  verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get","watch","list"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
- kind: ServiceAccount
  name: external-dns
  namespace: YOUR_NAMESPACE
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: k8s.gcr.io/external-dns/external-dns:v0.7.6
        env:
          - name: AWS_REGION
            value: AWS_REGION_VALUE # ap-south-1 put your CloudMap NameSpace region
        args:
        - --source=service
        - --source=ingress
        - --domain-filter=DOMAIN_FILTER # Makes ExternalDNS see only the namespaces that match the specified domain. Omit the filter if you want to process all available namespaces.
        - --provider=aws-sd
        - --aws-zone-type=private # Only look at public namespaces. Valid values are public, private, or no value for both)
        - --txt-owner-id=kafka-identifier

External-dns pod 将轮询 kubernetes 服务中的更改,如果发现任何更改,它将使用 external-dns.alpha.kubernetes.io/hostname 注释将该负载均衡器的 dns 映射到云映射命名空间.

有关自动注册的更多详细信息, https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws-sd.md