Come esporre il servizio kubernetes al pubblico senza hardcoding a minion IP?

voti
21

Ho un cluster kubernetes esecuzione con 2 servi. Attualmente faccio il mio servizio accessibile in 2 fasi:

  1. Inizia regolatore replica & pod
  2. Get IP minion (usando kubectl get minions) e impostarlo come publicIPs per il servizio.

Qual è la prassi consigliata per esporre servizio al pubblico? Il mio approccio sembra sbagliato perché ho hard-code l'IP-s dei singoli minion IP-s. Sembra anche di bypassare le funzionalità di bilanciamento del carico di servizi kubernetes perché i clienti avrebbero dovuto accedere ai servizi in esecuzione su singoli servitori direttamente.

Per configurare il controller di replica e pod io uso:

id: frontend-controller
kind: ReplicationController
apiVersion: v1beta1
desiredState:
  replicas: 2
  replicaSelector:
    name: frontend-pod
  podTemplate:
    desiredState:
      manifest:
        version: v1beta1
        id: frontend-pod
        containers:
          - name: sinatra-docker-demo
            image: madisn/sinatra_docker_demo
            ports:
              - name: http-server
                containerPort: 4567
    labels:
      name: frontend-pod

Per configurare il servizio (dopo aver ottenuto minion ip-s):

kind: Service
id: frontend-service
apiVersion: v1beta1
port: 8000
containerPort: http-server
selector:
  name: frontend-pod
labels:
  name: frontend
publicIPs: [10.245.1.3, 10.245.1.4]
È pubblicato 21/04/2015 alle 11:17
fonte dall'utente
In altre lingue...                            


5 risposte

voti
8

Come ho già detto nel commento di cui sopra, la createExternalLoadBalancer è l'astrazione appropriata che si sta cercando, ma purtroppo non è ancora implementato per tutti i fornitori di cloud, e in particolare per vagabonda, che si sta utilizzando a livello locale.

Una possibilità sarebbe quella di utilizzare gli IP pubblici per tutti i servitori del cluster per tutti i servizi che si desidera essere esternalizzato. Il traffico destinato al servizio finirà su uno dei servitori, dove verrà intercettata dal processo Kube-proxy e reindirizzato a un contenitore che corrisponde al selettore etichetta per il servizio. Questo potrebbe portare ad un salto in più attraverso la rete (se si terra su un nodo che non ha il pod in esecuzione a livello locale), ma per le applicazioni che non sono estremamente sensibili alla latenza di rete questo non sarà probabilmente evidente.

Risposto il 23/04/2015 a 04:36
fonte dall'utente

voti
7

Come Robert ha detto nella sua risposta questo è qualcosa che sta arrivando, ma purtroppo non è ancora disponibile.

Sono attualmente in esecuzione un cluster kubernetes sulla nostra rete datacenter. Ho 1 master e 3 servi tutti in esecuzione su CentOS 7 virtuali (vCenter). Il modo in cui ho trattato questo era quello di creare un server dedicato "Kube-proxy". Io fondamentalmente sto solo facendo funzionare il servizio Kube-Proxy (insieme con flanella per il networking) e poi l'assegnazione di indirizzi IP "pubblici" per la scheda di rete collegata a questo server. Quando dico pubblica intendo indirizzi sulla nostra rete datacenter locale. Poi, quando creo un servizio che vorrei accedere al di fuori del cluster ho appena impostato il valore publicIPs ad uno degli indirizzi IP disponibili sul server Kube-proxy. Quando qualcuno o qualcosa tenta di connettersi a questo servizio al di fuori del cluster che colpirà il Kube-proxy e quindi essere reindirizzato al corretto minion.

Anche se questo potrebbe sembrare un lavoro intorno, questo è in realtà simile a quello che ci si aspetta di accadere una volta sono venuti fuori con un costruito in soluzione a questo problema.

Risposto il 27/04/2015 a 00:48
fonte dall'utente

voti
1

Questo è per MRE. Non ho avuto abbastanza spazio nell'area dei commenti per pubblicare questa risposta così ho dovuto creare un'altra risposta. Spero che questo ti aiuti:

Abbiamo effettivamente allontanati dal kubernetes poiché questo distacco risposta. Se non ricordo male anche se tutto quello che ho davvero dovuto fare è stato eseguito il file eseguibile Kube-proxy su una CentOS VM dedicato. Ecco quello che ho fatto:

