Wednesday, February 3, 2021

What I learned about Kubernetes - (Namespace)

                               ဒီ article မှာတော့ Kubernetes ရဲ့ namespace အကြောင်းကို ပြောချင်ပါတယ်။

What is Namespace in Kubernetes?


                
                ကျွန်တော်တို့ အရင် Episodes တွေမှာ တည်ဆောက်ခဲ့သမျှ Deployment, Pod, ReplicaSet, Services အကုန်လုံးသည် Namespace တစ်ခုအတွင်းမှာသာဖြစ်သည်။ ဘယ် Namespace အတွင်းလဲဆိုတော့ Default Namespace တစ်ခုအတွင်းမှာ တည်ဆောက်ခဲ့တာဖြစ်ပါတယ်။ ဒီတော့ Namespace ဆိုတာ ကျွန်တော် နားလည်သလို ပြောရရင် သီးသန့် ထားတဲ့နေရာတစ်ခုဖြစ်ပါတယ်။ ဥပမာ environment တစ်ခု မှာ Application Suite တစ်ခုစီတိုင်းအတွက် အသုံးပြုထားတဲ့ Kubernetes cluster တွေ တစ်ခုနဲ့အထက်ရှိမယ် အဲ့တော့ တည်ဆောက်လိုက်သမျှ Pods တွေ Services တွေကို Default Namespace ထဲ အကုန်စုပြုံထည့်ပြီး သုံးနေရင် manage လုပ်ရတာ overhead ဖြစ်နေမှာဖြစ်တဲ့အတွက် App suite တစ်ခု Namespace တစ်ခု ပုံစံမျိုး ဒါမဟုတ် Prod Env အတွက် က Prod Namespace , UAT Env အတွက် က UAT Namespace တစ်ခု စီ ခွဲပြီး Pods တွေ Services တွေကို deploy လုပ် စတဲ့ နေရာမှာ Namespace ကို အသုံးပြုပါတယ်။

                    အောက်မှာပြထားတဲ့ပုံအတိုင်းပဲ Kubernetes cluster တစ်ခုရဲ့ Namespace တွေကို ကြည့်ချင်ရင် $kubectl get namespace command ကိုအသုံးပြုပီး ကြည့်နိုင်ပါတယ်။ ပုံတွင် Kubernetes cluster မှာ default အနေနဲ့ Namespace ၄ ခုပါရှိပါတယ်။ နောက်ထပ် command တစ်ခုဖြစ်တဲ့ $kubectl get all ကို အသုံးပြုရင် လက်ရှိ Kubernetes cluster မှာ တည်ဆောက်ထားသမျှ အားလုံးကို ပြပေးတာဖြစ်ပါတယ်။ ဒီနေရာမှာ $kubetcl get all ဆိုပြီး enter ခေါက်လိုက်တာနဲ့ result ဘာလို့ပြလဲ ဆိုတော့ ကျွန်တော်တို့ တည်ဆောက်ခဲ့သမျှ အားလုံးက "default namespace" ထဲ ရောက်သွားတဲ့အတွက် သတ်သတ်ကြီး namespace ကို mention ခေါ်စရာမလိုပဲ ကြည့်လိုရနိုင်တာဖြစ်ပါတယ်။ နောက်ထပ် command တစ်ခုကို ကြည့်မယ်ဆိုရင် $kubectl -n default get all မှာဆိုရင်တော့ -n = namespace "default namespace"ထဲမှာ တည်ဆောက်ထားသမျှ အားလုံးကို ကြည့်ချင်တယ်ဆိုရင် အခုလိုမျိုး အသုံးပြုရမှာဖြစ်ပါတယ်။










What is Kube-system namespace?


                   Kubernetes တစ်ခု စတင်တည်ဆောက်ထဲက ပါဝင်လာတဲ့ Namespace တစ်ခုဖြစ်ပါတယ်။ ဘာအတွက် အသုံးပြုလဲဆိုရင် ဒီ Kubernetes တစ်ခု run ဖို့အတွက် လိုအပ်တဲ့ services တွေ ဖြစ်တဲ့ networking, dns service, နောက် kube-{controller, scheduler, api, proxy, etc..} စတဲ့ Services တွေ အတွက် သီးသန့် ထားထားတဲ့ နေရာတစ်ခုဖြစ်ပါတယ်။






