{"id":1003,"date":"2020-08-31T09:39:33","date_gmt":"2020-08-31T09:39:33","guid":{"rendered":"https:\/\/blog.samarthya.me\/wps\/?p=1003"},"modified":"2020-09-04T10:15:24","modified_gmt":"2020-09-04T10:15:24","slug":"playground-k8s","status":"publish","type":"post","link":"https:\/\/blog.samarthya.me\/wps\/2020\/08\/31\/playground-k8s\/","title":{"rendered":"PlayGround: K8S"},"content":{"rendered":"<p>I have been working on Kubernetes cluster and will soon plan to give a Kubernetes Certified Developer exam. In my quest, I will just record some commands that I found helpful or useful in this blog. It may be multi-part, as I will keep adding on a daily basis the commands that I will be learning.<\/p>\n<h2>Labels<\/h2>\n\n\n<pre class=\"wp-block-code\"><code>> k get nodes\nNAME             STATUS                     ROLES    AGE    VERSION\ndocker-desktop   Ready,SchedulingDisabled   master   105d   v1.16.6-beta.0<\/code><\/pre>\n\n\n\n<p>Adding a label to the node<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> k label node docker-desktop nodeName=docker-node\nnode\/docker-desktop labeled<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>> k get nodes --show-labels\nNAME             STATUS                     ROLES    AGE    VERSION          LABELS\ndocker-desktop   Ready,SchedulingDisabled   master   105d   v1.16.6-beta.0   beta.kubernetes.io\/arch=amd64,beta.kubernetes.io\/os=linux,kubernetes.io\/arch=amd64,kubernetes.io\/hostname=docker-desktop,kubernetes.io\/os=linux,node-role.kubernetes.io\/master=,nodeName=docker-node<\/code><\/pre>\n\n\n\n<p>Notice the new label at the end <code>nodeName=docker-node<\/code>. You can also validate the label has been applied by using the selector<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>>k get nodes -l nodeName=docker-node\nNAME             STATUS                     ROLES    AGE    VERSION\ndocker-desktop   Ready,SchedulingDisabled   master   105d   v1.16.6-beta.0<\/code><\/pre>\n\n\n\n<p>I will create a nginx-pod on my local <code>Docker CE\/Kubernetes <\/code>and validate the Scheduling.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>nodeSelector<\/code><br><em>object<\/em><\/td><td>NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node&#8217;s labels for the pod to be scheduled on that node. More info: https:\/\/kubernetes.io\/docs\/concepts\/configuration\/assign-pod-node\/<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    run: nginx\n    app: nginx-on-node\n  name: nginx-node\nspec:\n  nodeSelector:\n    nodeName: docker-node\n  containers:\n    - image: nginx\n      name: nginx-container\n      resources:\n        limits:\n          memory: 500Mi\n          cpu: 500m\n        requests:\n          memory: 250Mi\n          cpu: 500m\n  dnsPolicy: ClusterFirst\n  restartPolicy: Never\nstatus: {}<\/code><\/pre>\n\n\n\n<p>What I have used is a <code>nodeSelector<\/code> that uses the label define in the section above. As the only node on my local machine is the <code>docker-desktop<\/code> and it has a setting as SchedulingDisabled the container will forever be in the Pending state.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> k get nodes\nNAME             STATUS                     ROLES    AGE    VERSION\ndocker-desktop   Ready,SchedulingDisabled   master   105d   v1.16.6-beta.0<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>> k get all\nNAME                        READY   STATUS    RESTARTS   AGE\npod\/curl-69c656fd45-zwt8n   1\/1     Running   0          7d\npod\/nginx-node              0\/1     Pending   0          15m<\/code><\/pre>\n\n\n\n<p>A quick describe on the pod<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> k describe pod\/nginx-node\n\nName:         nginx-node\nNamespace:    default\nPriority:     0\nNode:         &lt;none>\nLabels:       app=nginx-on-node\n              run=nginx\nAnnotations:  kubectl.kubernetes.io\/last-applied-configuration:\n                {\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"nginx-on-node\",\"run\":\"nginx\"},\"name\":\"nginx-node\",\"namespace...\nStatus:       Pending\nIP:           \nIPs:          &lt;none>\nContainers:\n  nginx-container:\n    Image:      nginx\n    Port:       &lt;none>\n    Host Port:  &lt;none>\n    Limits:\n      cpu:     500m\n      memory:  500Mi\n    Requests:\n      cpu:        500m\n      memory:     250Mi\n    Environment:  &lt;none>\n    Mounts:\n      \/var\/run\/secrets\/kubernetes.io\/serviceaccount from default-token-ksbmz (ro)\nConditions:\n  Type           Status\n  PodScheduled   False \nVolumes:\n  default-token-ksbmz:\n    Type:        Secret (a volume populated by a Secret)\n    SecretName:  default-token-ksbmz\n    Optional:    false\nQoS Class:       Burstable\nNode-Selectors:  nodeName=docker-node\nTolerations:     node.kubernetes.io\/not-ready:NoExecute for 300s\n                 node.kubernetes.io\/unreachable:NoExecute for 300s\nEvents:\n  Type     Reason            Age        From               Message\n  ----     ------            ----       ----               -------\n  Warning  FailedScheduling  &lt;unknown>  default-scheduler  0\/1 nodes are available: 1 node(s) were unschedulable.<\/code><\/pre>\n\n\n\n<p>It validates the <code>un-scedulable<\/code> node. To overcome this handicap, I will use the <code>uncordon<\/code> <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>k uncordon -h\nMark node as schedulable.\n\nExamples:\n  # Mark node \"foo\" as schedulable.\n  $ kubectl uncordon foo\n\nOptions:\n      --dry-run=false: If true, only print the object that would be sent, without sending it.\n  -l, --selector='': Selector (label query) to filter on\n\nUsage:\n  kubectl uncordon NODE &#91;options]<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>> k uncordon docker-desktop\nnode\/docker-desktop uncordoned<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>> k get all\nNAME                        READY   STATUS              RESTARTS   AGE\npod\/curl-69c656fd45-zwt8n   1\/1     Running             0          7d\npod\/nginx-node              0\/1     ContainerCreating   0          7m12s<\/code><\/pre>\n\n\n\n<p>The moment I mark it as <code>schedulable<\/code> the state changes and I can see the Container creating. A quick describe will show the events<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> Type     Reason            Age        From                     Message\n  ----     ------            ----       ----                     -------\n  Warning  FailedScheduling  &lt;unknown>  default-scheduler        0\/1 nodes are available: 1 node(s) were unschedulable.\n  Warning  FailedScheduling  &lt;unknown>  default-scheduler        0\/1 nodes are available: 1 node(s) were unschedulable.\n  Warning  FailedScheduling  &lt;unknown>  default-scheduler        0\/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate.\n  Normal   Scheduled         &lt;unknown>  default-scheduler        Successfully assigned default\/nginx-node to docker-desktop\n  Normal   Pulling           6m11s      kubelet, docker-desktop  Pulling image \"nginx\"\n  Normal   Pulled            6m6s       kubelet, docker-desktop  Successfully pulled image \"nginx\"\n  Normal   Created           6m6s       kubelet, docker-desktop  Created container nginx-container\n  Normal   Started           6m6s       kubelet, docker-desktop  Started container nginx-container<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Annotations<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>> k annotate pods nginx-node description='My nginx-node on a specific node'\npod\/nginx-node annotated<\/code><\/pre>\n\n\n\n<p>A describe call for the pod <code>nginx-node<\/code> can reveal the annotation.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Annotations:  description: My nginx-node on a specific node<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Create<\/h2>\n\n\n\n<p><code>k create -h<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Available Commands:\n  clusterrole         Create a ClusterRole.\n  clusterrolebinding  Create a ClusterRoleBinding for a particular ClusterRole\n  configmap           Create a configmap from a local file, directory or literal value\n  cronjob             Create a cronjob with the specified name.\n  deployment          Create a deployment with the specified name.\n  job                 Create a job with the specified name.\n  namespace           Create a namespace with the specified name\n  poddisruptionbudget Create a pod disruption budget with the specified name.\n  priorityclass       Create a priorityclass with the specified name.\n  quota               Create a quota with the specified name.\n  role                Create a role with single rule.\n  rolebinding         Create a RoleBinding for a particular Role or ClusterRole\n  secret              Create a secret using specified subcommand\n  service             Create a service using specified subcommand.\n  serviceaccount      Create a service account with the specified name<\/code><\/pre>\n\n\n\n<p>Lets create a deployment<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>k create deploy bbdeploy --image=busybox --dry-run=true -o yaml<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  creationTimestamp: null\n  labels:\n    app: bbdeploy\n  name: bbdeploy\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: bbdeploy\n  strategy: {}\n  template:\n    metadata:\n      creationTimestamp: null\n      labels:\n        app: bbdeploy\n    spec:\n      containers:\n      - image: busybox\n        name: busybox\n        resources: {}\nstatus: {}<\/code><\/pre>\n\n\n\n<p>Lets change the replicas to 2 and create the deployment<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>k describe deploy<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Name:                   bbdeploy\nNamespace:              default\nCreationTimestamp:      Mon, 31 Aug 2020 16:14:00 +0530\nLabels:                 app=bbdeploy\nAnnotations:            deployment.kubernetes.io\/revision: 1\n                        kubectl.kubernetes.io\/last-applied-configuration:\n                          {\"apiVersion\":\"apps\/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"bbdeploy\"},\"name\":\"bbdeploy\",\"namespace\":\"defaul...\nSelector:               app=bbdeploy\nReplicas:               2 desired | 2 updated | 2 total | 0 available | 2 unavailable\nStrategyType:           RollingUpdate\nMinReadySeconds:        0\nRollingUpdateStrategy:  25% max unavailable, 25% max surge\nPod Template:\n  Labels:  app=bbdeploy\n  Containers:\n   busybox:\n    Image:      busybox\n    Port:       &lt;none>\n    Host Port:  &lt;none>\n    Limits:\n      cpu:     250m\n      memory:  500Mi\n    Requests:\n      cpu:        250m\n      memory:     500Mi\n    Environment:  &lt;none>\n    Mounts:       &lt;none>\n  Volumes:        &lt;none>\nConditions:\n  Type           Status  Reason\n  ----           ------  ------\n  Available      False   MinimumReplicasUnavailable\n  Progressing    True    ReplicaSetUpdated\nOldReplicaSets:  &lt;none>\nNewReplicaSet:   bbdeploy-5797fdc756 (2\/2 replicas created)\nEvents:\n  Type    Reason             Age   From                   Message\n  ----    ------             ----  ----                   -------\n  Normal  ScalingReplicaSet  7s    deployment-controller  Scaled up replica set bbdeploy-5797fdc756 to 2<\/code><\/pre>\n\n\n\n<p>Similar example for Nginx<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>--- # My deployment\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  labels:\n    app: nginx-webserver\n  name: deploy-nginx-deploy\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: nginx-webserver-pod\n  template:\n    metadata:\n      labels:\n        app: nginx-webserver-pod\n    spec:\n      containers:\n        - image: nginx\n          name: nginx\n          resources:\n            requests:\n              cpu: 250m\n              memory: 500Mi\n            limits:\n              cpu: 250m\n              memory: 500Mi<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>k get pods --show-labels\nNAME                                   READY   STATUS    RESTARTS   AGE    LABELS\ndeploy-nginx-deploy-6d45895bf5-mv9wr   1\/1     Running   0          21s    app=nginx-webserver-pod,pod-template-hash=6d45895bf5\ndeploy-nginx-deploy-6d45895bf5-vpt6p   1\/1     Running   0          21s    app=nginx-webserver-pod,pod-template-hash=6d45895bf5<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>k get deploy --show-labels\nNAME                  READY   UP-TO-DATE   AVAILABLE   AGE    LABELS\ndeploy-nginx-deploy   2\/2     2            2           32s    app=nginx-webserver<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-pullquote has-background has-luminous-vivid-orange-background-color is-style-solid-color\"><blockquote class=\"has-text-color has-black-color\"><p>Scaling to 3<\/p><\/blockquote><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>> k scale --replicas=3 deploy\/deploy-nginx-deploy\ndeployment.apps\/deploy-nginx-deploy scaled<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>k get all\nNAME                                       READY   STATUS              RESTARTS   AGE\npod\/deploy-nginx-deploy-6d45895bf5-79kd7   0\/1     ContainerCreating   0          4s\npod\/deploy-nginx-deploy-6d45895bf5-mv9wr   1\/1     Running             0          5m\npod\/deploy-nginx-deploy-6d45895bf5-vpt6p   1\/1     Running             0          5<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I have been working on Kubernetes cluster and will soon plan to give a Kubernetes Certified Developer exam. In my quest, I will just record some commands that I found helpful or useful in this blog. It may be multi-part, as I will keep adding on a daily basis the commands that I will be [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1006,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[34],"tags":[105],"class_list":["post-1003","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-technical","tag-plaground","post_format-post-format-image"],"_links":{"self":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/1003","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/comments?post=1003"}],"version-history":[{"count":0,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/1003\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media\/1006"}],"wp:attachment":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media?parent=1003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/categories?post=1003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/tags?post=1003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}