Serviço de Kubernetes visível externamente no Azure

3

Estou implantando uma pilha ELK em um cluster do Kubernetes (v1.4.5) no Azure. Esta é a configuração que cria o Kibana Service e 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

Eu implanto via kubectl apply -f deployment.yml . Limpo toda a pilha ELK via kubectl delete namespace logging .
Há um balanceador de carga no Azure, com pool de back-end dos agentes k8s. Quando eu implantar, um ip público e uma regra são adicionados ao balanceador de carga. E eu posso acessar Kibana no meu navegador usando seu endereço IP do pool Parte frontal de endereços do balanceador de carga.

E aqui está o problema 1) e eu quero alcançar 2):

  1. Toda vez que eu kubect apply , um novo endereço IP e regra são adicionados ao pool front-end do balanceador de carga. Estranhamente, o anterior Endereços IP e regras ainda estão lá (mesmo que eu execute kubectl delete namespace logging antes de implantar, o que sugere que os endereços IP e regras usados anteriormente devem ser liberados. Eu verifiquei o código aqui e, tanto quanto eu posso ver, existem funções que garantem que não há endereços IP públicos obsoletos e regras de balanceamento de carga). Endereços IP adicionados a partir de implantações anteriores não podem acessar o serviço Kibana atualmente implantado.
  2. Eu quero ter um nome DNS que os clientes (por exemplo, meu navegador < - > kibana, servidor de gravação em log < - > logstash) da pilha ELK possam usar para se referir aos serviços ELK sem precisar codificar endereços IP nos clientes (portanto, as reimplementações da pilha ELK são transparentes para os clientes).

O que eu tentei até agora: criei manualmente um endereço IP público com um nome de DNS pelo Painel do Azure. Adicionei as regras de balanceamento de carga ao Balanceador de carga, que são semelhantes às criadas automaticamente em kubectl apply . Tentei usar esse IP público criado manualmente na especificação do serviço kibana em externalIPs e, em seguida, em loadBalancerIP ( k8s docs )

Quando o external IPs é definido para o IP público, kubectl describe service --namespace=logging retorna

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

No entanto, as solicitações para o nome do DNS ou diretamente para o tempo limite externo do IP. Quando eu defino o loadBalancerIP na especificação do Serviço, kubectl describe service retorna uma saída semelhante, mas sem a linha IPs Externos, e novamente, um novo endereço IP público + regras são criadas no balanceador de carga. Novamente, não é possível usar o nome do DNS / ip do IP público que criei manualmente.

Qualquer ajuda seria muito apreciada:)

    
por Joro Tenev 08.03.2017 / 13:02

1 resposta

2

Ah. O mais fácil é evitar a exclusão do serviço antes de cada implantação. Na minha experiência, os serviços tendem a ser muito duradouros; eles fornecem uma maneira boa e fixa de se referir a coisas sem ter que se preocupar com valores dinâmicos para portas, ips, dns, etc.

Na especificação de serviço Kibana, remova a entrada nodePort da configuração da porta, para que o serviço possa fazer sua própria coisa; uma coisa a menos para pensar. Não defina valores para loadBalancerIP ou externalIPs. As mesmas regras se aplicam aos outros serviços.

Para os arquivos de configuração da pilha ELK (não me lembro da aparência deles), consulte outros componentes pelos nomes de serviço: não é necessário usar IPs codificados ou algo do tipo. (Não faço ideia se você estava fazendo isso, mas apenas no caso.)

Permite que os serviços sejam criados; obtenha o IP externo do balanceador de carga e conecte-o à sua configuração de DNS.

Você pode continuar usando namespaces se preferir fazer as coisas, mas não excluir todo o namespace para limpar os componentes Deployments for ELK.

Divida sua especificação de pilha ELK em arquivos separados para Implantações e Serviços (tecnicamente, não tenho certeza se isso é necessário; talvez você consiga se safar), para poder usar:

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

ou um comando similar para atualizar as implantações sem incomodar os serviços.

Se você precisar (ou preferir) excluir a pilha ELK de outra maneira antes de criar uma nova, também poderá usar:

kubectl -n logging delete deployments --all

para excluir todas as implantações no namespace de registro. Para mim, essa opção parece um pouco mais perigosa do que precisa ser.

Uma segunda opção seria:

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

Se você não se importa com a digitação extra

Outra opção seria adicionar um novo marcador, algo como:

role: application

ou

stack: ELK

para cada uma das especificações de implantação. Do que você pode usar:

kubectl delete deployments -l stack=ELK

para limitar o escopo da exclusão ... mas, novamente, isso parece perigoso.

A minha preferência seria, a menos que houvesse alguma razão imperiosa para não dividir a configuração em arquivos > 2 e usar:

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

para ajudar a evitar quaisquer acidentes induzidos por erros tipográficos.

Eu desmembramento um pouco mais, com uma pasta separada para cada componente que contém uma implantação e um serviço, aninhados juntos como faz sentido (mais fácil de manter em um repositório, mais fácil se mais de uma pessoa precisar fazer alterações em componentes relacionados, mas separados), e geralmente com scripts bash create / destroy para fornecer algo como documentação ... mas você tem a idéia.

Configure desta forma, você deve ser capaz de atualizar qualquer um ou todos os componentes de implantação sem quebrar sua configuração de DNS / balanceamento de carga.

(Claro, isso tudo supõe que ter tudo em um arquivo não é um tipo de exigência difícil ... nesse caso, não tenho uma boa resposta para você do alto da minha cabeça. .)

    
por 10.03.2017 / 01:05