简体   繁体   中英

Kubernetes - Ingress / Service / LB

I am new to K8s and this is my first time trying to get to grips with it. I am trying to set up a basic Nodejs Express API using this deployment.yml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - image: registry.gitlab.com/<project>/<app>:<TAG>
        imagePullPolicy: Always
        name: api
        env:
        - name: PORT
          value: "8080"
        ports:
          - containerPort: 8080
            hostPort: 80
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          timeoutSeconds: 1
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          timeoutSeconds: 1
      imagePullSecrets:
        - name: registry.gitlab.com

Which is being deployed via gitlab-ci. This is working and I have set up a service to expose it:

apiVersion: v1
kind: Service
metadata:
  name: api-svc
  labels:
    app: api-svc
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: api
  type: LoadBalancer

But I have been looking into ingress to have a single point of entry for possibly multiple services. I have been reading through Kubernetes guides and I read through this Kubernetes Ingress Example and this is the ingress.yml I created:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  backend:
    serviceName: api-svc
    servicePort: 80

But this did not work, when I visited the external IP address that was generated from the ingress and I just 502 error pages.

Could anyone point me in the right direction, what am I doing wrong or what am I missing? I see that in the example link above that there is an nginx-rc.yml which I deployed exactly like in the example and that was created but still got nothing from the endpoint. The API was accessible from the Service external IP though..

Many Thanks

I have looked into it again and think I figured it out.

In order for Ingress to work on GCE you need to define your backend service das a NodePort not as ClusterIP or LoadBalancer.

Also you need to make sure the http health check to / works (you'll see the Google L7 Loadbalancer hitting your service quite a lot on that url) and then it's available.

Thought I would post my working deployment/service/ingress

So after much effort in getting this working, here is what I used to get it working:

Deployment

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: backend-api-v2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: backend-api-v2
    spec:
      containers:
      - image: registry.gitlab.com/<project>/<app>:<TAG>
        imagePullPolicy: Always
        name: backend-api-v2
        env:
        - name: PORT
          value: "8080"
        ports:
          - containerPort: 8080
        livenessProbe:
          httpGet:
            # Path to probe; should be cheap, but representative of typical behavior
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          timeoutSeconds: 5
      imagePullSecrets:
        - name: registry.gitlab.com

Service

apiVersion: v1
kind: Service
metadata:
  name: api-svc-v2
  labels:
    app: api-svc-v2
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 31810
    protocol: TCP
    name: http
  selector:
    app: backend-api-v2

Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - host: api.foo.com
    http:
      paths:
      - path: /v1/*
        backend:
          serviceName: api-svc
          servicePort: 80
      - path: /v2/*
        backend:
          serviceName: api-svc-v2
          servicePort: 80

The important bits to notice as @Tigraine pointed out is the service is using type: NodePort and not LoadBalancer , I have also defined a nodePort but I believe it will create one if you leave it out.

It will use the default-http-backend for any routes that don't match the rules this is a default container that GKE runs in the kube-system namespace. So if I visited http://api.foo.com/bob I get the default response of default backend - 404 .

Hope this helps

Looks like you're exposing your service to port 80 but your container is exposing 8080 so any request to the service is going to fail.

Also, have a look at the sample ingress resource ( https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/complete-example/cafe-ingress.yaml ), you need to also define which hosts / paths route when the ingress controller is hit. (ie example.foo.com --> api-svc)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM