קצת על Kubernetes Deployments

Kubernetes Deployments הוא "כלי" שמאפשר לנו להפוך את תהליך יצירת הPODS שלנו לאוטומטי, אנו מגדירים את המצב (STATE) שאנו מעוניינים שהPOD שלנו יהיה בו, והקלסטר יידאג ליצור, לנהל ולשמור את המצב (STATE) שביקשנו.

דוגמאות לשימוש בDeployment

Scaling
מאפשר לבנו לבחור את מספר הרפליקציות שאנו מעוניינים שהDeployment ייצור לאפלקציה ספציפית. בנוסף ליצירת מס הרפלקציות שביקשנו, הDeployment יוודא שהרפלקציות שלנו יהיו מחולקות בצורה מאוזנת בין הNodes שלנו בשביל זמינות (Availability)

Self-Healing
כשאחד מהPODS שלנו נהרס,או נמחק בטעות, הDeployment ירים אחד חדש במקומו מיידית. אם הגדרתי שאני מעוניין ב6 רפליקציות למערכת שלי, ומחקתי בטעות רפליקה – הDeployment יידאג להרים רפליקה חדשה במקום.

Rolling Updates
בעזרת Deployment, אנו יכולים להחליף/לשנות IMAGE של קונטיינר, הDeployment יחליף קונטיינרים קיימים בגירסה החדשה בשלבים, הסיבה שאנו מעוניינים בכך היא שאם אנו נעשה דפלוי לאפלקציה החדשה שלנו בבת אחת – יהיה זמן מסויים של אי זמינות של המערכת, כאשר אנו עושים את הדפלוי בשלבים – החלפה של IMAGE בזה אחר זה אין לנו מצב של אי זמינות. כשיש לנו גירסה חדשה לאפלקציה שלנו ואנו רוצים לעשות לה דפלוי – אנו נעשה שימוש בDeployment.


הקובץ YAML הבא (נקרא לו example.yaml) למשל, מציין שאנו מעוניינים ב6 רפליקות, ובקונטיינר (במקרה שלנו קונטיינר אחד בלבד) בשם nginx שיריץ …nginx (במקרה שלנו 1.15.4).

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

כדי להפעיל את הדפלוימנט שיצרנו נריץ את הפקודה הבאה

kubectl create -f example.yaml

ונקבל בחזרה שורה שאומרת:
deployment.apps/nginx-deployment created

אחרי שהפעלנו את הדפלוימנט הזה נריץ את הפקודה הבאה כדי לראות את רשימת הדפלוימנט שלנו ונשים לב שנקבל פלט שמכיל את שם הדפלוימנט שלנו (nginx-deployment), את כמות הרפלקציות שביקשנו (Desired) שבמקרה שלנו הוא 6, ופרטים נוספים.

kubectl get deployments

ונקבל במיקרה שלי:

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 6 6 6 6 30s

כדי לקבל מידע נוסף על דפלוימנט ספציפי נריץ את הפקודה הבאה , שימו לב שהפקודה צריכה להכיל את שם הדפלוימנט שאנו מעוניינים לקבל מידע נוסף לגביו, במיקרה שלנו nginx-deployment

kubectl describe deployment nginx-deployment

ועכשיו אנו רואים פרטים מלאים, כמו פורטים, סוג הIMAGE וכו.

אגב, אם נריץ את הפקודה

kubectl get pods

במיקרה שלנו אנו ניראה שיש 6 PODS שרצים (כיון שביקשנו 6 רפליקות).

NAME READY STATUS RESTARTS AGE
nginx-deployment-d55b94fd-8qbrs 1/1 Running 0 100s
nginx-deployment-d55b94fd-9rc4t 1/1 Running 0 100s
nginx-deployment-d55b94fd-dj4lx 1/1 Running 0 100s
nginx-deployment-d55b94fd-g278x 1/1 Running 0 100s
nginx-deployment-d55b94fd-kp4v6 1/1 Running 0 100s
nginx-deployment-d55b94fd-pvq87 1/1 Running 0 100s


