הגדרת Multus עם IPVLAN ו-Whereabouts

במאמר הזה מוסבר איך להגדיר Pods ב-Google Kubernetes Engine (GKE) עם כמה ממשקי רשת באמצעות Multus CNI, הפלאגין IPVLAN CNI והפלאגין Whereabouts IPAM.

הפלאגין IPVLAN CNI מספק קישוריות בשכבה 2 לממשקי Pod נוספים, והפלאגין Whereabouts IPAM מקצה להם כתובות IP באופן דינמי.

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

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

לפני שתקראו את המאמר הזה, חשוב שתכירו את המושגים הבאים:

יתרונות השימוש ב-Multus עם IPVLAN

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

  • בידוד תנועה: בידוד של סוגים שונים של תנועה לשיפור האבטחה והביצועים. לדוגמה, אפשר להפריד בין תנועה רגישה של ניהול לבין תנועת נתונים של אפליקציות.
  • הפרדה בין מישור הבקרה למישור הנתונים: הקצאת ממשק הרשת הראשי לתעבורת הנתונים של מישור הבקרה, והפניית תעבורת הנתונים של מישור הנתונים עם תפוקה גבוהה דרך ממשק IPVLAN משני.
  • שכנות בשכבה 2: עמידה בדרישות של אפליקציות שצריכות קישוריות ישירה בשכבה 2 בין Pods באותה רשת משנית.

מגבלות

יש למערכת Multus עם IPVLAN ו-Whereabouts את המגבלות הבאות:

  • פודים שמוגדרים עם ממשקי Multus לא יכולים להשתמש בו-זמנית ביכולות המובנות של GKE לריבוי רשתות. הגדרת הרשת של Pod צריכה להשתמש ב-Multus או בריבוי הרשתות המובנה של האשכול.
  • כדי ש-Multus עם IPVLAN ו-Whereabouts יפעל כמו שצריך, נדרש פתרון ARP של שכבה 2 בתוך Pod.
  • כברירת מחדל, רשתות משנה של VPC לא מאפשרות פתרון ARP בממשקים משניים של מכונות וירטואליות ב-Compute Engine. כדי לאפשר את פתרון ה-ARP הזה, אפשר להירשם לגרסת טרום-השקה (Preview) הפרטית של התכונה resolve-subnet-mask על ידי פתיחת בקשת תמיכה.

איך Multus עובד עם IPVLAN ו-Whereabouts

‫Multus הוא מטא-תוסף CNI שמאפשר ל-Pods להתחבר לכמה רשתות. ‫Multus פועל כרכיב מפנה (dispatcher), שקורא לפלאגינים אחרים של CNI כדי להגדיר ממשקי רשת על סמך משאבי NetworkAttachmentDefinition. אתם מגדירים כל רשת נוספת באמצעות NetworkAttachmentDefinition, שמציין איזה פלאגין CNI (כמו IPVLAN) ואיזה פלאגין IPAM (כמו Whereabouts) ישמשו לרשת הזו.

בתרשים הבא מוצגת ארכיטקטורת Multus עם תוספי IPVLAN ו-Whereabouts.התוסף Whereabouts פועל עם Multus ו-IPVLAN כדי לנהל את כתובות ה-IP (IPAM) של ממשקי הרשת הנוספים של ה-Pods.

תרשים שמראה איך Multus,‏ IPVLAN ו-Whereabouts פועלים יחד ב-GKE.
איור 1. ארכיטקטורת Multus עם תוספי IPVLAN ו-Whereabouts.

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

