O roteamento interno do cluster do Kubernetes não está funcionando (serviço NodePort)

1

Estou trabalhando na criação de um cluster do Kubernetes por enquanto. Minha configuração possui dois nós e um mestre. Todas as três máquinas estão sendo executadas em um cluster Proxmox e possuem duas interfaces de rede virtual. Uma das interfaces (listadas abaixo) está em uma rede interligada com as outras máquinas. O outro é exposto a uma rede interna.

A configuração da rede é semelhante às interfaces em ponte:

Network: 10.10.0.0  
Broadcast: 10.10.255.255  
Netmask: 255.255.0.0  

kubernetes-master IP: 10.10.0.1
kubernetes-worker01 IP: 10.10.0.2
kubernetes-worker02 IP: 10.10.0.3

Todos os servidores podem conversar entre si sem problemas. Ainda não configurei nenhum tipo de firewall.

root@kubernetes-master:~/manifests# kubectl get nodes
NAME        STATUS    AGE
10.10.0.2   Ready     5d
10.10.0.3   Ready     5d

Eu tenho um aplicativo Hello World nodeJS que fornece um servidor HTTP na porta 8080 e exibe "Hello world" quando consultado. Está configurado assim:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-node-deployment
spec:
  replicas: 4
  template:
    metadata:
      labels:
        app: hello-node
    spec:
      containers:
      - name: hello-node
        image: kubernetes-master:5000/hello-node:v1
        ports:
        - containerPort: 8080

Em seguida, criei um novo serviço que deve expor a implantação por meio do NodePort.

apiVersion: v1
kind: Service
metadata:
  name: hello-node-service
  labels:
    app: hello-node
spec:
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: hello-node
  type: NodePort

Depois de iniciar o serviço e a implantação:

root@kubernetes-master:~/manifests# kubectl describe service hello-node-service
Name:           hello-node-service
Namespace:      default
Labels:         app=hello-node
Selector:       app=hello-node
Type:           NodePort
IP:         10.100.0.88
Port:           <unset> 8080/TCP
NodePort:       <unset> 30862/TCP
Endpoints:      192.168.0.22:8080,192.168.0.23:8080,192.168.0.89:8080 + 1 more...
Session Affinity:   None
No events.

root@kubernetes-master:~/manifests# kubectl get pods --selector="app=hello-node" --output=wide
NAME                                    READY     STATUS    RESTARTS   AGE       IP             NODE
hello-node-deployment-815057587-0w896   1/1       Running   0          24m       192.168.0.89   10.10.0.2
hello-node-deployment-815057587-62d2b   1/1       Running   0          24m       192.168.0.23   10.10.0.3
hello-node-deployment-815057587-d6t4z   1/1       Running   0          24m       192.168.0.90   10.10.0.2
hello-node-deployment-815057587-k7qcx   1/1       Running   0          24m       192.168.0.22   10.10.0.3

Depois disso, o mestre não pode entrar em contato com nenhum dos nós na porta do nó fornecido (10.10.0.2:30862, 10.10.0.2:30862). A conexão trava e não tem sucesso.

Se eu me conectar ao nó via ssh, posso consultar com êxito o serviço falando diretamente com o pod:

root@kubernetes-worker02:~# curl http://192.168.0.22:8080
Hello World!

Estou sentindo falta de algo aqui? Esse é o comportamento esperado ou minha configuração está quebrada?

    
por Benjamin 28.01.2017 / 03:06

1 resposta

1

O Kubernetes requer mais do que apenas os nós capazes de falar uns com os outros. Também requer uma rede (ou tabela de roteamento) para que os pods possam se comunicar. É essencialmente outra rede apenas para os pods (geralmente chamada de rede overlay / underlay) que permite que o pod no nodeA converse com os pods no nodeB.

Da aparência, você não tem a rede do pod configurada. Você pode implementar redes de sobreposição de várias maneiras (que é uma das razões pelas quais é tão confuso). Leia mais sobre os requisitos de rede aqui .

Com apenas 2 nós, eu recomendaria que você configurasse o que eu gostaria de chamar de "no SDN Kubernetes" e apenas adicionasse manualmente as rotas do pod a cada nó. Isso exigiria que você fizesse duas coisas.

  1. Especifique a sub-rede para pods em cada nó
  2. Executar manualmente um comando para criar a rota

Eu tenho detalhes sobre como fazer isso no meu post que escrevi sobre o assunto .

Infelizmente, a configuração da rede de pods só vai te levar a metade do caminho. Para implementar serviços automáticos do NodePort, você também precisa instalar o kube-proxy. O trabalho do kube-proxy é observar em qual porta um serviço é iniciado e então rotear essa porta para o serviço / pod correto dentro do cluster. Ele faz isso por meio de tabelas de IP e é principalmente automático.

Não consegui encontrar um bom exemplo de implantação manual do kube-proxy (geralmente é feito através de sua ferramenta de implantação). Veja um exemplo de DaemonSet a ferramenta kubeadm deve ser criada automaticamente para executar o proxy-kube em cada nó no cluster.

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  generation: 1
  labels:
    component: kube-proxy
    k8s-app: kube-proxy
    kubernetes.io/cluster-service: "true"
    name: kube-proxy
    tier: node
  name: kube-proxy
  namespace: kube-system
spec:
  selector:
    matchLabels:
      component: kube-proxy
      k8s-app: kube-proxy
      kubernetes.io/cluster-service: "true"
      name: kube-proxy
      tier: node
  template:
    metadata:
      labels:
        component: kube-proxy
        k8s-app: kube-proxy
        kubernetes.io/cluster-service: "true"
        name: kube-proxy
        tier: node
    spec:
      containers:
      - command:
        - kube-proxy
        - --kubeconfig=/run/kubeconfig
        image: gcr.io/google_containers/kube-proxy-amd64:v1.5.2
        imagePullPolicy: IfNotPresent
        name: kube-proxy
        securityContext:
          privileged: true
        terminationMessagePath: /dev/termination-log
        volumeMounts:
        - mountPath: /var/run/dbus
          name: dbus
        - mountPath: /run/kubeconfig
          name: kubeconfig
      dnsPolicy: ClusterFirst
      hostNetwork: true
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      volumes:
      - hostPath:
          path: /etc/kubernetes/kubelet.conf
        name: kubeconfig
      - hostPath:
          path: /var/run/dbus
        name: dbus

Um outro recurso que pode ser útil é o Kubernetes the Hard Way . Ele não é diretamente aplicável à execução em VMs no proxmox (ele pressupõe o GCE ou o AWS), mas mostra as etapas mínimas e os recursos necessários para executar um cluster do Kubernetes em funcionamento.

    
por 30.01.2017 / 05:49