Exposer les ports 80 et 443 sur Google Container Engine sans équilibreur de charge

23

Actuellement, je travaille sur un petit projet de loisir que je ferai open source une fois qu'il sera prêt. Ce service fonctionne sur Google Container Engine. J'ai choisi GCE pour éviter les tracas de configuration, les coûts sont abordables et pour apprendre de nouvelles choses.

Mes pods fonctionnent bien et j'ai créé un service de type LoadBalancerpour exposer le service sur les ports 80 et 443. Cela fonctionne parfaitement.

Cependant, j'ai découvert que pour chaque LoadBalancerservice, un nouvel équilibreur de charge Google Compute Engine est créé. Cet équilibreur de charge est assez cher et vraiment terminé pour un projet de loisir sur une seule instance.

Pour réduire les coûts, je cherche un moyen d'exposer les ports sans l'équilibreur de charge.

Ce que j'ai essayé jusqu'à présent:

Existe-t-il un moyen d'exposer les ports 80 et 443 pour une seule instance sur Google Container Engine sans équilibreur de charge?

Ruben Ernst
la source

Réponses:

10

Oui, via des IP externes sur le service. Exemple de service que j'ai utilisé:

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

Veuillez noter que les IP répertoriées dans le fichier de configuration doivent être l'IP interne sur GCE.

ConnorJC
la source
Merci! Mais je pense que j'ai raté quelque chose. Le service est déployé mais impossible à partir d'Internet. J'ai défini les règles de pare-feu correctes. Le service affiche le bonexternalIp
Ruben Ernst
Désolé pour la réponse tardive, j'ai oublié que j'ai passé du temps sur le même problème. Les adresses IP répertoriées doivent être l' adresse IP interne et non externe (au moins sur GCE).
ConnorJC
Merci, c'était la solution! Malheureusement, je ne suis pas encore autorisé à voter ... J'ai laissé tomber ce commentaire pour vous faire savoir que cette réponse combinée avec le commentaire ci-dessus (qui était la clé) a résolu mon problème!
Ruben Ernst
1
Pourriez-vous (ou @RubenErnst) développer un peu la réponse? En particulier, «les IP répertoriées sur GCE doivent être l'IP intrenal». De quelle IP parlez-vous? Êtes-vous en mesure de faire fonctionner cela avec une adresse IP statique affectée à votre cluster à nœud unique?
Brett
@Brett: Désolé pour ma réponse tardive. Votre question a-t-elle déjà répondu entre-temps?
Ruben Ernst
4

En plus de l'excellente solution de ConnorJC: la même solution est également décrite dans cette question: Kubernetes - puis-je éviter d'utiliser le GCE Load Balancer pour réduire les coûts?

Le "internalIp" fait référence à l'IP interne de l'instance de calcul (alias le nœud) (comme on le voit sur Google Cloud Platform -> Google Compute Engine -> VM Instances)

Ce commentaire donne un indice sur la raison pour laquelle l'IP interne et non l'IP externe doit être configuré.

De plus, après avoir configuré le service pour les ports 80 et 443, j'ai dû créer une règle de pare-feu autorisant le trafic vers mon nœud d'instance:

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

Après cette configuration, j'ai pu accéder à mon service via http (s): // externalIp

derMikey
la source
L'utilisation de l'IP interne du nœud a fait l'affaire. 👍 Une telle confusion avec la dénomination!
James
1

Si vous n'avez qu'un seul pod, vous pouvez utiliser hostNetwork: truepour cela:

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

Notez qu'en faisant cela, votre pod héritera du résolveur DNS de l'hôte et non de Kubernetes. Cela signifie que vous ne pouvez plus résoudre les services de cluster par nom DNS. Par exemple, dans l'exemple ci-dessus, vous ne pouvez pas accéder au staticservice à l' adresse http: // static . Vous pouvez toujours accéder aux services par leur IP de cluster, qui sont injectés par des variables d'environnement .

Cette solution est meilleure que l'utilisation de l'IP externe du service car elle contourne le proxy de cube, et vous recevrez l'IP source correcte.

sera sera
la source
1

Pour synthétiser les réponses de @ConnorJC @ derMikey en ce qui a fonctionné exactement pour moi:

Étant donné un pool de clusters exécuté sur le instance 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

J'ai rendu le service:

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

puis ouvert le pare-feu pour toutes les (?) ips du projet:

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

puis my-appétait accessible via l' IP publique de l'instance GCE34.56.7.001 (pas l' IP du cluster)

micimiser
la source
0

Je préfère ne pas utiliser les équilibreurs de charge cloud, jusqu'à ce que cela soit nécessaire, en raison du coût et du blocage des fournisseurs.

Au lieu de cela, j'utilise ceci: https://kubernetes.github.io/ingress-nginx/deploy/

C'est un pod qui exécute un équilibreur de charge pour vous. Cette page contient des notes d'installation spécifiques à GKE.

Michael Cole
la source