Kubernetes - resolve hostname of a service - kubernetes

I would like to perform a call to my echo-server but I can not figure out what's the hostname of my service:
orion:webanalytics papaburger$ kubectl get services -n web-analytics
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
echo-server ClusterIP 10.100.92.251 <none> 80/TCP 87m
web-api ClusterIP 10.100.92.250 <none> 8080/TCP 87m
I have tried to reach using kubectl exec -it curl-curl0 -- curl http://web-analytics.echo-server.svc.cluster.local/heythere but it fails:
curl: (6) Couldn't resolve host 'web-analytics.echo-server.svc.cluster.local'
If I change web-analytics.echo-server.svc.cluster.local to cluster ip, it works.
How can I make my pods (web-api) reach the echo server?
edit:
orion:webanalytics papaburger$ kubectl get ep -n web-analytics
NAME ENDPOINTS AGE
echo-server 172.16.187.247:80 95m
web-api 172.16.184.217:8080 95m

it should be like this
the service name is always like this
<service-name>.<namespace-name>.svc.cluster.local
kubectl exec -it curl-curl0 -- curl http://echo-servcer.web-analytics.svc.cluster.local/heythere
or alternative way would be you can directly curl the POD_IP:80

The DNS name is referred incorrectly, it follows the following format
my-svc.my-namespace.svc.cluster-domain.example
Based on the kubectl output, the DNS should be
echo-server.web-analytics.svc.cluster.local
The respective curl will be -
kubectl exec -it curl-curl0 -- curl http://echo-server.web-analytics.svc.cluster.local/heythere

Related

Kubernetes: port-forward for service object getting timed out

I am trying to port-forward to k8s service object which is getting timed out. I am using the k8s cluster in my docker desktop.
Is that some additional setting required for this?
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 205d
springboot-ms LoadBalancer 10.106.71.156 127.0.0.240 8080:30742/TCP 18m
Here is the port-forward:
$ kubectl port-forward service/springboot-ms 8080:8080
error: timed out waiting for the condition
However, if I perform the port-forward to my deployment object, it works perfectly.
$ kubectl port-forward deployment/springboot-ms 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Handling connection for 8080

How to get the hostname of a service in Kubernetes?

I need the hostname of the service lensespostgres-postgresql, but I get an error:
$ kubectl get services -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP ........ <none> 443/TCP 20m
lensespostgres-postgresql ClusterIP ........ <none> 5432/TCP 14m
lensespostgres-postgresql-headless ClusterIP None <none> 5432/TCP 14m
$ ping lensespostgres-postgresql.default.svc.cluster.local
ping: lensespostgres-postgresql.default.svc.cluster.local: Name or service not known
Why?
To get the hostname of the service you need dnsutils
If dnsutils is not installed please follow the below steps
sudo apt-get install dnsutils
sudo apt-get update
Create the yaml file for dnsutils as mentioned in the link
Apply the created yaml file using the below command
kubectl apply -f dnsutils.yaml
To get the hostname of the service use the below command:
kubectl exec -ti dnsutils -- nslookup <service-name>
For the further information of yaml file and steps you can refer this link
I have tried this in my project and it worked for me

What is the kubectl equivalent commands to "minikube service <service name>"?

I have executed minikube service mynginx1 and the result is:
|-----------|----------|-------------|-----------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|----------|-------------|-----------------------------|
| default | mynginx1 | 8080-80 | http://192.168.85.153:31706 |
|-----------|----------|-------------|-----------------------------|
What are the kubectl equivalent commands so that I can retrieve the URL if I am not using minikube?
To expose k8s application you can use kubectl expose
to create service of type NodePort:
kubectl expose pod <pod_name> --type NodePort --port 8080
or
kubectl expose deployment <deployment_name> --type NodePort --port 8080
then when you list your services you will see:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
<service_name> NodePort 10.99.147.24 <none> 8080:31208/TCP 3s
Notice two ports under PORT column: 8080:31208/TCP. First is in-cluster port and the second is a node port. So now you can access your service with nodePort using: <node-IP>:31208 from outside of a cluster.
There is another option which only applies of you are running in cloud environment and LoadBalancers are supported (so if you are either using k8s as a service solution or running self hosted k8s in cloud with cloud provider configured).
You can create a service of type LoadBalancer like following:
kubectl expose pod <pod_name> --type LoadBalacer --port 8080
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
<service_name> LoadBalancer 10.107.151.19 x.x.x.x 8080:31111/TCP 2s
and now use EXTERNAL-IP address to connect to your service: x.x.x.x:8080
Port forward worked for me
kubectl port-forward deployment/es-manual 9200:9200
I had the same issue as the OP when trying to use Docker Desktop instead of Minikube - Docker desktop now comes with a Kubernetes single-node cluster so I didn't see the need to install Minikube in order to play with Kubernetes on my dev machine.
Assuming you use kubectl get services to list your services, you can then use kubectl cluster-info to get your master node ip.
OOTB, Docker Desktop sets 127.0.0.1 as the master node ip (or you could use kubernetes.docker.internal)
>> kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloworld NodePort 10.107.197.207 <none> 80:32714/TCP 71m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h4m
>> kubectl cluster-info
Kubernetes control plane is running at https://kubernetes.docker.internal:6443
CoreDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
With the above information I can launch helloworld at http://kubernetes.docker.internal:32714/ or http://127.0.0.1:32714/
equivalent to minikube service mynginx1
would be
kubectl get service mynginx1