אם נמחוק אחד מהPOD שלנו , על ידי הפקודה
kubectl delete nginx-deployment-d55b94fd-8qbrs למשל
אנו ניראה שPOD חדש נוצר במקומו כמעט מיידית כיון שדרשנו שיהיו לנו 6 רפליקות.
ונוכיח את זה על ידי הרצת הפקודה kubectl get pods שוב, ובמיקרה שלי הפלט שהתקבל הוא

nginx-deployment-d55b94fd-9rc4t 1/1 Running 0 2m15s
nginx-deployment-d55b94fd-dj4lx 1/1 Running 0 2m15s
nginx-deployment-d55b94fd-g278x 1/1 Running 0 2m15s
nginx-deployment-d55b94fd-kp4v6 1/1 Running 0 2m15s
nginx-deployment-d55b94fd-pvq87 1/1 Running 0 2m15s
nginx-deployment-d55b94fd-rnnjz 1/1 Running 0 9s

כאשר ניתן לראות שהPOD האחרון נוצר לפני 9 שניות על מנת להחליף את הPOD שמחקתי, לעומת האחרים שנוצרו לפני 2 דקות.

קצת על קוברנטיס (Kubernetes)

קצת על קוברנטיס (Kubernetes)

קוברנטיס הוא כלי לאוטומטציה וניהול של קונטיינרים.

ההיררכיה בקוברנטיס היא:
Cluster – > Node – > Pod

למה אנחנו צריכים אותו?

  • לאפשר לקונטיינרים לתקשר בניהם כאשר הם נמצאים בNODES שונים
  • למנוע כפילות של כתובת IP זהה בין דוקרים שממוקמים בNODES שונים
  • כשמחליפים קונטיינר – הוא בדרכ יקבל כתובת IP חדשה שזה מצב שאנו לא תמיד מעוניינים בו.
  • היחידה הקטנה ביותר בקוברנטיס נקראת POD,
    הPOD יכול להכיל קונטיינר אחד או קבוצה של קונטיינרים. כל הקויינטנרים שנמצאים באותו POD יקבלו את אותה כתובת IP, וכל POD שממוקם בקלסטר יקבל כתובת IP ייחודית באותו IP SPACE.
  • כל הקונטיינרים יכולים לתקשר עם קונטיינרים אחרים ללא NAT.
  • כתובת הIP שהקונטיינר מזהה ככתובת IP ששייכת לו היא אותה כתובת IP שהקונטיינרים האחרים רואים כשייכת להם.

הNetwork Overlay אחראי על חלוקת כתובת הIP.
הEtcd הוא Key-Value דאטאבייס לאובייקטים של קוברנטיס
הKubelet הוא הסרביס של קוברנטיס שרץ על כל הנודים בקלסטר – גם במאסטר וגם בWORKERS.


קוברנטיס כולל רכיבים שונים שעובדים ביחד ומאפשרים את תפקודו של הקוברנטיס קלסטר. כדי לראות את כל הPODS שאחראים על תפקודו של הקוברנטיס שלנו נריץ את הפקודה הבאה:

kubectl get pods -n kube-system

כל POD שמופיע לנו הוא בעצם POD שמריץ בתוכו רכיב שקשור לקוברנטיס עצמו. הרכיבים העיקריים הם:

kube-apiserver
זהו הAPI הראשי של קוברנטיס. הוא מבוסס REST. למשל הפקודה שהרצנו מקודם – kubectl get pods מבצעת למעשה פנייה לAPI.

etcd
מנהל את נושא המידע – סטורג של הקלסטר. לא מדובר בסטורג' שמאחסן בתוכו את האתר את הקבצים שלנו למשל, מדובר בסטורג שמחזיק את הדאטא שקשור לכמה PODS רצים כרגע, NODES, איזה כתובת IP יש לכל אחד וכו – כל המידע שדרוש לקוברנטיס בשביל לנהל ולהחזיק את הקלסטר שלנו.
במידה ויש לנו יותר מMASTER אחד, etcd ידאג שהדאטא הזה יהיה מסונכרן בין כל הMasters שלנו.

