Networking — DNS, Ingress, TLS, NetworkPolicy
Service DNS: שם קצר מול FQDN
Section titled “Service DNS: שם קצר מול FQDN”| מאיפה פונים | כתובת | דוגמה |
|---|---|---|
| אותו namespace | שם ה-Service | redis, postgres:5432 |
| namespace אחר | <SERVICE>.<NS>.svc.cluster.local | redis.trident-dev.svc.cluster.local |
kubectl -n <NS> exec deploy/<SERVICE> -- python -c "import socket; print(socket.gethostbyname('redis'))"kubectl -n <NS> exec deploy/<SERVICE> -- python -c "import socket; print(socket.gethostbyname('redis.<NS>.svc.cluster.local'))"איך מוודאים: שתי הפקודות מדפיסות את אותה כתובת (ClusterIP של ה-Service). gaierror = השם לא קיים או שגוי.
Service → Pods: למה אין endpoints
Section titled “Service → Pods: למה אין endpoints”kubectl -n <NS> get svc <SERVICE> -o jsonpath='{.spec.selector}{"\n"}'kubectl -n <NS> get endpointslices -l kubernetes.io/service-name=<SERVICE>kubectl -n <NS> get pods -l trident.dev/service=<SERVICE> --show-labelsאיך מוודאים: ב-endpointslices העמודה ENDPOINTS מכילה כתובות Pod. ריקה = ה-selector של ה-Service לא תואם ל-labels של ה-Pods, או שה-Pods לא Ready (probes). השוואה: extraSelectorLabels ב-Deployment מול ב-Service (values).
Ingress ו-TLS
Section titled “Ingress ו-TLS”kubectl -n <NS> get ingresskubectl -n <NS> describe ingress <SERVICE>kubectl get ingressclasskubectl -n <NS> get secret <SECRET> -o jsonpath='{.type}{"\n"}' # the TLS Secret named in the Ingressחמש נקודות לבדוק כש-Ingress לא עובד (404, תעודה שגויה, אין תגובה):
ingressClassName: nginx— מתאים ל-get ingressclass.- ה-host בכלל (rule) ובתוך
tls.hosts— אותו ערך. (values) serviceNameו-servicePortשל ה-backend קיימים ב-namespace.- ה-Secret מסוג
kubernetes.io/tlsקיים ב-namespace של ה-Ingress (secrets). - ה-header
Hostבבקשה תואם ל-host. בלי זה controller מחזיר 404 משלו.
curl --resolve אל ה-NodePort
Section titled “curl --resolve אל ה-NodePort”ה-controller חשוף ב-NodePort על ה-VM. את המספר מגלים, לא מנחשים — הוא משתנה בין cluster-ים.
kubectl -n ingress-nginx get svc# PORT(S) column looks like 80:30593/TCP,443:31651/TCP -> <PORT> is the number after "443:"curl -k --resolve <HOST>:<PORT>:<VM_IP> https://<HOST>:<PORT>/info# TRIDENT (port differs per cluster): curl -k --resolve dev.trident.test:31651:192.168.242.130 https://dev.trident.test:31651/info--resolve <HOST>:<PORT>:<VM_IP>אומר ל-curl: "ל-host הזה בפורט הזה, השתמש בכתובת הזאת" — בלי לשנות/etc/hosts. ה-URL ו-ה-Hostheader נשארים<HOST>, אז ה-Ingress מתאים לכלל.-kמדלג על אימות התעודה (תעודה self-signed).
curl --cacert <FILE> --resolve <HOST>:<PORT>:<VM_IP> https://<HOST>:<PORT>/info# TRIDENT: curl --cacert ~/.local/share/trident/tls/ca.crt --resolve dev.trident.test:31651:192.168.242.130 https://dev.trident.test:31651/infoעם --cacert מוודאים גם שהתעודה נחתמה על ידי ה-CA הנכון — בדיקה אמיתית יותר מ--k.
איך מוודאים: JSON עם service, version (שווה ל-<CANDIDATE>) ו-environment (שווה ל-<ENV>). Could not resolve host = שכחת --resolve. 404 מ-nginx = ה-Host/הכלל לא תואמים. Connection refused = פורט שגוי.
/etc/hosts לדפדפן
Section titled “/etc/hosts לדפדפן”לדפדפן אין --resolve; מוסיפים שורה לקובץ המארח (במחשב שממנו גולשים):
<VM_IP> <HOST>הדפדפן עדיין צריך את ה-NodePort ב-URL: https://<HOST>:<PORT>/.
לקרוא את /info ולהוכיח שה-DB מקבל data
Section titled “לקרוא את /info ולהוכיח שה-DB מקבל data”Synced/Healthy לא מוכיח שהמערכת עובדת. קרא את /info פעמיים בהפרש של כמה שניות:
| שדה | מה טוב |
|---|---|
version | שווה ל-candidate שעשה promote ל-<ENV> |
accepted | עולה בין שתי הקריאות = data זורם |
queue_depth | קרוב ל-0 (התור מתרוקן) |
dropped_queue_full | ישר (לא עולה); מספר גדול ויציב הוא היסטוריה, לא תקלה |
detections=0 צפוי ב"ים שקט" (ה-contract: quiet sea → אין זיהוי). כדי להוכיח את מסלול ה-DB מפעילים תרחיש quick-transit בסימולטור (פורט ops 9101; ב-image יש python ואין curl):
kubectl -n <NS> exec deploy/acoustic-simulator -- python -c "import urllib.request as u; u.urlopen(u.Request('http://127.0.0.1:9101/scenarios/quick-transit', method='POST'))"kubectl -n <NS> exec postgres-0 -- psql -U trident -d trident -c 'select count(*) from detections'איך מוודאים: אחרי כדקה (התרחיש נמשך 60 שניות) count גדול מ-0. הרץ שוב את השאילתה ומספר עולה = מסלול simulator → ingest-api → redis → signal-processor → postgres עובד. (trident/trident = POSTGRES_USER/POSTGRES_DB ב-values.)
NetworkPolicy: default-deny ו-allow
Section titled “NetworkPolicy: default-deny ו-allow”ב-Kubernetes ברירת המחדל שטוחה: כל Pod מדבר עם כל Pod. NetworkPolicy הופכת את זה ל-allowlist: קודם חוסמים הכול, ואז פותחים רק את מסלול הנתונים.
מסלול הנתונים ב-TRIDENT: simulator → ingest-api → redis ← signal-processor → postgres.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-ingress namespace: <NS>spec: podSelector: {} policyTypes: [Ingress]---apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-redis-from-api-and-processor namespace: <NS>spec: podSelector: matchLabels: {trident.dev/service: redis} policyTypes: [Ingress] ingress: - from: - podSelector: matchLabels: {trident.dev/service: ingest-api} - podSelector: matchLabels: {trident.dev/service: signal-processor} ports: - {protocol: TCP, port: 6379}---apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-ingest-api namespace: <NS>spec: podSelector: matchLabels: {trident.dev/service: ingest-api} policyTypes: [Ingress] ingress: - from: - podSelector: matchLabels: {trident.dev/service: acoustic-simulator} - namespaceSelector: matchLabels: {kubernetes.io/metadata.name: ingress-nginx} ports: - {protocol: TCP, port: 8080}podSelector: {}בליingress:= בוחר את כל ה-Pods וחוסם כל כניסה אליהם.- כל allow בוחר את Pod היעד ב-
podSelectorהעליון, ואת המקור ב-from. כלל דומה נדרש גם ל-postgres (מ-signal-processor, פורט 5432). - ה-
namespaceSelectorמאפשר לתעבורה מה-ingress controller להגיע ל-ingest-api. בלעדיו ה-Ingress נחסם. - אם Prometheus מגרד את פורטי
ops/httpמ-namespace אחר — צריך allow גם לו (SHOULD, תלוי ב-contract). - ב-values של ה-chart אותה מדיניות נכתבת תחת
networkPolicies(values).
kubectl create --dry-run=client -f networkpolicies.yaml -o name # syntax check, no cluster changekubectl -n <NS> get networkpolicykubectl -n <NS> describe networkpolicy allow-redis-from-api-and-processorאיך מוודאים: dry-run מדפיס networkpolicy.networking.k8s.io/... לכל מדיניות. בדיקה חיה: מ-Pod אסור (למשל simulator → redis) החיבור נכשל ב-timeout, ומ-Pod מותר (ingest-api → redis) הוא מצליח.
kubectl -n <NS> exec deploy/acoustic-simulator -- python -c "import socket; socket.create_connection(('redis', 6379), 3)" # must failkubectl -n <NS> exec deploy/ingest-api -- python -c "import socket; socket.create_connection(('redis', 6379), 3); print('ok')" # must print okCNI: האם המדיניות נאכפת בכלל?
Section titled “CNI: האם המדיניות נאכפת בכלל?”cat /etc/k8s-manager/cni # TRIDENT lab: prints canalkubectl -n kube-system get pods | grep -E 'canal|flannel|calico'איך מוודאים: canal (או calico). אם רק flannel — בדיקת ה"אסור" חייבת להיכשל; אם היא מצליחה, המדיניות לא נאכפת.