Kubernetes - ttulka/technologies GitHub Wiki
- Pods
- ReplicaSets
- Deployments
- Services
- Ingress
- Networking
- Namespaces
- Persistent Volumes
- ConfigMaps
- Kubernetes API
- RBAC (Role-Based Access Control)
- Custom Resources
- Kubernetes Operator
- Service Catalog
- Service Account
- Resources
kubectl get all # shows all objects
kubectl get nodes # shows k8s nodes
kubectl delete deployment,services -l app=nginx # bulk delete by label
kubectl cluster-info
kubectl config view
Node (Minion) - a physical or virtual machine.
Cluster - a set of nodes grouped together.
Pod - a basic kind of k8s objects, a group of containers (typically of different kind).
- Each pod has a unique IP address in the Kubernetes cluster.
- Pod can have multiple containers. The containers share the same port space, as such they can communicate via localhost.
- Containers in a pod share the same volume, same ip, port space, IPC namespace.
kubectl get pods # lists pods
kubectl get pods -o=wide # wide output
kubectl get pods -l environment=production,tier=frontend # by labels
kubectl run mypod --image=myimage # runs myimage docker container as a pod
kubectl get pods mypod # shows info about the pod
kubectl describe pod mypod # describes the pod
kubectl edit pod mypod # edit currently running config
kubectl exec -it mypod -- sh # executes 'sh' command on the pod interactively
kubectl logs mypod # shows log messages for the pod
# pod-definition.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
app: myapp
type: back-end
spec:
containers:
- name: myimage-container
image: myimage
env:
- name: MY_VAR
value: test123
kubectl create -f pod-definition.yml
kubectl delete pod mypod
A new recommended alternative to Replication Controllers.
# replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myreplica
spec:
selector:
machLabels:
app: myapp
replicas: 3
template:
metadata:
name: mypod
labels:
app: myapp
spec:
containers:
- name: myimage-container
image: myimage
kubectl create -f replicaset.yml
kubectl get replicaset # shows the set
kubectl describe replicaset myreplica
kubectl get pods # shows three pods
kubectl edit replicaset myreplica # edit currently running config
kubectl scale replicaset --replicas=5 myreplica # scales the replicaset
Deployments are ReplicaSets with rolling updates.
- Seamlesly deploys k8s objects.
The Deployment resource automates the process of moving from one version of the application to the next, with zero downtime and in case of failures, it enables us to quickly roll back to the previous version.
# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment
spec:
selector:
machLabels:
app: myapp
replicas: 3
template:
metadata:
name: mypod
labels:
app: myapp
spec:
containers:
- name: myimage-container
image: myimage
kubectl create -f deployment.yml
kubectl get deployments
kubectl scale deployment --replicas=3 mydeployment
Rolling update is the default deployment strategy.
kubectl rollout status deployment mydeployment # status log
kubectl apply -f deployment.yml # updates deployment
kubectl rollout history deployment mydeployment # shows revisions
kubectl rollout undo deployment mydeployment # rollbacks changes
kubectl delete deployment mydeployment # deletes deployment
Stable network abstraction points that provide TCP and UDP load-balancing across a dynamic set of Pods. Are access points for users.
- Pods are not meant to be visible from inside the cluster.
- Services must be used to expose the pods to other services or external users.
- Services are long-running objects, pods are short-living.
Services do the heavy lifting, of discovering services and load balancing between Pods (instances).
Services bring stable IP addresses and DNS names to the unstable world of Pods.
# service.yml
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
nodePort: 30008
selector:
app: myapp
Types can be:
-
ClusterIP
- only accessible from inside the cluster, not externally.- Typical choice for microservices.
-
NodePort
- exposed to the ouside world.- Typical choice for webapps.
minikube service <service-name> --url
prints URL of exposed service.
Ingres exposes multiple Services through a single cloud load-balancer.
It creates a LoadBalancer Service, on port 80 or 443, and uses host-based and path-based routing to send traffic to the correct backend Service.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-example
spec:
ingressClassName: nginx
rules:
- host: hello.example.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello
port:
number: 8080
- host: example.org
http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello
port:
number: 8080
Every Pod gets its own IP address. Pods on a Node can communicate with all Pods on all Nodes without NAT.
Containers within a Pod share their network namespaces - including their IP address and MAC address. Containers within a Pod can all reach each other's ports on localhost
.
DNS address is assigned to a Pod <service>.<namespace>.svc.cluster.local
.
nslookup db
cat /etc/resolv.conf
K8s uses directories for objects.
Namespaces a good way of sharing a single cluster among different departments and environments like DEV, QA, PROD.
kubectl get ns # shows namespaces
kubectl get po -n kube-system
# permanently save the namespace for commands in the context:
kubectl config set-context --current --namespace=<myns>
DNS is formed from namespaces: <service-name>.<namespace-name>.svc.cluster.local
Low-level resources, such as nodes and persistentVolumes, are not in any namespace:
kubectl api-resources --namespaced=false
PersistentVolume (PV) - Storing data locally in a directory of the host.
# db-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
labels:
app: db
spec:
replicas: 1
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: postgres:9.4
volumeMounts:
- name: db-data
mountPath: /var/lib/postgresql/data
volumes:
- name: db-data
hostPath:
path: /mnt/some/dir/data/
type: DirectoryOrCreate
PersistentVolumeClaim (PVC) - Separate configuration of volumes to be referenced from the deployment.
- K8s search all volume definitions to satisfy the claim.
-
storageClassName
can optionaly be used to select a particular volume.
# db-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
labels:
app: db
spec:
replicas: 1
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: postgres:9.4
volumeMounts:
- name: db-data
mountPath: /var/lib/postgresql/data
volumes:
- name: db-data
persistentVolumeClaim:
claimName: postgres-pvc
# db-storage.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
storageClassName: mylocalstorage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-storage
spec:
storageClassName: mylocalstorage
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/some/dir/data/
type: DirectoryOrCreate
Used to store non-confidential data in key-value pairs.
- Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume.
- Decouple environment-specific configuration from your container images.
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
data:
# property-like keys; each key maps to a simple value
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
# file-like keys
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
Used in a Pod:
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: alpine
command: ["sleep", "3600"]
env:
# Define the environment variable
- name: PLAYER_INITIAL_LIVES # Notice that the case is different here
# from the key name in the ConfigMap.
valueFrom:
configMapKeyRef:
name: myconfigmap # The ConfigMap this value comes from.
key: player_initial_lives # The key to fetch.
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: myconfigmap
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# You set volumes at the Pod level, then mount them into containers inside that Pod
- name: config
configMap:
# Provide the name of the ConfigMap you want to mount.
name: myconfigmap
# An array of keys from the ConfigMap to create as files
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"
The core of Kubernetes' control plane is the API server. The API server exposes an HTTP API that lets end users, different parts of your cluster, and external components communicate with one another.
kubectl cluster-info
# shows cluster endpoint addresses
kubectl proxy --port 9000 &
# exposes the API on localhost and takes care of authentication
curl http://localhost:9000/api/v1/pods
# call the API
without kubectl proxy:
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
curl -k $APISERVER/api -H "Authorization: Bearer $TOKEN"
Kubernetes is a least-privilege deny-by-default system - all actions are denied by default, it supports only allow-rules.
- Roles define a set of permissions:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: shield
name: read-deployments
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "watch", "list"]
- RoleBindings grant those permissions to users:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-deployments
namespace: shield
subjects:
- kind: User
name: sky ### the authenticated user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: read-deployments ### the Role to bind to the user
apiGroup: rbac.authorization.k8s.io
Roles and RoleBindings are namespaced objects. ClusterRoles and ClusterRoleBindings are cluster-wide objects and apply to all Namespaces.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: tomas
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
Custom resources are extensions of the Kubernetes API.
A resource is an endpoint in the Kubernetes API that stores a collection of API objects of a certain kind; for example, the built-in pods resource contains a collection of Pod objects.
A custom resource is an extension of the Kubernetes API that is not necessarily available in a default Kubernetes installation. It represents a customization of a particular Kubernetes installation.
The Operator pattern combines custom resources and custom controllers.
A Kubernetes operator is a method of packaging, deploying, and managing a Kubernetes application. A Kubernetes application is both deployed on Kubernetes and managed using the Kubernetes API (application programming interface) and kubectl tooling.
It is a way to run complex stateful applications on Kubernetes with control of their life-cycle.
A Kubernetes operator is an application-specific controller that extends the functionality of the Kubernetes API to create, configure, and manage instances of complex applications on behalf of a Kubernetes user.
An operator is a custom Kubernetes controller that uses custom resources (CR) to manage applications and their components.
Service Catalog is an extension API that enables applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.
A service account provides an identity for processes that run in a Pod.
kubectl get serviceaccounts
A credential (token), certificate bundle, default namespace for the service account is placed into the filesystem of a Pod:
/var/run/secrets/kubernetes.io/serviceaccount/token
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
/var/run/secrets/kubernetes.io/serviceaccount/namespace
APISERVER=https://kubernetes.default.svc
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
TOKEN=$(cat ${SERVICEACCOUNT}/token)
CACERT=${SERVICEACCOUNT}/ca.crt
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
Every namespace has a default service account resource called default
. When not specified, the default service account is assigned to a Pod automatically.
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
---
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: build-robot
- https://labs.play-with-k8s.com
- https://kind.sigs.k8s.io
- https://kops.sigs.k8s.io
- https://krew.sigs.k8s.io
- https://kustomize.io
- https://kubectl.docs.kubernetes.io
- https://svc-cat.io
- https://helm.sh
- https://tilt.dev
- https://rancher.com
- https://knative.dev
- https://kubeless.io
- https://k3s.io
- https://kompose.io
- https://github.com/kelseyhightower/kubernetes-the-hard-way
- https://github.com/kubernetes/kops
- https://github.com/bitnami-labs/sealed-secrets
- https://github.com/loft-sh/kiosk
- https://github.com/clastix/capsule
- https://github.com/corneliusweig/ketall
- https://github.com/wave-k8s/wave
- https://github.com/EmberStack/kubernetes-reflector
- https://keda.sh
- https://learnk8s.io/production-best-practices/
- https://k8slens.dev
- https://k9scli.io
- https://www.kubecost.com
- kubectl cheatsheet
- Cheatsheet Kubernetes A4
- https://etcd.io
- https://coredns.io
- What is mTLS? (in Kubernetes)
- Helm best practices
- IAM roles for Kubernetes service accounts - deep dive
- The life of a DNS query in Kubernetes
- kcp - a minimal Kubernetes API server
- Crossplane as a Kubernetes type system