How to create a new custom namespace?


                Namespace အသစ်တစ်ခု create လုပ်ဖို့အတွက် YAML file နဲ့ create လုပ်နိုင်သလို YAML file မသုံးပဲနဲ့ တိုက်ရိုက် create ပြုလုပ်နိုင်တယ်။

Using $kubectl create namespace to create new namespace




Creating new namespace with definition file (YAML)




How to switch the default namespace?



                    လက်ရှိ default namespace က "default" namespace ဖြစ်ပြီး တည်ဆောက်လိုက်သမျှ pods တွေ services တွေက default namespace မှာ သွားထားမှာဖြစ်ပါတယ်။ default namespace ကို ပြောင်းချင်တယ်ဆိုရင် ပြောင်းနိုင်ပါတယ်။ အောက်ပုံမှာဆိုရင် default namespace ကို "prod-env" ကို ပြောင်းလိုက်တဲ့အခါ default namespace မှာ အရင်က create လုပ်ခဲ့တာတွေ ပြန်ခေါ်ကြည့်ချင်ရင် "-n default" ဆိုပြီး သုံးမှသာ ကြည့်နိုင်တော့မှာဖြစ်ပါတယ်။




                           



                                     အပေါ်ပုံမှာဆိုရင် redis pod တစ်ခု ကို default namespace ဖြစ်တဲ့ "prod-env" မှာ တစ်ခု "uat-env" namespace မှာ တစ်ခု ဆိုပြီး pod တည်ဆောက်ရာမှာ namespace ကိုဘယ်လိုမျိုး အသုံးပြုလဲ တည်ဆောက်လိုက်တဲ့ pod ကို ပြန်ခေါ်ကြည့်ရာမှာလဲ namespace အလိုက် ဘယ်လိုမျိုး ကြည့်ရလဲ​ ဆိုတာ ပြထားပါတယ်။ Prod-env ရဲ့ pods ကို ကြည့်တဲ့အခါ "prod-env" က default namespace ဖြစ်သွားတဲ့အတွက် mention ခေါ်ပြီး ကြည့်စရာမလိုတော့ဘူးဖြစ်ပါတယ်။

So, how do we define "namespace" inside the definition file (YAML) and create?


                    ကျွန်တော်တို့ YAML file ကို အသုံးပြုပီး Pods, Serivces တွေကို တည်ဆောက်ရင်း တစ်ခါထဲ namespace ကို assign လုပ်လို့ရပါတယ်။ အောက်ပုံမှာ nginx-deployment တစ်ခု ကို "uat-env" namespace မှာ ထားပြီး တည်ဆောက်ပြထားပါတယ်။ အဓိက ကတော့ "metadata session မှာ namespace: uat-env" ဆိုပြီး သတ်မှတ်လိုက်တာဖြစ်ပါတယ်။





What are Resource Quota and Limit Range in a namespace?



                Pods တွေဆိုတာလည်း ကျွန်တော်တို့ VM တွေလိုပဲ သူလဲပဲ underlying node ရဲ့ resources တွေကို မှီခိုပြီး run နေတာဖြစ်ပါတယ်။ Resources တွေဆိုတာ {CPU, MEMORY, STORAGE} စတာတွေဖြစ်တယ်။ အဲ့တော့ ဒီ Pods တွေရဲ့ resource consumption ကို ထိန်းချုပ်ဖို့အတွက် ဒီ Resource Quota နဲ့ Limit Range ကို အသုံးပြုပြီး သတ်မှတ်လို့ရပါတယ်။

Resource Quota


                Resource Quota က သူက ဒီ namespace တစ်ခုအတွင်းမှာ run နေတဲ့ pods တွေသည် total resource ဘယ်လောက်ထိကို ပေးသုံးမယ် ဆိုပြီး သတ်မှတ်တဲ့နေရာမှာ အသုံးပြုတယ်။

Limit Range


            Limit Range ဆိုတာက ကျတော့ ဒီ namespace တစ်ခု အတွင်းမှာ ရှိတဲ့ pod တစ်ခုချင်းစီ ရဲ့ resource consumption ကို ထိန်းချုပ်တဲ့ နေရာမှာ အသုံးပြုပါတယ်။


How to check whethere namespace has defined Resource Quota and Limit Range?


                $kubectl describe namespace <namespace-name> ဖြင့် ဒီ namespace မှာ resource quota and limit range policies သတ်မှတ်ထားလား ကြည့်နိုင်တယ်။




