Kubernetes – Endpoints
February 4, 2019It’s quite possible that you could have a Kubernetes cluster but never have to know what an endpoint is or does, even though you’re using them behind the scenes. Just in case you need to use one though, or if you need to do some troubleshooting, we’ll cover the basics of Kubernetes endpoints in this post.
Endpoints – The Theory
During the post where we first learned about Kubernetes Services, we saw that we could use labels to match a frontend service with a backend pod automatically by using a selector. If any new pods had a specific label, the service would know how to send traffic to it. Well the way that the service knows to do this is by adding this mapping to an endpoint. Endpoints track the IP Addresses of the objects the service send traffic to. When a service selector matches a pod label, that IP Address is added to your endpoints and if this is all you’re doing, you don’t really need to know much about endpoints. However, you can have Services where the endpoint is a server outside of your cluster or in a different namespace (which we haven’t covered yet).
What you should know about endpoints is that there is a list of addresses your services will send traffic and its managed through endpoints. Those endpoints can be updated automatically through labels and selectors, or you can manually configure your endpoints depending on your use case.
Endpoints – In Action
Let’s take a look at some endpoints that we’ve used in our previous manifests. Lets deploy this manifest as we did in our previous posts and take a look to see what our endpoints are doing.
apiVersion: apps/v1 #version of the API to use
kind: Deployment #What kind of object we're deploying
metadata: #information about our object we're deploying
name: nginx-deployment #Name of the deployment
labels: #A tag on the deployments created
app: nginx
spec: #specifications for our object
replicas: 2 #The number of pods that should always be running
selector: #which pods the replica set should be responsible for
matchLabels:
app: nginx #any pods with labels matching this I'm responsible for.
template: #The pod template that gets deployed
metadata:
labels: #A tag on the replica sets created
app: nginx
spec:
containers:
- name: nginx-container #the name of the container within the pod
image: nginx #which container image should be pulled
ports:
- containerPort: 80 #the port of the container within the pod
---
apiVersion: v1 #version of the API to use
kind: Service #What kind of object we're deploying
metadata: #information about our object we're deploying
name: ingress-nginx #Name of the service
spec: #specifications for our object
type: NodePort #Ignore for now discussed in a future post
ports: #Ignore for now discussed in a future post
- name: http
port: 80
targetPort: 80
nodePort: 30001
protocol: TCP
selector: #Label selector used to identify pods
app: nginx
Code language: PHP (php)
We can deploy this manifest running:
kubectl apply -f [manifest file].yml
Code language: CSS (css)
Now that its done we should be able to see the endpoints that were automatically created when our service selector matched our pod label. To see this we can query our endpoints through kubectl.
kubectl get endpoints
Code language: JavaScript (javascript)
Your results will likely have different addresses than mine, but for reference, here are the endpoints that were returned.
The ingress-nginx endpoint is the one we’re focusing on and you can see it has two endpoints listed, both on port 80.
Now those endpoints should be the IP addresses of our pods that we deployed in our manifest. To test this, lets use the get pods command with the -o wide switch to show more output.
kubectl get pods -o wide
Code language: JavaScript (javascript)
You can see that the IP addresses associated with the pods matches the endpoints. So we proved that the endpoints are matching under the hood.
How about if we want to manually edit our endpoints if we don’t have a selector? Maybe we’re trying to have a resource to access an external service that doesn’t live within our Kubernetes cluster? We could create our own endpoint to do this for us. A great example might be an external database service for our web or app containers.
Let’s look at an example where we’re using an endpoint to access an external resource from a container. In this case we’ll access a really simple web page just for a test. For reference, I accessed this service from my laptop first to prove that it’s working. If you’re doing this in your lab, you’ll need to spin up a web server and modify the IP Addresses accordingly.
I know that it’s not very exciting, but it’ll get the job done. Next up we’ll deploy our Endpoint and a service with no selector. The following manifest should do the trick. Notice the ports used and the IP Address specified in the endpoint.
kind: "Service"
apiVersion: "v1"
metadata:
name: "external-web"
spec:
ports:
-
name: "apache"
protocol: "TCP"
port: 80
targetPort: 80
---
kind: "Endpoints"
apiVersion: "v1"
metadata:
name: "external-web"
subsets:
-
addresses:
-
ip: "10.10.50.53" #The IP Address of the external web server
ports:
-
port: 80
name: "apache"
Code language: PHP (php)
Then we’ll deploy the manifest file to get our service and endpoint built.
kubectl apply -f [manifest file]
Code language: CSS (css)
Let’s check the endpoint just to make sure it looks correct.
kubectl get endpoints
Code language: JavaScript (javascript)
Once the service and endpoint are deployed, we’ll deploy a quick container into our cluster so we can use it to curl our web page as a test. We’ll use the imperative commands instead of a manifest file this time.
kubectl create -f https://k8s.io/examples/application/shell-demo.yaml
kubectl exec -it shell-demo -- /bin/bash
apt-get update
apt-get install curl
curl external-web
Code language: JavaScript (javascript)
The curl command worked when performing a request against the “external-web” service, so we know it’s working!
Summary
If you’ve been following the series so far, you’ve already been using endpoints but just didn’t know it. You can add your own endpoints manually if you have a use case such as accessing a remote service like a database but for now its probably enough just to get the idea that they exist and that you can modify them if necessary.
As your said, you mean we can add public ip or some ip that the cluster have reachability, we can add this ip as an endpoint and can be used as internal k8s svc ?
Sorry for my bad english.
How do the endpoint and service know each other? I mean, with the shell-demo pod, it sends a request to the service using its name, and then the service finds the right endpoint… by its metada name? or by the port’s name?
[…] 5. Endpoints […]
How we can target external dynamic endpoint.
Do we need to define a cron job for that if yes
How I can pass output of that file as endpoints
I want to point out that the post uses an external endpoint as an example.
In general, endpoints are created for you automatically when creating a “Service”. You can use endpoints for your own purposes, but I’m not sure that Kubernetes was really meant to use endpoints for external resources.
You could setup a cron job to update the endpoints if you wanted to do that, or create a controller that updated the endpoints as needed.
If you’re doing a lot of dynamic updates perhaps a service mesh is needed instead.
for example, I have one address that is an api endpoint and it has some URIs in there, like http://172.17.0.1:3002/document/456789000145
I tried to do your example but it did not work for this.
How can I proceed?
[…] Control Plane (its kube-controller-manager) will remove the pod from the endpoints (see Kubernetes – Endpoints) and a corresponding Service will stop sending traffic to this […]
[…] the good news is that the the internet is awash of articles about this. However, after attempting to implement any of them, I was consistently getting 502 errors – […]