Назад | Перейти на главную страницу

Внешне видимая служба Kubernetes в Azure

Я развертываю стек ELK в кластере Kubernetes (v1.4.5) в Azure. Это конфигурация, которая создает Kibana Service и Deployment.

# deployment.yml
---
apiVersion: v1
kind: Namespace
metadata:
  name: logging
---
# elasticsearch deployment and Service
---
# logstash Deployment and Service
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: kibana
  namespace: logging
spec:
  replicas: 1
  template:
    metadata:
      labels:
        component: kibana
    spec:
      containers:
      - name: kibana
        image: sebp/elk:521
        env:
          - name: "LOGSTASH_START"
            value: "0"
          - name: "ELASTICSEARCH_START"
            value: "0"
        ports:
        - containerPort: 5601
          name: ui
          protocol: TCP
        volumeMounts:
          - name: config-volume
            mountPath: '/opt/kibana/config/'
      volumes:
      - name: config-volume
        configMap:
          name: kibana-config
---
apiVersion: v1
kind: Service
metadata:
  name: kibana
  namespace: logging
  labels:
    component: kibana
spec:
  type: LoadBalancer
  ports:
  - port: 5601
    protocol: TCP
    targetPort: ui
    nodePort: 30257
  selector:
    component: kibana

Я развертываю через kubectl apply -f deployment.yml. Я очищаю весь стек ELK через kubectl delete namespace logging.
В Azure есть балансировщик нагрузки с внутренним пулом агентов k8s. При развертывании в подсистему балансировки нагрузки добавляются общедоступный IP-адрес и правило. И я могу получить доступ к кибане в своем браузере, используя ее IP-адрес из пула адресов переднего плана балансировщика нагрузки.

И вот проблема 1) и хочу добиться 2):

  1. Каждый раз, когда я kubect apply, а новый IP-адрес и правило добавляются в пул переднего плана балансировщика нагрузки. Как ни странно, предыдущие IP-адреса и правила все еще существуют (хотя я запускаю kubectl delete namespace logging перед развертыванием, что предполагает освобождение ранее используемых IP-адресов и правил. Я проверил код Вот и, насколько я понимаю, есть функции, которые гарантируют отсутствие устаревших общедоступных IP-адресов и правил балансировки нагрузки). IP-адреса, добавленные из предыдущих развертываний, не могут получить доступ к развернутой в настоящее время службе Kibana.
  2. Я хочу иметь DNS-имя, которое клиенты (например, мой браузер <-> kibana, генерирующий журнал сервер <-> logstash) из стека ELK могут использовать для ссылки на службы ELK без необходимости жесткого кодирования IP-адресов в клиентах (так что повторное развертывание стека ELK прозрачно для клиентов).

То, что я пробовал до сих пор: я создал вручную общедоступный IP-адрес с именем DNS через панель мониторинга Azure. Я добавил в подсистему балансировки нагрузки правила балансировки нагрузки, похожие на те, которые созданы автоматически на kubectl apply. Я попытался использовать этот созданный вручную общедоступный IP-адрес в спецификации службы kibana в разделе externalIPs а затем под loadBalancerIP (k8s документы).
Если для externalIP задан общедоступный IP-адрес, kubectl describe service --namespace=logging возвращается

Name:           kibana
Namespace:      logging
Labels:         component=kibana
Selector:       component=kibana
Type:           LoadBalancer
IP:         10.x.xxx.xx
External IPs:       52.xxx.xxx.xxx   <- this is the IP I manually created
LoadBalancer Ingress:   52.xxx.xxx.xxx
Port:           <unset> 5601/TCP
NodePort:       <unset> 30257/TCP
Endpoints:      10.xxx.x.xxx:5601
Session Affinity:   None
Events:
  FirstSeen LastSeen    Count   From            SubobjectPath   Type        Reason          Message
  --------- --------    -----   ----            -------------   --------    ------          -------
  15m       15m     1   {service-controller }           Normal      CreatingLoadBalancer    Creating load balancer
  14m       14m     1   {service-controller }           Normal      CreatedLoadBalancer Created load balancer