In primo luogo ho rimosso Firewalld e mettere in atto iptables. Kube-proxy si basa su iptables per gestire il NAT e reindirizzamenti.

In secondo luogo, è necessario installare flanneld in modo da poter disporre di una scheda ponte sulla stessa rete i servizi finestra mobile in esecuzione sui vostri servitori.

Poi quello che ho fatto è stato assegnare più indirizzi IP alla scheda di rete locale installato sulla macchina. Questi saranno gli indirizzi IP è possibile utilizzare quando la creazione di un servizio. Questi saranno gli indirizzi disponibili al di fuori del cluster.

Una volta che è tutto curato è possibile avviare il servizio proxy. Si collegherà al Maestro, e prendere un indirizzo IP per la rete di bridge di flanella. Poi sarà sincronizzare tutte le regole di iptables e si dovrebbe essere impostato. Ogni volta che un nuovo servizio si aggiunge creerà le regole proxy e replicare queste regole in tutti i tirapiedi (e il proxy). Finché è stato specificato un indirizzo IP disponibile sul server proxy allora che server proxy inoltrerà tutto il traffico per tale indirizzo IP verso la corretta minion.

Spero che questo è un po 'più chiaro. Ricorda però non sono stato parte del progetto kubernetes per circa 6 mesi, quindi non sono sicuro che cosa è cambiato sono state fatte da quando ho lasciato. Si potrebbe anche avere una funzione sul posto che gestisce questo genere di cose. Se non Speriamo che questo aiuta lo si ottiene curato.

Risposto il 20/12/2015 a 13:16
fonte dall'utente

voti
2

Se si sta eseguendo un cluster a livello locale, una soluzione che ho usato è stato quello di esporre il servizio sul tuo kubernetes nodi utilizzando la direttiva nodeport nella definizione del servizio e quindi round robin per ogni nodo del cluster con HAproxy.

Ecco cosa esporre il nodeport appare come segue:

apiVersion: v1
kind: Service
metadata:
  name: nginx-s
  labels:
    name: nginx-s
spec:
  type: NodePort
  ports:
    # must match the port your container is on in your replication controller
    - port: 80
      nodePort: 30000
  selector:
    name: nginx-s

Nota: il valore specificato deve essere compreso nell'intervallo configurato per le porte dei nodi. (Default: 30.000-32.767)

Ciò espone il servizio sulla data nodeport su ogni nodo del cluster. Poi ho creato una macchina separata della rete che esegue haproxy interna e un firewall che è raggiungibile esternamente sul nodeport specificato (s) che si desidera esporre.

Se si guarda al vostro tavolo nat su uno dei padroni di casa, si può vedere che cosa sta facendo.

root@kube01:~# kubectl create -f nginx-s.yaml
You have exposed your service on an external port on all nodes in your
cluster.  If you want to expose this service to the external internet, you may
need to set up firewall rules for the service port(s) (tcp:30000) to serve traffic.

See http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md for more details.
services/nginx-s
root@kube01:~# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
KUBE-PORTALS-CONTAINER  all  --  anywhere             anywhere             /* handle ClusterIPs; NOTE: this must be before the NodePort rules */
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL
KUBE-NODEPORT-CONTAINER  all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL /* handle service NodePorts; NOTE: this must be the last rule in the chain */

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
KUBE-PORTALS-HOST  all  --  anywhere             anywhere             /* handle ClusterIPs; NOTE: this must be before the NodePort rules */
DOCKER     all  --  anywhere            !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
KUBE-NODEPORT-HOST  all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL /* handle service NodePorts; NOTE: this must be the last rule in the chain */

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        anywhere

Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

Chain KUBE-NODEPORT-CONTAINER (1 references)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             /* default/nginx-s: */ tcp dpt:30000 redir ports 42422

Chain KUBE-NODEPORT-HOST (1 references)
target     prot opt source               destination
DNAT       tcp  --  anywhere             anywhere             /* default/nginx-s: */ tcp dpt:30000 to:169.55.21.75:42422

Chain KUBE-PORTALS-CONTAINER (1 references)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             192.168.3.1          /* default/kubernetes: */ tcp dpt:https redir ports 51751
REDIRECT   tcp  --  anywhere             192.168.3.192        /* default/nginx-s: */ tcp dpt:http redir ports 42422