How to define Limit Range policy in a namespace?


                Limit range policy ကို namespace တစ်ခုမှာ သတ်မှတ်ဖို့အတွက် limit-range definition file (YAML) တစ်ခု create လုပ်ရပါမယ်။ ပြီးရင် $kubectl create ဖြင့် create လုပ်တဲ့အခါ limit-range policy ကို အသုံးပြုချင်တဲ့ namespace ကို ပါ တွဲပြီး create လုပ်ပေးရပါမယ်။ အောက်ပုံမှာ cpu resource limit range definition file တစ်ခု ကို တည်ဆောက်တယ် ပြီးရင် "prod-end" namespace နဲ့ တွဲပြီး သတ်မှတ်ပါတယ်။ အဲ့အခါ နောက်ပိုင်း Prod-env မှာ Pod တည်ဆောက်တဲ့အခါ ဒီ resource limit range အတွင်းပဲ Pod သည် အသုံးပြုပြီး ကျော်ပြီးအသုံးပြုရင် Error (Forbidden) ဆိုပြီး ပြမှာဖြစ်ပါတယ်။



How to create a Pod with limit range?


            Pod တစ်ခု ကို Limit Range policy သတ်မှတ်ပြီး ဘယ်လိုတည်ဆောက်မလဲ ဆိုတော့ definition file ထဲမှာ resource limit သတ်မှတ်မယ် သတ်မှတ်တဲ့ resource limit က define လုပ်ထားတဲ့ policy အတွင်း ဝင်တယ်ဆိုရင် create လုပ်ခွင့်ပေးမယ် မဝင်ခဲ့ဘူးဆိုရင်တော့ Error ပြပေးမှာဖြစ်ပါတယ်။ အောက်ပုံမှာ Nginx-Pod တစ်ခုကို cpu-resource min-200m and max-800m ဆိုပြီး တည်ဆောက်တယ် Prod-Env namespace မှာ သတ်မှတ်ထား တဲ့ policy ဖြစ်တဲ့ min-200 and max-800m အတွင်း ဝင်တဲ့အတွက် create လုပ်ခွင့်ပေးတယ်။ သတ်မှတ်ထား တဲ့ min-max range အတွင်း မဝင်ခဲ့ရင်တော့ Error ပြပြီး create လုပ်ခွင့်ပေးမှာမဟုတ်ပါဘူး။



                Pod create လုပ်ပြီးလို့ $kubectl describe pod <pod-name> ဖြင့် detail information ကြည့်တဲ့အခါ pod ရဲ့ limits မှာ cpu policy define လုပ်ထားတာ တွေ့မှာဖြစ်ပါတယ်။








                    အပေါ်ပုံမှာဆိုရင် Nginx-pod ရဲ့ အသုံးပြုမယ့် cpu-resource က သတ်မှတ်ထားတဲ့ policy အတွင်း မဝင်တဲ့ အတွက် create လုပ်ခွင့်မပေးတာတွေ့ရပါမယ်။

What if you don't define a limit range while creating a pod under a namespace with defined limit-range policy?


                    Pod တစ်ခုကို limit range မသတ်မှတ်ပဲ limit range define လုပ်ထားတဲ့ namespace တစ်ခုအောက်မှာ တည်ဆောက်လိုက်တယ်ဆိုပါစို့.. အဲ့အခါ ဘယ်လိုဖြစ်မလဲဆိုတော့ create လုပ်လိုက်တဲ့ pod သည် Policy သတ်မှတ်ထားတဲ့  default value အတိုင်း ရရှိမှာဖြစ်ပါတယ်။ 



                Limit Range က သတ်မှတ်ပေးတဲ့ default value ကို သိချင်ရင် အောက်မှာ ပြထားတဲ့ ပုံအတိုင်း $kubectl get limitrange <limitrange-name> -o yaml -n prod-env ဆိုပြီး YAML output ထုတ်ပြီး ကြည့်လို့ရပါတယ်။





Defining the CPU unit



                အခု တောက်လျှောက်သတ်မှတ်လာခဲ့တဲ့ CPU unit အကြောင်းကို အနည်းငယ်ရှင်းပြချင်ပါတယ်။ ဒီ "m" ရဲ့ အရှည် က "milicore" or "milicpu" ဖြစ်ပါတယ်။ Kubernetes မှာ သုံးတဲ့ CPU usage အတွက် unit ဖြစ်ပါတယ်။ သူ့ ရဲ့ ပုံစံကတော့ 1vCPU = 1000m ဖြစ်ပါတယ်။ 