כשמשתמשים ב-Multus עם IPVLAN ו-Whereabouts ב-GKE, בדרך כלל יש ל-Pods את הגדרות הממשק הבאות:

  • הממשק הראשי (eth0): GKE Dataplane V2 מנהל את הממשק הזה ומספק קישוריות לאשכול כברירת מחדל.
  • ממשקים נוספים (net1 וכו'): ‫Multus מנהל את הממשקים האלה. ‫Multus מפעיל את התוסף IPVLAN CNI במצב Layer 2 לכל NetworkAttachmentDefinition שאתם מציינים בהערות של Pod. ההגדרה הזו מספקת קישוריות בשכבה 2 לרשת VPC משנית.
  • ניהול כתובות IP‏ (IPAM): אתם מגדירים את התוסף Whereabouts IPAM בתוך NetworkAttachmentDefinition. התוסף Whereabouts IPAM מקצה באופן דינמי כתובות IP לממשקי IPVLAN הנוספים מתוך טווח מוגדר מראש.

תזמון של Pod עם כמה רשתות

כשיוצרים Pod ומציינים NetworkAttachmentDefinition בהערות שלו, מתזמן GKE ממקם את ה-Pod רק בצומת שיכול לעמוד בדרישות הרשת. מתזמן המשימות מזהה צמתים במאגר צמתים שהוגדר בהם ממשק רשת משני נדרש. תהליך זיהוי הצומת הזה עוזר לוודא שהמתזמן מתזמן את ה-Pod בצומת שיכול להתחבר לרשת הנוספת ולקבל כתובת IP מהטווח שצוין.

בקטעים הבאים מוסבר איך להגדיר את Multus עם הפלאגינים IPVLAN ו-Whereabouts באשכול GKE.

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:

  • מפעילים את Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם כבר התקנתם את ה-CLI של gcloud, הריצו את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • מתקינים את כלי שורת הפקודה kubectl.
  • מגדירים אשכול GKE בגרסה 1.28 ואילך עם Dataplane V2,‏ IP Alias וריבוי רשתות מופעלים. הוראות מפורטות זמינות במאמר הגדרת תמיכה בריבוי רשתות עבור Pods. הפעלת ריבוי רשתות מפעילה גם את התכונות Multi-IP-Subnet ו-Persistent-IP HA Policy, שמייתרות את הצורך בהגדרה ידנית של קישוריות בין צמתים.
  • כדי להבטיח תאימות, צריך להשתמש בגרסה של Multus CNI שאושרה על ידי GKE (כמו גרסה 4.2.1).

הגדרת VPC

כדי להגדיר את הענן הווירטואלי הפרטי (VPC) לשימוש עם Multus, כולל יצירת רשת משנה לרשת של הצמתים וטווחים משניים לרשת של ה-Pod, מבצעים את השלבים הבאים:

  1. יוצרים VPC חדש או משתמשים ב-VPC קיים:

    gcloud compute networks create VPC_NAME \
    --subnet-mode=custom
    

    מחליפים את VPC_NAME בשם של ה-VPC.

  2. יוצרים רשת משנה חדשה ב-VPC:

    gcloud compute networks subnets create SUBNET_NAME \
        --range=PRIMARY_RANGE \
        --network=VPC_NAME \
        --region=REGION \
        --secondary-range=SECONDARY_RANGE_NAME=SECONDARY_RANGE_CIDR
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫SUBNET_NAME: השם של תת-הרשת החדשה.
    • ‫PRIMARY_RANGE: טווח ה-CIDR הראשי של תת-הרשת, למשל 10.0.1.0/24. הפקודה הזו משתמשת בטווח הזה לממשקי צמתים.
    • ‫VPC_NAME: השם של ה-VPC.
    • ‫REGION: האזור של רשת המשנה, למשל us-central1.
    • ‫SECONDARY_RANGE_NAME: השם של טווח כתובות ה-IP המשני של ה-Pods בתת-הרשת.
    • ‫SECONDARY_RANGE_CIDR: טווח ה-CIDR המשני של ה-Pods, למשל 172.16.1.0/24. ממשקים נוספים ב-Pods משתמשים בטווח הזה.

    הפקודה הזו יוצרת רשת משנה עם טווח CIDR ראשי לממשק צומת נוסף וטווח משני לממשקי Pod נוספים.

יצירת אשכול GKE Standard

יוצרים אשכול GKE Standard עם הפעלת רשתות מרובות:

gcloud container clusters create CLUSTER_NAME \
    --cluster-version=CLUSTER_VERSION \
    --enable-dataplane-v2 \
    --enable-ip-alias \
    --enable-multi-networking

מחליפים את מה שכתוב בשדות הבאים:

  • ‫CLUSTER_NAME: השם של האשכול החדש.
  • ‫CLUSTER_VERSION: הגרסה של אשכול GKE. צריך להשתמש בגרסה 1.28 ואילך.

הפעלת ריבוי רשתות מאפשרת ליצור מאגרי צמתים עם כמה ממשקי רשת, שנדרשים ל-Multus CNI.

יצירת מאגר צמתים ב-GKE Standard

יוצרים מאגר צמתים של GKE Standard שמחובר לרשתות VPC נוספות:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster CLUSTER_NAME \
    --zone "ZONE" \
    --additional-node-network network=VPC_NAME,subnetwork=SUBNET_NAME \
    --additional-pod-network subnetwork=SUBNET_NAME,pod-ipv4-range=SECONDARY_RANGE_NAME,max-pods-per-node=8

מחליפים את מה שכתוב בשדות הבאים:

  • ‫NODEPOOL_NAME: השם של מאגר הצמתים החדש.
  • ‫CLUSTER_NAME: שם האשכול.
  • ‫ZONE: האזור של מאגר הצמתים, למשל us-central1-c.
  • ‫VPC_NAME: השם של ה-VPC הנוסף.
  • ‫SUBNET_NAME: שם תת-הרשת.
  • ‫SECONDARY_RANGE_NAME: השם של טווח כתובות ה-IP המשני של Pods ברשת המשנה.

הפקודה הזו יוצרת מאגר צמתים שבו לצמתים יש ממשק רשת נוסף ב-SUBNET_NAME, ו-Pods בצמתים האלה יכולים להשתמש בכתובות IP מ-SECONDARY_RANGE_NAME. אפשר גם לציין פרמטר stack-type (תצוגה מקדימה) לדגל --additional-node-network. מידע נוסף זמין במאמר בנושא הגדרת תמיכה בריבוי רשתות עבור Pods.

מידע נוסף על יצירת אשכולות GKE עם יכולות של ריבוי רשתות זמין במאמר הגדרת תמיכה בריבוי רשתות עבור pods.

החלת הפריסה של Multus

כדי להפעיל כמה ממשקי רשת לפודים, צריך להתקין את הפלאגין Multus CNI. שומרים את המניפסט הבא, שכולל את DaemonSet הנדרש ואת Custom Resource Definition (CRD), בשם multus-manifest.yaml:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: ippools.whereabouts.cni.cncf.io
spec:
  group: whereabouts.cni.cncf.io
  names:
    kind: IPPool
    listKind: IPPoolList
    plural: ippools
    singular: ippool
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        description: IPPool is the Schema for the ippools API
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
                of an object. Servers should convert recognized schemas to the latest
                internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
                object represents. Servers may infer this from the endpoint the client
                submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: IPPoolSpec defines the desired state of IPPool
            properties:
              allocations:
                additionalProperties:
                  description: IPAllocation represents metadata about the pod/container
                    owner of a specific IP
                  properties:
                    id:
                      type: string
                    podref:
                      type: string
                  required:
                  - id
                  type: object
                description: Allocations is the set of allocated IPs for the given
                  range. Its indices are a direct mapping to the IP with the same
                  index/offset for the pools range.
                type: object
              range:
                description: Range is a RFC 4632/4291-style string that represents
                  an IP address and prefix length in CIDR notation
                type: string
            required:
            - allocations
            - range
            type: object
        type: object
    served: true
    storage: true
status:
  acceptedNames:
    kind: ""
    plural: ""
  conditions: []
  storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.4.1
  name: overlappingrangeipreservations.whereabouts.cni.cncf.io
spec:
  group: whereabouts.cni.cncf.io
  names:
    kind: OverlappingRangeIPReservation
    listKind: OverlappingRangeIPReservationList
    plural: overlappingrangeipreservations
    singular: overlappingrangeipreservation
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        description: OverlappingRangeIPReservation is the Schema for the OverlappingRangeIPReservations
          API
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: OverlappingRangeIPReservationSpec defines the desired state
              of OverlappingRangeIPReservation
            properties:
              containerid:
                type: string
              podref:
                type: string
            required:
            - containerid
            type: object
        required:
        - spec
        type: object
    served: true
    storage: true
status:
  acceptedNames:
    kind: ""
    plural: ""
  conditions: []
  storedVersions: []
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: multus-cni-config
  namespace: kube-system
  labels:
    app: gke-multinet
data:
  cni-conf.json: |
    {
      "name": "multus-cni-network",
      "type": "multus",
      "confDir": "/etc/cni/net.d",
      "namespaceIsolation": true,
      "logLevel": "verbose",
      "logFile": "/var/log/multus.log",
      "kubeconfig": "/var/lib/kubelet/kubeconfig",
      "clusterNetwork": "gke-pod-network"
    }
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: network-attachment-definitions.k8s.cni.cncf.io
spec:
  group: k8s.cni.cncf.io
  scope: Namespaced
  names:
    plural: network-attachment-definitions
    singular: network-attachment-definition
    kind: NetworkAttachmentDefinition
    shortNames:
    - net-attach-def
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        description: 'NetworkAttachmentDefinition is a CRD schema specified by the Network Plumbing
            Working Group to express the intent for attaching pods to one or more logical or physical
            networks. More information available at: https://github.com/k8snetworkplumbingwg/multi-net-spec'
        type: object
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this represen
                tation of an object. Servers should convert recognized schemas to the
                latest internal value, and may reject unrecognized values. More info:
                https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
                object represents. Servers may infer this from the endpoint the client
                submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: 'NetworkAttachmentDefinition spec defines the desired state of a network attachment'
            type: object
            properties:
              config:
                description: 'NetworkAttachmentDefinition config is a JSON-formatted CNI configuration'
                type: string
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: multus-role
rules:
- apiGroups: ["k8s.cni.cncf.io"]
  resources:
  - '*'
  verbs:
  - '*'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: whereabouts
rules:
- apiGroups:
  - whereabouts.cni.cncf.io
  resources:
  - ippools
  - overlappingrangeipreservations
  verbs:
  - get
  - list
  - watch
  - create
  - update
  - patch
  - delete
- apiGroups:
  - coordination.k8s.io
  resources:
  - leases
  verbs:
  - create
- apiGroups:
  - coordination.k8s.io
  resources:
  - leases
  resourceNames:
  - whereabouts
  verbs:
  - '*'
- apiGroups: [""]
  resources:
  - pods
  verbs:
  - list
  - get
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: multus-role-binding
subjects:
- kind: Group
  name: system:nodes
roleRef:
  kind: ClusterRole
  name: multus-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: whereabouts-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: whereabouts
subjects:
- kind: ServiceAccount
  name: whereabouts-sa
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: whereabouts-sa
  namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: gke-multinet
  namespace: kube-system
  labels:
    app: gke-multinet
spec:
  selector:
    matchLabels:
      app: gke-multinet
  template:
    metadata:
      labels:
        app: gke-multinet
    spec:
      priorityClassName: system-node-critical
      hostNetwork: true
      tolerations:
      - operator: Exists
      serviceAccountName: whereabouts-sa
      containers:
      - name: whereabouts-gc
        command: [/ip-control-loop]
        args:
        - "--log-level=debug"
        - "--enable-pod-watch=false"
        - "--cron-schedule=* * * * *"
        image: gcr.io/gke-release/whereabouts:v0.7.0-gke.3@sha256:2bb8450a99d86c73b262f5ccd8c433d3e3abf17d36ee5c3bf1056a1fe479e8c2
        env:
        - name: NODENAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName
        - name: WHEREABOUTS_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
      initContainers:
      - name: install-multus-config
        image: gcr.io/gke-release/multus-cni:v4.2.1-gke.6@sha256:25b48b8dbbf6c78a10452836f52dee456514783565b70633a168a39e6d322310
        args:
        - "--cni-conf-dir=/host/etc/cni/net.d"
        - "--multus-conf-file=/tmp/multus-conf/00-multus.conf"
        - "--multus-log-level=verbose"
        - "--multus-kubeconfig-file-host=/var/lib/kubelet/kubeconfig"
        - "--skip-multus-binary-copy=true"
        - "--skip-config-watch=true"
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: true
        volumeMounts:
        - name: cni
          mountPath: /host/etc/cni/net.d
        - name: multus-cfg
          mountPath: /tmp/multus-conf
      - name: install-whereabouts
        command: ["/bin/sh"]
        args:
        - -c
        - >
          SLEEP=false /install-cni.sh
        image: gcr.io/gke-release/whereabouts:v0.7.0-gke.3@sha256:2bb8450a99d86c73b262f5ccd8c433d3e3abf17d36ee5c3bf1056a1fe479e8c2
        env:
        - name: NODENAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName
        - name: WHEREABOUTS_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: true
        volumeMounts:
        - name: cni
          mountPath: /host/etc/cni/net.d
        - name: cnibin
          mountPath: /host/opt/cni/bin
      - name: install-binary
        image: gcr.io/gke-release/multus-cni:v4.2.1-gke.6@sha256:25b48b8dbbf6c78a10452836f52dee456514783565b70633a168a39e6d322310
        command: ["/gkecmd"]
        args:
        - "-operation=copy"
        - "-cni-bin-dir=/host/opt/cni/bin"
        resources:
          requests:
            cpu: "10m"
            memory: "100Mi"
          limits:
            cpu: "10m"
            memory: "100Mi"
        securityContext:
          privileged: true
        volumeMounts:
        - name: cnibin
          mountPath: /host/opt/cni/bin
      volumes:
      - hostPath:
          path: /var/lib/kubelet/kubeconfig
          type: File
        name: kubelet-credentials
      - name: cni
        hostPath:
          path: /etc/cni/net.d
          type: DirectoryOrCreate
      - name: cnibin
        hostPath:
          path: /home/kubernetes/bin
          type: DirectoryOrCreate
      - name: multus-cfg
        configMap:
          name: multus-cni-config
          items:
          - key: cni-conf.json
            path: 00-multus.conf
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 2
    type: RollingUpdate

לאחר מכן, מחילים את המניפסט על האשכול:

kubectl apply -f multus-manifest.yaml

יצירת מניפסט של NetworkAttachmentDefinition

כדי לאפשר ל-Pods להתחבר לרשתות נוספות, צריך ליצור NetworkAttachmentDefinition manifest. המניפסט הזה מגדיר איך רכיבי ה-Pod מתחברים לרשת ומציין את טווח כתובות ה-IP שמוקצה על ידי פלאגין IPAM, כמו Whereabouts. הטווח הזה חייב להיות חלק מרשת המשנה שמחברת את ממשקי הרשת הנוספים של הצמתים.

  1. שומרים את המניפסט הזה בתור nad.yaml. במניפסט הזה נעשה שימוש בתוספים IPVLAN ו-Whereabouts.

    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: NAD_NAME
    spec:
      config: '{
        "cniVersion": "0.3.1",
        "plugins": [
          {
            "type": "ipvlan",
            "master": "eth1",
            "mode": "l2",
            "ipam": {
              "type": "whereabouts",
              "range": SECONDARY_RANGE_NAME
            }
          }
        ]
      }'
    

    המניפסט כולל את השדות הבאים:

    • ‫NAD_NAME: השם של NetworkAttachmentDefinition.
    • ‫master: השם של ממשק הרשת המשני של הצומת, שמשמש כממשק master עבור IPVLAN. ב-GKE, ממשקי רשת משניים מתחילים בדרך כלל ב-eth1 והשמות שלהם הם רציפים. כדי לוודא מהו שם הממשק, מתחברים לצומת באמצעות SSH ומריצים את הפקודה ip addr.
    • ‫range: טווח כתובות ה-IP של הממשקים של ה-Pod, שהוא זהה לטווח המשני של כתובות IPv4 שיצרתם עבור ה-Pods ‏ (SECONDARY_RANGE_NAME). לדוגמה, 172.16.1.0/24.
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f nad.yaml
    

