|
@@ -0,0 +1,345 @@
|
|
|
+---
|
|
|
+# Prepares the environment for the apps-placement exercise, and cleans up afterwards.
|
|
|
+#
|
|
|
+# TODO: create some projects:
|
|
|
+# - one with a project node selector
|
|
|
+# and a deployment with conflicting node {selector|affinity} ???
|
|
|
+# - one with a very low quota
|
|
|
+# and a deployment which exceeds the quota
|
|
|
+# - taint a node
|
|
|
+# and select a deployment to run a pod on it
|
|
|
+# then debug these conditions and fix them
|
|
|
+#
|
|
|
+# TODO: make two nodes unschedulable, create a project, and deploy an application, scale to three
|
|
|
+# make the nodes schedulable again, use podAntiAffinity to disperse the pods, scale to 6 and see scheduling
|
|
|
+#
|
|
|
+# simulate load (loadtest? loadgenerator?) beyond container's cpu limit and then improve performance by raising limit
|
|
|
+#
|
|
|
+# TODO: probes with extremely low cpu limit, see them crashloop, fix it
|
|
|
+#
|
|
|
+# use stress-ng ap to allocate all memory (more than limit), monitor the metrics to diagnose the crash
|
|
|
+#
|
|
|
+# client-server apps, low limits, monitor performance
|
|
|
+#
|
|
|
+# custom metrics, grafana
|
|
|
+#
|
|
|
+# TODO: run two instances on the same node, no pdb, drain the node - observe failure in another terminal
|
|
|
+# repeat with pdb, see no failures
|
|
|
+#
|
|
|
+# recreate strategy, rollout a change, observe outage in another terminal
|
|
|
+# switch to rolling w/maxUnavailable, repeat, see no failures
|
|
|
+#
|
|
|
+# deploy an app w/requests, generate load, observe timing
|
|
|
+# add HPA, generate load, compare
|
|
|
+#
|
|
|
+- name: Prepare (or clean up) the exercise of apps-placement.
|
|
|
+ hosts: localhost
|
|
|
+ gather_subset: min
|
|
|
+ become: no
|
|
|
+ tasks:
|
|
|
+ - name: Prereqs
|
|
|
+ include_role:
|
|
|
+ name: check-env
|
|
|
+
|
|
|
+ - name: Ensure the projects are there
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: v1
|
|
|
+ kind: namespace
|
|
|
+ name: "{{ item.name }}"
|
|
|
+ resource_definition:
|
|
|
+ metadata:
|
|
|
+ annotations:
|
|
|
+ openshift.io/node-selector: "{{ item.nodeselector | default(omit) }}"
|
|
|
+ loop:
|
|
|
+ - name: apps-selector-conflict
|
|
|
+ nodeselector: kubernetes.io/hostname=worker03
|
|
|
+ - name: apps-selector-impossible
|
|
|
+ - name: apps-lowquota
|
|
|
+ - name: apps-taint
|
|
|
+ - name: apps-antiaffinity
|
|
|
+ #- name: apps-lowlimit
|
|
|
+ - name: apps-pdb
|
|
|
+
|
|
|
+ - name: Deployment conflicting node selector
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: apps/v1
|
|
|
+ kind: deployment
|
|
|
+ namespace: apps-selector-conflict
|
|
|
+ name: conflict
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ replicas: 3
|
|
|
+ selector:
|
|
|
+ matchLabels:
|
|
|
+ app: hello
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ labels:
|
|
|
+ app: hello
|
|
|
+ spec:
|
|
|
+ nodeSelector:
|
|
|
+ kubernetes.io/hostname: worker01
|
|
|
+ containers:
|
|
|
+ - name: hello
|
|
|
+ image: quay.io/redhattraining/hello-world-nginx:latest
|
|
|
+ ports:
|
|
|
+ - name: http
|
|
|
+ containerPort: 8080
|
|
|
+
|
|
|
+ - name: Deployment with an impossible node selector
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: apps/v1
|
|
|
+ kind: deployment
|
|
|
+ namespace: apps-selector-impossible
|
|
|
+ name: select
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ replicas: 3
|
|
|
+ selector:
|
|
|
+ matchLabels:
|
|
|
+ app: hello
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ labels:
|
|
|
+ app: hello
|
|
|
+ spec:
|
|
|
+ nodeSelector:
|
|
|
+ impossible: nodelabel
|
|
|
+ containers:
|
|
|
+ - name: hello
|
|
|
+ image: quay.io/redhattraining/hello-world-nginx:latest
|
|
|
+ ports:
|
|
|
+ - name: http
|
|
|
+ containerPort: 8080
|
|
|
+
|
|
|
+ - name: Ensure low quota on the lowquota project
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: v1
|
|
|
+ kind: resourcequota
|
|
|
+ resource_definition:
|
|
|
+ metadata:
|
|
|
+ name: compute-quota
|
|
|
+ namespace: apps-lowquota
|
|
|
+ spec:
|
|
|
+ hard:
|
|
|
+ requests.cpu: 500m
|
|
|
+ requests.memory: 512Mi
|
|
|
+ limits.cpu: 1000m
|
|
|
+ limits.memory: 1Gi
|
|
|
+
|
|
|
+ - name: Deployment exceeding quota
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: apps/v1
|
|
|
+ kind: deployment
|
|
|
+ namespace: apps-lowquota
|
|
|
+ name: quota
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ replicas: 3
|
|
|
+ selector:
|
|
|
+ matchLabels:
|
|
|
+ app: hello
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ labels:
|
|
|
+ app: hello
|
|
|
+ spec:
|
|
|
+ containers:
|
|
|
+ - name: hello
|
|
|
+ image: quay.io/redhattraining/hello-world-nginx:latest
|
|
|
+ ports:
|
|
|
+ - name: http
|
|
|
+ containerPort: 8080
|
|
|
+ resources:
|
|
|
+ requests:
|
|
|
+ memory: 1Gi
|
|
|
+ cpu: 2
|
|
|
+
|
|
|
+ - name: Taint a node
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: v1
|
|
|
+ kind: node
|
|
|
+ name: worker01
|
|
|
+ state: patched
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ taints:
|
|
|
+ - effect: NoSchedule
|
|
|
+ key: foo
|
|
|
+ value: bar
|
|
|
+
|
|
|
+ - name: Deployment targetting tainted node
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: apps/v1
|
|
|
+ kind: deployment
|
|
|
+ namespace: apps-taint
|
|
|
+ name: tainted
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ replicas: 3
|
|
|
+ selector:
|
|
|
+ matchLabels:
|
|
|
+ app: hello
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ labels:
|
|
|
+ app: hello
|
|
|
+ spec:
|
|
|
+ nodeSelector:
|
|
|
+ kubernetes.io/hostname: worker01
|
|
|
+ containers:
|
|
|
+ - name: hello
|
|
|
+ image: quay.io/redhattraining/hello-world-nginx:latest
|
|
|
+ ports:
|
|
|
+ - name: http
|
|
|
+ containerPort: 8080
|
|
|
+
|
|
|
+ - name: Make nodes unschedulable
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: v1
|
|
|
+ kind: node
|
|
|
+ name: "{{ item }}"
|
|
|
+ state: patched
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ unschedulable: true
|
|
|
+ loop:
|
|
|
+ - worker01
|
|
|
+ - worker02
|
|
|
+
|
|
|
+ - name: Deployment on the only available node, to be preferred
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: apps/v1
|
|
|
+ kind: deployment
|
|
|
+ namespace: apps-antiaffinity
|
|
|
+ name: dislike
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ replicas: 3
|
|
|
+ selector:
|
|
|
+ matchLabels:
|
|
|
+ app: hello
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ labels:
|
|
|
+ app: hello
|
|
|
+ spec:
|
|
|
+ #affinity:
|
|
|
+ # podAntiAffinity:
|
|
|
+ # preferredDuringSchedulingIgnoredDuringExecution:
|
|
|
+ # - weight: 10
|
|
|
+ # podAffinityTerm:
|
|
|
+ # labelSelector:
|
|
|
+ # matchLabels:
|
|
|
+ # app: hello
|
|
|
+ # topologyKey: kubernetes.io/hostname
|
|
|
+ containers:
|
|
|
+ - name: hello
|
|
|
+ image: quay.io/redhattraining/hello-world-nginx:latest
|
|
|
+ ports:
|
|
|
+ - name: http
|
|
|
+ containerPort: 8080
|
|
|
+
|
|
|
+ - name: Deployment on the only available node, to be required
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: apps/v1
|
|
|
+ kind: deployment
|
|
|
+ namespace: apps-antiaffinity
|
|
|
+ name: refuse
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ replicas: 3
|
|
|
+ selector:
|
|
|
+ matchLabels:
|
|
|
+ app: hello
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ labels:
|
|
|
+ app: hello
|
|
|
+ spec:
|
|
|
+ #affinity:
|
|
|
+ # podAntiAffinity:
|
|
|
+ # requiredDuringSchedulingIgnoredDuringExecution:
|
|
|
+ # labelSelector:
|
|
|
+ # matchLabels:
|
|
|
+ # app: hello
|
|
|
+ # topologyKey: kubernetes.io/hostname
|
|
|
+ containers:
|
|
|
+ - name: hello
|
|
|
+ image: quay.io/redhattraining/hello-world-nginx:latest
|
|
|
+ ports:
|
|
|
+ - name: http
|
|
|
+ containerPort: 8080
|
|
|
+
|
|
|
+ - name: Make nodes schedulable again
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: v1
|
|
|
+ kind: node
|
|
|
+ name: "{{ item }}"
|
|
|
+ state: patched
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ unschedulable: false
|
|
|
+ loop:
|
|
|
+ - worker01
|
|
|
+ - worker02
|
|
|
+
|
|
|
+ - name: Deployment on the same node for PDB
|
|
|
+ kubernetes.core.k8s:
|
|
|
+ kubeconfig: tmp/kubeconfig-ocp4
|
|
|
+ validate_certs: no
|
|
|
+ api_version: apps/v1
|
|
|
+ kind: deployment
|
|
|
+ namespace: apps-pdb
|
|
|
+ name: budget
|
|
|
+ resource_definition:
|
|
|
+ spec:
|
|
|
+ replicas: 2
|
|
|
+ selector:
|
|
|
+ matchLabels:
|
|
|
+ app: hello
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ labels:
|
|
|
+ app: hello
|
|
|
+ spec:
|
|
|
+ affinity:
|
|
|
+ nodeAffinity:
|
|
|
+ preferredDuringSchedulingIgnoredDuringExecution:
|
|
|
+ - preference:
|
|
|
+ matchExpressions:
|
|
|
+ - key: kubernetes.io/hostname
|
|
|
+ operator: In
|
|
|
+ values:
|
|
|
+ - worker02
|
|
|
+ weight: 50
|
|
|
+ containers:
|
|
|
+ - name: hello
|
|
|
+ image: quay.io/redhattraining/hello-world-nginx:latest
|
|
|
+ ports:
|
|
|
+ - name: http
|
|
|
+ containerPort: 8080
|
|
|
+
|
|
|
+...
|