Ref:


After learning limit-range, Let's define Resource Quota?


                    Resource Quota က အပေါ်မှာ ပြောခဲ့သလိုပဲ pod တစ်ခု ချင်းစီ ကို control လုပ်တာမဟုတ်ပဲ ဒီ namespace တစ်ခုမှာ total resource consumption ဘယ်လောက်ဆိုပြီး သတ်မှတ်တာဖြစ်ပါတယ်။

How to create a Resource Quota definition file (YAML) 

                    ထုံးစံအတိုင်း Limit Range မှာ လုပ်ခဲ့သလိုပဲ Resource Quota definition file (YAML) တစ်ခု ကို create လုပ်ပြီး သတ်မှတ်ချင်တဲ့ namespace အောက်မှာ create လုပ်ပေးရမှာဖြစ်ပါတယ်။ 




                    အပေါ်ပုံမှာ Resource  Quota policy အရ

1. pod: 10 ---> prod-env namespace အတွင်းမှာ pods 10 ပဲ အသုံးပြုနိုင်မယ်
2. requests.cpu: 7 ---> Container အားလုံးအတွက် Total CPU Request သည် vCPU=7core ထက်မကျော်ရဘူး
3. request.memory: 25Gi ---> Container အားလုံး အတွက် Total Mem Request သည် 25GB ထက်မကျော်ရဘူး
4. limit.cpu: 8 --->  Container အားလုံးအတွက် Total CPU Limit သည် vCPU=8core ထက်မကျော်ရဘူး
5. limit.memory: 32Gi ---> Container အားလုံးအတွက် Total Mem Request သည် 32GB ထက်မကျော်ရဘူး
ဆိုပြီး သတ်မှတ်ထားတာဖြစ်ပါတယ်။



How to create a Pod with Resource Quota?


                Pod create လုပ်တဲ့နေရာမှာ Resource Quota ပဲဖြစ်ဖြစ် Limit Range နဲ့ပဲ ဖြစ်ဖြစ် spec: session ရဲ့ resource: အောက်မှာ သတ်မှတ်ရမှာဖြစ်ပါတယ်။





                        အပေါ်ပုံမှာပြထားတဲ့ nginx-pod resource policy မှာဆိုရင် request for {cpu | mem} သည် {1vcpu: 1Gi} အနေနှင့် min သတ်မှတ်ထားပြီး ၎င်း nginx-pod အတွက် limit က တော့ {cpu: 2vCPU, mem:2Gi} အထိ max အသုံးပြုလို့ရနိုင် ကြောင်း သတ်မှတ်ထားတာဖြစ်ပါတယ်။ 
                        Pod ကို စ create လုပ်လိုက်ပြီး တစ်ပြိုင်နက် တစ်ဖက်ခြမ်း မှာ $kubectl get resourcequote (or) $kubectl describe namespace prod-env ကိုအသုံးပြုပြီး ကြည့်လိုက်လျှင် nginx-pod အတွက် { cpu | mem } resources စတင် ပေးလိုက်ရပြီဖြစ်လို့ default cpu and mem limit ထဲကနေ လျော့ သွားတာကို တွေ့ရမှာဖြစ်ပါတယ်။

                    အခုအောက်ပုံမှာဆိုရင် နောက်ထပ် pod "redis" ကို ထပ်တည်ဆောက်လိုက်တဲ့အခါ သတ်မှတ်ထားတဲ့ default resources value ရဲ့ range အတွင်း ဝင်နေသမျှကတော့ create လုပ်လို့ရနေအုံးမှာဖြစ်ပြီး ကျော်လွန်သွားရင်တော့ forbidden error ဆိုပြီး ပြမှာဖြစ်ပါတယ်။




                    အောက်ပုံကိုကြည့်မယ်ဆိုရင်တော့ busybox pod cpu.limit မှာ လက်ကျန် cpu limit ထပ် ပိုပြီး သတ်မှတ် ထားတဲ့အတွက် pod creation လုပ်လို့မရတာကို တွေ့ရမှာဖြစ်ပါတယ်။




That's it 😊


Pls Like and Subscribe Our Root Of Info FB Page and Youtube Channel


https://www.facebook.com/rootofinfo


https://www.youtube.com/channel/UCkOi7WxhUBKONv3uD0CvuWw?view_as=subscriber


Thank you!!!





Share:

0 comments:

Post a Comment