Is it somehow possible to expose a kubernetes service to the outside world? I am currently developping an application which need to communicate with a service, and to do so I need to know the pod ip and port address, which I withing the kubernetes cluster can get with the kubernetes services linked to it, but outside the cluster I seem to be unable to find it, or expose it?
apiVersion: v1
kind: Service
metadata:
name: kafka-broker
spec:
ports:
- name: broker
port: 9092
protocol: TCP
targetPort: kafka
selector:
app: kafka
sessionAffinity: None
type: ClusterIP
I could containerize the application, put it in a pod, and run it within kubernetes, but for fast development it seems tedious to have to go through this, for testing such a small things such as connectivity?
Someway i can expose the service, and thereby reach the application in its selector?
you can use: NodePort or Load balancer type services as mentioned in other answers. or even ingress.
But as you are asking for developer purpose only, I suggest to start a testing pod in given namespace and check connectivity from that pod. You can get actual SSH access to running pod kubectl exec -it {PODNAME} /bin/sh
Use Service type as NodePort or Loadbalancer. Latter is recommended if you are running in cloud like Azure,AWS or GCD
refer the same below
apiVersion: v1
kind: Service
metadata:
name: kafka-broker
spec:
ports:
- name: broker
port: 9092
protocol: TCP
targetPort: kafka
selector:
app: kafka
sessionAffinity: None
type: NodePort
In order to expose your Kubernetes service to the internet you must change the ServiceType
.
Your service is using the default which is ClusterIP
, it exposes the Service on a cluster-internal IP, making it only reachable within the cluster.
1 - If you use cloud provider like AWS or GCP The best option for you is to use the LoadBalancer
Service Type: which automatically exposes to the internet using the provider Load Balancer.
Run: kubectl expose deployment deployment-name --type=LoadBalancer --name=service-name
Where deployment-name
must be replaced by your actual deploy name. and the same goes for the desired service-name
wait a few minutes and the kubectl get svc
command will give you the external IP and PORT:
owilliam@minikube:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d21h
nginx-service-lb LoadBalancer 10.96.125.208 0.0.0.0 80:30081/TCP 36m
2 - If you are running Kubernetes locally (like Minikube) the best option is the Nodeport
Service Type: It it exposes the service to the Cluster Node( the hosting computer). Which is safer for testing purposes than exposing the service to the whole internet.
Run: kubectl expose deployment deployment-name --type=NodePort --name=service-name
Where deployment-name
must be replaced by your actual deploy name. and the same goes for the desired service-name
Bellow are my outputs after exposing an Nginx webserver to the NodePort
for your reference:
user@minikube:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d21h
service-name NodePort 10.96.33.84 <none> 80:31198/TCP 4s
user@minikube:~$ minikube service list
|----------------------|---------------------------|-----------------------------|-----|
| NAMESPACE | NAME | TARGET PORT | URL |
|----------------------|---------------------------|-----------------------------|-----|
| default | kubernetes | No node port |
| default | service-name | http://192.168.39.181:31198 |
| kube-system | kube-dns | No node port |
| kubernetes-dashboard | dashboard-metrics-scraper | No node port |
| kubernetes-dashboard | kubernetes-dashboard | No node port |
|----------------------|---------------------------|-----------------------------|-----|
user@minikube:~$ curl http://192.168.39.181:31198
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...//// suppressed output
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
user@minikube:~$