Before discussing the Kubernetes approach to networking, it is worthwhile to contrast it with the "normal" way networking works with Docker.

Be default, Docker uses host-private networking, so containers can talk to other containers only if they are on the same machine. In order for Docker containers to communicate across nodes, there must be allocated ports on the machine's own IP address, which are then forwarded or proxied to the containers.

Coordinating ports across multiple developers is very difficult to do at scale and exposes users to cluster-level issues outside of their control. Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. We give every pod its own cluster-private-IP address so you do not need to explicitly create links between pods or map container ports to host ports. This means that containers within a pod can all reach each other's ports on localhost, and all pods in a cluster can see each other without a NAT.

Exposing pods to the cluster

Create a nginx deployment, and note that it has a container port specification. This makes it accessible from any node in your cluster.

apiVersion: apps/v1
kind: Deployment
metadata:
	name: my-nginx
	namespace: my-nginx
spec:
	selector:
		matchLabels:
			run: my-nginx
	replicas: 2
	template:
		metadata:
			labels:
				run: my-nginx
		spec:
			containers:
			- name: my-nginx
				image: nginx
				ports:
				- containerPort: 80

Check the nodes the pod is running on:

kubectl create ns my-nginx

kubectl -n my-nginx apply -f ${yaml-file}

kubectl -n my-nginx get pods -o wide

Creating a Service

So we have pods running nginx in a flat, cluster wide, address space. In theory, you could talk to these pods directly, but what happens when a node dies? The pods die with it, and the Deployment will create new ones, with different IPs. This is the problem a Service solves.

A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality. When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the Service, and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service.

You can create a Service for your 2 nginx replicas with kubectl expose: