Public IP fronting a k8s Service has no DNS name in ACS - kubernetes

I've created a k8s Service to publicly front my WebApi pod in my ACS Windows cluster. It works great but there is no DNS name associated with the Public IP resources that is created. This prohibits me from adding it as an endpoint for a Traffic Manager profile, roadblock!
I can manually assign a DNS name to the Public IP, but then I'd be touching an ACS created resource, which makes me uncomfortable. But I REALLY want a static DNS name and the features of TrafficMgr to be in front of it.
This feels like a significant deficiency. Any advice?

there is a feature request in upstream
https://github.com/kubernetes/kubernetes/issues/50062

When you create a service, Kubernete automatically create a dns for it as long as kube-dns is running. The service name becomes the dns for accessing the pod withing the cluster and resolves to the cluster IP. So you can use the service name within other pods in the cluster.
https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#dns

Related

How to keep IP address of a pod static after pod dies

I am new to learning kubernetes, and I understand that pods have dynamic IP and require some other "service" resource to be attached to a pod to use the fixed IP address. What service do I require and what is the process of configuration & How does AWS-ECR fit into all this.
So if I have to communicate from a container of a pod to google.com, Can I assume my source as the IP address of the "service", if I have to establish a connection?
Well, for example on Azure, this feature [Feature Request] Pod Static IP is under request:
See https://github.com/Azure/AKS/issues/2189
Also, as I know, you can currently assign an existing IP adress to a load balancer service or an ingress controller
See https://learn.microsoft.com/en-us/azure/aks/static-ip
By default, the public IP address assigned to a load balancer resource
created by an AKS cluster is only valid for the lifespan of that
resource. If you delete the Kubernetes service, the associated load
balancer and IP address are also deleted. If you want to assign a
specific IP address or retain an IP address for redeployed Kubernetes
services, you can create and use a static public IP address
As you said we needs to define a service which selects all the required pods and then you would be sending requests to this service instead of the pods.
I would suggest you to go through this https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types.
The type of service you need basically depends on the use-case.
I will give a small overview so you get an idea.
Usually when pods only have internal requests ClusterIP is used
Node port allow external requests but is basically used for testing and not for production cases
If you also have requests coming from outside the cluster you would usually use load balancer
Then there is another option for ingress
As for AWS-ECR, its basically a container registry where you store your docker images and pull from it.

Kubernetes internal wildcard DNS record

I'd like to create a wildcard DNS record that maps to a virtual IP inside my k8s cluster. This is because I want requests from my pods to any subdomain of a given name to map to a specific set of endpoints. I.e. requests from:
something.my-service.my-namespace.svc.cluster.local
something-else.my-service.my-namespace.svc.cluster.local
any-old-thing-my-pod-came-up-with.my-service.my-namespace.svc.cluster.local
to all resolve to the same virtual IP, and therefore to the same cluster (i.e. I would like these requests to be routed to endpoints in the same way a service does).
I've seen some other solutions that involve creating and modifying the cluster DNS service (i.e. kube-dns or CoreDNS) config. This doesn't work for me- the main reason I'm asking this question is to achieve declarative config.
What I've tried:
Service .metadata.name: '*.my-service'. Failed because '*.my-service' is not a valid service name.
Service .spec.ports.name: '*'. Not a valid port name.
Not an option:
Ingress. I cannot expose these services to the wider internet.
Pod hostname/subdomain. AFAIK DNS entries created by pod hostname/subdomain will not have a virtual IP that may resolve to any of a number of pods. (Quoting from https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-hostname-and-subdomain-fields) "DNS serves an A record at that name, pointing to the Pod’s IP."
wild card dns is not supported for kubernetes services. what you can do is front the service with an ingress controller. with ingress you can use wild card dns. refer the below PR
https://github.com/kubernetes/kubernetes/pull/29204

Frontend communication with API in Kubernetes cluster

