Базовая балансировка TCP/UDP-трафика#

Ниже приведен пример развертывания DNS-сервера в кластере и настройки балансировки TCP- и UDP-трафика для него с использованием ресурса TransportServer. ANIC будет передавать все соединения или датаграммы, поступающие на порт 5353, в поды DNS-сервера.

Предварительные действия#

  1. Установите ANIC:

    • Убедитесь, что ресурс GlobalConfiguration развернут и ANIC использует его.

    • Откройте порт 5353 как для TCP, так и для UDP-трафика.

  2. Сохраните публичный IP-адрес ANIC в переменной оболочки:

    $ IC_IP=XXX.YYY.ZZZ.III
    
  3. Сохраните порт 5353 ANIC в переменной оболочки:

    $ IC_5353_PORT=<номер порта>
    

    Примечание

    Если вы хотите настроить ANIC с помощью сервиса LoadBalancer, то в нем нельзя использовать протоколы TCP и UDP одновременно. В этом случае создайте два отдельных сервиса: для TCP и для UDP. Соответственно, у вас будет два разных публичных IP-адреса (см. примеры на последнем шаге).

  4. Убедитесь, что у вас установлена утилита dig (используется для тестирования).

    Примечание

    В процессе установки ANIC ресурс GlobalConfiguration должен быть развернут в пространстве имен angie-ingress с именем angie-configuration. Если это не так, обновите файл global-configuration.yaml, указав правильные пространство имен и имя.

Балансировка TCP/UDP-трафика#

  1. Разверните DNS-сервер:

    • Разверните две реплики CoreDNS, настроенные на пересылку DNS-запросов на 8.8.8.8.

    • Создайте сервис coredns, который откроет порт 5353 как для TCP, так и для UDP.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns
    data:
      Corefile: |
        .:5353 {
          forward . 8.8.8.8:53
          log
        }
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: coredns
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: coredns
      template:
        metadata:
          labels:
            app: coredns
        spec:
          containers:
          - name: coredns
            image: coredns/coredns:1.10.0
            args: [ "-conf", "/etc/coredns/Corefile" ]
            volumeMounts:
            - name: config-volume
              mountPath: /etc/coredns
              readOnly: true
            ports:
            - containerPort: 5353
              name: dns
              protocol: UDP
            - containerPort: 5353
              name: dns-tcp
              protocol: TCP
            securityContext:
              readOnlyRootFilesystem: true
          volumes:
            - name: config-volume
              configMap:
                name: coredns
                items:
                - key: Corefile
                  path: Corefile
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: coredns
    spec:
      selector:
       app: coredns
      ports:
      - name: dns
        port: 5353
        protocol: UDP
      - name: dns-tcp
        port: 5353
        protocol: TCP
    

    Примените настройки:

    $ kubectl apply -f dns.yaml
    
  2. Настройте слушатели.

    Обновите ресурс GlobalConfiguration, добавив два слушателя: один для TCP-порта 5353 и один для UDP-порта 5353:

    apiVersion: k8s.angie.software/v1alpha1
    kind: GlobalConfiguration
    metadata:
      name: angie-configuration
      namespace: angie-ingress
    spec:
      listeners:
      - name: dns-udp
        port: 5353
        protocol: UDP
      - name: dns-tcp
        port: 5353
        protocol: TCP
    

    Примените настройки:

    $ kubectl apply -f global-configuration.yaml
    
  3. Проверьте, что конфигурация успешно применена, просмотрев события GlobalConfiguration:

    $ kubectl describe gc angie-configuration -n angie-ingress
    

    Пример вывода:

    Events:
      Type    Reason   Age               From  Message
      ----    ------   ----              ----  -------
      Normal  Updated  0s (x2 over 10s)  anic  GlobalConfiguration anic/angie-configuration was updated
    
  4. Настройте балансировку нагрузки.

    Создайте ресурс TransportServer, чтобы настроить балансировку TCP:

    apiVersion: k8s.angie.software/v1alpha1
    kind: TransportServer
    metadata:
      name: dns-tcp
    spec:
      listener:
        name: dns-tcp
        protocol: TCP
      upstreams:
      - name: dns-app
        service: coredns
        port: 5353
      action:
        pass: dns-app
    

    Примените настройки:

    $ kubectl apply -f transport-server-tcp.yaml
    
  5. Проверьте, что конфигурация успешно применена:

    $ kubectl describe ts dns-tcp
    

    Пример вывода:

    Events:
      Type    Reason          Age   From  Message
      ----    ------          ----  ----  -------
      Normal  AddedOrUpdated  3s    anic  Configuration for default/dns-tcp was added or updated
    
  6. Создайте ресурс TransportServer, чтобы настроить балансировку UDP:

    apiVersion: k8s.angie.software/v1alpha1
    kind: TransportServer
    metadata:
      name: dns-udp
    spec:
      listener:
        name: dns-udp
        protocol: UDP
      upstreams:
      - name: dns-app
        service: coredns
        port: 5353
      upstreamParameters:
        udpRequests: 1
        udpResponses: 1
      action:
        pass: dns-app
    

    Примените настройки:

    $ kubectl apply -f transport-server-udp.yaml
    
  7. Проверьте, что конфигурация успешно применена:

    $ kubectl describe ts dns-udp
    

    Пример вывода:

    Events:
      Type    Reason          Age   From  Message
      ----    ------          ----  ----  -------
      Normal  AddedOrUpdated  0s    anic  Configuration for default/dns-udp was added or updated
    
  8. Протестируйте конфигурацию.

    Чтобы проверить, что настроенный балансировщик нагрузки TCP/UDP работает, разрешите DNS-имя kubernetes.io с помощью DNS-сервера.

    Разрешение kubernetes.io через TCP:

    $ dig @$IC_IP -p $IC_5353_PORT kubernetes.io +tcp
    
    ; <<>> DiG 9.10.3-P4-Debian <<>> @<REDACTED> -p 5353 kubernetes.io +tcp
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44784
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;kubernetes.io.                 IN      A
    
    ;; ANSWER SECTION:
    kubernetes.io.          3596    IN      A       147.75.40.148
    
    ;; Query time: 134 msec
    ;; SERVER: <REDACTED>#5353(<REDACTED>)
    ;; WHEN: Thu Mar 12 22:01:55 UTC 2020
    ;; MSG SIZE  rcvd: 71
    

    Разрешение kubernetes.io через UDP:

    $ dig @$IC_IP -p $IC_5353_PORT kubernetes.io
    
    ; <<>> DiG 9.10.3-P4-Debian <<>> @<REDACTED> -p 5353 kubernetes.io
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39087
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;kubernetes.io.                 IN      A
    
    ;; ANSWER SECTION:
    kubernetes.io.          2157    IN      A       147.75.40.148
    
    ;; Query time: 134 msec
    ;; SERVER: <REDACTED>#5353(<REDACTED>)
    ;; WHEN: Thu Mar 12 22:02:12 UTC 2020
    ;; MSG SIZE  rcvd: 71