{"id":20303576,"url":"https://github.com/elahe-dastan/sky","last_synced_at":"2025-03-04T07:12:20.374Z","repository":{"id":113152884,"uuid":"297062903","full_name":"elahe-dastan/sky","owner":"elahe-dastan","description":"How I learn Kubernetes","archived":false,"fork":false,"pushed_at":"2022-12-20T13:40:41.000Z","size":117,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-14T11:14:32.184Z","etag":null,"topics":["emptydir-volume","helm","helm-chart","mysql-container","persistent-volumes","pod-restarts","statefulsets","volume-mount","workload"],"latest_commit_sha":null,"homepage":"","language":"Smarty","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elahe-dastan.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-20T11:38:42.000Z","updated_at":"2022-02-22T23:20:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"6f074fb7-c2dd-4287-a46a-f73c4502b769","html_url":"https://github.com/elahe-dastan/sky","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elahe-dastan%2Fsky","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elahe-dastan%2Fsky/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elahe-dastan%2Fsky/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elahe-dastan%2Fsky/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elahe-dastan","download_url":"https://codeload.github.com/elahe-dastan/sky/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241801257,"owners_count":20022389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["emptydir-volume","helm","helm-chart","mysql-container","persistent-volumes","pod-restarts","statefulsets","volume-mount","workload"],"created_at":"2024-11-14T16:39:23.730Z","updated_at":"2025-03-04T07:12:20.339Z","avatar_url":"https://github.com/elahe-dastan.png","language":"Smarty","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sky \nIn sky repository I want to put all the stuff I use for learning kubernetes Let me start with this picture\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"image/kubernetese.jpeg\"\u003e\u003c/img\u003e\n\u003c/p\u003e\n\n## Probes\n- liveness probe: to know when to restart a container\n- readiness probe: to know when a container is ready to start accepting traffic\n- startup probe: to know when a container application has started\n\n## Liveness\nIn the liveness directory, I have put a pod configuration and defined a liveness command.\n\n## Deploy mysql\nIn many cases your app has a database dependency, so you should first deploy a database.\nHere I deployed a mysql container that in the stateful directory you can see the files.\nLet's see what we need, first of all we want a persistent storage like disk, so our data won't be missed if our pod restarts, so we need a `PersistentVolume` then a `PersistentVolumeClaim` and after those we can go to the `DeploymentConfig` part and add a volume mount.\n\n(Note: Many private cloud providers (for example the private cloud of the company you are working in) may not let you get persistent volumes so all you need is a persistent volume claim)\n\n## Statefulsets\nI want to tell the story I went through, one day my team lead asked to deploy a project on the cloud with it's dependencies,\nI had no experience in working with kubernetese so I started from very beginning I thought that I had to deploy the \nproject's database before deploying itself I found a very simple sample (stateful directory) and everything was fine till\nI asked myself a question what does `clusterIP: None` mean??? well, to be honest I didn't completely understand what it\nmeans :sweat_smile: but it led me to another concept `statefulsets` I want to explain it as complete as I can.\u003cbr/\u003e\n\n#### Workloads\nWorkloads are objects that set deployment rules for pods.Based on these rules, Kubernetese performs the deployment and\nupdates the workload with the current state of the application.Workloads let you define the rules for application\nscheduling, scaling and upgrade.The most frequently used workloads are `Deployment` and `StatefulSets`. A question probably\npopped up in your mind is this what is the difference??? They say `Deployment` should be used for stateless applications\nand `StatefulSets` should be used for stateful applications, now we come to this question Why?? Now I want to continue my\nstory I wanted to deploy a database, so my application was stateful and if I wanted to listen to their advice I had to use\n`StatefulSets` workload, but the example I was following had used `Deploymeny` workload which confused me.Here is what was\ngoing on.\u003cbr/\u003e\nI wanted to deploy a mysql container, so I needed a `PersistentVolume`, the pod may restart for various reasons and if I \ndon't use an underlying persistent volume I lose all my data.I have put the access mode of the persistent volume equal to\n`ReadWriteOne` it means that the storage can only be accessed by a single node **but wait** what if the pod restarts??!\n**then the newer pod cannot access the persistent volume cause it's another pod??!** here is why we use Statefulsets.\n##### StatefulSets VS Deployment\nWhen we use `Deployment` workload if a pod restarts then the newer pod is completely different from the first one, and the\npersistent volume thinks it's another node and doesn't let access, but statefulsets workload manage pods with their unique\nid (for example hostname) so if a pod restarts the newer pod has the same unique id, so the persistent volume thinks it's\nthe same node as a result the pod has all the failed pod accesses.Another question rises up, in my stateful directory I \nhave used deployment workload so what if it restarts, it cannot connect to the persistent volume any more??! well, what I\nhave done in that directory is called `Single-instance stateful application`.\n\n##### Single-instance stateful application\nif I manage more than one pod then you're right everything will be broken but in that specific example everything works \nfine because\u003cbr/\u003e\n- first:It is single instance\n- second:it's `Strategy` is `Recreate`\n\nI cannot have more than one pod, **Why?** the underlying persistent volume is ReadWriteOnce so more than one pod cannot \naccess it.You may ask about what the statefulset workload does, **it gives each pod its own persistent volume**.\u003cbr/\u003e\nThe strategy should be `Recreate` so the first pod terminates completely and a new one with the exact same configuration \nwill be managed, so it doesn't loose any access.\n\nWith the preceding explanation you should have concluded that in case of a stateful application `Rolling Update` is impossible.\n\n##### Accessing mysql instance\nI had my mysql pod up and running, I decided to have a mysql client pod and use it query my mysql. I wrote this command:\u003cbr/\u003e\n```sh\n$ kubectl run -it --rm --image=mysql:8.0 --restart=Never --requests=cpu=100m,memory=256Mi mysql-client -- mysql -h mysql -ppassword\n```\nand unexpectedly I got this error\u003cbr/\u003e\nfailed to open log file \"/var/log/pods/...\":open /var/log/pods/... no such file or directory\u003cbr/\u003e\nThis error can have so many reasons, in my case it needed a persistent volume. **Why??** read another story:\u003cbr/\u003e\nWe all know that everything in a container lives as long as the container is up and running and since the container be\ndeleted all the data in the container is gone forever except we manage a volume. Once, I wanted to create a mysql \ncontainer and I hadn't passed any volume I deleted the container and after some time I created another mysql container\nsurprisingly all the previous data was there :flushed: it happens because in the `Dockerfile` of mysql image is set a \nvolume.\nI was using `OpenShift` and openshift checks that the dockerfile needs a volume and doesn't let me create a pod without\nit.\n\n#### deployment strategies\n- recreate: terminate the old version and release the new one\n- ramped: release a new version on a rolling update fashion, one after the other\n- blue/green: release a new version alongside the old version then switch traffic\n- canary: release a new version to a subset of users, then proceed to a full rollout\n- a/b testing: release a new version to a subset of users in a precise way (HTTP headers, cookie, weight, etc.).\n\n### Pod Management Policy\nThe story that took me here is funny. I wanted to have a [h2o cluster](https://h2o.ai/), in this cluster one pod that is the master should mark itself as ready to accept load and all other pods mark themselves as not ready (we do it by using isLeader route as the rediness probe). This may cause a problem, usually and by default the `podManagementPolicy` is set OrderedReady in which kuberenetes deploys one pod waits for it to be running and ready then deploys the second pod and so on. In our h2o cluster this puts us in trouble cause our worker pods will never mark themselves as ready and we can't scale our pods to the number we desire. The solution is cchaning the `podManagementPolicy` to Parallel.\n\n#### Parallel Pod Management\nParallel pod management tells the StatefulSet contriller to launch or terminate all Pods in parallel, and to **not wait for Pods to become Running and Ready** or completely terminated prior ro launching or terminating another Pod.\n\n##### Pay attention\nIf your StatefulSet is up and then you want to change the podManagementPolicy you get this error ```error: Edit cancelled, no valid changes were saved``` that's because:\n\n![PodManagementPolicy](https://user-images.githubusercontent.com/36500888/170239794-9f9913ba-b42b-4aec-8d05-eee318b9a527.png)\n\nYou have to delete yout manifest, change and apply again.\n\n## Service \nI got a little confused.What does a **Service** exactly do??\u003cbr/\u003e\nIt is both a load balancer and a DNS name.\n\n## Empty Dir\nI want to create a redis pod and I have the same problem that I had while creating mysql pod.Redis has a volume mount in \nit's Dockerfile but I don't want the data on my redis to be persistent in fact I want my redis to be as fast as possible,\nso I don't want it to write data on the disk as a result I used Empty Dir. Here is more explanation:\nAn emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that \nnode. As the name says, it is initially empty. Containers in the Pod can all read and write the same files in the emptyDir \nvolume, though that volume can be mounted at the same or different paths in each Container. When a Pod is removed from a \nnode for any reason, the data in the emptyDir is deleted forever.(Note: A Container crashing does NOT remove a Pod from \na node, so the data in an emptyDir volume is safe across Container crashes.)\n\n## Disable Redis Persistence\nRedis cloud provides two methods to persist the data to disk. They are Append Only File (AOF) and Snapshot (RDB).\nSnapshot or RDB takes the data at that moment and writes it to the disk, in a binary file called dump.rdb.\nOn the other hand, AOF writes all the incoming “write” commands to the disk. Data persistence is optional, and we can disable it too.\nThough persistence prevents data loss, it increases the disk space usage abundantly. So, in cases where we can't persist \nlarge data on disk, we disable persistence.\n\n## Route\nIn order for services to be exposed externally, an OpenShift route allows you to associate a service with an \nexternally-reachable host name. This edge host name is then used to route traffic to the service. \n\n## lost + found\nOnce, I wanted to create a postgres pod, and I got an error containing the key word `lost + found`, here is the problem,\nwhen you create a pod or a container and set a **volume** it is mandatory that the directory on the host that you wanna \nmount to be completely \"empty\" which is not always the case. A simple solution is to use `PGDATA`, this is what happens \nyou have a `mount path` which is a path inside your container and this path is mounted to the root of a disk as a volume, \nbut the root of the disk is not empty, so you don't change the mount path, and it is still mounted to the root of the disk, \nbut you say that the `PGDATA` which is the place on the disk that you want to write and read from is a subdirectory on the \ndisk.\n\n## Object Spec and Status\nAlmost every Kubernetes object includes two nested object fields that govern the object's configuration: the object spec and the object status. For objects that have a spec, you have to set this when you create the object, providing a description of the characteristics you want the resource to have: its `desired state`.\n\nThe status describes the `current state` of the object, supplied and updated by the Kubernetes system and its components. The Kubernetes control plane continually and actively manages every object's actual state to match the desired state you supplied.\n\n## Common oc commands\n1. push manifest to kubernetes: oc apply -f \u003cfile\u003e\n2. BuildConfig manifest is a kind to build an image and we run it by: oc start-build \u003cname\u003e\n3. you can get your buildconfigs by: oc get bc\n4. you can get your imagestreams by: oc get is\n5. oc port-forward {pod} port:port\n6. get resource of namespace: oc describe quota\n7. get resource of group: oc describe appliedclusterresourcequota\n8. test pod: \nkubectl run nats-box --timeout=10m --image=natsio/nats-box:latest --rm -it --restart=Never --command -- sh\n## docker container ip\n## oc vs kubectl\n\n## If the container doesn't have anything to do?? busybox-sleep\n## invalid port range\n## Connect to one pod from another\n\nDelete all spark application that is failed:\n\n```bash\noc get sparkapplication -o json | jq '.items[] | select(.status.applicationState.state == \"FAILED\") | .metadata.name' -r | xargs oc delete sparkapplication '{}'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felahe-dastan%2Fsky","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felahe-dastan%2Fsky","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felahe-dastan%2Fsky/lists"}