Search code examples
nginxkuberneteskubernetes-ingressnginx-ingressserver-name

kubernetes ingress server-alias only applies to one ingress host


According to this doc (https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#server-alias), I'm able to add additional server_name to the nginx config file. However, it adds the extra server_name to all of my hosts, which cause conflicts for sure. Is there a way to add server-alias only for one of my hosts? Say I only want to add 10.10.0.100 to my test1 host. Ingress example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/server-alias: 10.10.0.100
spec:
  rules:
  - host: test1.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: test1-service
            port:
              number: 8000
        pathType: Prefix
  - host: test2.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: test2-service
            port:
              number: 8000
        pathType: Prefix


Solution

  • TL;DR

    You can split your Ingress resource on multiple objects (which will work together) to add Annotations to only specific hosts.

    Annotations can only be set on the whole kubernetes resource, as they are part of the resource metadata. The ingress spec doesn't include that functionality at a lower level.

    -- Stackoverflow.com: Questions: Apply nginx-ingress annotations at path level


    Extending on the answer to give an example of how such setup could be created. Let's assume (example):

    • All required domains pointing to the Service of type LoadBalancer of nginx-ingress-controller:
      • hello.kubernetes.docker.internal - used in host .spec
      • hello-two.kubernetes.docker.internal - used in annotations .metadata
      • --
      • goodbye.kubernetes.docker.internal - used in host .spec
      • goodbye-two.kubernetes.docker.internal- used in annotations .metadata

    Skipping the Deployment and Service definitions, the Ingress resources should look like below:

    hello-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-ingress
      annotations:
        nginx.ingress.kubernetes.io/server-alias: "hello-two.kubernetes.docker.internal"
    spec:
      rules:
      - host: hello.kubernetes.docker.internal # <-- IMPORTANT  
        http:
          paths:
          - path: /
            backend:
              service:
                name: hello-service
                port:
                  number: 80
            pathType: Prefix
    

    goodbye-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: goodbye-ingress
      annotations:
        nginx.ingress.kubernetes.io/server-alias: "goodbye-two.kubernetes.docker.internal"
    spec:
      rules:
      - host: goodbye.kubernetes.docker.internal # <-- IMPORTANT 
        http:
          paths:
          - path: /
            backend:
              service:
                name: goodbye-service
                port:
                  number: 80
            pathType: Prefix
    

    Above definitions will create 2 Ingress resources that will be merged:

    • hello-service will respond for:
      • hello.kubernetes.docker.internal
      • hello-two.kubernetes.docker.internal
    • goodbye-service will respond for:
      • goodbye.kubernetes.docker.internal
      • goodbye-two.kubernetes.docker.internal

    Running:

    • $ kubectl get ingress:
    NAME              CLASS    HOSTS                                ADDRESS     PORTS   AGE
    goodbye-ingress   <none>   goodbye.kubernetes.docker.internal   localhost   80      36m
    hello-ingress     <none>   hello.kubernetes.docker.internal     localhost   80      36m
    

    Additional resources: