Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/elahe-dastan/sky
How I learn Kubernetes
https://github.com/elahe-dastan/sky
emptydir-volume helm helm-chart mysql-container persistent-volumes pod-restarts statefulsets volume-mount workload
Last synced: about 1 month ago
JSON representation
How I learn Kubernetes
- Host: GitHub
- URL: https://github.com/elahe-dastan/sky
- Owner: elahe-dastan
- Created: 2020-09-20T11:38:42.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2022-12-20T13:40:41.000Z (about 2 years ago)
- Last Synced: 2024-11-14T16:47:31.574Z (3 months ago)
- Topics: emptydir-volume, helm, helm-chart, mysql-container, persistent-volumes, pod-restarts, statefulsets, volume-mount, workload
- Language: Smarty
- Homepage:
- Size: 114 KB
- Stars: 5
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
Awesome Lists containing this project
README
# sky
In sky repository I want to put all the stuff I use for learning kubernetes Let me start with this picture
![]()
## Probes
- liveness probe: to know when to restart a container
- readiness probe: to know when a container is ready to start accepting traffic
- startup probe: to know when a container application has started## Liveness
In the liveness directory, I have put a pod configuration and defined a liveness command.## Deploy mysql
In many cases your app has a database dependency, so you should first deploy a database.
Here I deployed a mysql container that in the stateful directory you can see the files.
Let'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.(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)
## Statefulsets
I 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,
I had no experience in working with kubernetese so I started from very beginning I thought that I had to deploy the
project's database before deploying itself I found a very simple sample (stateful directory) and everything was fine till
I asked myself a question what does `clusterIP: None` mean??? well, to be honest I didn't completely understand what it
means :sweat_smile: but it led me to another concept `statefulsets` I want to explain it as complete as I can.#### Workloads
Workloads are objects that set deployment rules for pods.Based on these rules, Kubernetese performs the deployment and
updates the workload with the current state of the application.Workloads let you define the rules for application
scheduling, scaling and upgrade.The most frequently used workloads are `Deployment` and `StatefulSets`. A question probably
popped up in your mind is this what is the difference??? They say `Deployment` should be used for stateless applications
and `StatefulSets` should be used for stateful applications, now we come to this question Why?? Now I want to continue my
story I wanted to deploy a database, so my application was stateful and if I wanted to listen to their advice I had to use
`StatefulSets` workload, but the example I was following had used `Deploymeny` workload which confused me.Here is what was
going on.
I wanted to deploy a mysql container, so I needed a `PersistentVolume`, the pod may restart for various reasons and if I
don't use an underlying persistent volume I lose all my data.I have put the access mode of the persistent volume equal to
`ReadWriteOne` it means that the storage can only be accessed by a single node **but wait** what if the pod restarts??!
**then the newer pod cannot access the persistent volume cause it's another pod??!** here is why we use Statefulsets.
##### StatefulSets VS Deployment
When we use `Deployment` workload if a pod restarts then the newer pod is completely different from the first one, and the
persistent volume thinks it's another node and doesn't let access, but statefulsets workload manage pods with their unique
id (for example hostname) so if a pod restarts the newer pod has the same unique id, so the persistent volume thinks it's
the same node as a result the pod has all the failed pod accesses.Another question rises up, in my stateful directory I
have used deployment workload so what if it restarts, it cannot connect to the persistent volume any more??! well, what I
have done in that directory is called `Single-instance stateful application`.##### Single-instance stateful application
if I manage more than one pod then you're right everything will be broken but in that specific example everything works
fine because
- first:It is single instance
- second:it's `Strategy` is `Recreate`I cannot have more than one pod, **Why?** the underlying persistent volume is ReadWriteOnce so more than one pod cannot
access it.You may ask about what the statefulset workload does, **it gives each pod its own persistent volume**.
The strategy should be `Recreate` so the first pod terminates completely and a new one with the exact same configuration
will be managed, so it doesn't loose any access.With the preceding explanation you should have concluded that in case of a stateful application `Rolling Update` is impossible.
##### Accessing mysql instance
I 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:
```sh
$ kubectl run -it --rm --image=mysql:8.0 --restart=Never --requests=cpu=100m,memory=256Mi mysql-client -- mysql -h mysql -ppassword
```
and unexpectedly I got this error
failed to open log file "/var/log/pods/...":open /var/log/pods/... no such file or directory
This error can have so many reasons, in my case it needed a persistent volume. **Why??** read another story:
We all know that everything in a container lives as long as the container is up and running and since the container be
deleted all the data in the container is gone forever except we manage a volume. Once, I wanted to create a mysql
container and I hadn't passed any volume I deleted the container and after some time I created another mysql container
surprisingly all the previous data was there :flushed: it happens because in the `Dockerfile` of mysql image is set a
volume.
I was using `OpenShift` and openshift checks that the dockerfile needs a volume and doesn't let me create a pod without
it.#### deployment strategies
- recreate: terminate the old version and release the new one
- ramped: release a new version on a rolling update fashion, one after the other
- blue/green: release a new version alongside the old version then switch traffic
- canary: release a new version to a subset of users, then proceed to a full rollout
- a/b testing: release a new version to a subset of users in a precise way (HTTP headers, cookie, weight, etc.).### Pod Management Policy
The 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.#### Parallel Pod Management
Parallel 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.##### Pay attention
If 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:![PodManagementPolicy](https://user-images.githubusercontent.com/36500888/170239794-9f9913ba-b42b-4aec-8d05-eee318b9a527.png)
You have to delete yout manifest, change and apply again.
## Service
I got a little confused.What does a **Service** exactly do??
It is both a load balancer and a DNS name.## Empty Dir
I 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
it'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,
so I don't want it to write data on the disk as a result I used Empty Dir. Here is more explanation:
An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that
node. As the name says, it is initially empty. Containers in the Pod can all read and write the same files in the emptyDir
volume, though that volume can be mounted at the same or different paths in each Container. When a Pod is removed from a
node for any reason, the data in the emptyDir is deleted forever.(Note: A Container crashing does NOT remove a Pod from
a node, so the data in an emptyDir volume is safe across Container crashes.)## Disable Redis Persistence
Redis cloud provides two methods to persist the data to disk. They are Append Only File (AOF) and Snapshot (RDB).
Snapshot or RDB takes the data at that moment and writes it to the disk, in a binary file called dump.rdb.
On the other hand, AOF writes all the incoming “write” commands to the disk. Data persistence is optional, and we can disable it too.
Though persistence prevents data loss, it increases the disk space usage abundantly. So, in cases where we can't persist
large data on disk, we disable persistence.## Route
In order for services to be exposed externally, an OpenShift route allows you to associate a service with an
externally-reachable host name. This edge host name is then used to route traffic to the service.## lost + found
Once, I wanted to create a postgres pod, and I got an error containing the key word `lost + found`, here is the problem,
when you create a pod or a container and set a **volume** it is mandatory that the directory on the host that you wanna
mount to be completely "empty" which is not always the case. A simple solution is to use `PGDATA`, this is what happens
you 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,
but 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,
but 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
disk.## Object Spec and Status
Almost 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`.The 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.
## Common oc commands
1. push manifest to kubernetes: oc apply -f
2. BuildConfig manifest is a kind to build an image and we run it by: oc start-build
3. you can get your buildconfigs by: oc get bc
4. you can get your imagestreams by: oc get is
5. oc port-forward {pod} port:port
6. get resource of namespace: oc describe quota
7. get resource of group: oc describe appliedclusterresourcequota
8. test pod:
kubectl run nats-box --timeout=10m --image=natsio/nats-box:latest --rm -it --restart=Never --command -- sh
## docker container ip
## oc vs kubectl## If the container doesn't have anything to do?? busybox-sleep
## invalid port range
## Connect to one pod from anotherDelete all spark application that is failed:
```bash
oc get sparkapplication -o json | jq '.items[] | select(.status.applicationState.state == "FAILED") | .metadata.name' -r | xargs oc delete sparkapplication '{}'
```