במדריך הזה מוסבר איך להשתמש באופרטור Strimzi כדי לפרוס אשכולות של Apache Kafka.
Kafka היא מערכת הודעות מבוזרת בקוד פתוח שנועדה לטפל בנתוני סטרימינג בזמן אמת, בנפח גבוה ובקצב העברה גבוה. הוא מאפשר לכם ליצור צינורות להעברת נתונים בזמן אמת, כדי להעביר נתונים בצורה מהימנה בין מערכות ואפליקציות שונות, ולתמוך במשימות של עיבוד וניתוח.
אופרטורים הם תוספי תוכנה שמשתמשים במשאבים מותאמים אישית כדי לנהל אפליקציות ורכיבים שלהן. במאמר תבנית אופרטור במסמכי Kubernetes בקוד פתוח אפשר לקרוא מידע נוסף על הסיבות לשימוש באופרטורים. אופרטור Strimzi מציע גמישות באפשרויות הפריסה ומאפשר להשתמש ב-taints וב-tolerances של Kubernetes כדי להריץ את Kafka בצמתים ייעודיים.
המדריך הזה מיועד לאדמינים של פלטפורמות, למומחי Cloud Architect ולמומחי תפעול שרוצים לפרוס אשכולות Kafka ב-GKE.
הפתרון הזה הוא נקודת התחלה טובה אם אתם רוצים ללמוד איך לפרוס אשכולות של Kafka באמצעות אופרטור של צד שלישי כדי להפוך את הניהול לאוטומטי ולצמצם שגיאות.
מטרות
- תכנון ופריסה של תשתית GKE ל-Apache Kafka
- פריסה והגדרה של אופרטור Strimzi
- הגדרת Apache Kafka באמצעות אופרטור Strimzi
יתרונות
היתרונות של Strimzi כוללים:
- אופרטורים של Strimzi מספקים גישה פשוטה ומקורית ל-Kubernetes לניהול אשכולות Kafka. Strimzi משתמש במשאבים מותאמים אישית שמייצגים נושאים ומשתמשים ב-Kafka, וכך הופך את ניהול האשכולות לפשוט יותר ומתאים לשיטות המומלצות של Kubernetes.
- האבטחה היא ערך עליון ב-Strimzi כברירת מחדל, ולכן המערכת יוצרת אישורים למאזינים ותומכת בשיטות אימות מאובטחות כמו TLS, SCRAM-SHA ו-OAuth. Strimzi מטפל גם ב-NetworkPolicies לכל מאזיני Kafka.
- Strimzi לא מסתמך על תלות חיצונית. הוא כולל אשכולות של Kafka ושל ZooKeeper עם כלי ייצוא מובנים של מדדים, כך שלא צריך להשתמש בכלים נוספים. אפשר גם לשנות את ההגדרות של הברוקר כדי לעמוד בדרישות ספציפיות.
ארכיטקטורת פריסה
קלאסטר Kafka מורכב משרת אחד או יותר, שנקראים ברוקרים, שפועלים יחד כדי לנהל זרמי נתונים נכנסים ולאפשר העברת הודעות בשיטת publish-subscribe ללקוחות Kafka, שנקראים צרכנים.
לכל מחיצת נתונים באשכול Kafka מוקצה ברוקר ראשי, שאחראי על ניהול כל פעולות הקריאה והכתיבה למחיצה הזו. למחיצה יכולים להיות גם ברוקרים עוקבים שמבצעים שכפול פסיבי של הפעולות של הברוקר הראשי.
בהגדרה טיפוסית, ZooKeeper מתאם בין אשכולי Kafka על ידי עזרה בבחירת מוביל בין הברוקרים, ומבטיח מעבר חלק לגיבוי במקרה של בעיות.
אפשר גם לפרוס את ההגדרה של Kafka בלי Zookeeper על ידי הפעלת מצב KRaft, אבל הקהילה של Strimzi לא רואה בשיטה הזו פתרון מוכן לייצור כי היא לא כוללת תמיכה במשאבי KafkaTopic, באימות של פרטי הכניסה ועוד.
זמינות ותוכנית התאוששות מאסון (DR)
במדריך הזה נעשה שימוש במאגרי צמתים ואזורים נפרדים עבור אשכולות Kafka ו-ZooKeeper, כדי להבטיח זמינות גבוהה ולהתכונן להתאוששות מאסון.
שימוש בכמה צמתים ואזורים הוא חיוני כדי להשיג אשכול Kubernetes עם זמינות גבוהה בגלל הסיבות הבאות: Google Cloud
- עמידות בפני תקלות: מספר צמתים מחלקים את עומס העבודה בין הצמתים באשכול, וכך מבטיחים שאם צומת אחד ייכשל, הצמתים האחרים יוכלו להשתלט על המשימות, ולמנוע השבתה והפרעות בשירות.
- יכולת הרחבה: שימוש בכמה צמתים עוזר להבטיח שניתן להוסיף או להסיר צמתים לפי הצורך, וכך להקצות משאבים בצורה אופטימלית ולעמוד בדרישות של תנועה מוגברת או עומסי עבודה גדולים יותר.
- זמינות גבוהה: שימוש בכמה אזורים בתוך אזור עוזר להבטיח יתירות ומצמצם את הסיכון לנקודת כשל יחידה. אם יש הפסקה זמנית בשירות באזור זמינות שלם, האשכול יכול להמשיך לפעול באזורים אחרים, וכך לשמור על זמינות השירות.
- יתירות גיאוגרפית: באמצעות פריסת צמתים באזורים שונים, הנתונים והשירותים של האשכול מפוזרים גיאוגרפית, מה שמספק עמידות מפני אסונות טבע, הפסקות חשמל או שיבושים מקומיים אחרים שעשויים להשפיע על אזור יחיד.
- עדכונים ותחזוקה מתמשכים: שימוש בכמה אזורים עוזר לוודא שאפשר לבצע עדכונים ותחזוקה מתמשכים בצמתים נפרדים בלי להשפיע על הזמינות הכוללת של האשכול. כך אפשר להבטיח שירות רציף, וגם לבצע עדכונים ותיקונים בצורה חלקה.
- הסכמי רמת שירות (SLA): Google Cloud מספקת הסכמי רמת שירות לפריסות מרובות אזורים, ומציעה רמת זמינות וזמן פעולה תקינה מינימליים.
תרשים פריסה
בתרשים הבא מוצג אשכול Kafka שפועל בכמה צמתים ואזורים באשכול GKE:
בתרשים, Kafka StrimziPodSet נפרס על פני שלושה צמתים בשלושה אזורים שונים. אפשר לשלוט בהגדרה הזו באמצעות הגדרת הכללים affinity ו-topology spread של ה-Pod הנדרש במפרט של המשאב המותאם אישית StrimziPodSet.
אם אזור אחד נכשל, באמצעות ההגדרה המומלצת, GKE מתזמן מחדש את ה-Pods בצמתים חדשים ומשכפל נתונים מהרפליקות שנותרו, גם עבור Kafka וגם עבור Zookeeper.
בתרשים הבא מוצג ZooKeeper StrimziPodSet שנפרס בשלושה צמתים בשלושה אזורים שונים:
המשאב המותאם אישית StrimziPodSet
במדריך הזה נעשה שימוש במשאב המותאם אישית StrimziPodSet שהוצג בגרסה 0.29 של Strimzi, במקום ב-StatefulSets.
המשאבים StrimziPodSet מאפשרים לשפר את יכולת ההתאמה של האשכול, ומאפשרים להעביר אפשרויות הגדרה, כך שתוכלו לבצע שינויים ב-Pods ברמת פירוט גבוהה יותר. המשאב StrimziPodSet מופעל כברירת מחדל בגרסאות Strimzi
0.35 ואילך.
עלויות
במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:
כדי להעריך את ההוצאות בהתאם לתחזית השימוש שלכם, אתם יכולים להיעזר במחשבון העלויות.
כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.
לפני שמתחילים
- נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
-
התקינו את ה-CLI של Google Cloud.
-
אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.
-
כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:
gcloud init -
יוצרים או בוחרים Google Cloud פרויקט.
תפקידים שנדרשים כדי לבחור או ליצור פרויקט
- Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
-
יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (יצירת פרויקטים) (
roles/resourcemanager.projectCreator), שכולל את ההרשאהresourcemanager.projects.create. איך מקצים תפקידים
-
יוצרים Google Cloud פרויקט:
gcloud projects create PROJECT_ID
מחליפים את
PROJECT_IDבשם של פרויקט Google Cloud שיוצרים. -
בוחרים את הפרויקט שיצרתם: Google Cloud
gcloud config set project PROJECT_ID
מחליפים את
PROJECT_IDבשם הפרויקט ב- Google Cloud .
מפעילים את ממשקי ה-API של Compute Engine, IAM, GKE, Backup for GKE ו-Resource Manager:
תפקידים שנדרשים להפעלת ממשקי API
כדי להפעיל ממשקי API, צריך את תפקיד ה-IAM 'אדמין של שימוש בשירות' (
roles/serviceusage.serviceUsageAdmin), שכולל את ההרשאהserviceusage.services.enable. איך מקצים תפקידיםgcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com gkebackup.googleapis.com cloudresourcemanager.googleapis.com -
התקינו את ה-CLI של Google Cloud.
-
אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.
-
כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:
gcloud init -
יוצרים או בוחרים Google Cloud פרויקט.
תפקידים שנדרשים כדי לבחור או ליצור פרויקט
- Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
-
יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (יצירת פרויקטים) (
roles/resourcemanager.projectCreator), שכולל את ההרשאהresourcemanager.projects.create. איך מקצים תפקידים
-
יוצרים Google Cloud פרויקט:
gcloud projects create PROJECT_ID
מחליפים את
PROJECT_IDבשם של פרויקט Google Cloud שיוצרים. -
בוחרים את הפרויקט שיצרתם: Google Cloud
gcloud config set project PROJECT_ID
מחליפים את
PROJECT_IDבשם הפרויקט ב- Google Cloud .
מפעילים את ממשקי ה-API של Compute Engine, IAM, GKE, Backup for GKE ו-Resource Manager:
תפקידים שנדרשים להפעלת ממשקי API
כדי להפעיל ממשקי API, צריך את תפקיד ה-IAM 'אדמין של שימוש בשירות' (
roles/serviceusage.serviceUsageAdmin), שכולל את ההרשאהserviceusage.services.enable. איך מקצים תפקידיםgcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com gkebackup.googleapis.com cloudresourcemanager.googleapis.com -
נותנים תפקידים לחשבון המשתמש. מריצים את הפקודה הבאה לכל אחד מהתפקידים הבאים ב-IAM:
roles/storage.objectViewer, roles/logging.logWriter, roles/container.clusterAdmin, roles/container.serviceAgent, roles/iam.serviceAccountAdmin, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmingcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
מחליפים את מה שכתוב בשדות הבאים:
-
PROJECT_ID: מזהה הפרויקט. -
USER_IDENTIFIER: המזהה של חשבון המשתמש . לדוגמה,myemail@example.com. -
ROLE: תפקיד ה-IAM שאתם מקצים לחשבון המשתמש.
-
הכנת הסביבה
במדריך הזה תשתמשו ב-Cloud Shell כדי לנהל משאבים שמתארחים ב- Google Cloud. ב-Cloud Shell מותקן מראש התוכנה שדרושה למדריך הזה, כולל kubectl, CLI של gcloud, Helm ו-Terraform.
כדי להגדיר את הסביבה באמצעות Cloud Shell:
מפעילים סשן של Cloud Shell מGoogle Cloud המסוף על ידי לחיצה על Activate Cloud Shell
. Google Cloud סשן יופעל בחלונית התחתונה של מסוף Google Cloud .
הגדרת משתני סביבה:
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=kafka export REGION=us-central1מחליפים את
PROJECT_ID: your Google Cloud במזהה הפרויקט.משכפלים את המאגר מ-GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samplesעוברים לספריית העבודה:
cd kubernetes-engine-samples/streaming/
יצירת תשתית האשכול
בקטע הזה מריצים סקריפט של Terraform כדי ליצור אשכול GKE אזורי עם זמינות גבוהה ועם צמתים פרטיים. השלבים הבאים מאפשרים גישה ציבורית למישור הבקרה. כדי להגביל את הגישה, צריך להגדיר את האשכול כך שמישור הבקרה יהיה חשוף רק בנקודת הקצה הפנימית.
אפשר להתקין את האופרטור באמצעות אשכול רגיל או Autopilot.
רגילה
בתרשים הבא מוצג אשכול אזורי רגיל עם צמתים פרטיים של GKE, שנפרס בשלושה אזורים שונים:
כדי לפרוס את התשתית הזו, מריצים את הפקודות הבאות מ-Cloud Shell:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=kafka/terraform/gke-standard init
terraform -chdir=kafka/terraform/gke-standard apply -var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
כשמופיעה בקשה, כותבים yes. יכול להיות שיעברו כמה דקות עד שהפקודה הזו תושלם ועד שהאשכול יציג סטטוס של מוכנות.
Terraform יוצר את המשאבים הבאים:
- רשת VPC ותת-רשת פרטית לצמתים של Kubernetes.
- נתב לגישה לאינטרנט דרך NAT.
- אשכול GKE עם צמתים פרטיים באזור
us-central1. - 2 מאגרי צמתים עם הפעלה של שינוי גודל אוטומטי (1-2 צמתים לכל אזור, צומת אחד לכל אזור לכל הפחות)
ServiceAccountעם הרשאות רישום ביומן ומעקב.- גיבוי ל-GKE לצורך התאוששות מאסון.
- השירות המנוהל של Google Cloud ל-Prometheus לניטור אשכולות.
הפלט אמור להיראות כך:
...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
Outputs:
kubectl_connection_command = "gcloud container clusters get-credentials strimzi-cluster --region us-central1"
טייס אוטומטי
התרשים הבא מציג אשכול אזורי של GKE עם צמתים פרטיים ב-Autopilot:
כדי לפרוס את התשתית, מריצים את הפקודות הבאות מ-Cloud Shell:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=kafka/terraform/gke-autopilot init
terraform -chdir=kafka/terraform/gke-autopilot apply -var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
כשמופיעה בקשה, כותבים yes. יכול להיות שיעברו כמה דקות עד שהפקודה הזו תושלם ועד שהאשכול יציג סטטוס של מוכנות.
Terraform יוצר את המשאבים הבאים:
- רשת VPC ורשת משנה פרטית לצמתים של Kubernetes.
- נתב לגישה לאינטרנט דרך NAT.
- אשכול GKE עם צמתים פרטיים באזור
us-central1. ServiceAccountעם הרשאות רישום ביומן ומעקב- השירות המנוהל של Google Cloud ל-Prometheus לניטור אשכולות.
הפלט אמור להיראות כך:
...
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
Outputs:
kubectl_connection_command = "gcloud container clusters get-credentials strimzi-cluster --region us-central1"
מתבצעת התחברות לאשכול
מגדירים את kubectl לתקשורת עם האשכול:
gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --region ${REGION}
פריסת אופרטור Strimzi באשכול
בקטע הזה פורסים את אופרטור Strimzi באמצעות תרשים Helm. יש גם כמה דרכים אחרות לפריסת Strimzi.
מוסיפים את מאגר Strimzi Helm Chart:
helm repo add strimzi https://strimzi.io/charts/מוסיפים מרחב שמות לאופרטור Strimzi ולמקלט Kafka:
kubectl create ns kafkaפורסים את אופרטור האשכול Strimzi באמצעות Helm:
helm install strimzi-operator strimzi/strimzi-kafka-operator -n kafkaכדי לפרוס את Strimzi Cluster Operator ואת אשכולי Kafka במרחבי שמות שונים, מוסיפים את הפרמטר
--set watchNamespaces="{kafka-namespace,kafka-namespace-2,...}"לפקודת helm.מוודאים ש-Strimzi Cluster Operator נפרס בהצלחה באמצעות Helm:
helm ls -n kafkaהפלט אמור להיראות כך:
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION strimzi-operator kafka 1 2023-06-27 11:22:15.850545 +0200 CEST deployed strimzi-kafka-operator-0.35.0 0.35.0
פריסת Kafka
אחרי שפורסים את האופרטור באשכול, אפשר לפרוס מופע של אשכול Kafka.
בקטע הזה, תפרסו את Kafka בתצורה בסיסית, ואז תנסו תרחישים שונים של תצורה מתקדמת כדי לענות על דרישות הזמינות, האבטחה והיכולת למעקב.
הגדרה בסיסית
ההגדרה הבסיסית של מופע Kafka כוללת את הרכיבים הבאים:
- שלוש רפליקות של ברוקרים של Kafka, עם מינימום של שתי רפליקות זמינות שנדרשות לעקביות של האשכול.
- שלוש רפליקות של צמתי ZooKeeper, שיוצרות אשכול.
- שני מאזינים של Kafka: אחד ללא אימות, ואחד שמשתמש באימות TLS עם אישור שנוצר על ידי Strimzi.
- הערכים של Java MaxHeapSize ו-MinHeapSize מוגדרים ל-4 GB עבור Kafka ול-2 GB עבור ZooKeeper.
- הקצאת משאבי CPU של בקשת CPU אחת ומגבלות CPU של 2 גם ל-Kafka וגם ל-ZooKeeper, יחד עם בקשות ומגבלות של 5GB זיכרון ל-Kafka (4GB לשירות הראשי ו-0.5GB ל-metrics exporter) ו-2.5GB ל-ZooKeeper (2GB לשירות הראשי ו-0.5GB ל-metrics exporter).
- Entity-operator עם הבקשות והמגבלות הבאות:
-
tlsSidecar: 100 m/500 m CPU ו-128 Mi זיכרון. -
topicOperator: 100 m/500 m CPU ו-512 Mi זיכרון. -
userOperator: 500 m CPU ו-2 Gi זיכרון.
-
- נפח אחסון של 100GB מוקצה לכל Pod באמצעות
premium-rwostorageClass. - הגדרת Tolerations, nodeAffinities ו-podAntiAffinities לכל עומס עבודה, כדי להבטיח חלוקה נכונה בין הצמתים, תוך שימוש במאגרי הצמתים המתאימים ובאזורים שונים.
- תקשורת בתוך האשכול מאובטחת באמצעות אישורים בחתימה עצמית: רשויות אישורים (CA) נפרדות לאשכול וללקוחות (mTLS). אפשר גם להגדיר שימוש ברשות אישורים אחרת.
ההגדרה הזו מייצגת את ההגדרה המינימלית שנדרשת ליצירת אשכול Kafka שמוכן לייצור. בקטעים הבאים מוצגות הגדרות בהתאמה אישית לטיפול בהיבטים כמו אבטחת אשכולות, רשימות של בקרת גישה (ACL), ניהול נושאים, ניהול אישורים ועוד.
יצירת אשכול Kafka בסיסי
יוצרים אשכול Kafka חדש באמצעות ההגדרה הבסיסית:
kubectl apply -n kafka -f kafka-strimzi/manifests/01-basic-cluster/my-cluster.yamlהפקודה הזו יוצרת משאב מותאם אישית של Kafka באופרטור Strimzi, שכולל בקשות ומגבלות של CPU וזיכרון, בקשות של אחסון בלוקים ושילוב של taints ו-affinities כדי להפיץ את ה-Pods שהוקצו בין צמתי Kubernetes.
ממתינים כמה דקות בזמן ש-Kubernetes מפעיל את עומסי העבודה הנדרשים:
kubectl wait kafka/my-cluster --for=condition=Ready --timeout=600s -n kafkaמוודאים שעומסי העבודה של Kafka נוצרו:
kubectl get pod,service,deploy,pdb -l=strimzi.io/cluster=my-cluster -n kafkaהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE pod/my-cluster-entity-operator-848698874f-j5m7f 3/3 Running 0 44m pod/my-cluster-kafka-0 1/1 Running 0 5m pod/my-cluster-kafka-1 1/1 Running 0 5m pod/my-cluster-kafka-2 1/1 Running 0 5m pod/my-cluster-zookeeper-0 1/1 Running 0 6m pod/my-cluster-zookeeper-1 1/1 Running 0 6m pod/my-cluster-zookeeper-2 1/1 Running 0 6m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-cluster-kafka-bootstrap ClusterIP 10.52.8.80 <none> 9091/TCP,9092/TCP,9093/TCP 5m service/my-cluster-kafka-brokers ClusterIP None <none> 9090/TCP,9091/TCP,9092/TCP,9093/TCP 5m service/my-cluster-zookeeper-client ClusterIP 10.52.11.144 <none> 2181/TCP 6m service/my-cluster-zookeeper-nodes ClusterIP None <none> 2181/TCP,2888/TCP,3888/TCP 6m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-cluster-entity-operator 1/1 1 1 44m NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE poddisruptionbudget.policy/my-cluster-kafka 2 N/A 1 5m poddisruptionbudget.policy/my-cluster-zookeeper 2 N/A 1 6m
המפעיל יוצר את המשאבים הבאים:
- שני
StrimziPodSetsל-Kafka ול-ZooKeeper. - שלושה פודים של רפליקות של ברוקר Kafka.
- שלושה רכיבי Pod לשכפול של ZooKeeper.
- 2
PodDisruptionBudgets, כדי להבטיח זמינות מינימלית של שני עותקים לשמירה על עקביות האשכול. - שירות בשם
my-cluster-kafka-bootstrap, שמשמש כשרת bootstrap ללקוחות Kafka שמתחברים מתוך אשכול Kubernetes. כל מאזיני Kafka הפנימיים זמינים בשירות הזה. - שירות ללא ראש שנקרא
my-cluster-kafka-brokersשמאפשר תרגום DNS של כתובות ה-IP של פודים של ברוקרים של Kafka באופן ישיר. השירות הזה משמש לתקשורת בין ברוקרים. - שירות בשם
my-cluster-zookeeper-clientשמאפשר למתווכי Kafka להתחבר לצמתי ZooKeeper כלקוחות. - שירות ללא ראש שנקרא
my-cluster-zookeeper-nodesומאפשר פתרון DNS של כתובות IP של ZooKeeper Pod ישירות. השירות הזה משמש לחיבור בין רפליקות של ZooKeeper. - פריסת Deployment בשם
my-cluster-entity-operatorשמכילה את topic-operator ו-user-operator ומאפשרת ניהול של משאבים מותאמים אישיתKafkaTopicsו-KafkaUsers.
אפשר גם להגדיר שני NetworkPolicies כדי לאפשר קישוריות למאזיני Kafka מכל Pod ומרחב שמות. כללי המדיניות האלה גם יגבילו את החיבורים ל-ZooKeeper למתווכים, ויאפשרו תקשורת בין ה-Pods של האשכול לבין יציאות שירות פנימיות שמוגבלות לתקשורת באשכול.
אימות וניהול משתמשים
בקטע הזה מוסבר איך להפעיל את האימות וההרשאה כדי לאבטח את רכיבי ה-Kafka Listener ולשתף את פרטי הכניסה עם לקוחות.
Strimzi מספק שיטה מקורית ב-Kubernetes לניהול משתמשים באמצעות User Operator נפרד ומשאב Kubernetes מותאם אישית תואם, KafkaUser, שמגדיר את תצורת המשתמש. הגדרת המשתמש כוללת הגדרות לאימות ולהרשאה, ומקצה את המשתמש המתאים ב-Kafka.
Strimzi יכול ליצור מאזינים ומשתמשים של Kafka שתומכים בכמה מנגנוני אימות, כמו אימות שמבוסס על שם משתמש וסיסמה (SCRAM-SHA-512) או TLS. אפשר גם להשתמש באימות OAuth 2.0, שלרוב נחשב לגישה טובה יותר בהשוואה לשימוש בסיסמאות או באישורים לאימות, בגלל האבטחה וניהול פרטי הכניסה החיצוניים.
פריסת אשכול Kafka
בקטע הזה מוסבר איך לפרוס אופרטור של Strimzi שמדגים יכולות של ניהול משתמשים, כולל:
- קלאסטר Kafka עם אימות מבוסס-סיסמה (SCRAM-SHA-512) שמופעל באחד מהמאזינים.
KafkaTopicעם 3 העתקים.KafkaUserעם רשימת ACL שבה מצוין שלמשתמש יש הרשאות קריאה וכתיבה בנושא.
מגדירים את אשכול Kafka לשימוש במאזין עם אימות SCRAM-SHA-512 מבוסס-סיסמה ביציאה 9094 והרשאה פשוטה:
kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/my-cluster.yamlיוצרים
Topic,Userו-Pod של לקוח כדי להריץ פקודות מול אשכול Kafka:kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/topic.yaml kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/my-user.yaml
Secretmy-userעם פרטי הכניסה של המשתמש מותקן ב-Pod של הלקוח כVolume.פרטי הכניסה האלה מאשרים שלמשתמש יש הרשאות לפרסם הודעות בנושא באמצעות מאזין עם אימות מבוסס-סיסמה (SCRAM-SHA-512) מופעל.
יוצרים תרמיל לקוח:
kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/kafkacat.yamlממתינים כמה דקות עד שה-Pod של הלקוח יהפוך ל-
Readyואז מתחברים אליו:kubectl wait --for=condition=Ready pod --all -n kafka --timeout=600s kubectl exec -it kafkacat -n kafka -- /bin/shיוצרים הודעה חדשה עם פרטי הכניסה
my-userומנסים לצרוך אותה:echo "Message from my-user" |kcat \ -b my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9094 \ -X security.protocol=SASL_SSL \ -X sasl.mechanisms=SCRAM-SHA-512 \ -X sasl.username=my-user \ -X sasl.password=$(cat /my-user/password) \ -t my-topic -P kcat -b my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9094 \ -X security.protocol=SASL_SSL \ -X sasl.mechanisms=SCRAM-SHA-512 \ -X sasl.username=my-user \ -X sasl.password=$(cat /my-user/password) \ -t my-topic -Cהפלט אמור להיראות כך:
Message from my-user % Reached end of topic my-topic [0] at offset 0 % Reached end of topic my-topic [2] at offset 1 % Reached end of topic my-topic [1] at offset 0מקלידים
CTRL+Cכדי להפסיק את התהליך של החשבון לשימוש פרטי.יציאה מהמעטפת של ה-Pod
exit
גיבויים ותוכנית התאוששות מאסון (DR)
למרות שאופרטור Strimzi לא מציע פונקציונליות גיבוי מובנית, אפשר ליישם אסטרטגיות גיבוי יעילות על ידי ביצוע דפוסים מסוימים.
אפשר להשתמש בגיבוי ל-GKE כדי לגבות:
- מניפסטים של משאבים ב-Kubernetes.
- משאבים מותאמים אישית של Strimzi API וההגדרות שלהם, שחולצו משרת ה-API של Kubernetes באשכול שעובר גיבוי.
- נפחי אחסון שתואמים למשאבי PersistentVolumeClaim שנמצאו במניפסטים.
אפשר גם לבצע גיבוי של אשכול Kafka שנפרס באמצעות האופרטור Strimzi. אתם צריכים לגבות:
- ההגדרה של Kafka, שכוללת את כל המשאבים המותאמים אישית של Strimzi API, כמו
KafkaTopicsו-KafkaUsers. - הנתונים, שמאוחסנים ב-PersistentVolumes של ברוקרי Kafka.
אחסון של מניפסטים של משאבי Kubernetes, כולל הגדרות Strimzi, במאגרי Git יכול לבטל את הצורך בגיבוי נפרד של הגדרות Kafka, כי אפשר להחיל מחדש את המשאבים על אשכול Kubernetes חדש כשצריך.
כדי להגן על שחזור נתונים של Kafka בתרחישים שבהם מופעלת מכונת שרת Kafka או אשכול Kubernetes שבו Kafka פרוס, מומלץ להגדיר את מחלקת האחסון של Kubernetes שמשמשת להקצאת נפחי אחסון עבור ברוקרים של Kafka עם האפשרות reclaimPolicy שמוגדרת ל-Retain. מומלץ גם לצלם תמונות מצב של נפחי Kafka broker.
המאניפסט הבא מתאר StorageClass שמשתמש באפשרות reclaimPolicyRetain:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: premium-rwo-retain
...
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
בדוגמה הבאה מוצג StorageClass שנוסף ל-spec של משאב מותאם אישית של אשכול Kafka:
# ...
spec:
kafka:
# ...
storage:
type: persistent-claim
size: 100Gi
class: premium-rwo-retain
במקרה כזה, נפחי אחסון קבועים (PersistentVolumes) שהוקצו באמצעות מחלקת האחסון לא נמחקים גם כשבקשת נפח האחסון הקבוע (PersistentVolumeClaim) המתאימה נמחקת.
כדי לשחזר את מופע Kafka באשכול Kubernetes חדש באמצעות ההגדרה הקיימת ונתוני מופע הברוקר:
- החלת משאבי Strimzi Kafka מותאמים אישית קיימים (
Kakfa,KafkaTopic,KafkaUserוכו') על אשכול Kubernetes חדש - מעדכנים את ה-PersistentVolumeClaims עם השם של מופעי ברוקר Kafka החדשים ל-PersistentVolumes הישנים באמצעות המאפיין
spec.volumeNameב-PersistentVolumeClaim.
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.
מחיקת הפרויקט
כדי למחוק Google Cloud פרויקט:
gcloud projects delete PROJECT_ID
מחיקת המשאבים הבודדים
אם השתמשתם בפרויקט קיים ואתם לא רוצים למחוק אותו, אתם יכולים למחוק את המשאבים בנפרד.
מגדירים משתני סביבה.
export PROJECT_ID=${PROJECT_ID} export KUBERNETES_CLUSTER_PREFIX=kafka export REGION=us-central1מריצים את הפקודה
terraform destroy:export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) terraform -chdir=kafka/terraform/FOLDER destroy -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}מחליפים את
FOLDERב-gke-autopilotאו ב-gke-standard.כשמופיעה בקשה, כותבים
yes.חיפוש כל הדיסקים שלא צורפו:
export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")השלב הזה נדרש כי כברירת מחדל, Strimzi משתמש בפרמטר
deleteClaim: falseלאחסון. אם מוחקים את האשכול, כל הדיסקים נשארים זמינים.מוחקים את הדיסקים:
for i in $disk_list; do disk_name=$(echo $i| cut -d'|' -f1) disk_zone=$(echo $i| cut -d'|' -f2|sed 's|.*/||') echo "Deleting $disk_name" gcloud compute disks delete $disk_name --zone $disk_zone --quiet done
המאמרים הבאים
- כדאי להעמיק את הקריאה ולהכיר דוגמאות לארכיטקטורות, תרשימים ושיטות מומלצות בנושאי Google Cloud. כל אלה זמינים במרכז הארכיטקטורה של Cloud.
- איך מגבים את האשכולות באמצעות Backup for GKE