Inside of a Kubernetes Cluster I am running 1 node with 2 deployments. React front-end and a .NET Core app. I also have a Load Balancer service for the front end app. (All working: I can port-forward to see the backend deployment working.)
Question: I'm trying to get the front end and API to communicate. I know I can do that with an external facing load balancer but is there a way to do that using the clusterIPs and not have an external IP for the back end?
The reason we are interested in this, it simply adds one more layer of security. Keeping the API to vnet only, we are removing one more entry point.
If it helps, we are deploying in Azure with AKS. I know they have some weird deployment things sometimes.
Pods running on the cluster can talk to each other using a ClusterIP service, which is the default service type. You don't need a LoadBalancer service to make two pods talk to each other. According to the docs on this topic
ClusterIP exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. This is the default ServiceType.
As explained in the Discovery documentation, if both Pods (frontend and API) are running on the same namespace, the frontend just needs to send requests to the name of the backend service.
If they are running on different namespaces, the frontend API needs to use a fully qualified domain name to be able to talk with the backend.
For example, if you have a Service called "my-service" in Kubernetes Namespace "my-ns" a DNS record for "my-service.my-ns" is created. Pods which exist in the "my-ns" Namespace should be able to find it by simply doing a name lookup for "my-service". Pods which exist in other Namespaces must qualify the name as "my-service.my-ns". The result of these name lookups is the cluster IP.
You can find more info about how DNS works on kubernetes in the docs.
The problem with this configuration is the idea that the Frontend app will be trying to reach out to the API via the internal cluster. But it will not. My app, on the client's browser can not reach services and pods in my Kluster.
My cluster will need something like nginx or another external Load Balancer to allow my client side api calls to reach my API.
You can alternatively used your front end app, as your proxy, but that is highly not advised!
I'm trying to get the front end and api to communicate
By api, if you mean the Kubernetes API server, first setup a service account and token for the front-end pod to communicate with the Kubernetes API server by following the steps here, here and here.
is there a way to do that using the clusterIPs and not have an external IP for the back end
Yes, this is possible and more secure if external access is not needed for the service. Service type ClusterIP will not have an ExternalIP and the pods can talk to each other using ClusterIP:Port within the cluster.

Should the Kubernetes api server be accesible as https://kubernetes:443 from any pod in the cluster?

According to the Kubernetes docs,
The kubernetes service (in all namespaces) is configured with a virtual IP address that is redirected (via kube-proxy) to the HTTPS endpoint on the apiserver.
For some reason I can't access kubernetes from a non-default namespace, unless I manually create the service there (or use kubernetes.default). Looking at the code I see the kubernetes service is created in namespace default, is it also available in other namespaces? If so, how is that accomplished? How might I debug it?
I've been finding it difficult to Google this, since "kubernetes service" is not really a great search keyword.
For the record, I'm using GKE.
Service kubernetes is only available in Namespace default.
If you want to access API server using this service, you need to use kubernetes.default
Services are assigned a DNS A record for a name of the form
my-svc.my-namespace.svc.cluster.local
This resolves to the cluster IP of the Service.
That means, you need to use kubernetes.default.svc.cluster.local
You can skip svc.cluster.local.
So to access a kubernetes Service, you need to provide kubernetes.default.
If you want to access from default namespace, you can skip namespace part.
See details in here.
Also,
When you create a pod, if you do not specify a service account, it is automatically assigned the default service account in the same namespace.
You can access the API from inside a pod using automatically mounted service account credentials, as described in Accessing the Cluster.

Like to know Kubernetes API server Host from the app deployed on to POD in a cluster

Like to know if there is a way to identify Master IP address (API server Host & port) from the application that I run in POD?. ( say I create a kubernetes cluster A, with Master public IP address x.x.x.x; and I create a pod with my app (say a golang or J2ee) on a kubernetes minion belonging to that cluster A. From the App process that is running on cluster A minion , we like to know the public IP address of that Master (x.x.x.x) )
I do not find any Environmental variables for the same.
Can any one help?.
The api service is exposed via a k8s service. You would need to use the API to access the service config. You can get access to the API through the service endpoint (the address is in an env variable) but you'll have to have the necessary creds to do anything useful. They're in a subdirectory of /var/run/secrets/kubernetes.io depending on which service account your pod is running under. You can either access the endpoint directly, over https or you can run a proxy in your pod. See http://kubernetes.io/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod.
An example of using curl to hit the API server is given in https://stackoverflow.com/a/30739416/191215.
The api endpoint you want is /api/v1/endpoints. Look for the item with a metadata.name of kubernetes. The external endpoint should be one of the subsets addresses.
I believe this is true for all k8s implementations but have only tested it on GKE and from docker-machine.
The DNS name kubernetes should resolve to a virtual IP address that will route to the master so that you can hit the apiserver.