צירוף של Pod לרשתות נוספות

כדי לצרף Pod לרשת נוספת, מוסיפים את ההערה k8s.v1.cni.cncf.io/networks למניפסט של ה-Pod. אם יש כמה רשתות, צריך לספק רשימה מופרדת בפסיקים של שמות NetworkAttachmentDefinition בפורמט הבא: <namespace>/<nad-name>.

בדוגמה הבאה מוצג מניפסט של Pod שמצורף ל-NetworkAttachmentDefinition בשם NAD_NAME במרחב השמות default:

apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: default/NAD_NAME
spec:
  containers:
  - name: sample-container
    image: nginx

מחליפים את NAD_NAME בשם של NetworkAttachmentDefinition שיצרתם.

כשמחילים את המניפסט הזה, Kubernetes יוצר את ה-Pod עם ממשק רשת נוסף (net1) שמחובר לרשת שצוינה ב-NetworkAttachmentDefinition.

אימות כתובת ה-IP הנוספת של ה-Pod

כדי לוודא שה-Pod מקבל כתובת IP נוספת אחרי שמחברים אותו לרשת נוספת, בודקים את ממשקי הרשת בתוך ה-Pod:

  1. כדי לבדוק את samplepod ולאמת את כתובת ה-IP הנוספת, משתמשים בפקודה הבאה:

    $kubectl describe pod PODNAME
    

    מחליפים את PODNAME בשם של ה-Pod, למשל samplepod.

  2. בודקים את הפלט. בממשק eth0 מופיעה כתובת ה-IP הראשית של ה-Pod. הפלאגין Whereabouts מקצה את כתובת ה-IP הנוספת לממשק אחר, כמו net1.

    הפלט אמור להיראות כך:

    k8s.v1.cni.cncf.io/network-status:
      [{
        "name": "gke-pod-network",
        "interface": "eth0",
        "ips": [
          "10.104.3.4"
        ],
        "mac": "ea:e2:f6:ce:18:b5",
        "default": true,
        "dns": {},
        "gateway": [
          "\u003cnil\u003e"
        ]
      },{
        "name": "default/my-nad",
        "interface": "net1",
        "ips": [
          "10.200.1.1"
        ],
        "mac": "42:01:64:c8:c8:07",
        "dns": {}
      }]
    k8s.v1.cni.cncf.io/networks: default/my-nad
    

    בדוגמה הזו, 10.104.5.19 היא כתובת ה-IP הראשית ב-eth0, ו-10.200.1.1 היא כתובת ה-IP הנוספת ב-net1.

המאמרים הבאים