issue accesing one service from another kubernetes - kubernetes

Trying to connect to one service from another in the same namespace. Using ClusterIP for creating the service. once the service is created use that Ip to access the service. Requests are successful sometimes and sometimes it is failing, I see both the pods are up and running. Below is the service configuration
apiVersion: v1 kind: Service metadata: name: serviceA spec: selector: app: ServiceA ports: - name: http port: 80 targetPort: 8080 type: ClusterIP
apiVersion: v1 kind: Service metadata: name: serviceB spec: selector: app: ServiceB ports: - name: http port: 80 targetPort: 8123 type: ClusterIP

Please use service name in invoking it as below
http://serviceA:80
K8s offers DNS for Services and Pods
Kubernetes creates DNS records for Services and Pods. You can contact Services with consistent DNS names instead of IP addresses.

Related

Kubernetes Ingress - how to access my service on my computer?

I have the following template, with a deployment, a service and an Ingress. I ran minikube addons enable ingress locally to add an ingress controller before.
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi
labels:
app: fastapi
spec:
replicas: 1
selector:
matchLabels:
app: fastapi
template:
metadata:
labels:
app: fastapi
spec:
containers:
- name: fastapi
image: datamastery/fastapi
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
spec:
selector:
app: fastapi
type: LoadBalancer
ports:
- protocol: TCP
port: 5000
targetPort: 3000
nodePort: 30002
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: datamastery.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: fastapi-service
port:
number: 3000
When I run kubectl get servicesI get:
fastapi-service LoadBalancer 10.108.5.228 <pending> 5000:30002/TCP 5d22h
I my etc/hosts/ file I added the following:
10.108.5.228 datamastery.com
Normally I would expect now to be able to open my service in the browser, but nothing happens. What did I do wrong? Did I miss something in the template? Is the IP wrong? Something in the hosts file?
Thank you!
fastapi-service LoadBalancer 10.108.5.228 5000:30002/TCP 5d22h
10.108.5.228 is an address within your SDN. Only members of your SDN can reach this address, it is unlikely your workstation would have a route sending this trafic to one of your Kubernetes nodes.
<pending> means your cluster is not integrated with a cloud provider with LoadBalancer capabilities. When in doubt: you should use ClusterIP as your service type. LoadBalancer only makes sense in specific cases. While setting a nodePort as you did is also not required (would make sense with a NodePort service, which is as well useful in few use cases, though should not be used otherwise).
You did create an Ingress. If you have an Ingress Controller, you want to connect to that ip/port. The Host header would tell your ingress controller where to route this, within your SDN.
I believe what you are doing here is trying to combine two different things.
NodePort is only sufficient if you have only one node OR you really control where your service pods getting deployed. Otherwise it is not suitable to use the node IP to access services.
To overcome this issue we usually use ingress as a service proxy. Incoming traffic will be routed to the correct service pods depending on the URL and port. Ingress also manages the SSL termination. So basically this is your first "load balancer" as ingress assigned traffic to services across nodes and pods.
In production environment you deploy the ingress controller with the type: Loadbalancer in the kube-system namespace, example for Nginx-ingress:
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
namespace: kube-system
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: LoadBalancer
ports:
- port: 80
name: http
targetPort: 80
- port: 443
name: https
targetPort: 443
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
This would spin up a cloud load balancer of your provider and link it to the ingress service in your cluster. So basically now you would have a real load balancer in place balancing traffic between your nodes and ingress routes them to your services and services to your pods.
Back to your question:
In your config files you try to spin up a service with the type: LoadBalancer. This would skip the ingress part and spin up a second cloud load balancer from your provider dedicated for this single service.
You have to remove the type (and nodePort) to use default ClusterIP for your service.
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
spec:
selector:
app: fastapi
ports:
- protocol: TCP
port: 3000
targetPort: 3000
In addition you have mentioned a wrong port. Your ingress object points on port 3000. You Service object on port 5000. So we also change this.
With this config your traffic on the FQDN is routed to ingress, to ClusterIP service on port 3000 to your pods.

Kubernetes Externalname service - how to connect

