utilizar servicios requerimientos que principiantes para instalar enmilocalfunciona ejemplo como cluster kubernetes

servicios - ¿Cómo exponer el servicio de kubernetes al público sin codificación para miniar IP?



requerimientos para instalar kubernetes (5)

Como dijo Robert en su respuesta, esto es algo que se avecina, pero desafortunadamente todavía no está disponible.

Actualmente estoy ejecutando un clúster Kubernetes en nuestra red de centros de datos. Tengo 1 maestro y 3 minions todos corriendo en CentOS 7 virtuales (vcenter). La forma en que manejé esto fue crear un servidor dedicado "kube-proxy". Básicamente, solo ejecuto el servicio Kube-Proxy (junto con Flannel para redes) y luego asigno direcciones IP "públicas" al adaptador de red conectado a este servidor. Cuando digo público me refiero a direcciones en nuestra red de centros de datos locales. Luego, cuando creo un servicio al que me gustaría acceder fuera del clúster, simplemente establezco el valor de publicIPs en una de las direcciones IP disponibles en el servidor proxy de Kube. Cuando alguien o algo intenta conectarse a este servicio desde fuera del clúster, llegará al proxy kube y luego será redirigido al siervo adecuado.

Si bien esto puede parecer una solución alternativa, en realidad es similar a lo que esperaría que sucediera una vez que hayan encontrado una solución integrada para este problema.

Tengo un grupo de kubernetes corriendo con 2 minions. Actualmente hago accesible mi servicio en 2 pasos:

  1. Iniciar el controlador de replicación y el pod
  2. Obtenga minion IP (usando kubectl get minions ) y configúrelo como publicIPs para el Servicio.

¿Cuál es la práctica sugerida para exponer el servicio al público? Mi enfoque parece incorrecto porque codifico las IP-s de los IP-s de minions individuales. También parece pasar por alto las capacidades de equilibrio de carga de los servicios kubernetes porque los clientes tendrían que acceder a los servicios que se ejecutan directamente en los minions individuales.

Para configurar el controlador de replicación y el pod utilizo:

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

Para configurar el servicio (después de obtener 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]


Como mencioné en el comentario anterior, createExternalLoadBalancer es la abstracción adecuada que está buscando, pero desafortunadamente aún no está implementado para todos los proveedores de la nube, y en particular para vagrant, que está utilizando localmente.

Una opción sería usar las direcciones IP públicas para todos los minions en su grupo para todos los servicios que desea que se externalicen. El tráfico destinado al servicio terminará en uno de los minions, donde será interceptado por el proceso kube-proxy y redirigido a un pod que coincida con el selector de etiquetas para el servicio. Esto podría resultar en un salto adicional a través de la red (si aterriza en un nodo que no tiene el pod ejecutándose localmente) pero para las aplicaciones que no son extremadamente sensibles a la latencia de la red, esto probablemente no se notará.


Esto es para MrE. No tenía suficiente espacio en el área de comentarios para publicar esta respuesta, así que tuve que crear otra respuesta. Espero que esto ayude:

Nos hemos alejado de Kubernetes desde que publicamos esta respuesta. Si recuerdo correctamente, todo lo que tenía que hacer era ejecutar el ejecutable kube-proxy en una máquina virtual CentOS dedicada. Aquí esta lo que hice:

Primero quité Firewalld y puse iptables en su lugar. Kube-proxy se basa en iptables para manejar su redirección y NAT.

En segundo lugar, debes instalar flanneld para poder tener un adaptador de puente en la misma red que los servicios de Docker que se ejecutan en tus minions.

Entonces, lo que hice fue asignar varias direcciones IP al adaptador de red local instalado en la máquina. Estas serán las direcciones IP que puede utilizar al configurar un servicio. Estas serán las direcciones disponibles FUERA de su grupo.

Una vez que todo esté cuidado, puede iniciar el servicio proxy. Se conectará al maestro y tomará una dirección IP para la red del puente de franela. Luego sincronizará todas las reglas de IPtables y deberás configurarlas. Cada vez que se agrega un nuevo servicio, creará las reglas de proxy y replicará esas reglas en todos los minions (y su proxy). Siempre que haya especificado una dirección IP disponible en su servidor proxy, ese servidor proxy reenviará todo el tráfico para esa dirección IP al servidor correspondiente.

Espero que esto sea un poco más claro. Recuerde que no he sido parte del proyecto Kubernetes durante aproximadamente 6 meses, así que no estoy seguro de qué cambios se han hecho desde que me fui. Incluso pueden tener una característica en su lugar que maneja este tipo de cosas. Si no es de esperar, esto te ayuda a cuidarlo.


Puede utilizar el recurso Ingress para permitir que las conexiones externas desde fuera de un clúster Kubernetes lleguen a los servicios del clúster.

Suponiendo que ya tiene un Pod desplegado, ahora necesita un recurso de Servicio, por ejemplo:

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

Y necesita un recurso de 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 Para poder utilizar los recursos de Ingress, necesita un controlador de ingreso implementado.

Ahora, siempre que conozca su IP maestra Kubernetes, puede acceder a su aplicación desde fuera de un clúster Kubernetes con: curl http://<master_ip>:80/ -H ''Host: foo.bar.com''

Si usa algún servidor DNS, puede agregar este registro: foo.bar.com IN A <master_ip> o agregar esta línea a su /etc/hosts : <master_ip> foo.bar.com y ahora solo puede ejecutar: curl foo.bar.com

Tenga en cuenta que de esta manera siempre foo.bar.com a foo.bar.com usando el puerto 80. Si desea usar algún otro puerto, le recomiendo usar un Servicio de tipo NodePort, solo para ese puerto que no sea 80. Hará que el puerto se pueda resolver, independientemente de la IP de Kubernetes VM que uses (cualquier Master o cualquier Minion IP está bien). Ejemplo de un servicio de este tipo: 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 Y si tiene <master_ip> foo.bar.com en su archivo / etc / hosts, entonces puede acceder a: foo.bar.com:2222


Si está ejecutando un clúster localmente, una solución que utilicé fue exponer el servicio en sus nodos kubernetes mediante la directiva nodeport en su definición de servicio y luego redirigir a todos los nodos de su clúster con HAproxy.

Aquí es cómo se ve la exposición del nodo:

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: el valor que especifique debe estar dentro del rango configurado para los puertos de nodo. (predeterminado: 30000-32767)

Esto expone el servicio en el puerto de nodo dado en cada nodo de su grupo. Luego, configuro una máquina separada en la red interna que ejecuta haproxy y un firewall al que se puede acceder externamente en los puertos de puertos específicos que desea exponer.

Si observa su tabla nat en uno de sus hosts, puede ver lo que está haciendo.

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:~#

Particularmente esta linea

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

Y finalmente, si miras netstat, puedes ver que kube-proxy está escuchando y esperando ese servicio en ese puerto.

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

Kube-proxy escuchará en un puerto para cada servicio y realizará la traducción de la dirección de red a su subred virtual en la que residen sus contenedores. (¿Creo?) Usé franela.

Para un clúster de dos nodos, la configuración de HAproxy puede parecer similar a esto:

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

Y su servicio ahora es accesible en el puerto 80 a través de HAproxy. Si alguno de sus nodos se cae, los contenedores se moverán a otro nodo gracias a los controladores de replicación y HAproxy solo se enrutará a los nodos que estén vivos.

Sin embargo, tengo curiosidad por saber qué métodos han usado otros, eso es justo lo que se me ocurrió. Normalmente no publico en el desbordamiento de pila, así que disculpas si no sigo las convenciones o el formato correcto.