kube-controller-manager
מאחד בתוכו רכיבים שונים לחבילה אחת.
הוא מחזיק בתוכו את כל השירותים והספריות הדרושות לקוברנטיס. אם אנו מתייחסים ל jube-apiserver כפרונט של קוברנטיס, אזי ה kube-controller-manager הוא למעשה הבקאנד של קוברנטיס.

kube-scheduler
אחראי על יצירת הPODS, מתי להריץ אותם, מתי לכבות אותם, באיזה Node עצמאי להריץ אותם וכו.

kube-proxy
כל NODE זקוק לkube-proxy שלנו, הוא אחראי על התקשורת בין הNODES השונים על ידי הוספת כללי Firewall. כאשר POD בNODE X צריך לדבר עם POD שממוקם בNODE Y חייב להיות ROUTE וRULE שמאפשר את זה.

kubelet
הAGENT שמריץ את הקונטיינרים שלנו בכל NODE. הוא בעצם המתווך בין הAPI של קוברנטיס לדוקר. (Docker במקרה שלנו, אגב קוברנטיס תומך לא רק בדוקר).
הוא רץ כSERVICE ולא כPOD (כי הוא אחראי למעשה על הרצת הקונטיינר) ולכן הוא לא מופיע לנו ברשימת הPODS. כדי לראות אותו נריץ את הפקודה:

sudo systemctl status kubelet

מצאתם טעות? הערות? שאלות? הסתדרתם? נתקעתם? כתבו לי בתגובות!

יצירת kubernetes קלסטר בסיסי בקלות

מדריך ליצירת kubernetes קלסטר בסיסי בקלות

לא יודעים מה זה קוברנטיס? ליחצו כאן


פירוט השלבים:
שלב 1: התקנת DOCKER
שלב 2: התקנת kubeadm, kubelet ו kubectl
שלב 3: הפעלת המסטר נוד (Master Node) שלנו
שלב 4: צירוף 2 הNODES שלנו לקלסטר
שלב 5: הגדרות רשת עם Flannel

מכונה = Node
לשם ההדגמה אנו ניצור kubernetes קלסטר שמורכב מ3 מכונות , 2 מכונות שיהיו הNODES ומכונה אחת שתהיה הNode Master שלנו.
לשרת המסטר שלנו נקרא k8master , לשרת NODE הראשון נקרא k8node1 ולשני k8node2
ההפצה שבחרתי לעבוד איתה בהדגמה היא Ubuntu 18 LTS

בMASTER שלנו אנו נתקין:
* Docker
* Kubeadm
* Kubelet
* Kubectl
* Control Plane

בנודים שלנו נתקין:
* Docker
* Kubeadm
*Kybelet
*Kubectl

ולשם קישוריות רשת נשתמש בFlannel


השלב הראשון – התקנת DOCKER

השלב הראשון הוא להתקין DOCKER בכל אחת מהמכונות שלנו (במקרה שלנו 3 מכונות שמריצות אובונטו), להסבר איך להתקין ניתן ללחוץ כאן


השלב השני: התקנת kubeadm, kubelet ו kubectl

השלב השני הוא להתקין את השירותים הנל בכל אחת מהמכונות שלנו, להסבר כיצד ניתן להתקין אותם באובונטו ניתן ללחוץ כאן


השלב השלישי: הפעלת המסטר נוד (Master Node) שלנו

בשרת המסטר שלנו נריץ את הפקודה הבאה: (לוקח לה בדרכ כמה דקות עד שהפקודה מסיימת את הפעולה)

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

אחרי כמה דקות, נקבל פלט שמכיל את הפקודה אותה אני נצטרך להריץ אחכ בכל Node שלנו על מנת שהוא יוכל להצטרף לקלסטר. חשוב לשמור את הפקודה ואת הטוקן – כי בלעדיו לא תוכלו לצרף Nodes לCluster שלכם. במקרה שלי הפלט שהתקבל הוא

