Exponga los puertos 80 y 443 en Google Container Engine sin balanceador de carga

23

Actualmente estoy trabajando en un pequeño proyecto de pasatiempo que haré de código abierto una vez que esté listo. Este servicio se ejecuta en Google Container Engine. Elegí GCE para evitar problemas de configuración, los costos son asequibles y aprender cosas nuevas.

Mis pods están funcionando bien y creé un servicio con tipo LoadBalancerpara exponer el servicio en los puertos 80 y 443. Esto funciona perfectamente.

Sin embargo, descubrí que para cada LoadBalancerservicio, se crea un nuevo equilibrador de carga de Google Compute Engine. Este equilibrador de carga es bastante costoso y realmente ha terminado para un proyecto de hobby en una sola instancia.

Para reducir los costos, estoy buscando una manera de exponer los puertos sin el equilibrador de carga.

Lo que he probado hasta ahora:

¿Hay alguna manera de exponer los puertos 80 y 443 para una sola instancia en Google Container Engine sin un equilibrador de carga?

Ruben Ernst
fuente

Respuestas:

10

Sí, a través de IP externas en el servicio. Ejemplo de servicio que he usado:

apiVersion: v1
kind: Service
metadata:
  name: bind
  labels:
    app: bind
    version: 3.0.0
spec:
  ports:
    - port: 53
      protocol: UDP
  selector:
    app: bind
    version: 3.0.0
  externalIPs:
    - a.b.c.d
    - a.b.c.e

Tenga en cuenta que las IP enumeradas en el archivo de configuración deben ser la IP interna en GCE.

ConnorJC
fuente
¡Gracias! Pero creo que me perdí algo. El servicio se implementa pero no se puede acceder desde Internet. Establecí las reglas correctas del firewall. El servicio muestra el correctoexternalIp
Ruben Ernst
Perdón por la respuesta tardía, olvidé que dediqué tiempo exactamente al mismo problema. Las IP enumeradas deben ser la IP interna , no externa (al menos en GCE).
ConnorJC
Gracias, esa fue la solución! Desafortunadamente, aún no se me permite votar ... ¡Dejé este comentario para hacerle saber que esta respuesta combinada con el comentario anterior (que fue la clave) resolvió mi problema!
Ruben Ernst
1
¿Le gustaría (o @RubenErnst) ampliar un poco la respuesta? En particular, "las IP enumeradas en GCE deben ser la IP intrenal". ¿A qué IP te refieres? ¿Puede hacer que esto funcione con una IP estática asignada a su clúster de nodo único?
Brett
@Brett: Perdón por mi respuesta tardía. ¿Su pregunta ya ha sido respondida mientras tanto?
Ruben Ernst
4

Además de la excelente y funcional solución de ConnorJC: La misma solución también se describe en esta pregunta: Kubernetes : ¿puedo evitar usar el equilibrador de carga GCE para reducir los costos?

El "internalIp" se refiere a la ip interna de la instancia de cómputo (también conocida como el nodo) (como se ve en Google Cloud Platform -> Google Compute Engine -> VM Instances)

Este comentario da una pista de por qué se debe configurar la IP interna y no la externa.

Además, después de haber configurado el servicio para los puertos 80 y 443, tuve que crear una regla de firewall que permitiera el tráfico a mi nodo de instancia:

gcloud compute firewall-rules create your-name-for-this-fw-rule --allow tcp:80,tcp:443 --source-ranges=0.0.0.0/0

Después de esta configuración, podría acceder a mi servicio a través de http (s): // externalIp

derMikey
fuente
Usar el IP interno del nodo hizo el truco. 👍 ¡Qué confusión con los nombres!
James
1

Si solo tiene exactamente un pod, puede usarlo hostNetwork: truepara lograr esto:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: caddy
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: caddy
    spec:
      hostNetwork: true # <---------
      containers:
      - name: caddy
        image: your_image
        env:
        - name: STATIC_BACKEND # example env in my custom image
          value: $(STATIC_SERVICE_HOST):80

Tenga en cuenta que al hacer esto, su pod heredará la resolución DNS del host y no la de Kubernetes. Eso significa que ya no puede resolver los servicios de clúster por nombre DNS. Por ejemplo, en el ejemplo anterior no puede acceder al staticservicio en http: // static . Todavía puede acceder a los servicios por su IP de clúster, que son inyectadas por variables de entorno .

Esta solución es mejor que usar el IP externo del servicio, ya que omite el proxy kube, y recibirá la IP de origen correcta.

voluntad
fuente
1

Para sintetizar las respuestas de @ConnorJC @ derMikey en lo que funcionó exactamente para mí:

Dado un grupo de clústeres que se ejecuta en la instancia de Compute Engine :

gce vm name: gke-my-app-cluster-pool-blah`
internal ip: 10.123.0.1
external ip: 34.56.7.001 # will be publically exposed

Hice el servicio:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-app
  name: my-app-service
spec:
  clusterIP: 10.22.222.222
  externalIPs:
  - 10.123.0.1 # the instance internal ip
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: my-app
  type: ClusterIP

y luego abrió el firewall para todos los (?) ips en el proyecto:

gcloud compute firewall-rules create open-my-app --allow tcp:80,tcp:443 --source-ranges=0.0.0.0/0

y luego my-appfue accesible a través de la IP pública de la instancia de GCE34.56.7.001 (no la IP del clúster)

micimizar
fuente
0

Prefiero no usar los equilibradores de carga en la nube, hasta que sea necesario, debido al costo y al bloqueo del proveedor.

En cambio, uso esto: https://kubernetes.github.io/ingress-nginx/deploy/

Es un pod que ejecuta un equilibrador de carga para usted. Esa página tiene notas de instalación específicas de GKE.

Michael Cole
fuente