Chain KUBE-PORTALS-HOST (1 references)
target     prot opt source               destination
DNAT       tcp  --  anywhere             192.168.3.1          /* default/kubernetes: */ tcp dpt:https to:169.55.21.75:51751
DNAT       tcp  --  anywhere             192.168.3.192        /* default/nginx-s: */ tcp dpt:http to:169.55.21.75:42422
root@kube01:~#

Particolarmente questa linea

DNAT       tcp  --  anywhere             anywhere             /* default/nginx-s: */ tcp dpt:30000 to:169.55.21.75:42422

E, infine, se si guarda al netstat, si può vedere Kube-proxy è in ascolto e in attesa di quel servizio su quella porta.

root@kube01:~# netstat -tupan | grep 42422
tcp6       0      0 :::42422                :::*                    LISTEN      20748/kube-proxy
root@kube01:~#

Kube-proxy in ascolto su una porta per ogni servizio, e fare la traduzione degli indirizzi di rete nella vostra sottorete virtuale che i vostri contenitori risiedono in. (Credo?) Ho usato flanella.


Per un cluster a due nodi, che la configurazione HAproxy potrebbe essere simile a questo:

listen sampleservice 0.0.0.0:80
    mode http
    stats enable
    balance roundrobin
    option httpclose
    option forwardfor
    server noname 10.120.216.196:30000 check
    server noname 10.155.236.122:30000 check
    option httpchk HEAD /index.html HTTP/1.0

E il servizio è ora raggiungibile sulla porta 80 tramite HAproxy. Se uno dei nodi scendere, i contenitori verranno spostati in un altro nodo grazie alla replica controller e HAproxy sarà unica strada per i nodi che sono vivi.

Sono curioso di ciò che altri hanno utilizzato metodi, però, è proprio quello che mi è venuta. Io di solito non post su stack overflow, quindi mi scuso se non sto seguendo le convenzioni o la formattazione corretta.

Risposto il 05/05/2016 a 00:15
fonte dall'utente

voti
0

È possibile utilizzare Ingress risorsa per consentire le connessioni esterne al di fuori di un cluster kubernetes per raggiungere i servizi cluster.

Supponendo che si dispone già di un baccello distribuito, è ora necessario una risorsa di servizio, ad esempio:

apiVersion: v1 kind: Service metadata: name: frontend-service labels: tier: frontend spec: type: ClusterIP selector: name: frontend-pod ports: - name: http protocol: TCP # the port that will be exposed by this service port: 8000 # port in a docker container; defaults to what "port" has set targetPort: 8000

E avete bisogno di una risorsa Ingress: apiVersion: extensions/v1beta1 kind: Ingress metadata: name: frontend-ingress spec: rules: - host: foo.bar.com http: paths: - path: / backend: serviceName: frontend-service # the targetPort from service (the port inside a container) servicePort: 8000 Al fine di essere in grado di utilizzare le risorse di Ingress, avete bisogno di qualche controllo ingresso distribuito.

Ora, a condizione che si conosce il padrone IP kubernetes, è possibile accedere all'applicazione di fuori di un cluster kubernetes con: curl http://<master_ip>:80/ -H 'Host: foo.bar.com'


Se si utilizza un po 'di server DNS, è possibile aggiungere questo record: foo.bar.com IN A <master_ip>o aggiungere questa riga al vostro /etc/hostsfile di: <master_ip> foo.bar.come ora si può semplicemente eseguire: curl foo.bar.com


Si noti che in questo modo si avrà sempre accesso foo.bar.comutilizzando la porta 80. Se si desidera utilizzare qualche altra porta, mi consiglia di utilizzare un servizio di tipo NodePort, solo per quella porta non-80 uno. Farà che porta risolvibile, non importa quale kubernetes VM IP si utilizza (ogni master o qualsiasi minion IP va bene). Esempio di tale servizio: apiVersion: v1 kind: Service metadata: name: frontend-service-ssh labels: tier: frontend spec: type: NodePort selector: name: frontend-pod ports: - name: ssh targetPort: 22 port: 22 nodePort: 2222 protocol: TCP E se avete <master_ip> foo.bar.comnel vostro / etc / hosts, allora si può accedere a:foo.bar.com:2222

Risposto il 28/03/2017 a 15:25
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more