{"id":1372,"date":"2021-03-12T23:25:06","date_gmt":"2021-03-12T23:25:06","guid":{"rendered":"https:\/\/dft.wiki\/?p=1372"},"modified":"2026-06-09T09:26:50","modified_gmt":"2026-06-09T13:26:50","slug":"kubernetes-cheat-sheet","status":"publish","type":"post","link":"https:\/\/dft.wiki\/?p=1372","title":{"rendered":"Kubernetes Cheat Sheet"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4090 size-medium\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2021\/03\/K8s-300x157.png\" alt=\"\" width=\"300\" height=\"157\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2021\/03\/K8s-300x157.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2021\/03\/K8s.png 567w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>If you have ever worked with containers such as Docker, you know how efficient and fast they are.<\/p>\n<p>Kubernetes is a container orchestrator that automates deployments and shutdowns to make applications highly available and elastic in response to demand fluctuations.<\/p>\n<p>Everything starts with a Cluster, the &#8220;pool&#8221; that contains N resources called Nodes.<\/p>\n<p>The first node is the &#8220;master&#8221; and manages the workload on the other nodes, called &#8220;workers&#8221;.<\/p>\n<p>Pods (which contain the containers running the application) are distributed among the nodes for better performance.<\/p>\n<p>Kubernetes can scale the number of nodes up or down based on parameters such as CPU or RAM usage, indicating whether physical resources are insufficient or idle.<\/p>\n<hr \/>\n<p><strong>INSTALLING KUBERNETES<\/strong><\/p>\n<pre>curl -LO https:\/\/storage.googleapis.com\/kubernetes-release\/release\/$(curl -s https:\/\/storage.googleapis.com\/kubernetes-release\/release\/stable.txt)\/bin\/linux\/amd64\/kubectl\r\nchmod +x .\/kubectl\r\nsudo mv .\/kubectl \/usr\/local\/bin\/kubectl<\/pre>\n<p>Download the configuration file from your Kubernetes server and assign it to a variable (store it in a safe location with appropriate permissions):<\/p>\n<pre>export KUBECONFIG=kube1-kubeconfig.yaml<\/pre>\n<hr \/>\n<p><strong>MANAGING KUBERNETES<\/strong><\/p>\n<p>Useful commands for managing the cluster:<\/p>\n<pre>kubectl --help\r\nkubectl get nodes\r\nkubectl cluster-info<\/pre>\n<p>Example of a simple manual container deployment:<\/p>\n<pre>kubectl run nginx-api --image=nginx --port=80\r\nkubectl get pods\r\nkubectl describe pods\r\nkubectl delete pods nginx-api<\/pre>\n<p><strong>Getting a Shell into the Container<\/strong><\/p>\n<pre>kubectl <strong>exec --stdin --tty<\/strong> nginx-api-***********-**** -- bash<\/pre>\n<pre>kubectl <strong>exec -it<\/strong> nginx-api-***********-**** -- bash<\/pre>\n<p><strong>Automating Deployments<\/strong><\/p>\n<p>Create <strong>deployments.yaml<\/strong> using the template below (indentation must be respected):<\/p>\n<pre>apiVersion: apps\/v1\r\nkind: <strong>Deployment<\/strong>\r\nmetadata:\r\n  name: <strong>nginx-deployment<\/strong>\r\n  labels:\r\n    app: <span style=\"color: #339966;\"><strong>nginx-instance<\/strong><\/span>\r\nspec:\r\n  replicas: 6\r\n  selector:\r\n    matchLabels:\r\n      app: <span style=\"color: #339966;\"><strong>nginx-instance<\/strong><\/span>\r\n  template:\r\n    metadata:\r\n      labels:\r\n        app: <span style=\"color: #339966;\"><strong>nginx-instance<\/strong><\/span>\r\n    spec:\r\n      containers:\r\n      - name: <span style=\"color: #339966;\"><strong>nginx-instance<\/strong><\/span>\r\n        image: <strong>nginx<\/strong>\r\n        imagePullPolicy: Always\r\n        ports:\r\n        - containerPort: <strong>80<\/strong><\/pre>\n<pre>kubectl apply -f <strong>nginx-deployment.yaml<\/strong><\/pre>\n<p>Editing the deployment configuration:<\/p>\n<pre>export KUBE_EDITOR=nano\r\nkubectl edit deployment <strong>nginx-deployment\r\n<\/strong>kubectl get pods -o wide\r\n<\/pre>\n<p><strong>Load Balancer<\/strong><\/p>\n<p>Create a file called <strong>loadbalancer.yaml<\/strong> as shown below:<\/p>\n<pre>apiVersion: v1\r\nkind: <strong>Service<\/strong>\r\nmetadata:\r\n  name: <span style=\"color: #ff9900;\"><strong>nginx-loadbalancer<\/strong><\/span>\r\n  annotations:\r\n    service.beta.kubernetes.io\/linode-loadbalancer-throttle: <strong>\"5\"<\/strong>\r\n  labels:\r\n    app: <span style=\"color: #ff9900;\"><strong>nginx-loadbalancer<\/strong><\/span>\r\nspec:\r\n  type: <strong>LoadBalancer<\/strong>\r\n  selector:\r\n    app: <span style=\"color: #339966;\"><strong>nginx-instance<\/strong><\/span>\r\n  ports:\r\n    - name: http\r\n      protocol: TCP\r\n      port: 80\r\n      targetPort: 80\r\n  sessionAffinity: None<\/pre>\n<pre>kubectl apply -f <strong>loadbalancer.yaml\r\n<\/strong>kubectl get services\r\nkubectl describe service <strong>nginx-loadbalancer<\/strong><\/pre>\n<p><strong>Port Forwarding<\/strong><\/p>\n<pre>kubectl port-forward app-********-***** 8080:80\r\nkubectl port-forward pods\/app-********-***** 8080:80\r\nkubectl port-forward deployment\/app 8080:80\r\nkubectl port-forward replicaset\/app-******** 8080:80\r\nkubectl port-forward service\/app 8080:80<\/pre>\n<p><strong>NGINX is now accessible externally through the load balancer service!<\/strong><\/p>\n<p>Other useful commands:<\/p>\n<pre>kubectl get pods -w\r\nkubectl get all\r\nkubectl scale deploy\/nginx --replicas=3\r\nkubectl rollout status deploy\/nginx\r\nkubectl rollout undo deploy\/nginx\r\nkubectl deploy nginx --image=nginx:1.17-alpine -o yaml --dry-run=client\r\nkubectl explain services<\/pre>\n<hr \/>\n<p><strong>BONUS<\/strong><\/p>\n<p>Recover an accidentally deleted manifest file from a K8s runtime:<\/p>\n<pre>kubectl get &lt;resource-type&gt; &lt;resource-name&gt; -n &lt;namespace&gt; -o yaml &gt; manifest.yaml<\/pre>\n<p>Install the Helm package manager:<\/p>\n<pre>curl https:\/\/raw.githubusercontent.com\/helm\/helm\/main\/scripts\/get-helm-3 | bash<\/pre>\n<p>Free <strong>SSL\/TLS<\/strong> certificate from <strong>Let&#8217;s Encrypt<\/strong>.<\/p>\n<p>Install the prerequisites:<\/p>\n<pre>helm repo add jetstack https:\/\/charts.jetstack.io\r\nhelm repo add ingress-nginx https:\/\/kubernetes.github.io\/ingress-nginx\r\nhelm repo update<\/pre>\n<pre>helm install cert-manager jetstack\/cert-manager --namespace cert-manager --create-namespace --version v1.17.2 --set crds.enabled=true\r\nhelm upgrade --install ingress-nginx ingress-nginx\/ingress-nginx --namespace ingress-nginx --create-namespace --set controller.kind=DaemonSet --set controller.hostNetwork=true --set controller.daemonset.useHostPort=true --set controller.service.type=\"\" --set controller.ingressClassResource.name=nginx<\/pre>\n<p>Optionally, <strong>Traefik<\/strong> can be set as the default ingress controller:<\/p>\n<pre>helm repo add traefik https:\/\/traefik.github.io\/charts \r\nhelm install traefik traefik\/traefik<\/pre>\n<p><strong>Cluster Issuer<\/strong><\/p>\n<pre>cat &lt; cluster-issuer.yml\r\napiVersion: cert-manager.io\/v1\r\nkind: ClusterIssuer\r\nmetadata:\r\n  name: letsencrypt\r\nspec:\r\n  acme:\r\n    email: <span style=\"text-decoration: underline;\"><strong>admin@example.com<\/strong><\/span>\r\n    server: <strong>https:\/\/acme-staging-v02.api.letsencrypt.org\/directory<\/strong>\r\n#    server: <strong>https:\/\/acme-v02.api.letsencrypt.org\/directory<\/strong>\r\n    privateKeySecretRef:\r\n      name: letsencrypt\r\n    solvers:\r\n    - http01:\r\n        ingress:\r\n          class: nginx\r\nEOF\r\nkubectl apply -f cluster-issuer.yml\r\nsleep 10\r\nkubectl get clusterissuer\r\nkubectl describe clusterissuer<\/pre>\n<p><strong>Certificate<\/strong><\/p>\n<pre>cat &lt; certificate.yml\r\napiVersion: cert-manager.io\/v1\r\nkind: Certificate\r\nmetadata:\r\n  name: <strong>certificate-name<\/strong>\r\n  namespace: default\r\nspec:\r\n  secretName: <strong>tls-secret-name<\/strong>\r\n  issuerRef:\r\n    name: letsencrypt\r\n    kind: ClusterIssuer\r\n  dnsNames:\r\n  - <span style=\"text-decoration: underline;\"><strong>app.dev.example.com<\/strong><\/span>\r\n<strong>#  - app.example.com\r\n# Up to 100 additional domains per single cert.<\/strong>\r\nEOF\r\nkubectl apply -f certificate.yml\r\nsleep 10\r\nkubectl describe certificate\r\nkubectl describe certificaterequest\r\nkubectl describe order\r\nkubectl describe challenges<\/pre>\n<p>Inline creation of an ingress with an SSL certificate:<\/p>\n<pre>kubectl create ingress &lt;ingress-name&gt; --rule=example.com\/*=web:80,tls=&lt;certificate-name&gt;<\/pre>\n<p>Rollout (or rollback) and restart of all pods in a deployment:<\/p>\n<pre>kubectl rollout restart deployment &lt;deployment-name&gt;<\/pre>\n<p>Meet <code>etcd<\/code>, the distributed key-value store that guarantees the integrity of critical data in a distributed system like K8s [<a href=\"https:\/\/etcd.io\/\">Link<\/a>].<\/p>\n<ul>\n<li>It runs in the background and keeps all nodes in a K8s cluster in sync.<\/li>\n<li>It provides strong consistency and distributed coordination using the Raft algorithm.<\/li>\n<li>It makes intensive use of non-volatile memory and only returns success when a quorum is reached.<\/li>\n<\/ul>\n<pre>sudo apt-get update\r\nwget https:\/\/github.com\/etcd-io\/etcd\/releases\/download\/v<strong>3.6.6<\/strong>\/etcd-v<strong>3.6.6<\/strong>-linux-amd64.tar.gz\r\ntar -xvzf etcd-v<strong>3.6.6<\/strong>-linux-amd64.tar.gz\r\ncd etcd-v<strong>3.6.6<\/strong>-linux-amd64\/\r\nsudo mv etcd etcdctl \/usr\/local\/bin\/ &amp;&amp; etcd --version\r\nsudo mkdir -p \/etc\/etcd \/var\/lib\/etcd\r\nsudo useradd -r -s \/sbin\/nologin etcd\r\ncat &lt;&lt;EOF &gt; \/etc\/systemd\/system\/etcd.service\r\n[Unit]\r\nDescription=etcd key-value store\r\nDocumentation=https:\/\/etcd.io\/docs\/\r\nAfter=network.target\r\n[Service]\r\nUser=etcd\r\nType=notify\r\nExecStart=\/usr\/local\/bin\/etcd \u2013name default \u2013data-dir \/var\/lib\/etcd \u2013listen-client-urls http:\/\/0.0.0.0:2379 \u2013advertise-client-urls http:\/\/localhost:2379\r\nRestart=on-failure\r\nLimitNOFILE=40000\r\n[Install]\r\nWantedBy=multi-user.target\r\nEOF\r\nsudo systemctl daemon-reload\r\nsudo chown -R etcd:etcd \/var\/lib\/etcd\r\nsudo chmod 700 \/var\/lib\/etcd\r\nsudo systemctl enable etcd --now<\/pre>\n<p>Now, test it:<\/p>\n<pre>etcdctl put hello \"Ubuntu 24.04\"<\/pre>\n<pre>etcdctl get hello<\/pre>\n<hr \/>\n<p><strong>SEE ALSO<\/strong><\/p>\n<p><strong>Minikube<\/strong> on Ubuntu 22.04 [<a href=\"https:\/\/dft.wiki\/?p=3087\">Link<\/a>].<\/p>\n<p><strong>MicroK8s<\/strong> on Ubuntu 22.04 [<a href=\"https:\/\/dft.wiki\/?p=3151\">Link<\/a>].<\/p>\n<p><strong>K3s<\/strong> on Ubuntu 22.04 [<a href=\"https:\/\/dft.wiki\/?p=3105\">Link<\/a>].<\/p>\n<p><strong>Kubernetes<\/strong> Persistent Volumes [<a href=\"https:\/\/dft.wiki\/?p=1435\">Link<\/a>].<\/p>\n<p><strong>Kubernetes<\/strong> Dashboard [<a href=\"https:\/\/dft.wiki\/?p=4114\">Link<\/a>].<\/p>\n<p><strong>kURL<\/strong> &#8211; Open Source Kubernetes Installer [<a href=\"https:\/\/kurl.sh\/\">Link<\/a>].<\/p>\n<p><strong>K0s<\/strong> &#8211; Single Binary K8s [<a href=\"https:\/\/github.com\/k0sproject\/k0s\">Link<\/a>]<\/p>\n<p><strong>K9s<\/strong> &#8211; CLI Tool [<a href=\"https:\/\/github.com\/derailed\/k9s\">Link<\/a>].<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have ever worked with containers such as Docker, you know how efficient and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,6],"tags":[],"class_list":["post-1372","post","type-post","status-publish","format-standard","hentry","category-linux","category-raspberry-pi"],"_links":{"self":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/1372","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1372"}],"version-history":[{"count":34,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/1372\/revisions"}],"predecessor-version":[{"id":5770,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/1372\/revisions\/5770"}],"wp:attachment":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1372"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1372"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1372"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}