בדף הזה מוסבר איך להגדיר את התכונה 'הפניית תנועה לשירותים' עבור ה-Pods.
כדי להבין איך פועל ניהול התעבורה בין שירותים, אפשר לעיין במאמר איך פועל ניהול התעבורה בין שירותים.
דרישות
- GKE בגרסה 1.30 ואילך.
מגבלות
- ל-
ServiceFunctionChainיכולה להיות פונקציית שירות אחת לכל היותר. - מומלץ להשתמש במקסימום 100 צמתים בתוספת 10 זוגות של
ServiceFunctionChainו-TrafficSelector. - התכונה 'הפניית תנועה בשירות GKE' זמינה רק בצמתים שפועלת בהם תמונת הצומת של מערכת הפעלה שמותאמת לקונטיינרים.
- התכונה 'הפניית תנועה בשירות GKE' תומכת רק בכתובות IP של יציאה ושל יעד.
- התכונה 'הפניית תנועה לשירותים' לא מטפלת בקונפליקטים שמתעוררים כשמחילים על אותו נושא כמה TrafficSelector עם אורך קידומת זהה. כדי למנוע התנגשויות, מומלץ לתכנן מראש את בוררי התנועה עם טווחי כתובות IP שלא חופפים ועם קריטריונים ברורים לבחירה.
הטמעה של ניהול תעבורה בין שירותים
התכונה GKE Service Steering מאפשרת לכם להתאים אישית את זרימת תעבורת הרשת באשכול ולשלוט בה. בקטע הזה נסביר איך להטמיע את התכונה 'הפניית תנועה לשירותים' באמצעות דוגמה של שער אינטרנט.
נניח שאתם רוצים ליצור שער אינטרנט שמאבטח את התנועה ממכשירי לקוח של משתמשי קצה לאינטרנט. מסיים VPN מושך תנועה אל השער המנוהל באמצעות מנהרה מאובטחת. תנועת המשתמשים הסופיים מנותבת מחדש לחומת האש ואז לשרת הפרוקסי. הפרוקסי מבצע תרגום של כתובת הרשת של המקור (SNAT) בתעבורת הנתונים, מסווה את כתובת המקור המקורית ושולח אותה לאינטרנט.
כדי להטמיע את התכונה 'הפניית תנועה לשירותים' ב-GKE, צריך לבצע את הפעולות הבאות:
- יוצרים VPC עם MTU של 8896.
- יוצרים אשכול GKE.
- יוצרים את ה-Pods של פונקציית השירות ואת השירות.
- יוצרים את
ServiceFunctionChain. - יוצרים את המשאב
TrafficSelectorשמפנה אלServiceFunctionChain.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
הכנת VPC
מכינים VPC. התכונה Service Steering משתמשת באנקפסולציה כדי להפנות את התנועה לפונקציות השירות המתאימות. אנקפסולציה כוללת הוספה של כותרות נוספות לכל מנה, מה שמגדיל את גודל המנה. לא נדרשת הגדרה מיוחדת ב-VPC כדי להשתמש בהפניית תנועה לשירותים. במהלך ההכנה של VPC, מומלץ לקחת בחשבון את התקורה של האנקפסולציה כשקובעים את גודל MTU. מידע נוסף זמין במאמר רשת VPC עם MTU מוגדר.
הפקודה הבאה מגדירה את גודל ה-MTU ב-VPC:
gcloud compute networks create VPC_NETWORK_NAME --mtu=8896
מחליפים את VPC_NETWORK_NAME בשם של רשת ה-VPC שמכילה את רשת המשנה.
יצירת אשכול GKE
כדי להפעיל את היכולות המתקדמות של ניהול כתובות IP וניתוב רשת שנדרשות להטמעה של Service Steering ב-GKE, צריך ליצור אשכול GKE עם GKE Dataplane V2 באופן הבא:
gcloud container clusters create CLUSTER_NAME \
--network VPC_NAME \
--release-channel RELEASE_CHANNEL \
--cluster-version CLUSTER_VERSION \
--enable-dataplane-v2 \
--enable-ip-alias
מחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_NAME: שם האשכול. -
VPC_NAME: השם של ה-VPC שאליו רוצים לשייך את האשכול. -
RELEASE_CHANNEL: שם ערוץ ההפצה. -
VERSION: גרסת GKE, שצריכה להיות 1.30 ואילך. אפשר גם להשתמש בדגל--release-channelכדי לבחור ערוץ הפצה. לגרסת הערוץ צריכה להיות גרסת ברירת מחדל 1.30 ומעלה.
יצירת ServiceFunction תרמילים
כדי ליצור את שרשרת השירותים, צריך לפרוס את ה-Pod של ה-VPN terminator ואת ה-Pods של פונקציות השירות הנדרשות בתוך האשכול. Pods מכילים את האפליקציות בקונטיינרים שמבצעות את הפונקציות של הרשת.
ה-Pod של VPN terminator הוא לרוב פונקציית השירות הראשונה בשרשרת, שמסיימת את התנועה שנכנסת לאשכול דרך ה-VPN. לאחר מכן, הוא מכוון את פונקציות השירות האחרות, כמו חומות אש ואיזון עומסים, לעיבוד נוסף לפני ההגעה ליעד הסופי.
בקובץ התצורה לדוגמה הבא מוגדרים שלושת הרכיבים הבאים, שחיוניים לניהול תנועה ברשת באשכול:
- VPN Pod: יוצר נקודת קצה של רשת וירטואלית פרטית (VPN) בתוך האשכול, שמאפשרת תקשורת מאובטחת ומוצפנת בין האשכול לבין רשתות חיצוניות.
- פריסת חומת אש: פריסה של כמה עותקים של Pod של חומת אש, שמספקים אבטחה ואיזון עומסים.
- Proxy DaemonSet: פורס Pod של proxy בכל צומת של האשכול, כדי להבטיח שאפשר לעבד את תעבורת הרשת באופן מקומי לפני שהיא מועברת לשירותים אחרים כמו חומת אש.
שומרים את קובץ המניפסט לדוגמה הבא בשם service_function.yaml:
apiVersion: v1
kind: Pod
name: vpn
namespace: vpn
labels:
app: vpn
spec:
containers:
- name: vpn
image: openvpn
ports:
- containerPort: 51820
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: firewall
namespace: firewall
spec:
replicas: 3
selector:
matchLabels:
app: firewall
template:
metadata:
labels:
app: firewall
spec:
containers:
- name: firewall
image: firewall
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: proxy
namespace: proxy
spec:
selector:
matchLabels:
app: proxy
template:
metadata:
labels:
app: proxy
spec:
containers:
- name: proxy
image: proxy
החלת המניפסט:
kubectl apply -f service_function.yaml
יצירת ServiceFunctionChains
כדי להגדיר רצף של פונקציות רשת לתעבורת נתונים, יוצרים צינור שבו כל פונקציה, כמו חומת אש, שרת Proxy ומאזן עומסים, מבצעת את המשימה הספציפית שלה לפני העברת תעבורת הנתונים לפונקציה הבאה.
שומרים את קובץ המניפסט לדוגמה הבא בשם ServiceFunctionChain.yaml:
apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
name: firewall
spec:
sessionAffinity:
clientIpNoDestination:
timeoutSeconds: 3600 # 1hr
serviceFunctions:
- name: firewall
namespace: firewall
podSelector:
matchLabels:
app: firewall
---
apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
name: proxy
spec:
sessionAffinity:
clientIpNoDestination: {}
serviceFunctions:
- name: proxy
namespace: proxy
podSelector:
matchLabels:
app: proxy
החלת המניפסט:
kubectl apply -f ServiceFunctionChain.yaml
פונקציות השירות מוגדרות בשורה בתוך ServiceFunctionChain באמצעות השדה serviceFunctions. פונקציית שירות היא בורר נקודות קצה.
יצירת משאב TrafficSelector
כדי להגדיר איפה ואיזו תנועה נבחרת לניתוב תנועה לשירותים, יוצרים את המשאב TrafficSelector שמפנה אל ServiceFunctionChains כדי להחיל אותו על התנועה שנבחרה.
שומרים את קובץ המניפסט לדוגמה הבא בשם TrafficSelector.yaml:
apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
name: vpn-to-firewall
spec:
serviceFunctionChain: firewall
subject:
pods:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: vpn
podSelector:
matchLabels:
app: vpn
egress:
to:
ipBlock:
cidr: 0.0.0.0/0
ports:
- allPorts:
protocol: UDP
- allPorts:
protocol: TCP
---
apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
name: firewall-to-proxy
spec:
serviceFunctionChain: proxy
subject:
pods:
namespaceSelector:
kubernetes.io/metadata.name: firewall
podSelector:
app: firewall
egress:
to:
ipBlock:
cidr: 0.0.0.0/0
ports:
- allPorts:
protocol: UDP
- allPorts:
protocol: TCP
החלת המניפסט:
kubectl apply -f TrafficSelector.yaml
פתרון בעיות שקשורות לניתוב שירותים
בקטע הזה מוסבר איך לפתור בעיות שקשורות ל-GKE Service Steering.
התנועה ברשת לא זורמת
כדי לנפות את הבעיה, אפשר לבצע את הפעולות הבאות:
שלב 1: מוודאים שההגדרה servicePathId מוגדרת ב-ServiceFunctionChain
מוודאים שהאפשרות servicePathId מוגדרת ב-ServiceFunctionChain. לכל אובייקט ServiceFunctionChain מוקצה מזהה ייחודי servicePathId, כמו בדוגמה הבאה:
apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
name: firewall
spec:
serviceFunctions:
- name: firewall
namespace: firewall
podSelector:
matchLabels:
app: firewal
status:
servicePathId: 1
שלב 2: מוודאים שנוצר שירות Kubernetes לכל פונקציית שירות
שירות ClusterIP נוצר באופן אוטומטי לכל פונקציית שירות. אפשר לראות את רשימת השירותים באמצעות kubectl:
kubectl get svc -A -l networking.gke.io/managed-by=service-steering-controller.gke.io
שלב 3: מוודאים שנוצרת רשומת מיפוי של bpf בכל צומת כדי לאחסן את כתובת ה-IP של הפונקציה של כל שירות
לכל פונקציית שירות נוצרת רשומה במפת ה-BPF בכל צומת כדי לאחסן את כתובת ה-IP של השירות.
כדי לקבל את השם של anetd ה-Pod:
kubectl get pods -n kube-system -o wide -l k8s-app=cilium
רושמים את השם של ה-Pod, למשל anetd.
מריצים את הפקודה הבאה:
kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcpath list
מחליפים את ANETD-POD-NAME בשם של ה-Pod anetd.
הפלט אמור להיראות כך:
PATH SERVICE FUNCTION ADDRESS
(1, 1) 10.4.10.124
שלב 4: מוודאים שנוצרו רשומות של מיפוי bpf במפה sfcselect
בצומת, אם יש פודים שנבחרו על ידי TrafficSelector, נוצרות רשומות של מפת bpf במפה sfcselect. בדוגמה הבאה אפשר לראות שתנועת TCP/UDP
מכל יציאה של נקודת הקצה (Pod) 3783 לכתובת ה-IP של היעד 10.0.2.12 מנותבת אל
ServiceFunctionChain.
מריצים את הפקודה הבאה:
kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcselect list
מחליפים את ANETD-POD-NAME בשם בפועל של ה-Pod של anetd באשכול.
הפלט אמור להיראות כך:
SELECTOR PATH
3783, egress, 0/TCP, 10.0.2.12/32 /32 (1, 1)
3783, egress, 0/UDP, 10.0.2.12/32 /32 (1, 1)
שלב 5: שימוש ב-tcpdump ביציאה 7081 כדי ללכוד ולנתח את תעבורת הרשת
התכונה 'ניתוב שירותים' מבצעת אנקפסולציה של Geneve ביציאת UDP 7081. אפשר להשתמש ב-tcpdump בצמתים הרלוונטיים כדי לנתח את זרימת התנועה ולזהות את המקום שבו הבעיה מתרחשת.
המאמרים הבאים
- מידע נוסף על תמיכה במספר רשתות עבור תרמילים
- מידע על ניהול תעבורה בשירותים
- מידע נוסף על הגדרת תמיכה במספר רשתות עבור Pods