Certified Kubernetes Administrator: Core Concepts
Cluster Architecture#
Control Plane#
Master Node: Manage, Plan, Schedule, and Monitor Nodes
ETCD Cluster: Highly available key/value database
kube-scheduler: Identifies the right node to place a container on
Node-Controller: Manages nodes
Replication-Controller: Ensures desired number of containers are running in a replication group
kube-apiserver: Orchestrates all operations within the cluster and exposes the API\
Workers#
Worker Nodes: Host applications as Containers
A container runtime engine, like Docker, must be installed and available on all nodes
kubelet: Agent that runs on each node in a cluster and listens for instructions from the API as well as monitors status of all the other node
kube-proxy: Service ensures that the rules are in place on the worker nodes so the containers can communicate between each othe
Docker vs. Containerd#
Docker support was removed from Kubernetes, but Docker images still work because they adhere to imagespec
containerd: Container runtime used by Docker that can be ran by itselfctr
: Debugging tool bundled with containerdnerdctl
: Provides a Docker-like for containerd
Supports docker compose
Supports newest features in containerdcrictl
: Provides a CLI for Container Runtime Interface (CRI) compatible container runtimes
Installed separately
Used to inspect and debug container runtimes
Works across different runtimes
ETCD for Beginners#
ETCD is a distributed reliable key-value store
Key-Value Store: Stores information as documents and all information on an item is contained in the corresponding document
To install ETCD, download and extract the binary then run the service
It will run on port 2379 and clients can be attachedetcdctl
: Command client
etcdctl put key1 value1
: Sets a key
ectdctl get key1
: Gets a key value
ETCD in Kubernetes#
Stores information on the Nodes, PODs, Configs, Secrets, etc.
All changes are updated in the ETCD server, and is not considered completed until changed\
Setup#
Manual#
The binary is downloaded, then manually set as a service by executing the etcd
command with the required options
kubeadm#
ETCD is deployed as a pod in the clustedkubectl exec etcd-master -n kube-system etcdctl get / --prefic -keys-only
: Get keys stored in the ETCD pod\
In a HA Environment, there are multiple ETCD masters
Kube-API Server#
When running a command, it is sent to the kube-apiserver
POST requests can also be sent in place of commands:curl -X POST /api/v1/namespaces/default/pods ...
: Creates a Pod
The scheduler detects there is a pod with no node assigned, then chooses a pod and communicates to the kube-apiserver
The apiserver instructs the kubelet to create a pod
The kubelet communicates the change to the apiserver, which updates ETCD
Kube Controller Manager#
A controller is a process that continuously monitors the system and takes necessary actions to keep the system in a specified state
Node Controller: Responsible for monitoring the status of the nodes and takes action to keep applications running
Checks status every 5 second
After 40 seconds of no heartbeat, a node is marked unreachable
After 5 minutes, the node is evicted and pods are moved to healthy nodes
Replication Controller: Responsible for monitoring the status of replicasets and ensures the number of pods are available within a set
If a pod dies, it creates another pod
There are many types of controllers in a Kubernetes Cluster, and are all packaged in the Kube-Controller-Manager
kubeadm deploys the kube-controller-manager as a pod\
Kube Scheduler#
Responsible which pod goes on which node
Does not actually place the pod, the kubelet does
The scheduler looks at each pod and finds the correct node for it based on requirements (CPU, Memory, Labels, etc.)
The scheduler ranks the nodes and assigns on a rank from 0-10
kubeadm deploys the scheduler as a pod
Kubelet#
- Registers nodes
- Creates pods
- Monitors nodes and pods The kubelet service is not installed by kubeadm and must be manually installed on each node
Kube Proxy#
Every pod can reach every pod
A pod network is an internal network each pod communicates with
Applications are deployed as services so they can be available to the cluster
The service has an assigned IP
kube-proxy: Process that runs on each that looks for new services, then creates the appropriate rules to route traffic through the pods
kubeadm deploys kube-proxy as a pod
Pods#
Pod: A single instance of an application and is the smallest object that can be created in Kubernetes
Containers are not added to existing pods to scale
Pods can container multiple containers, but the containers are not of the same imagekubectl run nginx --image nginx
: Deploys a docker container by creating a pod using the NGINX Docker Imagekubectl get pods
: Lists Pods
Pods with YAML#
Kubernetes uses YAML files as inputs for creation of objects
A Kubernetes definition file always contains the following four top-level fields:
apiVersion: v1
kind: Pod
metadata:
name: myapp-prod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
- image: nginx
apiVersion
: The version of the API the object will be created withkind
: Type of object being createdmetadata
: Data about the object in the form of a dictionaryspec
: Specifications pertaining to the objectkubectl create -f pod-definition.yml
: Creates the object listed in the specified filekubectl describe pod myapp-pod
: Lists information on the specified pod
ReplicaSets#
Replication Controller: Runs multiple instances of a single Pod in a cluster
A replication controller also brings up new pods when a pod fails and ensures the necessary number of pods are running
Replication assists with load balancing and scaling by deploying multiple nodes in the cluster across nodes
ReplicaSet: New recommended utility to manage replication
To create a replication controller:
rc-definition.yml
:
apiVersion: v1
kind: ReplicationController
metadata:
name: myapp-rc
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-prod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
template
: Pod template to be created by the replication controller, which will contain the contents of a Pod YAML filekubectl create -f rc-definition.yml
: Creates the replication controllerkubectl get replicationcontroller
: Lists replication controller\
To create a replicaset:replicaset-definition.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-replicaset
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-prod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
selector
: Identifies applicable pods, as ReplicaSets can manage pods that were not created by it. It is not a required fieldkubectl create -f replicaset-definition.yml
: Creates the replicasetkubectl get replicaset
: Lists replicasets
ReplicaSets can begin monitoring existing pods upon creation if said pods match the selector criteriakubectl delete replicaset myapp-replicaset
: Deletes the specified replicaset and the underlying pods\
Scale#
To scale:
- Manually edit the
replicas
value in the definition file - Use the
kubectl scale --replicas=6 -f replicaset-definition.yml
command - Use the
kubectl scale --replicas=6 replicaset myapp-replicaset
command
Deployments#
Rolling Updates: Updating pods one by one to limit impact to accessibility
Deployment: Object that provides capability to upgrade with rolling updates, as well pause, and resume changesdeployment-definition.yml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-prod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
kubectl create -f deployment-definition.yml
: Creates the deployment
kubectl get deployments
: Lists deployments
kubectl get all
: Shows all objects created
Services: Node Port#
Services enable connectivity between groups of pods and external sources
Services are deployed as an object
Node Port Service: Listens to a port on the node and forward requests to a port running on the application
Target Port: Port on the pod that requests are forwarded to
Port: The port on the service
Node Port: Physical port on the Node that ranges from 30008-3276
Cluster IP: Virtual IP inside the cluster to allow communication between different services
LoadBalancer: Distributes load based on set requirementsservice-definition.yml
:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
nodePort: 30008
selector:
app: myapp
type: front-end
selector
: Selects the applicable pods based on labels
The service will be applied to all pods with the label app: myapp
kubectl get services
: Lists services
Services: Cluster IP#
Pods are assigned non-static IP addresses when created
A service can group like pods together and provide a single interface for access purposesservice-definition.yml
:
apiVersion: v1
kind: Service
metadata:
name: back-end
spec:
type: ClusterIP
ports:
- targetPort: 80
port: 80
selector:
app: myapp
type: back-end
Services: LoadBalancer#
Kubernetes supports integration with cloud provider LoadBalancers
Uses the same format as NodePort
YAML files, except type is set to LoadBalancer
:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: LoadBalancer
ports:
- targetPort: 80
port: 80
nodePort: 30008
selector:
app: myapp
type: front-end
Namespaces#
Objects are created in the default
namespace that was made available during the creation of the cluster
Another namespace called kubesystem
was also created for internal services
A third namespace, kubepublic
, was created in which resources meant to made public to users are held
Resources can be isolated in namespaces, i.e. Development vs. Production
Resources within the same namespace can reach other by the object name:mysql.connect("db-service)
To reach a service within another namespace, the name of the namespace needs to be appended to the service:mysql.connect("db-service.dev.svc.cluster.local")
When the service was created, a DNS entry was created in this format:
db-service
: Sevice Name
dev
: Namespace
svc
: Service
cluster.local
: Domainkubectl get pods -n [namespace]
: List pods in a specified namespacekubectle create -f definition.yml --namespace=[namespace]
: Creates the object in the specified namespace
The namespace can be applied in the metadata
section of a definition YAML file:
apiVersion: v1
kind: Pod
metadata:
name: myapp-prod
namespace: dev
labels:
app: myapp
type: front-end
spe
containers:
- name: nginx-container
- image: nginx
To create a new namespace:namespace-dev.yml
:
apiVersion: v1
kind: Namespace
metadata:
name: dev
A namespace can also be created with kubectl create namespace dev
To set the default namespace kubectl
reads from:\
kubectl config set-context $(kubectl config current-context) --namespace=namespace
To limit resources in a namespace, create a Resource Quota:compute-quota.yml
:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: dev
spec:
hard:
pods: "10"
requests.cpu: "4"
requests.memory: 5Gi
limits.cpu: "10"
limits.memory: 10Gi
Imperative vs. Declarative#
Imperative: A set of instructions written step by step
Using the kubectl
command for each step in order to deploy an object
Declarative: Requirements are declared and the system orchestrates the implementation process
Using a YAML file to deploy an object
Imperative#
Create Objects#
kubectl run --image=nginx nginx
kubectl create deployment --image=nginx nginx
kubectl expose deployment nginx --port 80
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml
--dry-run=client
: Will not create the object and will just return with the status of the deployment
-o yaml
: Output the resource definition in YAML formatkubectl expose pod nginx --type=NodePort --port=80 --name=nginx-service
: Create a Service named nginx of type NodePort to expose pod nginx’s port 80 on port 30080 on the nodes
Update Objects#
kubectl edit deployment nginx
kubectl scale deployment nginx --replicas=5
kubectl set image deployment nginx nginx=nginx:1.8
kubectl edit deployment nginx
: Will edit the pod-definition
file in the Kubernetes Memory, which is separate from the YAML used to deploy the podkubectl replace -f nginx.yaml
: Will replace the object with the object defined in the file
--force
: Will force the change
Declarative#
Create Objects#
kubectl apply -f nginx.yaml
kubectl apply -f /path/to/config-files
: Will apply all of the files in the directory\
Update Objects#
kubectl apply -f nginx.yaml
: Will update the object\
kubectl apply
Command#
When the apply command is run, the object is created if it does not already exist
A Live Object Configuration file is created within the cluster, which includes extra values used for maintaining state
The YAML is converted in JSON format and stored as the Last Applied Configuration
This JSON is stored in the annotations
value in the Live Object Configuration file