Однако запросы к имени DNS или напрямую к внешнему IP-адресу истекли. Когда я установил loadBalancerIP в спецификации сервиса, kubectl describe service возвращает аналогичный вывод, но без строки внешних IP-адресов, и снова новый общедоступный IP-адрес + правила создаются на балансировщике нагрузки. Опять же, невозможно использовать DNS-имя / IP-адрес публичного IP-адреса, который я создал вручную.

Любая помощь будет очень признательна :)

Ах. Проще всего было бы избежать удаления службы перед каждым развертыванием. По моему опыту, услуги, как правило, очень долговечны; они предоставляют удобный фиксированный способ обращения к вещам, не беспокоясь о динамических значениях портов, IPS, DNS и т. д.

В спецификации службы Kibana удалите запись nodePort из конфигурации порта, чтобы служба могла выполнять свои собственные функции; одной вещью меньше. Не устанавливайте значения для loadBalancerIP или externalIP. Те же правила применяются к другим сервисам.

Для файлов конфигурации стека ELK (я не припоминаю, как они выглядят), обращайтесь к другим компонентам по их именам служб: нет необходимости использовать жестко закодированные IP-адреса или что-то еще. (Не знаю, делали ли вы это, но на всякий случай.)

Разрешить создание сервисов; получите внешний IP-адрес балансировщика нагрузки и подключите его к конфигурации DNS.

Вы можете продолжать использовать пространства имен, если хотите, но не удаляйте все пространство имен, чтобы очистить развертывания для компонентов ELK.

Разделите спецификацию стека ELK на отдельные файлы для развертываний и служб (технически я не уверен, требуется ли это; возможно, вам удастся уйти), чтобы вы могли использовать:

kubectl delete -f logging-deployments.yaml
kubectl apply -f logging-deployments.yaml

или аналогичная команда для обновления развертываний, не беспокоя службы.

Если вам нужно (или вы предпочитаете) удалить стек ELK другим способом перед созданием нового, вы также можете использовать:

kubectl -n logging delete deployments --all

для удаления всех развертываний в пространстве имен журналирования. Мне этот вариант кажется немного более опасным, чем должен быть.

Второй вариант:

kubectl delete deployments kibana
kubectl delete deployments elasticsearch
kubectl delete deployments logstash

Если вы не против лишнего набора текста

Другой вариант - добавить новый ярлык, например:

role: application

или

stack: ELK

к каждой из спецификаций развертывания. Чем можно пользоваться:

kubectl delete deployments -l stack=ELK

чтобы ограничить объем удаления ... но опять же, это кажется опасным.


Я бы предпочел, если нет какой-либо основной причины не делать этого, разделить конфигурацию на> 2 файла и использовать:

kubectl create -f svc-logging.yaml
kubectl create -f deploy-logging.yaml
kubectl delete -f deploy-logging.yaml
kubectl apply -f deploy-logging.yaml
...  
etc

чтобы предотвратить любые неприятные происшествия, связанные с опечаткой.

Я разбиваю вещи немного дальше, с отдельной папкой для каждого компонента, который содержит развертывание и службу, вложенными вместе, что имеет смысл (проще сохранить в репо, проще, если более чем одному человеку нужно внести изменения в связанные, но отдельные компоненты), и обычно с помощью сценариев создания / уничтожения bash, чтобы предоставить что-то вроде документации ... но вы поняли идею.

Настроив таким образом, вы сможете обновлять любые или все компоненты развертывания, не нарушая конфигурацию DNS / балансировки нагрузки.

(Конечно, все это предполагает, что наличие всего в одном файле не является каким-то жестким требованием ... в этом случае у меня нет хорошего ответа для вас с головы до ног ...)