TCP- и UDP-балансировка для DNS#
В этом примере разворачивается ANIC и DNS-сервер, а затем настраивается балансировка TCP и UDP
для DNS-сервиса с использованием ключа stream-snippets
в ConfigMap.
Стандартные ресурсы Ingress в Kubernetes предполагают, что используется HTTP-трафик,
и не предназначены для обработки TCP- или UDP-трафика, поэтому,
чтобы встроить необходимую конфигурацию балансировки TCP/UDP в блок stream {}
,
используется ключ stream-snippets
из ConfigMap.
В ANIC можно использовать headless-сервис и его DNS-имя, чтобы получить реальные IP-адреса подов и балансировать нагрузку между ними. ANIC регулярно заново разрешает DNS-имя, чтобы автоматически обновлять его при добавлении или удалении подов.
Примечание
Для тестирования используется утилита dig. Убедитесь, что она установлена.
Для настройки TCP/UDP-балансировки используется родная конфигурация Angie.
Установите ANIC. Убедитесь, что порт 5353 открыт как для TCP-, так и для UDP-трафика.
Сохраните публичный IP-адрес ANIC в переменной оболочки:
$ IC_IP=<ваш_IP-адрес>
Сохраните порт 5353, используемый ANIC, в переменной оболочки:
$ IC_5353_PORT=<номер порта>
Примечание
Если вы хотите настроить ANIC с помощью сервиса
LoadBalancer
, то в нем нельзя использовать протоколы TCP и UDP одновременно. В этом случае создайте два отдельных сервиса: для TCP и для UDP. Соответственно, у вас будет два разных публичных IP-адреса (см. примеры ниже).Разверните DNS-сервер:
Разверните две реплики
CoreDNS
, настроенные на пересылку DNS-запросов на8.8.8.8
.Создайте два сервиса —
coredns
иcoredns-headless
.
Пример
apiVersion: v1 kind: ConfigMap metadata: name: coredns data: Corefile: | .:53 { 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: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP securityContext: allowPrivilegeEscalation: false capabilities: add: - NET_BIND_SERVICE drop: - all 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: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: coredns-headless spec: clusterIP: None selector: app: coredns ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
Примените настройки:
$ kubectl apply -f dns.yaml
Создайте конфигурацию балансировки нагрузки. В примере настраиваются два сервера: один принимает TCP-трафик на порту 5353, а второй — UDP-трафик на том же порту. Оба сервера балансируют входящий трафик между подами CoreDNS.
Пример
kind: ConfigMap apiVersion: v1 metadata: name: angie-config namespace: angie-ingress data: stream-snippets: | resolver kube-dns.kube-system.svc.cluster.local valid=5s; upstream coredns-udp { zone coredns-udp 64k; server coredns-headless.default.svc.cluster.local service=_dns._udp resolve; } server { listen 5353 udp; listen [::]:5353 udp; proxy_pass coredns-udp; proxy_responses 1; status_zone coredns-udp; } upstream coredns-tcp { zone coredns-tcp 64k; server coredns-headless.default.svc.cluster.local service=_dns-tcp._tcp resolve; } server { listen 5353; listen [::]:5353; proxy_pass coredns-tcp; status_zone coredns-tcp; }
ANIC поддерживает повторное разрешение DNS-имен с помощью параметра
resolve
в директивеupstream
. При использовании параметраresolve
, ANIC не завершит перезагрузку с ошибкой, если имя upstream-хоста не удается разрешить.Помимо IP-адресов, ANIC также может получать порты через DNS-записи типа SRV.
Для разрешения IP-адресов и портов ANIC использует Kube-DNS, который указывается в директиве
resolver
. Также устанавливается параметрvalid=5s
, чтобы ANIC повторно разрешал DNS-имена каждые 5 секунд.Вместо обычного сервиса
coredns
используетсяcoredns-headless
. Этот сервис создается как headless-сервис, то есть ему не выделяется виртуальный IP, и ANIC может разрешить все реальные IP-адреса подов CoreDNS.Примечание
ANIC завершит перезагрузку с ошибкой, если DNS-имя, указанное в директиве
resolver
, не может быть разрешено. Чтобы избежать этого, рекомендуется использовать виртуальный IP-адрес сервиса kube-dns вместо его DNS-имени.Обновите ConfigMap, добавив ключ
stream-snippets
с конфигурацией балансировки нагрузки.Используется ключ
stream-snippets
в объекте ConfigMap, чтобы настроить балансировку TCP- и UDP-трафика для наших подов CoreDNS.Примените настройки:
$ kubectl apply -f angie-config.yaml
Проверьте, что конфигурация успешно применена:
$ kubectl describe configmap angie-config -n angie-ingress . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Updated 3s ANIC Configuration from angie-ingress/angie-config was updated
Протестируйте DNS-сервер.
Чтобы проверить, что балансировка TCP/UDP работает, выполните разрешение имени
kubernetes.io
с использованием нашего DNS-сервера, доступного через ANIC.Разрешение
kubernetes.io
через UDP:$ dig @$IC_IP -p $IC_5353_PORT kubernetes.io ; <<>> DiG 9.10.6 <<>> @<REDACTED>> -p 5353 kubernetes.io ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33368 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;kubernetes.io. IN A ;; ANSWER SECTION: kubernetes.io. 299 IN A 45.54.44.100 ;; Query time: 111 msec ;; SERVER:<REDACTED>#5353(<REDACTED>) ;; WHEN: Fri Aug 17 12:49:54 BST 2018 ;; MSG SIZE rcvd: 71
Разрешение
kubernetes.io
через TCP:$ dig @$IC_IP -p $IC_5353_PORT kubernetes.io +tcp ; <<>> DiG 9.10.6 <<>> @<REDACTED> -p 5353 kubernetes.io +tcp ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49032 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;kubernetes.io. IN A ;; ANSWER SECTION: kubernetes.io. 146 IN A 45.54.44.100 ;; Query time: 95 msec ;; SERVER: <REDACTED>#5353(<REDACTED>) ;; WHEN: Fri Aug 17 12:52:25 BST 2018 ;; MSG SIZE rcvd: 71 Look at the Ingress Controller logs: $ kubectl logs <angie-ingress-pod> -n angie-ingress . . . <REDACTED> [17/Aug/2018:11:49:54 +0000] UDP 200 71 42 0.016 <REDACTED> [17/Aug/2018:11:52:25 +0000] TCP 200 73 44 0.098
Посмотрите логи:
$ kubectl logs <angie-ingress-pod> -n angie-ingress . . . <REDACTED> [17/Aug/2018:11:49:54 +0000] UDP 200 71 42 0.016 <REDACTED> [17/Aug/2018:11:52:25 +0000] TCP 200 73 44 0.098