6

We have defined our internal Load Balancer.

apiVersion: v1
kind: Service
metadata:
  name: ads-aks-test
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
spec:
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 9000
  selector:
    app: ads-aks-test

It has its IP and External IP. We want to access this service from VM in another Virtual Network. We need to know it's DNS name - fully qualified name in advance because we are deploying multiple applications from deployment platform and we want to know based on its Service Name how we can access it once it is being successfully deployed and not to wait for IP address to be determined (either manually or automatically). So for example that is our APP1, and after that automatically we install application APP2 which needs to reach this service. So for that reason we would like to avoid using the IP information.

How we can determine what is the service "hostname" by which we will access it from the second application?

Only information in docs which I found is: "If your service is using a dynamic or static public IP address, you can use the service annotation service.beta.kubernetes.io/azure-dns-label-name to set a public-facing DNS label." - but this is for public load balancer which we do not want!

vel
  • 1,000
  • 1
  • 13
  • 35

3 Answers3

3

Set up ExternalDNS in your K8s cluster. Here is a guide for Azure Private DNS. This will allow you to update the DNS record for any hostname you pick for the service, dynamically via Kubernetes resources.

Sample config looks like this (excerpted from Azure Private DNS guide)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: externaldns
spec:
  selector:
    matchLabels:
      app: externaldns
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: externaldns
    spec:
      containers:
      - name: externaldns
        image: k8s.gcr.io/external-dns/external-dns:v0.7.3
        args:
        - --source=service
        - --source=ingress
        - --domain-filter=example.com
        - --provider=azure-private-dns
        - --azure-resource-group=externaldns
        - --azure-subscription-id=<use the id of your subscription>
        volumeMounts:
        - name: azure-config-file
          mountPath: /etc/kubernetes
          readOnly: true
      volumes:
      - name: azure-config-file
        secret:
          secretName: azure-config-file
yoda_droid
  • 361
  • 1
  • 7
  • Good answer, this is also what Microsoft recommends in their documentation when it comes to publishing dns entries on your own domain https://learn.microsoft.com/en-us/azure/aks/static-ip#apply-a-dns-label-to-the-service – danielorn Feb 12 '21 at 20:00
  • Thank bot of you, I marked this as answer and awarded this as well :) since I see you are very skilled can you please help me with this issue? https://stackoverflow.com/questions/66190275/kubernetes-ingress-controller-cannot-tcp-connect-from-outside-virtual-machine thank you – vel Feb 13 '21 at 23:45
1

An internal load balancer makes a Kubernetes service accessible only to applications running in the same virtual network as the Kubernetes cluster.

https://learn.microsoft.com/en-us/azure/aks/internal-lb

it seems you want this configuration? is there a peering? you also need to allow communication in NSG . enter image description here

Anass Kartit
  • 2,017
  • 15
  • 22
  • Yes that is what we want to achieve. So how we can do it? Please take into account that 9000 is not the HTTP port but it is the port for TCP connection on which other applications/windows services from another VMs need to establish network connection. Thanks Anass – vel Feb 12 '21 at 09:37
0

you can do kubectl get svc

and use the External IP of service ads-aks-test as in annotation you have mentioned "true" so it will be internal IP.

if you are looking forward to resolving the services name in the same cluster you can use the service name itself.

https://kubernetes.io/docs/concepts/services-networking/service/

you can do something like : your-svc.your-namespace.svc.cluster.local

note it will only work when services are in the same Kubernetes cluster.

Harsh Manvar
  • 27,020
  • 6
  • 48
  • 102
  • thank you for your response. I know we can use IP I was looking for that another approach. Our name space is default. So the hostname will be: `ads-aks-test.default.svc.cluster.local` correct? But it can be only accessed from the other Pods in the cluster or from the Podes from another Nodes in the Cluster? It cannot be accessed from the Virtual Machine from another Subnet which is the reason why we created initially this Internal Load Balancer - so they could have connection. If that is the case then this unfortunately does not answer my problem how to resolve our issue... :( – vel Feb 05 '21 at 09:56
  • `ads-aks-test.default.svc.cluster.local` will work across cluster doesn't matter about nodes but if you are trying to connect from another subnet in same VPC best way is to set internal LB only and use it. – Harsh Manvar Feb 05 '21 at 09:59
  • Just to be in the same context are you looking forward to remove that internal LB ? and connect VM to K8s cluster without LB? in that case you can not use `ads-aks-test.default.svc.cluster.local` but yes you might be able use the `Node Port` service. – Harsh Manvar Feb 05 '21 at 10:00
  • No we do not want to remove internal LB. In Azure we have VM in another Virtual Network which needs to connect to service. That is why we have selected to use Internal Load Balancer. It needs to connect to port 9000. We want to use internal LB because in that way we will be able to connect from another VM which is NOT in the AKS cluster. That is supported! But since IP address is not predictable we want to use hostname which can be predictable comparing to the IP address which value is generated only after service is being created, while if we use hostname we can "predict" value in advance – vel Feb 05 '21 at 10:04
  • We would like to avoid using NodePort because all our apps outside the AKS know that they should connect to Port 9000 which is standard port for our App. If using NodePort then we need to set some other port to connect to , greater than 30000 which we would need to set... Thank you – vel Feb 05 '21 at 10:05
  • Okay got it your concerns. yes, you are right in case of node port but in background you can redirect requests to the target port. – Harsh Manvar Feb 05 '21 at 10:06
  • you can use the internal IP take it on lease also both are in same VPC you can use the direct IP of VM and fix them. – Harsh Manvar Feb 05 '21 at 10:08
  • maybe you also create inetnal dns record if you own domain corp.companyname.com or ad.companyname.com. This will insure that your internal DNS handles all queries – Harsh Manvar Feb 05 '21 at 10:15
  • when you stated that we should maybe use Node Port service - what difference it will be ? what will be the hostname in that case for our service? Thank you – vel Feb 05 '21 at 10:54
  • in Node Port you can use IP of nodes but again if autoscaling there might cause issue but if you can lease IP that may resolve issue. but better use internal DNS name with IP i think it will work. – Harsh Manvar Feb 05 '21 at 10:58
  • But for internal DNS name again we need to define in it hostname and IP address of the service correct? In that way again we cannot automatically connect our App2 from VM from another virtual network with our App1 NodePort Service since someone needs to do configuration manually?correct? We would like to deploy APP1 on AKS and APP2 on VM automatically and to connect them automatically by just installing the application on AKS cluster and by installing the APP on VM with DNS which we will know in advance.. I know that maybe this sounds complex, but this is quite regular and usual requirement – vel Feb 05 '21 at 11:11