אם אתם מפעילים אפליקציות באשכולות רגילים, kube-dns הוא ספק ה-DNS שמוגדר כברירת מחדל ועוזר לכם להפעיל גילוי שירותים ותקשורת. במאמר הזה מוסבר איך לנהל DNS באמצעות kube-dns, כולל הארכיטקטורה, ההגדרה ושיטות מומלצות לאופטימיזציה של פעולות ה-DNS בסביבת GKE.
המסמך הזה מיועד למפתחים, לאדמינים ולארכיטקטים שאחראים על ניהול DNS ב-GKE. למידע נוסף על תפקידים ומשימות נפוצים ב- Google Cloud, אפשר לעיין במאמר תפקידים ומשימות נפוצים של משתמשי GKE.
לפני שמתחילים, חשוב להכיר את השירותים של Kubernetes ואת המושגים הכלליים של DNS.
הסבר על ארכיטקטורת kube-dns
kube-dns פועל בתוך אשכול GKE כדי לאפשר פענוח DNS בין Pods לבין Services.
בתרשים הבא אפשר לראות איך ה-Pods שלכם מקיימים אינטראקציה עם שירות kube-dns:
רכיבים מרכזיים
kube-dns כולל את הרכיבים העיקריים הבאים:
kube-dnsPods: these Pods run thekube-dnsserver software. כמה עותקים של ה-Pods האלה פועלים במרחב השמותkube-system, והם מספקים זמינות גבוהה ויתירות.kube-dnsשירות: בטבלה הבאה מוצגת השוואה בין מגבלות ההגדרה והמדרגיות של הגרסאות הקודמות שלkube-dnsושל הגרסאות שמבוססות על CoreDNS:תכונה גרסה קודמת (kube-dns 1.35 ואילך) kube-dns ב-CoreDNS (מגרסה 1.36 ואילך) הגברת המוּדעוּת לנקודות קצה יודע על עד 1,000 נקודות קצה לכל שירות. אם לשירות יש יותר מ-1,000 פודים, kube-dns לא מודע לנקודות הקצה הנוספות. מודע לכל נקודות הקצה. הגרסה הזו משתמשת ב-EndpointSlices כדי להבטיח דיוק ולשפר את היעילות של שירותים גדולים. שרתי שמות Upstream מוגבל ל-3 תמיכה בעד 15 חיבורי TCP יוצאים בו-זמנית עד 200 תמיכה בעד 1,500 -
kube-dns-autoscaler: ה-Pod הזה משנה את מספר העותקים המשוכפלים שלkube-dnsבהתאם לגודל האשכול, שכולל את מספר הצמתים וליבות ה-CPU. הגישה הזו עוזרת להבטיח ש-kube-dnsיוכל להתמודד עם עומסים משתנים של שאילתות DNS.
פענוח DNS פנימי
כש-Pod צריך לפתור שם DNS בדומיין של האשכול, כמו
myservice.my-namespace.svc.cluster.local, מתרחש התהליך הבא:
- הגדרת ה-DNS של ה-Pod:
kubeletבכל צומת מגדיר את קובץ/etc/resolv.confשל ה-Pod. בקובץ הזה נעשה שימוש בkube-dnsשל שירותClusterIPכשרת השמות. - שאילתת DNS: ה-Pod שולח שאילתת DNS לשירות
kube-dns. תרגום שם (Name resolution):
- GKE גרסה 1.36 ואילך: ההטמעה שמבוססת על CoreDNS משתמשת ב-EndpointSlices כדי ש-
kube-dnsיכיר את כל ה-Pods בשירות. כך אפשר לשפר את הדיוק והיעילות של שירותים בקנה מידה גדול. - GKE גרסה 1.35 ואילך:
kube-dnsפותרת שמות על סמך Cloud Endpoints API מהדור הקודם, שמוגבל ל-1,000 נקודות קצה. אם לשירות יש יותר מ-1,000 פודים תומכים,kube-dnsלא מודע לנקודות הקצה הנוספות.
- GKE גרסה 1.36 ואילך: ההטמעה שמבוססת על CoreDNS משתמשת ב-EndpointSlices כדי ש-
תקשורת: ה-Pod משתמש בכתובת ה-IP שזוהתה כדי לתקשר עם שירות היעד.
פענוח DNS חיצוני
כשצריך לפתור שם DNS חיצוני או שם שנמצא מחוץ לדומיין של האשכול, kube-dns פועל כפתרון רקורסיבי. הוא מעביר את השאילתה לשרתי DNS במעלה הזרם שהוגדרו בקובץ ConfigMap. אפשר גם להגדיר פותרים בהתאמה אישית לדומיינים ספציפיים, שנקראים גם דומיינים מסוג stub. ההגדרה הזו מכוונת את kube-dns להעביר בקשות עבור הדומיינים האלה לשרתי DNS ספציפיים במעלה הזרם.
הגדרת DNS של Pod
ב-GKE, סוכן kubelet בכל צומת מגדיר את הגדרות ה-DNS של ה-Pods שפועלים בצומת הזה.
הגדרת הקובץ /etc/resolv.conf
כש-GKE יוצר Pod, סוכן kubelet משנה את הקובץ /etc/resolv.conf של ה-Pod. הקובץ הזה מגדיר את שרת ה-DNS לפתרון שמות ומציין דומיינים לחיפוש. כברירת מחדל, kubelet מגדיר את ה-Pod להשתמש בשירות ה-DNS הפנימי של האשכול, kube-dns, כשרת השמות שלו. הוא גם מאכלס את דומייני החיפוש בקובץ. דומייני החיפוש האלה מאפשרים לכם להשתמש בשמות לא מלאים בשאילתות DNS. לדוגמה, אם הפוד שולח שאילתה ל-myservice, Kubernetes מנסה קודם לפתור את myservice.default.svc.cluster.local, אחר כך את myservice.svc.cluster.local ואז את שאר הדומיינים מהרשימה search.
בדוגמה הבאה מוצגת הגדרת ברירת מחדל של /etc/resolv.conf:
nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local c.my-project-id.internal google.internal
options ndots:5
הקובץ הזה כולל את הערכים הבאים:
-
nameserver: מגדיר אתClusterIPשל שירותkube-dns. -
search: מגדיר את דומייני החיפוש שמצורפים לשמות לא מלאים במהלך חיפושי DNS. -
options ndots:5: הגדרת ערך הסף שלפיו GKE קובע אם שם הוא מוגדר במלואו. שם נחשב למוגדר במלואו אם יש בו חמש נקודות או יותר.
Pods שמוגדרים עם hostNetwork: true מקבלים בירושה את הגדרת ה-DNS מkube-dns ולא מבצעים שאילתה ישירות ל-kube-dns, אלא אם הם משתמשים ב-ClusterFirstWithHostNet dnsPolicy.
התאם אישית את kube-dns
kube-dns מספק פענוח DNS חזק כברירת מחדל. אתם יכולים להתאים את ההתנהגות שלו לצרכים ספציפיים, כמו שיפור היעילות של הרזולוציה או שימוש בשרתי DNS מועדפים. הגדרת דומיינים מסוג stub ושרתי שמות במעלה הזרם מתבצעת על ידי שינוי kube-dns ConfigMap במרחב השמות kube-system.
שינוי של kube-dns ConfigMap
כדי לשנות את kube-dns ConfigMap, מבצעים את הפעולות הבאות:
פותחים את ConfigMap לעריכה:
kubectl edit configmap kube-dns -n kube-systemבקטע
data, מוסיפים את השדותstubDomainsו-upstreamNameserversבאופן הבא:apiVersion: v1 kind: ConfigMap metadata: labels: addonmanager.kubernetes.io/mode: EnsureExists name: kube-dns namespace: kube-system data: stubDomains: | { "example.com": [ "8.8.8.8", "8.8.4.4" ], "internal": [ # Required if your upstream nameservers can't resolve GKE internal domains "169.254.169.254" # IP of the metadata server ] } upstreamNameservers: | [ "8.8.8.8", # Google Public DNS "8.8.4.4" # Google Public DNS Backup ]שומרים את ה-ConfigMap.
kube-dnsטוען מחדש את ההגדרה באופן אוטומטי.
דומיינים מסוג Stub
דומיינים מסוג Stub מאפשרים להגדיר פותרים מותאמים אישית של DNS לדומיינים ספציפיים. כש-Pod שולח שאילתה לשם בדומיין stub, kube-dns מעביר את השאילתה לפתרון שצוין במקום להשתמש במנגנון ברירת המחדל שלו לפתרון.
אתם כוללים קטע stubDomains בkube-dns ConfigMap.
בקטע הזה מצוינים הדומיין ושרתי השמות המתאימים במעלה הזרם.
kube-dns ואז מעביר שאילתות לשמות בדומיין הזה לשרתים המיועדים. לדוגמה, אפשר להפנות את כל שאילתות ה-DNS של internal.mycompany.com אל 192.168.0.10, ולהוסיף את "internal.mycompany.com": ["192.168.0.10"] אל stubDomains.
כשמגדירים מפענח DNS מותאם אישית לדומיין stub, כמו example.com, kube-dns מעביר את כל בקשות תרגום השמות של הדומיין הזה, כולל תת-דומיינים כמו *.example.com, לשרתים שצוינו.
שרתי שמות במעלה הזרם
אפשר להגדיר את kube-dns כך שישתמש בשרתי שמות בהתאמה אישית במעלה הזרם כדי לפתור שמות של דומיינים חיצוניים. ההגדרה הזו מורה ל-kube-dns להעביר את כל בקשות ה-DNS, מלבד הבקשות לדומיין הפנימי של האשכול (*.cluster.local), לשרתי ה-upstream המיועדים. יכול להיות ששרתי upstream מותאמים אישית לא יוכלו לפענח דומיינים פנימיים כמו metadata.internal ו-*.google.internal. אם מפעילים את איחוד הזהויות של עומסי עבודה ל-GKE או שיש עומסי עבודה שתלויים בדומיינים האלה, צריך להוסיף דומיין stub ל-internal ב-ConfigMap. משתמשים ב-169.254.169.254, כתובת ה-IP של שרת המטא-נתונים, כמפענח ה-DNS של דומיין ה-stub הזה.
ניהול פריסה מותאמת אישית של kube-dns
באשכול רגיל, kube-dns פועל כפריסה. פריסה kube-dns בהתאמה אישית מאפשרת לכם, כאדמינים של האשכול, לשלוט בפריסה ולהתאים אותה לצרכים שלכם, במקום להשתמש בפריסה שמוגדרת כברירת מחדל ב-GKE.
סיבות לפריסה בהתאמה אישית
כדאי לשקול פריסה מותאמת אישית של kube-dns מהסיבות הבאות:
- הקצאת משאבים: כוונון עדין של משאבי המעבד והזיכרון עבור
kube-dnsPods כדי לשפר את הביצועים באשכולות עם נפח תנועה גבוה של DNS. - גרסת התמונה: אפשר להשתמש בגרסה ספציפית של התמונה
kube-dnsאו לעבור לספק DNS חלופי כמו CoreDNS. - הגדרה מתקדמת: אפשר להתאים אישית את רמות הרישום ביומן, מדיניות האבטחה והתנהגות של שמירת DNS במטמון.
התאמה אוטומטית של נפח האחסון (autoscaling) לפריסות מותאמות אישית
ה-kube-dns-autoscaler המובנה פועל עם פריסת kube-dns שמוגדרת כברירת מחדל.
אם יוצרים פריסה מותאמת אישית של kube-dns, המערכת המובנית להתאמת קנה מידה אוטומטית לא מנהלת אותה. לכן, צריך להגדיר קנה מידה אוטומטי נפרד שמוגדר במיוחד למעקב אחרי מספר העותקים של פריסת ההתאמה האישית ולהתאמתם.
בגישה הזו צריך ליצור ולהטמיע הגדרה משלכם של שינוי גודל אוטומטי באשכול.
כשמנהלים פריסה בהתאמה אישית, האחריות על כל הרכיבים שלה מוטלת על המשתמש, למשל שמירה על עדכניות של תמונת ה-autoscaler. שימוש ברכיבים לא עדכניים עלול לגרום לירידה בביצועים או לכשלים ב-DNS.
הוראות מפורטות להגדרה ולניהול של פריסה משלכם של kube-dns
kube-dns זמינות במאמר הגדרת פריסה מותאמת אישית של kube-dns.
פתרון בעיות
למידע על פתרון בעיות ב-kube-dns, אפשר לעיין בדפים הבאים:
- לקבלת עצות לגבי
kube-dnsב-GKE, אפשר לעיין במאמר פתרון בעיות ב-kube-dnsב-GKE. - לקבלת עצות כלליות לגבי אבחון בעיות DNS ב-Kubernetes, אפשר לעיין במאמר ניפוי באגים בפתרון DNS.
אופטימיזציה של פענוח DNS
בקטע הזה מתוארות בעיות נפוצות ושיטות מומלצות לניהול DNS ב-GKE.
המגבלה של דומיינים לחיפוש ב-Pod dnsConfig
ב-Kubernetes, מספר הדומיינים של חיפוש DNS מוגבל ל-32. אם מנסים להגדיר יותר מ-32 דומיינים לחיפוש ב-dnsConfig של Pod, ה-kube-apiserver לא ייצור את ה-Pod, ותופיע שגיאה דומה לזו:
The Pod "dns-example" is invalid: spec.dnsConfig.searches: Invalid value: []string{"ns1.svc.cluster-domain.example", "my.dns.search.suffix1", "ns2.svc.cluster-domain.example", "my.dns.search.suffix2", "ns3.svc.cluster-domain.example", "my.dns.search.suffix3", "ns4.svc.cluster-domain.example", "my.dns.search.suffix4", "ns5.svc.cluster-domain.example", "my.dns.search.suffix5", "ns6.svc.cluster-domain.example", "my.dns.search.suffix6", "ns7.svc.cluster-domain.example", "my.dns.search.suffix7", "ns8.svc.cluster-domain.example", "my.dns.search.suffix8", "ns9.svc.cluster-domain.example", "my.dns.search.suffix9", "ns10.svc.cluster-domain.example", "my.dns.search.suffix10", "ns11.svc.cluster-domain.example", "my.dns.search.suffix11", "ns12.svc.cluster-domain.example", "my.dns.search.suffix12", "ns13.svc.cluster-domain.example", "my.dns.search.suffix13", "ns14.svc.cluster-domain.example", "my.dns.search.suffix14", "ns15.svc.cluster-domain.example", "my.dns.search.suffix15", "ns16.svc.cluster-domain.example", "my.dns.search.suffix16", "my.dns.search.suffix17"}: must not have more than 32 search paths.
השגיאה הזו מוחזרת מ-kube-apiserver בתגובה לניסיון ליצור Pod. כדי לפתור את הבעיה, צריך להסיר מנתיבי החיפוש הנוספים את ההגדרה.
מגבלת nameservers בשרת במעלה הזרם עבור kube-dns
בגרסאות קודמות של kube-dns (גרסה 1.35 ומטה) מספר upstreamNameservers מוגבל לשלושה. אם מגדירים יותר משלושה, Cloud Logging מציג שגיאה שדומה לזו:
Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update
בתרחיש הזה, kube-dns מתעלם מההגדרה upstreamNameservers וממשיך להשתמש בהגדרה הקודמת התקינה. כדי לפתור את הבעיה, צריך להסיר את upstreamNameservers הנוסף מ-kube-dns ConfigMap.
הגדלת הקיבולת kube-dns
ב-Standard clusters, אפשר להשתמש בערך נמוך יותר עבור nodesPerReplica
כדי ליצור יותר kube-dns Pods כשצמתים של אשכולות עוברים שינוי גודל. מומלץ מאוד להגדיר ערך מפורש לשדה max כדי לוודא שהמכונה הווירטואלית (VM) של מישור הבקרה של GKE לא תהיה עמוסה מדי בגלל המספר הגדול של רכיבי Pod kube-dns שעוקבים אחרי Kubernetes API.
אפשר להגדיר את הערך של השדה max למספר הצמתים באשכול.
אם באשכול יש יותר מ-500 צמתים, צריך להגדיר את הערך של השדה max ל-500.
אפשר לשנות את מספר העותקים המשוכפלים של kube-dns על ידי עריכת kube-dns-autoscaler ConfigMap.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
הפלט אמור להיראות כך:
linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'
מספר העותקים המשוכפלים של kube-dns מחושב באמצעות הנוסחה הבאה:
replicas = max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) )
כדי להגדיל את מספר המכונות, משנים את הערך של השדה nodesPerReplica לערך קטן יותר, ומוסיפים ערך לשדה max.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
ההגדרה הזו יוצרת Pod אחד לכל שמונה צמתים באשכול.kube-dns ב-cluster עם 24 צמתים יש 3 עותקים וב-cluster עם 40 צמתים יש 5 עותקים. אם גודל האשכול גדל מעבר ל-120 צמתים, מספר העותקים לא גדל מעבר ל-15, שהוא הערך של השדה max.kube-dns
כדי להבטיח רמת זמינות בסיסית של DNS באשכול, צריך להגדיר מספר מינימלי של עותקים משוכפלים בשדה kube-dns.
הפלט של kube-dns-autoscaler ConfigMap עם השדה min שמוגדר אמור להיראות כך:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
שיפור הזמנים של חיפושי DNS
יש כמה גורמים שיכולים לגרום לזמן אחזור ארוך בחיפושי DNS או לכשלים ברזולוציית DNS עם ספק kube-dns שמוגדר כברירת מחדל. יכול להיות שבאפליקציות יופיעו השגיאות האלה בתור שגיאות getaddrinfo EAI_AGAIN, שמצביעות על כשל זמני בפתרון שמות. הסיבות האפשריות:
- חיפושי DNS תכופים בעומס העבודה.
- צפיפות גבוהה של Pods לכל צומת.
- הפעלת
kube-dnsבמכונות וירטואליות מסוג Spot או במכונות וירטואליות שניתנות להפסקת פעולה, מה שעלול להוביל למחיקות לא צפויות של צמתים. - מגבלות חיבור: בגרסאות קודמות של
kube-dns(GKE גרסה 1.35 ואילך) יש מגבלה של 200 חיבורי TCP בו-זמנית. kube-dnsב-CoreDNS (GKE גרסה 1.36 ואילך) מסיר את המגבלות הקבועות האלה לחיבורים נכנסים ומספק קיבולת גבוהה משמעותית לחיבורים יוצאים.
כדי לשפר את זמני החיפוש ב-DNS:
- מומלץ להימנע מהרצת רכיבי מערכת קריטיים כמו
kube-dnsבמכונות וירטואליות מסוג Spot או במכונות וירטואליות שניתן לקטוע את הפעילות שלהן. יוצרים לפחות מאגר צמתים אחד עם מכונות וירטואליות רגילות, ללא מכונות וירטואליות זמניות או מכונות וירטואליות שניתנות להפסקת פעולה. כדי לוודא שעומסי עבודה קריטיים מתוזמנים בצמתים האמינים האלה, אפשר להשתמש ב-taints וב-tolerations. - מפעילים את NodeLocal
DNSCache. NodeLocalDNSCache שומר במטמון את תשובות ה-DNS ישירות בכל צומת, וכך מקצר את זמן האחזור ומפחית את העומס על שירות
kube-dns. אם מפעילים את NodeLocal DNSCache ומשתמשים בכללי מדיניות של רשת עם כללי ברירת מחדל של דחייה, צריך להוסיף מדיניות שתאפשר לעומסי עבודה לשלוח שאילתות DNS לקבוצות ה-Pod שלnode-local-dns. - הרחבת המינוי
kube-dns. - צריך לוודא שהאפליקציה משתמשת בפונקציות שמבוססות על
dns.resolve*ולא בפונקציות שמבוססות עלdns.lookup, כיdns.lookupהיא סינכרונית. - משתמשים בשמות דומיין שמוגדרים במלואם (FQDN), לדוגמה,
https://google.com./במקוםhttps://google.com/.
יכול להיות שיהיו כשלים בפענוח DNS במהלך שדרוגים של אשכולות GKE, בגלל שדרוגים מקבילים של רכיבי מישור הבקרה, כולל kube-dns.
בדרך כלל, הכשלים האלה משפיעים על אחוז קטן של צמתים. חשוב לבדוק היטב את השדרוגים של האשכולות בסביבה שאינה סביבת ייצור לפני שמחילים אותם על אשכולות בסביבת ייצור.
מוודאים שאפשר לגלות את השירות
kube-dns יוצר רק רשומות DNS לשירותים שיש להם נקודות קצה. אם לשירות אין נקודות קצה, kube-dns לא יוצר רשומות DNS עבור השירות הזה.
ניהול פערים ב-TTL של DNS
אם kube-dns מקבל תשובה ממפענח DNS במעלה הזרם עם TTL גדול או אינסופי, הוא שומר את ערך ה-TTL הזה. ההתנהגות הזו עלולה ליצור חוסר התאמה בין הרשומה שנשמרה במטמון לבין כתובת ה-IP בפועל.
ב-GKE, הבעיה הזו נפתרת בגרסאות ספציפיות של מישור הבקרה, כמו 1.21.14-gke.9100 ואילך או 1.22.15-gke.2100 ואילך. בגרסאות האלה מוגדר ערך TTL מקסימלי של 30 שניות לכל תגובת DNS עם ערך TTL גבוה יותר. ההתנהגות הזו דומה ל-NodeLocal DNSCache.
הצגת המדדים של kube-dns
אפשר לאחזר מדדים לגבי שאילתות DNS ישירות מ-kube-dns Pods.
אופן האחזור של המדדים האלה תלוי בגרסת GKE.
GKE מגרסה 1.36 ואילך
אם האשכול שלכם מריץ GKE מגרסה 1.36 ואילך (kube-dns ב-CoreDNS), אתם יכולים לעקוב אחרי ביצועי ה-DNS באמצעות לוחות בקרה מוגדרים מראש ב-Cloud Monitoring, או לאחזר מדדים באופן ידני מה-Pods.
הצגת מדדים במסוף Google Cloud
- נכנסים לדף Dashboards במסוף Google Cloud .
- בוחרים את מרכז הבקרה GKE DNS Observability - Cluster View.
לחלופין, אפשר לשלוח שאילתה לגבי המדדים האלה ישירות במסוף Google Cloud . כדי לעשות זאת, עוברים אל Monitoring > Metrics explorer ומחפשים את השמות הספציפיים של המדדים.
אחזור מדדים באופן ידני
כדי לאחזר מדדים מה-Pod באופן ידני:
מוצאים את
kube-dnsPods.kubectl get pods -n kube-system --selector=k8s-app=kube-dnsמעבירים את יציאה 9153 לאחד מה-Pods.
kubectl port-forward pod/POD_NAME -n kube-system 9153:9153מחליפים את
POD_NAMEבשם של אחד מ-kube-dnsPods מהפלט הקודם.גישה למדדים.
curl http://127.0.0.1:9153/metrics
GKE מגרסה 1.35 ומגרסאות קודמות
בגרסה הזו של kube-dns נעשה שימוש ב-Pods מרובי-קונטיינרים. כדי לאחזר מדדים, מבצעים את הפעולות הבאות:
מחפשים את
kube-dnsPods במרחב השמותkube-system.kubectl get pods -n kube-system --selector=k8s-app=kube-dnsהפניית יציאות (port-forward) ליציאות 10055 (למאגר
kube-dns) ו-10054 (למאגרdnsmasq):#For the kube-dns container kubectl port-forward pod/POD_NAME -n kube-system 10055:10055 #For the dnsmasq container kubectl port-forward pod/POD_NAME -n kube-system 10054:10054מחליפים את
POD_NAMEבשם של אחד מ-kube-dnsPods מהפלט הקודם. מריצים את הפקודות האלה להעברת פורטים בסשנים נפרדים של מסוף.גישה למדדים.
#Metrics from the kube-dns container curl http://127.0.0.1:10055/metrics #Metrics from the dnsmasq container curl http://127.0.0.1:10054/metrics
המאמרים הבאים
- כדאי לקרוא סקירה כללית על DNS של אשכולות ב-GKE.
- במאמר DNS for Services and Pods מופיעה סקירה כללית על השימוש ב-DNS באשכולות Kubernetes.
- איך מגדירים NodeLocal DNSCache
- איך מגדירים פריסת kube-dns בהתאמה אישית