CKAD theory pt.6 - Service Networking
This is part 6 of my personal notes I’ve written during preparation to CKAD.
Configuration
Services
Services provides an abstraction layer which provides network access to a dynamic set of pods.
Most services use selector
to determine which pods will receive traffice through
the service. All pods included in the service(also called Endpoints) are added and
removed to/from service dynamically without interruption for clients.
You can expose pod (po), service (svc), replicationcontroller (rc), deployment (deploy)
or a replicaset (rs) as a Service.
Service types
There are four service types in Kubernetes:
ClusterIP
- The services is exposed within the cluster using an internal IP address. The service is also accessible using the cluster DNS.NodePort
- The service is exposed externally via a port which listens on each node in the cluster.LoadBalancer
- The service is exposed through a load balancer outside of the clusterExternalName
- This maps the service to an external address. It is used to allow resources within the cluster to access things outside the cluster through a service. This only sets up a DNS mapping. It does not proxy traffic.
Exposing Kuberenetes resource as a Service via YAML
For example, to redirect traffic incoming to Service on port 80 to any pods with
label app=MyApp
to port 9376 define following YAML:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Exposing Kubernetes resource as a Service via CLI
Services can be exposed via kubectl expose
command. It will create a new Service object.
kubectl expose deployment nginx-deployment --port=443 --target-port=8443 --name=nginx-https --dry-run -o yaml
Or even shortened:
kubectl expose deployment nginx-deployment
The latter command will use the same name as deployment name, will use containerPort directive to determine port and targerPort.
NetworkPolicies
By default, pods are non-isolated. They accept traffic from any source, even from different namespaces. NetworkPolicies allow you restric traffic to only the traffic flows you actually want to allow. Once you’ve applied a NetworkPolicy to a POD, all traffic is denied, and only allowed traffic will flow.
- If there are not policies, all traffic is allowe
- If there is only a ingress policy, traffic FROM the sources mentioned in the ingress policy is allowed
- If there is only a egress policy, traffic TO the sources mentioned in the egress policy is allowed
- If there is a combination of ingress and egress policies, only traffic allowed by both will flow.
NetworkPolicy by itself is a separate Kubernetes object. Main NetworkPolicy fields:
podSelector
- determines which pods the NetworkPolicy applies topolicyTypes
- set ingress, egress or bothingress
- rules for incoming trafficegress
- rules for outgoing trafficrules
- whitelist(all not mentioned is blocked) rulesports
- specifies the protocols and ports that match the rulefrom/to
- selector that specifies the source(s) and destination(s) of network traffic that match the rule
Ingress and egress supports four kind of selectors to determine what to add to whitelist:
podSelector
- matches traffic from/to pods which match the selectornamespaceSelector
- matches traffic from/to pods which match the selector.namespaceSelector
andpodSelector
- If both podSelector and namespaceSelector are present, pods must match both for traffic to be allowedipBlock
- CIDR range of IPs
Here’s an example of NetworkPolicy in YAML:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
This rule isolated pods with role=db
in the default
namespace for both ingress and egress. Ingress allows
connections to all pods in the default
namespace with the label role=db
on TCP port 6379 from the matching
pods to the rules. Egress allows connection from any pod in the default
namespace with the label role=db
to CIDR on TCP port 5978.
You can get information on current NetworkPolicies in the cluster by:
kubectl get networkpolicies
kubectl describe networkpolicy my-network-policy
NetworkPolicies on AKS
To AKS cluster support NetworkPolicies, they must be enabled on creation. They aren’t enabled by default.
To enable them, create your cluster with --networkpolicy calico
on your az aks create
. It cannot
be applied after a cluster has already been created.
Links
- https://kubernetes.io/docs/concepts/services-networking/service/
- https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/
- https://blog.nillsf.com/index.php/2019/08/18/ckad-series-part-7-services-and-networking/
- https://kubernetes.io/docs/concepts/services-networking/network-policies/
Comments