A Service is an abstraction of a logical set of pods that helps define inbound and outbound network access. A Service uses a selector to target pods using the pods’ label. A Service exposes a logical set of pods as a network service providing a single IP address, DNS name, or load balancing to access the pods.
The Service type is defined in the manifest. The following are available Service types:

  • ClusterIP - exposes the service on an internal IP in the Kubernetes cluster (default)
  • NodePort - exposes the service on the same port of each node in the Kubernetes cluster
  • ExternalName - exposes the service using an arbitrary name
  • LoadBalancer - creates an external load balancer with a cloud provider (e.g. GCE ForwardingRules, AWS Elastic Load Balancer, Azure Load Balancer) and assigns a public IP to the service

ClusterIP Services are only accessible from within the Kubernetes cluster; all other options can handle requests to the Service from outside the Kubernetes cluster.
Services can be created imperatively for a running resource. At minimum the resource, object, and the service’s exposed proxy port are required e.g. kubectl expose [resource] [object] --port=[port number].
By default if no other options are given, a ClusterIP Service is created and the port specified is both the service’s proxy port on the local node and the container’s target port.
The following example creates a service for a deployment of two nginx pods. The service’s proxy port is 8080 to the container’s port 80.
First create the Deployment of 3 replicas of nginx and get endpoints of the deployment’s pods. We can use the deployment’s run label to output only the Deployment’s pods.

$ kubectl create deployment nginx --image=nginx:latest --replicas=3

deployment.apps/nginx created

$  kubectl get deploy --show-labels

nginx   3/3     3            3           7s    run=nginx

$ kubectl get pods -l run=nginx -o wide

nginx-9ffc7d87b-c6rmj   1/1     Running   0          79s   ubuntu   <none>    <none> 
nginx-9ffc7d87b-rnfq4   1/1     Running   0          79s   ubuntu   <none>    <none> 
nginx-9ffc7d87b-xq5r5   1/1     Running   0          79s   ubuntu   <none>    <none> 


Create a Service that exposes the Deployment on a proxy port of 8080 to the Deployment’s containers’ port 80. A Service is imperatively created by using kubectl expose.

$ kubectl expose deploy nginx --port=8080 --target-port=80 

service/nginx exposed


Describe the Service to verify its targets, shown in the Endpoints:

$ kubectl describe service nginx

Name:              nginx
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
Selector:          run=nginx
Type:              ClusterIP
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Session Affinity:  None

The Service defaulted to a ClusterIP type; the Service is only accessible from within the Kubernetes cluster. Creating a Service imperatively on a Deployment automated the label selector used to target the Deployment e.g. run=nginx. We confirm the proxy port is 8080 and sends traffic to port 80 on the container’s IP addresses.
Learn more about Services

Network Policies

Network policies determine how groups of pods communicate with each and other network endpoints. The network policy spec uses label selectors to target pods and defines inbound and outbound traffic rules for those pods. By default, pods accept traffic from any source. When a network policy selects pods within the same namespace, the network policy rejects any connections not allowed by the network policy. Network policies control ingress (inbound), egress (outbound), or both kinds of traffic between pods.
A Container Network Interface (CNI) network plugin implements network policies therefore a CNI plugin is required. Network Policies do not function in clusters that do not use a compatible CNI plugin.
The following selectors are used by network policies to target pods:

  • podSelector - selects pods using labels (pods must be in the same namespace as the network policy)
  • namespaceSelector - selects pods in an entire namespace for the ingress source or egress destination
  • podSelector and namespaceSelector - selects pods from a specific namespace
  • ipBlock - selects IP CIDR ranges to allow as an ingress source or egress destination

Network policies cannot be created imperatively. Kubernetes documentation provides several examples. This example denies all ingress traffic to pods in the namespace:

kind: NetworkPolicy
  name: default-deny-ingress
  podSelector: {}
  - Ingress

With the above deny-all network policy in place, an ingress network policy is required to allow inbound network traffic to reach affected pods.
The following example allows ingress traffic from pods labeled “network: allowed” to pods in the namespace.

kind: NetworkPolicy
  name: allow-all-ingress
  podSelector: {}
  - Ingress
  - from:
    - podSelector:
        network: allowed

Learn more about Network Policies

Practice Drill

  • Create a Deployment of 3 nginx pods.
  • Create a Service that exposes the Deployment outside the Kubernetes cluster on the Node Port 80.

As an additional exercise, try creating an nginx pod, a busybox pod, and a deny-all network policy then create an ingress network policy that uses a label from the busybox pod to allow traffic to the nginx pod.

RX-M offers complete CKAD Boot Camps to make securing your CKAD certification manageable.


Our team has been trusted to work alongside some of the world's leading companies