Deployment and Pod / Node Selection
Node Selector
apiVersion: v1
kind: Pod
metadata:
name: tom-web-pod
spec:
nodeSelector:
gpu: "nvidia"
containers:
- name: tom-web-container
image: thomaspk/dragons
The yaml file above shows how nodeSelector is used to ensure that this pod will only be scheduled on nodes that have this key value pair.
Node Affinity
apiVersion: v1
kind: Pod
metadata:
name: tom-web-pod
spec:
containers:
- name: tom-web-container
image: thomaspk/dragon
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # Use these rules for pod scheduling
nodeSelectorTerms: # Does not apply to already executing pods.
- matchExpressions:
- key: gpu
operator: In # operator 'Exists' checks if key defined.
values:
- nvidia
- amd
The yaml file show above does the same as the Node Selector yaml, except that it now uses affinity rules rathern than using node selection of labels. With this yaml definition, thomaspk/dragon
image based pods can be scheduled on nodes that must have either nvidia
or amd
set in their gpu
label. This is a hard requirement compared to using the preferredDuringSchedulingIgnoredDuringExectuion
affinity rule.
Deployment file
1apiVersion: apps/v1 # We have to specify the apps API group
2 # as it is not part of the core API group.
3kind: Deployment
4metadata:
5 name: web-deployment # The name used to reference this object (Deployment)
6 labels:
7 app: myapp-label # The labels to apply to this object (Deployment)
8 tier: frontend
9spec:
10 replicas: 2 # Create two pods for this Kubernetes object (Deployment)
11 selector:
12 matchLabels: # Tells deployment to match pods
13 app: myapp-selector # of this label (myapp-selector)
14 template: # Describes a pod template
15 metadata:
16 labels:
17 app: myapp-selector # Label the pods that are created
18 spec: # Specifications for the pod(s)
19 containers:
20 - image: thomaspk/web
21 name: myweb-container
22 ports:
23 - containerPort: 8080
24 name: http
25 protocol: TCP
An example of this deployment can be found at Documents/code/java/spring/boot/k8-app. We have to specify the pod specification in the deployment file so that Kubernetes can create these pods if they do not exist.
Rolling Updates
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: nginx-deploy
5spec:
6 replicas: 1
7 selector:
8 matchLabels:
9 app: nginx-deploy
10 strategy:
11 type: RollingUpdate
12 rollingUpdate:
13 maxSurge: 1
14 maxUnavailable: 2
15 template:
16 metadata:
17 creationTimestamp: null
18 labels:
19 app: nginx-deploy
20 spec:
21 containers:
22 - image: nginx:1.16
23 name: nginx
The example above shows how to create a rolling update deployment, specifying the maxSurge
and maxUnavailable
values. The nginx image can be updated to a new version with the command $ kubectl set image deployment/nginx-deploy nginx=nginx:1.17 --record
ReplicaSet file
ReplicaSets are a newer compared to ReplicationController, so we should be using ReplicaSets vs ReplicationControllers.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: tom-web-app
tier: frontend
spec:
replicas: 3
selector: # This is a mandatory field for ReplicaSet.
matchExpressions:
- key: app
operator: In
values:
- tom-app
matchLabels:
tier: frontend # See section 4.3.2 of Kubernetes In Action.pdf
template:
metadata:
labels:
tier: frontend
app: tom-app
spec:
containers:
- name: tom-app
image: thomaspk/web
ports:
- containerPort: 8080
protocol: TCP
An example where multiple selectors are used. Here the ReplicaSet requires pods with app in tom-app and tier=frontend.
Note that the
selector
is a mandatory field which allows it to understand what pods fall under its jurisdiction. It also means that it can control pods that were not created as part of this yaml file definition.The important definitions for a ReplicaSet are: replicas, selector (with MatchExpressions) and the pod template. The definition of the pod template is required, because if the required pod does not already exist, the ReplicaSet needs to know how to create the pod.
Health Probes
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: k8-java-app
5 labels:
6 app: myapp-label
7spec:
8 replicas: 1
9 selector:
10 matchLabels:
11 app: myapp-selector
12 template:
13 metadata:
14 labels:
15 app: myapp-selector
16 spec:
17 minReadySeconds: 30 # Optional. Minimum time by which pod should be ready.
18 containers:
19 - image: thomaspk/web
20 name: myweb-container
21 livenessProbe:
22 httpGet:
23 path: /actuator/health # The URL for kubernetes to do a health probe
24 port: 8080
25 initialDelaySeconds: 5 # Probe only after an initial delay of 5 seconds
26 timeoutSeconds: 1 # Response must be received in 1 second (UP or DOWN)
27 periodSeconds: 10 # Probe every 10 seconds
28 failureThreshold: 3 # Consider failed if 3 consecutive DOWN responses
29 ports:
30 - containerPort: 8080
31 name: http
32 protocol: TCP
Quota on Computing Resources
Namespace Resource Quota
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-ResourceQuota
namespace: dev
sepc:
hard:
pods: "10"
requests.cpu: "4"
requests.memory: 5Gi
limits.cpu: "10"
limits memory: 10Gi
A Resource Quota provides constraints that limit resource consumption by Namespace. It is a way to divide resources in a shared cluster between groups of users.
Container level Quota
apiVersion: v1
kind: Pod
metadata:
name: tom-app
labels:
app: tom-app
tier: frontend
spec:
containers:
- name: tom-web-app
image: thomaspk/fortune
ports:
- containerPort: 8080
resources:
requests: # The minimum amount of resources required for this container
memory: "1Gi"
cpu: 1
limits: # The maximum amount of resources to be allocated to this container
memory: "2Gi" # If the application uses more than this persistently,
cpu: 2 # it will be terminated by Kubernetes.
The yaml file above shows how requests and limits are specified at the container level.
Kubernetes will throttle the computing resources given to the container based on these specifications.
Default Limits & Requests
apiVersion: v1
kind: LimitRange
metadata:
name: computing-limit-range
spec:
limits:
- defaults:
cpu: 1
memory: 512Mi
defaultRequests:
cpu: 0.5
memory: 256Mi
type: Container
The yaml file show above is used to set the default cpu and memory requests and limits for all containers that do not have these explicitly specified.
Taints and Tollerations
apiVersion: v1
kind: Pod
metadata:
name: tom-web-app
spec:
containers:
- name: nginx
image: nginx
tolerations: # This applies at the pod level
- key: "department" # instead of the individual container level.
operator: "Equals"
value: "Marketing"
effect: "NoSchedule" # Do not place pod on node without required taint
tolerationSeconds: 3600 # Optional parameter. Take effect in an hour
The above yaml pod definition shows how this pod meant for the marketing department will run on nodes tainted with the key value pair department=Marketing
. The effect
can also have a value of PreferNoSchedule
for a soft preference of this rule or NoExecute
to stop execution of existing pods without a matching toleration.