In this section you will learn how to access your application from outside your cluster, and do service discovery.
If it's not already done install the minikube
addon ingress
:
$ minikube addons enable ingress
✅ ingress was successfully enabled
You are able to deploy an image with multiple replicas, but it is not very convenient to access it. You need to know the IP of a pod
to be able to target your application. And it's not accessible from the outside of the cluster.
What we need is a service
. It'll allow us to access our pods internally or externally.
First apply the deployment
:
$ kubectl apply -f 08-service/01-simple-deployment.yml
deployment.apps "simple-deployment" created
Now start another container. We will use it to see what we can access internally inside Kubernetes:
Apply the pod:
$ kubectl apply -f 08-service/02-bash.yml
pod "bash" created
And connect to it:
$ kubectl exec -it bash -- /bin/bash
root@bash:/#
Install dnsutils
& curl
in the container, you will need them:
root@bash:/# apt update && apt install dnsutils curl
[...]
You now have a shell inside a Kubernetes pod running in your cluster. Let this console open so you can type commands.
Try to curl one of the pods created by the deployment above. How can you access the deployment
without targeting a specific pod
?
Ok, now let's create our first service 03-internal-service.yml:
apiVersion: v1
kind: Service
metadata:
name: simple-internal-service
spec:
ports:
- port: 80
targetPort: 9876
selector:
app: simple-deployment
Let's have a look at the manifest:
kind
: Aservice
has the kindService
spec
:ports
: the list of ports to expose. Here we exportport
80
, but redirect internally all traffic to thetargetPort
9876
selector
: which pods to give access to
The selector part
selector:
app: simple-deployment
is central to Kubernetes. It is with those fields that you will tell Kubernetes which pods to give access through this service
.
Apply the service:
$ kubectl apply -f 08-service/03-internal-service.yml
service "simple-service" created
Your service is now accessible internally, try this in your bash
container:
root@bash:/# nslookup simple-internal-service
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: simple-internal-service.default.svc.cluster.local
Address: 10.96.31.244
Try to curl the /health
url, remember the ports
we choose in the service
.
Can you access this service from the outside of Kubernetes?
The answer is no, it's not possible. To do this you need an ingress
. Ingress means "entering into".
You need to connect internet to the ingress
that'll connect it to a service:
internet
|
[ ingress ]
--|-----|--
[ service ]
Let's create our ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: simple-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
backend:
serviceName: simple-internal-service
servicePort: 80
Let's have a look at the manifest:
kind
: Ingressmetadata
:annotations
: some annotations specific to the ingressnginx.ingress.kubernetes.io/ssl-redirect
: To fix a redirect, see this. This is only used if you use the nginx ingress
spec
:backend
: the default backend to redirect all the requests toserviceName
: the name of the Kubernetes traffic to redirect toservicePort
: the port of the service
Apply the ingress:
$ kubectl apply -f 08-service/04-ingress.yml
ingress.extensions "simple-ingress" created
Get the IP of your minikube cluster:
$ minikube ip
192.168.99.100
Open a browser on http://192.168.99.100/info
With this manifest we have a deployment
that manages pods. A service
that gives access to the pods, and an ingress
that gives access to the pod to the external world.
You have seen a lot different kind
of Kubernetes, let's take a step back and see how each kind
interact with each other:
+----------------------------------------------------------------------------------+
| |
| +-----------------------------+ |
| | | |
| | +-------------+ | |
| | | | | |
| | -> Pod | | |
| | --/ | | | |
+-------------+ +-------------+ | ---/ +-------------+ | |
| | | | | | --/ | |
| Ingress -----> Service ------------------\ | |
| | | | | | --\ +-------------+ | |
+-------------+ +-------------+ | ---\ | | | |
| | --\ | Pod | | |
| | -> | | |
| | +-------------+ | |
| | | |
| | Deployment | |
| +-----------------------------+ |
| |
| |
| |
| Kubernetes |
+----------------------------------------------------------------------------------+
- Deploy an nginx and expose it internally
- Read this and modify the ingress to have:
/simple
that goes to thesimple-service
/nginx
that goes to your nginx deployment
- Change the
selector
in yoursimple-service
look at what is happening
kubectl delete ingress,service,deployment,rs,pod --all
For 2), you need to add the metadata nginx.ingress.kubernetes.io/rewrite-target: /
to the ingress:
- It is possible to capture groups from paths into numbered placeholders and pass them to the rewrite target: https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md#rewrite-target
- Don't forget to create 2 deployments and 2 services.
- You can either change your
/etc/hosts
to add the name resolution forfoo.bar.com
, or usecurl http://YOUR-IP -H "Host: foo.bar.com"
- https://kubernetes.io/docs/concepts/services-networking/service/
- https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
- https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/
- https://kubernetes.io/docs/concepts/services-networking/ingress/
- https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/