commit a9ea8d4edca71facab433b1dd50e66af231be24d
parent 2a17c7b5b29236d89eb3ca1473cdc9b330c0ac21
Author: Alex Balgavy <alex@balgavy.eu>
Date: Mon, 31 Jan 2022 12:48:37 +0100
Update software containerization notes
Diffstat:
5 files changed, 240 insertions(+), 0 deletions(-)
diff --git a/content/softcont-notes/_index.md b/content/softcont-notes/_index.md
@@ -13,3 +13,7 @@ title = 'Software Containerisation'
9. [ConfigMaps & Secrets](configmaps-secrets)
10. [Deployment updates](deployment-updates)
11. [Helm: Kubernetes package manager](helm)
+12. [Network policies](network-policies)
+13. [Controlling access to Kubernetes API](controlling-access-to-kubernetes-api)
+14. [Affinity and anti-affinity](affinity-and-anti-affinity)
+15. [Pod disruption budget](pod-disruption-budget)
diff --git a/content/softcont-notes/affinity-and-anti-affinity.md b/content/softcont-notes/affinity-and-anti-affinity.md
@@ -0,0 +1,37 @@
++++
+title = 'Affinity and anti-affinity'
++++
+# Affinity and anti-affinity
+Scheduler takes care of placing pods on nodes to consume cluster resources in reasonable way.
+But you can control how the scheduler does that by using labesls and selectors.
+
+For example to:
+- ensure that certain group of pods ends up on nodes with specific type of hardware (use `nodeSelector` or `nodeAffinity`)
+- ensure that REST API and database pod end up on same node to reduce network latency during REST API calls to database (use inter-pod affinity `podAffinity`)
+- ensure that two replicas of database pod don't end up on the same node, to increase high availability if a node fails (inter-pod anti-affinity `podAntiAffinity`)
+
+Example:
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: nginx
+ labels:
+ env: test
+spec:
+ containers:
+ - name: nginx
+ image: nginx
+ nodeSelector:
+ size: large
+```
+
+
+Taints: features of Nodes allowing nodes to repel pods
+- add taint with `kubectl taint nodes node1 key1=value1:NoSchedule` (taint effect is `NoSchedule`, so no pod will be scheduled on node1 unless it has a toleration that matches key and label)
+ - effects are NoSchedule, PreferNoSchedule, and NoExecute (pod will be evicted from the node if already running on it)
+- to remove, `kubectl taint nodes node1 key1=value1:NoSchedule-`
+
+Tolerations: allow specific pod to be scheduled on a node despite of its taint
+- toleration "matches" a taint if keys are same + effects are same + operator is Exists or (operator is Equal and values equal)
diff --git a/content/softcont-notes/controlling-access-to-kubernetes-api.md b/content/softcont-notes/controlling-access-to-kubernetes-api.md
@@ -0,0 +1,63 @@
++++
+title = 'Controlling access to Kubernetes API'
++++
+# Controlling access to Kubernetes API
+Access to Kubernetes resources goes through 3 phases: authentication, authorization, admission control.
+
+Authentication: confirming identity of users
+- service account
+ - namespaced, created directly in Kubernetes, used by processes inside pods
+ - every namespace has its own "default" service account
+ - you can grant specific permissions to service accounts using a Role
+ - you can create a new service account using a YAML file; a new Secret (token) will be created automatically:
+
+ ```yaml
+ apiVersion :v1
+ kind: ServiceAccount
+ metadata:
+ name: my-service-account
+ ```
+ - use a service account in a pod by specifying its name in `spec.serviceAccount`
+- normal user
+ - global to cluster, may come form corporate database, used by human
+ - no Kubernetes API for creating User objects
+
+Authorization:
+- Role Based Access Control (RBAC): individual users have rights to perform specific tasks
+ - in Microk8s, use `microk8s enable rbac`
+ - uses `rbac.authorization.k8s.io` API group to drive auth decisions
+ - declares four Kubernetes objects:
+ - Role: namespace resource, applies to specific namespace that it belongs to
+ ```yaml
+ kind: Role
+ apiVersion: rbac.authorization.k8s.io/v1
+ metadata:
+ namespace: default
+ name: pod-reader
+ rules:
+ - apiGroups: [""] # indicates the core API group
+ resources: ["pods"]
+ verbs: ["get", "watch", "list"]
+ ```
+
+ - ClusterRole: not namespaced, can be used to apply permissions to multiple namespaces or entire cluster
+ - RoleBindings, ClusterRoleBindings: bind Roles/ClusterRoles to actual users, groups, userids, and service accounts.
+ ```yaml
+ kind: RoleBinding
+ apiVersion: rbac.authorization.k8s.io/v1
+ metadata:
+ name: read-pods
+ namespace: default
+ subjects:
+ - kind: User
+ name: lara
+ apiGroup: rbac.authorization.k8s.io
+ roleRef:
+ kind: Role
+ name: pod-reader
+ apiGroup: rbac.authorization.k8s.io
+ ```
+ - you can check permissions with e.g. `kubectl auth can-i list pod --namespace default --as lara1`
+- Attribute Based access Control: access rights granted to users through policies which combine attributes together
+- Node: node authorization authorizes API requests made by kubelets to perform specific API operations
+- WebHook: event notification via HTTP POST, web app POSTs message to URL when certain things happen
diff --git a/content/softcont-notes/network-policies.md b/content/softcont-notes/network-policies.md
@@ -0,0 +1,119 @@
++++
+title = 'Network policies'
++++
+# Network policies
+By default, pods allow all outbound (egress) and inbound (ingress) connections.
+Network policies let you restrict that, and are defined by YAML files.
+The Network plugin used in the cluster must support them.
+
+Policies always involve a pod at one or both ends, and are _additive_ (union).
+For connection between two pods, you must allow egress from source and ingress to destination.
+
+By default, pod non-isolated for ingress (all inbound allowed).
+
+Pod is _isolated_ for ingress if there is NetworkPolicy that selects the pod and has "ingress" in policyTypes.
+Then, only allowed connections are:
+- those that come from pod's node
+- those allowed by ingress list of some NetworkPolicy that applies to the pod for ingress
+
+policyTypes can be `["Ingress"]`, `["Egress"]`, `["Ingress", "Egress"]`, or none.
+This field indicates whether the policy applies to ingress/egress/both.
+If no policyTypes specified, ingress is set by default, and egress is set if NetworkPolicy has any egress rules.
+
+## Example: deny all
+
+```yaml
+kind: NetworkPolicy
+apiVersion: networking.k8s.io/v1
+metadata:
+ name: web-deny-all
+spec:
+ podSelector:
+ matchLabels:
+ app: web
+ ingress: []
+```
+
+In this example:
+- policyTypes not set, so default is ingress
+- set of ingress rules is empty, so no entry into pods selected by `podSelector` is allowed
+
+## Example: limit ingress to connections from certain pods
+```yaml
+kind: NetworkPolicy
+apiVersion: networking.k8s.io/v1
+metadata:
+ name: api-allow
+spec:
+ podSelector:
+ matchLabels:
+ app: bookstore
+ role: api
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ app: bookstore
+```
+
+In this example:
+- application with labels `app=bookstore role=api` can only be accessed from pods with label `app=bookstore`
+- policyTypes not specified, so default is ingress
+
+## Example: block traffic from other namespaces, allow from own
+```yaml
+kind: NetworkPolicy
+apiVersion: networking.k8s.io/v1
+metadata:
+ namespace: default
+ name: deny-from-other-namespaces
+spec:
+ podSelector:
+ matchLabels:
+ ingress:
+ - from:
+ - podSelector: {}
+```
+
+In this example:
+- policy applies to default namespace
+- `matchLabels` is empty, so applies to all pods in default namespace
+- allows ingress from any of selected pods (all in default namespace), all others are denied
+
+## Example: block all egress traffic from a pod
+```yaml
+kind: NetworkPolicy
+apiVersion: networking.k8s.io/v1
+metadata:
+ name: foo-deny-egress
+spec:
+ podSelector:
+ matchLabels:
+ app: foo
+ policyTypes:
+ - Egress
+ egress: []
+```
+
+In this case, we get a "bad address" error, because it fails to connect to DNS.
+To block all egress except DNS:
+
+```yaml
+kind: NetworkPolicy
+apiVersion: networking.k8s.io/v1
+metadata:
+ name: foo-deny-egress
+spec:
+ podSelector:
+ matchLabels:
+ app: foo
+
+ policyTypes:
+ - Egress
+ egress:
+ - ports:
+ - port: 53
+ protocol: UDP
+ - port: 53
+ protocol: TCP
+```
diff --git a/content/softcont-notes/pod-disruption-budget.md b/content/softcont-notes/pod-disruption-budget.md
@@ -0,0 +1,17 @@
++++
+title = 'Pod disruption budget'
++++
+# Pod disruption budget
+Pods may be disrupted because of events:
+- involuntary: hardware failure, destruction of node's VM, eviction of pod because node runs out of resources
+- voluntary: deleting Deployment, update of Deployment causing a restart, deletion of pod, draining of ndoe
+
+To mitigate involuntary disruption:
+- ensure pod requests the resources it needs
+- replicate application if you need higher availability
+- spread apps across racks (using anti-affinity) or across zones
+
+To deal with voluntary disruption:
+- app owners can create PodDisruptionBudget to limit number of Pods of replicates app that are down simultaneously
+- makes sense when app owner and cluster admin are different people/roles/vendors
+- reduction in number of pods during involuntary disruption will count against the budget