Kubernetes: expose multiple containers using service and ingress with static ip

7/17/2019

I'm trying to deploy two nodejs applications as two separate containers using Kubernetes, a defined service and an ingress with a static ip and a ssl certificate

I would like to deploy these micro-services using Kubernetes Engine of the GCP. I've added the second micro-service later than the other one. With only one container into the pod, everything works good. I've defined three yaml files: deployment.yaml, service.yaml, ingress.yaml.

deployment.yaml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: qa-chatbot-backend-deployment
spec:
  selector:
    matchLabels:
      app: service-backend1
  replicas: 1
  template:
    metadata:
      labels:
        app: service-backend1
    spec:
      containers:
        - name: serice-backend1
          image: gcr.io/project-id/serice-backend1:v1.0.1
          imagePullPolicy: Always
          command: ["npm", "start"]
          livenessProbe:
            httpGet:
              path: /
              port: 8081
              scheme: HTTP
            initialDelaySeconds: 30
            timeoutSeconds: 25
            periodSeconds: 30
            successThreshold: 1
            failureThreshold: 2
          readinessProbe:
            httpGet:
              path: /
              port: 8081
              scheme: HTTP
            initialDelaySeconds: 30
            timeoutSeconds: 25
            periodSeconds: 30
            successThreshold: 1
            failureThreshold: 2
          ports:
            - name: service1-port
              containerPort: 8081
        - name: service-backend2
          image: gcr.io/project-id/serice-backend2:v1.0.1
          imagePullPolicy: Always
          command: ["npm", "start"]
          livenessProbe:
            httpGet:
              path: /api/test
              port: 8082
              scheme: HTTP
            initialDelaySeconds: 30
            timeoutSeconds: 25
            periodSeconds: 30
            successThreshold: 1
            failureThreshold: 2
          readinessProbe:
            httpGet:
              path: /api/test
              port: 8082
              scheme: HTTP
            initialDelaySeconds: 30
            timeoutSeconds: 25
            periodSeconds: 30
            successThreshold: 1
            failureThreshold: 2
          ports:
            - name: service2-port
              containerPort: 8082

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: service-kube
spec:
  type: LoadBalancer
  ports:
    - targetPort: service1-port
      port: 80
      protocol: TCP
  selector:
    app: service-backend1

ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  labels:
    app: service-backend1
  name: ingress-kube
  annotations:
    kubernetes.io/ingress.global-static-ip-name: app-static-ip
spec:
  tls:
  - hosts:
    - custom-host.com
    secretName: custom-host-secret-name
  rules:
  - host: custom-host.com
    http:
      paths:
      - backend:
          serviceName: service-kube
          servicePort: 80

With this configuration, only one service is reachable, the first one

I've tried to add multiple ports into service.yaml

apiVersion: v1
kind: Service
metadata:
  name: service-kube
spec:
  type: LoadBalancer
  ports:
    - targetPort: service1-port
      port: 80
      protocol: TCP
    - targetPort: service2-port
      port: 80
      protocol: TCP
  selector:
    app: service-backend1

But i receive an error.

The Service "service-kube" is invalid: spec.ports[1]: Duplicate value: core.ServicePort{Name:"", Protocol:"TCP", Port:80, TargetPort:intstr.IntOrString{Type:0, IntVal:0, StrVal:""}, NodePort:0}

My goal is to expose on the domain custom-host.com two backends; one reachable on a specific path (api/*), the other one reachable to all the possible endpoints.

Thank you for your help

-- d_vucin91
kubernetes
kubernetes-ingress
kubernetes-service
microservices
static-ip-address

1 Answer

7/17/2019

You can't have a single service port send traffic to two different target ports. There must be two different ports on your service (or use two separate services). Then you should have two paths in your ingress that route to the appropriate service port.

You need to do something like this...

apiVersion: v1
kind: Service
metadata:
  name: service-kube
spec:
  type: LoadBalancer
  ports:
    - targetPort: service1-port
      port: 81
      protocol: TCP
    - targetPort: service2-port
      port: 82
      protocol: TCP
  selector:
    app: service-backend1
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  labels:
    app: service-backend1
  name: ingress-kube
  annotations:
    kubernetes.io/ingress.global-static-ip-name: app-static-ip
spec:
  tls:
  - hosts:
    - custom-host.com
    secretName: custom-host-secret-name
  rules:
  - host: custom-host.com
    http:
      paths:
      - backend:
          serviceName: service-kube
          servicePort: 81
        path: /api
      - backend:
          serviceName: service-kube
          servicePort: 82
        path: /
-- switchboard.op
Source: StackOverflow