kubeadm join 172.31.20.227:6443 --token k1vs3a.4i3zgo4zw725o3y7 --discovery-token-ca-cert-hash sha256:c94bb285d99e80c3674d8cc8951f957231b35431d5e0be982d4c0e9618156e06

לאחר מכן נריץ את הפקודה הבאה:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

ולבסוף נוודא שהכל בוצע במסטר שלנו על ידי הפקודה:

kubectl version

כאשר הפלט שאנו נקבל אמור להיות דומה ל:


Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.7", GitCommit:"6f482974b76db3f1e0f5d24605a9d1d38fad9a2b", GitTreeState:"clean", BuildDate:"2019-03-25T02:52:13Z", GoVersion:"go1.10.8", Compi3f1e0f5d24605a9d1d38fad9a2b", GitTreeState:"clean", BuildDate:"2019-03-25T02:52:13Z", GoVersion:"go1.10.8", Compiler:"gc", Platform:"linux/amd64"}                                                  dea457638b614ee17ef234dc34a6", GitTreeState:"clean", BuildDate:"2019-07-08T03:40:54Z", GoVersion:"go1.10.8", Comp
Server Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.10", GitCommit:"e3c134023df5dea457638b614ee17ef234dc34a6", GitTreeState:"clean", BuildDate:"2019-07-08T03:40:54Z", GoVersion:"go1.10.8", Compiler:"gc", Platform:"linux/amd64"}

אם נריץ את הפקודה הבאה במסטר שלנו

kubectl get nodes

אנו אמורים לקבל פלט שמראה שרק המסטר שלנו הוא חלק מהקלסטר וזה כמובן בגלל שעוד לא צירפנו את 2 השרתים האחרים.

user@servername:~$ kubectl get nodes
NAME                          STATUS     ROLES    AGE    VERSION
servername.serverdomain.com   NotReady   master   4m3s   v1.12.7

השלב הרביעי: צירוף 2 הNODES שלנו לקלסטר

בכל אחד מהשרתים האחרים שלנו, k8node1 ו k8node2 נריץ את הפקודה שקיבלנו (בשלב 3) מקודם שמכילה את הטוקן. במקרה שלי היא הייתה:

kubeadm join MYIPADDRESS:6443 --token k1vs3a.4i3zgo4zw725o3y7 --discovery-token-ca-cert-hash sha256:c94bb285d99e80c3674d8cc8951f957231b35431d5e0be982d4c0e9618156e06

אחרי שהרצנו את הפקודה ב2 השרתים (ייתכן ותתבקשו להוסיף sudo) נריץ בשרת הMaster שלנו (k8master) שוב את הפקודה הבאה:

user@servername:~$ kubectl get nodes

NAME                          STATUS     ROLES    AGE   VERSION
servername1.serverdomain.com   NotReady   master   10m   v1.12.7
servername2.serverdomain.com   NotReady   <none>   40s   v1.12.7
servername3.serverdomain.com   NotReady   <none>   85s   v1.12.7

ושימו לב שהפעם המסטר שלנו מזהה את 2 השרתים האחרים, כולם עדיין בסטטוס של NotReady.


השלב החמישי: הגדרות רשת עם Flannel

לקריאה מקדימה על networking בקוברנטיס:

בכל 3 המכונות (Nodes) – כולל מכונת הMaster שלנו נריץ את הפקודות הבאות

echo "net.bridge.bridge-nf-call-iptables=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

בשרת הMaster שלנו – ורק בו! נריץ את הפקודה הבאה:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml

לאחר מכן, כשנריץ את הפקודה:

kubectl get nodes

שוב, אנו אמורים לראות את 3 המכונות שלנו אבל הפעם כולן יהיו בסטטוס Ready.
נוכל להריץ גם את הפקודה הבאה:

kubectl get pods -n kube-system

שתאפשר לנו לראות גם את הPods שקשורים לFlannel


זהו, סיימנו להגדיר. מזל טוב!
קריאה נוספת:
לאתר הבית של קוברנטיס לקריאה נוספת ליחצו כאן
מה זה Pod?



מצאתם טעות? הערות? שאלות? הסתדרתם? נתקעתם? כתבו לי בתגובות!