We have two clusters. cluster1 has namespace- test1 and a service running as clusterip
we have to call that service from another cluster(cluster2) from namespace dev1.
I have defined externalname service in cluster2 pointing to another externalname service in cluster1.
And externalname service in cluster1 points to the original service running as clusterip.
In cluster2:
kind: Service
apiVersion: v1
metadata:
name: service
namespace: dev1
labels:
app: service
spec:
selector:
app: service
type: ExternalName
sessionAffinity: None
externalName: service2.test.svc.cluster.local
status:
loadBalancer: {}
In cluster1:Externalname service
kind: Service
apiVersion: v1
metadata:
name: service2
namespace: test1
labels:
app: service
spec:
selector:
app: service
type: ExternalName
sessionAffinity: None
externalName: service1.test1.svc.cluster.local
status:
loadBalancer: {}
in cluster1 clusterip service:
kind: Service
apiVersion: v1
metadata:
name: service1
namespace: test1
labels:
app: service1
spec:
ports:
- name: http
protocol: TCP
port: 9099
targetPort: 9099
selector:
app: service1
clusterIP: 102.11.20.100
type: ClusterIP
sessionAffinity: None
status:
loadBalancer: {}
But, there is no hit to the service in cluster1. I tried to add spec:port:9099 in externalname services as well, still it does not work.
What could be the reason. Nothing specific in logs too
This is not what ExternalName services are for.
ExternalName services are used to have a cluster internal service name that forwards traffic to another (internal or external) DNS name. In practice what an ExternalName does is create a CNAME record that maps the external DNS name to a cluster-local name. It does not expose anything out of your cluster. See documenation.
What you need to do is expose your services outside of your kubernetes clusters and they will become usable from the other cluster as well.
There are different ways of doing this.
For example:
NodePort service: when using a NodePort, your service will be exposed on each node in the cluster on a random high port (by default in the 30000-32767 range). If your firewall allows traffic to such port you could reach your service from using that port.
LoadBalancer service: if you are running kubernetes in an environment that supports Load Balancer allocation you could expose your service to the internet using a load balancer.
Ingress: if you have an ingress controller running in your cluster you could expose your workload using an Ingress.
On the other cluster, you could simply reach the service exposed.

Kubernetes external-IP doesn't work on all nodes

I have created a Kubernetes cluster by Kubeadm with 3 nodes. Their IP address and hostname are 10.10.10.146/24(k8s1, master), 10.10.10.135/24(k8s2), 10.10.10.170/24(k8s3).
Now I create a nginx service which contains 3 pods with this yaml file:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-app
image: nginx:1.14.0
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-app-srv
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
externalIPs:
- 10.10.100.1
Finally one of the pods was scheduled to k8s2 and two of them to k8s3.
Then if I route 10.10.100.0/24 to k8s2, only one pod work. If to k8s3, only two pods work. And if to k8s1, no pods work.
How can I make all pods work fine through external-IP from outside just like through cluster-IP from inside no matter which node I route the external-IP subnet to? Or that's not possible or I need something else such as Kubernetes Ingress?
There are several options to expose your service outside the cluster:
The first option is to use NodePort type of Kubernetes Service. This way Service will open a port on the network interface of each node in the cluster, and all traffic coming to that port will be forwarded to the service.
By default, port range for this kind of service is limited to 30000–32767.
Here is an example of Service NodePort configuration:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
type: NodePort
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
nodePort: 30080
The second option is available if you are running Kubernetes cluster in the clouds like AWS, GCP, Azure. If you create LoadBalancer type of service, it will create a new load balancer in the cloud and forward all traffic from that load balancer to the service.
The downside of this way is that each service creates a separate load balancer, which will cost you additional money.
Here is an example of Service LoadBalancer configuration:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
type: LoadBalancer
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
The third option is to use an Ingress object. An Ingress controller should be running in the cluster to configure the cloud networking according to the content of the Ingress object you created. Ingress can provide you functionality of routing requests to different services depending of dns name and URI path. You can also use it on bare-metal Kubernetes cluster, but in this case, you are responsible for routing network traffic to the Ingress controller, for example by firewall rules.
Here are a couple of examples of Ingress configuration:
# redirect all traffic to a service
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
backend:
serviceName: testsvc
servicePort: 80
# redirect traffic to a service for specified URI path
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80

Get an external IP for a Kubernetes LoadBalancer on Openstack

I'm just new with Kubernetes, I'm using OpenStack and I would like to create a load balancer to access my NodeJs server running on 3 pods. I get a pending loop when my load balancer try to get its public ip. I'm using kubeadm with calico.
Screen: Pending External IP
This is a workaround method. You can mention the external IP:
apiVersion: v1
kind: Service
metadata:
name: node-js
labels:
name: node-js
spec:
type: LoadBalancer
externalIPs:
- 10.240.0.4
ports:
- port: 80
targetPort: 80
nodePort: 30000
selector:
name: node-js

How to Kubernetes Angular.js service request backendapi service

----------------------- Thats backandapi Service-----------------------
apiVersion: v1
kind: Service
metadata:
name: backandapi-service
namespace: crm
labels:
app: backandapi-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: backandapi
And, Angular.js request to this service but Service changing ip adress.
How to access Services external endpoint from env or similar.
Depending on what provides your loadbalancer you will see different ways of doing this. Said short kubectl describe <your_svc> would return something like LoadBalancer Ingress firld, that on aws will look similar to blablabla-123123.eu-west-1.elb.amazonaws.com which you can use to access regardless of underlying IP