Kubernetes 1.13, CoreDNS - cluster curl service?

by default, in Kubernetes 1.13 CoreDNS is installed.
Can you please tell me how to make a curl in a cluster by the name of the service?
[root#master ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 24h
[root#master ~]# kubectl get services --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-system coredns ClusterIP 10.233.0.3 <none> 53/UDP,53/TCP,9153/TCP 21h
tools nexus-svc NodePort 10.233.17.152 <none> 8081:31991/TCP,5000:31111/TCP,8083:31081/TCP,8082:31085/TCP 14h
[root#master ~]# kubectl describe services nexus-svc --namespace=tools
Name: nexus-svc
Namespace: tools
Labels: tools=nexus
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"tools":"nexus"},"name":"nexus-svc","namespace":"tools"},"spec"...
Selector: tools=nexus
Type: NodePort
IP: 10.233.17.152
Port: http 8081/TCP
.....
So I get the correct answer.
[root#master ~]# curl http://10.233.17.152:8081
<!DOCTYPE html>
<html lang="en">
<head>
<title>Nexus Repository Manager</title>
....
And so no.
[root#master ~]# curl http://nexus-svc.tools.svc.cluster.local
curl: (6) Could not resolve host: nexus-svc.tools.svc.cluster.local; Unknown error
[root#master ~]# curl http://nexus-svc.tools.svc.cluster.local:8081
curl: (6) Could not resolve host: nexus-svc.tools.svc.cluster.local; Unknown error
Thanks.
coredns or kubedns are meant to resolve the service name to its clusterIP (normal service) or correspondent Pod IP (headless service) inside the kubernetes cluster not outside. You are trying to curl the service name on the node, not inside the pod and hence it is not able to resolve the service name to its clusterIP.
YOu can go inside the pod and try following:
kubectl exec -it <pod_name> bash
nslookup nexus-svc.tools.svc.cluster.local
It will return you cluster IP and it means coredns is working fine. If your pod has curl utility then you can also curl it using service name (but from inside the cluster only)
If you want to access the service from outside the cluster, this service already exposed as NodePort so you can access it using:
curl http://<node_ip>:31991
Hope this helps.

Kubernetes service external IP address remains pending with IBM Cloud (earlier called as Bluemix)

I'm following an example from Kubernetes in Action to run a simple docker image in kubernetes:
$ bx login --apikey #apiKey.json -a https://api.eu-de.bluemix.net
$ bx cs cluster-config my_kubernetes
$ export KUBECONFIG=..my_kubernetes.yml
Next, run the container:
$ kubectl run kubia --image=luksa/kubia --port=8080 --generator=run/v1
$ kubectl expose rc kubia --type=LoadBalancer --name kubia-http
$ kubectl get service
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.10.10.1 <none> 443/TCP 20h
kubia-http 10.10.10.12 <pending> 8080:32373/TCP 0m
Fifteen minutes later ...
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.10.10.1 <none> 443/TCP 20h
kubia-http 10.10.10.12 <pending> 8080:32373/TCP 15m
I don't have anything else running on the Kubernetes cluster.
To close out the thread here, LoadBalancer cannot be used in a lite (aka free) cluster tier. The differences between lite and standard clusters can be found here - https://console.bluemix.net/docs/containers/cs_planning.html#cs_planning.
Run the following to determine if there are any failure events.
kubectl describe svc kubia-http
Thanks to Chris Rosen's answer, I was able to find a workaround:
$ bx cs workers my_kubernetes
OK
ID Public IP Private IP Machine Type State Status
kube-par01-xxxxx 1.2.3.4 6.7.8.9 free normal Ready
Note the Public IP address: 1.2.3.4
Expose the service with NodePort:
$ kubectl expose rc kubia --type=NodePort --name kubia-http2
Check the NodePort details:
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.10.10.1 <none> 443/TCP 21h
kubia-http2 10.10.10.193 <nodes> 8080:31247/TCP 10s
Access the service using the exposed port on the worker Public IP address:
$ curl http://1.2.3.4:31247/
You've hit kubia-bjb59
Based on the posts above I was getting the following steps to work:
Prerequisites: Create a free Kubernetes cluster in the IBM Cloud and follow the steps (you need to have the ibmcloud and kubectl installed and connect to the remote cluster first)
kubectl get nodes
should return something like this
NAME STATUS ROLES AGE VERSION
10.76.197.55 Ready <none> 4h18m v1.18.10+IKS
Then,
kubectl apply -f https://k8s.io/examples/controllers/replication.yaml
replicationcontroller/nginx created
kubectl expose rc nginx --type=NodePort
service/nginx exposed
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 172.21.19.73 80:30634/TCP 70s
Note down the port, 30634 in my case
kubectl describe nodes |grep ExternalIP (to find out the external IP)
call IP:port
Have fun!
If your purpose is to test your application by having it the accessible to the external world , I would suggest using the NodePort service which can be used in the free tier service.
More Info can be found here : Expose service to world