Kubernetes Service: ExternalName

adil
3 min readJul 31, 2023

When you need to expose a pod, you should create a service and you should map the service to the pod.

However, you may map a service to an external domain as well.

Prerequisite:

I have a namespace: web
I have 2 pods in the web namespace: hello-nginx, hello-apache

I have a namespace: cache
I have a pod in the cache namespace: redis-cache

You can map your service to an external resource:

apiVersion: v1
kind: Service
metadata:
name: external-db-access
namespace: web
spec:
type: ExternalName
externalName: google.com

Make sure that your service has created:

kubectl describe svc/external-db-access -n web

Connect to the pod and check the DNS address of the service external-db-access:

➜  ~ kubectl exec -it hello-nginx -n web -- /bin/bash
root@hello-nginx:/# curl external-db-access
<!DOCTYPE html>
...

So, when I try to access to the service external-db-access in the namespaceweb, I will be forwarded to google.comthrough DNS.

Kubernetes will create a CNAME record on external-db-access service with the value google.com

Can I access external-db-access in another namespace?

Yes and no.

I have another pod in the cache namespace.

➜ ~ kubectl exec -it redis-cache -n cache — /bin/bash
root@redis-cache:/data# curl external-db-access
curl: (6) Could not resolve host: external-db-access

I can’t contact this domain directly since external-db-accessis in another namespace.

I need to specify the full FQDN of the external-db-access service in the cache namespace:

➜ ~ kubectl exec -it redis-cache -n cache — /bin/bash
root@redis-cache:/data# curl external-db-access.web.svc.cluster.local
<!DOCTYPE html>
...

Is there another use case for ExternalName?

If you want to access a service in another namespace, you may need ExternalName.

I will delete the serviceexternal-db-access in the web access:

➜ ~ kubectl delete svc/external-db-access -n web
service “external-db-access” deleted

I will expose the pod hello-nginx :

apiVersion: v1
kind: Service
metadata:
labels:
app: hello-nginx-expose
name: hello-nginx-expose
namespace: web
spec:
ports:
- name: 8181-80
port: 8181
protocol: TCP
targetPort: 80
selector:
run: hello-nginx
type: NodePort

I will try to access the podhello-nginxfrom the podhello-apache:

➜ ~ kubectl exec -it hello-apache -n web — /bin/bash
root@hello-apache:~# curl hello-nginx-expose:8181
<!DOCTYPE html>
...

Since the pod hello-nginx and the pod hello-apache in the same namespace, I can access it.

I can’t access it in the podredis-cache. Because it is in another namespace:

➜ ~ kubectl exec -it redis-cache -n cache — /bin/bash
root@redis-cache:/data# curl hello-nginx-expose:8181
curl: (6) Could not resolve host: hello-nginx-expose

I can access via full FQDN though:

➜  ~ kubectl exec -it redis-cache -n cache -- /bin/bash
root@redis-cache:/data# curl hello-nginx-expose.web.svc.cluster.local:8181
<!DOCTYPE html>
...

If you don’t want to access the service hello-nginx-exposevia full FQDN, you may want to create a service in the cache namespace:

apiVersion: v1
kind: Service
metadata:
name: hello-nginx-expose-reference
namespace: cache
spec:
type: ExternalName
externalName: hello-nginx-expose.web.svc.cluster.local

hello-nginx-expose-reference will be an alias for hello-nginx-expose.web.svc.cluster.local :

➜ ~ kubectl exec -it redis-cache -n cache — /bin/bash
root@redis-cache:~# curl hello-nginx-expose-reference:8181
<!DOCTYPE html>
...

--

--