In the previous chapter Create EKS managed node groups with Spot capacity we added a taint spotInstance: "true:PreferNoSchedule"
to both node groups. PreferNoSchedule is used to indicate we prefer pods not to be scheduled on Spot Instances. NoSchedule can also be used to enforce a hard discrimination as a taint. To overcome this taint, we need to add a toleration in the deployment. Read about how tolerations are applied and modify the monte-carlo-pi-service.yml file accordingly.
As per the tolerations documentation
the objective is to add the following section to the monte-carlo-pi-service.yml
.
The following toleration must be added at the spec.template.spec level
tolerations:
- key: "spotInstance"
operator: "Equal"
value: "true"
effect: "PreferNoSchedule"
Our next task before deployment is to add affinities to the configuration.
In the previous chapters we labeled managed node groups with On-Demand capacity with intent: control-apps and managed node groups with Spot capacity with intent: apps. Additionally EKS adds a label eks.amazonaws.com/capacityType and sets its value to ON_DEMAND for node groups with On-Demand capacity and SPOT for node group with Spot capacity.
To meet the requirements we defined in previous chapter: application to be deployed only on nodes that have been labeled with intent: apps
and application to prefer Spot Instances over on-demand Instances, we need to add two affinity properties:
Read about how affinities can be used to assign pods to nodes and modify the monte-carlo-pi-service.yml file accordingly.
As per the Assign Pods to Nodes documentation the objective is to add the following section to the monte-carlo-pi-service.yml
.
The following affinities must be added at the spec.template.spec level
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: eks.amazonaws.com/capacityType
operator: In
values:
- SPOT
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: intent
operator: In
values:
- apps
If you are still struggling with the implementation, then run below command to overwrite monte-carlo-pi-service.yml
template with the final solution.
cat <<EoF > ~/environment/monte-carlo-pi-service.yml
---
apiVersion: v1
kind: Service
metadata:
name: monte-carlo-pi-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: monte-carlo-pi-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: monte-carlo-pi-service
labels:
app: monte-carlo-pi-service
spec:
replicas: 2
selector:
matchLabels:
app: monte-carlo-pi-service
template:
metadata:
labels:
app: monte-carlo-pi-service
spec:
tolerations:
- key: "spotInstance"
operator: "Equal"
value: "true"
effect: "PreferNoSchedule"
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: eks.amazonaws.com/capacityType
operator: In
values:
- SPOT
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: intent
operator: In
values:
- apps
containers:
- name: monte-carlo-pi-service
image: ruecarlo/monte-carlo-pi-service
resources:
requests:
memory: "512Mi"
cpu: "1024m"
limits:
memory: "512Mi"
cpu: "1024m"
securityContext:
privileged: false
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
ports:
- containerPort: 8080
EoF