国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

這篇具有很好參考價(jià)值的文章主要介紹了Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

Submariner 是一個(gè)完全開源的項(xiàng)目,可以幫助我們?cè)诓煌?Kubernetes 集群之間(無論是在本地還是云端)實(shí)現(xiàn)網(wǎng)絡(luò)通信。Submariner 有以下功能:

  • 跨集群的 L3 連接
  • 跨集群的服務(wù)發(fā)現(xiàn)
  • Globalnet 支持 CIDR 重疊
  • 提供命令行工具 subctl 簡(jiǎn)化部署和管理
  • 兼容各種 CNI

1 Submariner 架構(gòu)

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

Submariner 由幾個(gè)主要部分組成:

  • Broker: 本質(zhì)上是兩個(gè)用于交換集群信息的 CRD(EndpointCluster),我們需要選擇一個(gè)集群作為 Broker 集群,其他集群連接到 Broker 集群的 API Server 來交換集群信息:
    • Endpoint:包含了 Gateway Engine 建立集群間連接需要的信息,例如 Private IP 和 Public IP,NAT 端口等等。
    • Cluster:包含原始集群的靜態(tài)信息,例如其 Service 和 Pod CIDR。
  • Gateway Engine:管理連接到其他集群的隧道。
  • Route Agent:負(fù)責(zé)將跨集群的流量路由到 active Gateway Node。
  • Service Discovery: 提供跨集群的 DNS 服務(wù)發(fā)現(xiàn)。
  • Globalnet(可選):處理具有重疊 CIDR 的集群互連。
  • Submariner Operator:負(fù)責(zé)在 Kubernetes 集群中安裝 Submariner 組件,例如 Broker, Gateway Engine, Route Agent 等等。

1.1 Service Discovery

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹
Submariner 中跨集群的 DNS 服務(wù)發(fā)現(xiàn)由以下兩個(gè)組件基于 Kubernetes?Multi-Cluster Service APIs 的規(guī)范來實(shí)現(xiàn):

  • Lighthouse Agent:訪問 Broker 集群的 API Server 與其他集群交換 ServiceImport 元數(shù)據(jù)信息。
    • 對(duì)于本地集群中已創(chuàng)建 ServiceExport 的每個(gè) Service,Agent 創(chuàng)建相應(yīng)的 ServiceImport 資源并將其導(dǎo)出到 Broker 以供其他集群使用。
    • 對(duì)于從其他集群導(dǎo)出到 Broker 中的 ServiceImport 資源,它會(huì)在本集群中創(chuàng)建它的副本。
  • Lighthouse DNS Server
    • Lighthouse DNS Server 根據(jù) ServiceImport 資源進(jìn)行 DNS 解析。
    • CoreDNS 配置為將?clusterset.local?域名的解析請(qǐng)求發(fā)往 Lighthouse DNS server。

MCS API 是 Kubernetes 社區(qū)定義的用于跨集群服務(wù)發(fā)現(xiàn)的規(guī)范,主要包含了 ServiceExport 和 ServiceImport 兩個(gè) CRD。

  • ServiceExport?定義了暴露(導(dǎo)出)到其他集群的 Service,由用戶在要導(dǎo)出的 Service 所在的集群中創(chuàng)建,與 Service 的名字和 Namespace 一致。
apiVersion: multicluster.k8s.io/v1alpha1
kind: ServiceExport
metadata:
  name: my-svc
  namespace: my-ns
  • ServiceImport:當(dāng)一個(gè)服務(wù)被導(dǎo)出后,實(shí)現(xiàn) MCS API 的控制器會(huì)在所有集群(包括導(dǎo)出服務(wù)的集群)中自動(dòng)生成一個(gè)與之對(duì)應(yīng)的 ServiceImport 資源。
apiVersion: multicluster.k8s.io/v1alpha1
kind: ServiceImport
metadata:
  name: my-svc
  namespace: my-ns
spec:
  ips:
  - 42.42.42.42 # 跨集群訪問的 IP 地址
  type: "ClusterSetIP"
  ports:
  - name: http
    protocol: TCP
    port: 80
  sessionAffinity: None

1.2 Gateway Engine

Gateway Engine 部署在每個(gè)集群中,負(fù)責(zé)建立到其他集群的隧道。隧道可以由以下方式實(shí)現(xiàn):

  • IPsec,使用 Libreswan 實(shí)現(xiàn)。這是當(dāng)前的默認(rèn)設(shè)置。
  • WireGuard,使用 wgctrl 庫(kù)實(shí)現(xiàn)。
  • VXLAN,不加密。

可以在使用 subctl join 命令加入集群的時(shí)候使用 --cable-driver 參數(shù)設(shè)置隧道的類型。

Gateway Engine 部署為 DaemonSet,只在有 submariner.io/gateway=true Label 的 Node 上運(yùn)行,當(dāng)我們使用 subctl join 命令加入集群的時(shí)候,如果沒有 Node 有該 Label,會(huì)提示我們選擇一個(gè) Node 作為 Gateway Node。

Submariner 也支持 active/passive 高可用模式的 Gateway Engine,我們可以在多個(gè)節(jié)點(diǎn)上部署 Gateway Engine。在同一時(shí)間內(nèi),只能有一個(gè) Gateway Engine 處于 active 狀態(tài)來處理跨集的流量,Gateway Engine 通過領(lǐng)導(dǎo)者選舉的方式確定 active 的實(shí)例,其他實(shí)例在 passive 模式下等待,準(zhǔn)備在 active 實(shí)例發(fā)生故障時(shí)接管。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

1.3 Globalnet

Submariner 的一大亮點(diǎn)是支持在不同集群間存在 CIDR 重疊的情況,這有助于減少網(wǎng)絡(luò)重構(gòu)的成本。例如,在部署過程中,某些集群可能使用了默認(rèn)的網(wǎng)段,導(dǎo)致了 CIDR 重疊。在這種情況下,如果后續(xù)需要更改集群網(wǎng)段,可能會(huì)對(duì)集群的運(yùn)行產(chǎn)生影響。

為了支持集群間重疊 CIDR 的情況,Submariner 通過一個(gè) GlobalCIDR 網(wǎng)段(默認(rèn)是 242.0.0.0/8)在流量進(jìn)出集群時(shí)進(jìn)行 NAT 轉(zhuǎn)換,所有的地址轉(zhuǎn)換都發(fā)生在 active Gateway Node 上。在 subctl deploy 部署 Broker 的時(shí)候可以通過 --globalnet-cidr-range 參數(shù)指定所有集群的全局 GlobalCIDR。在 subctl join 加入集群的時(shí)候還可以通過 --globalnet-cidr 參數(shù)指定該集群的 GlobalCIDR。

導(dǎo)出的 ClusterIP 類型的 Service 會(huì)從 GlobalCIDR 分配一個(gè) Global IP 用于入向流量,對(duì)于 Headless 類型的 Service,會(huì)為每個(gè)關(guān)聯(lián)的 Pod 分配一個(gè) Global IP 用于入向和出向流量。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

2 環(huán)境準(zhǔn)備

在本次實(shí)驗(yàn)中,我們使用一臺(tái)運(yùn)行 Ubuntu 20.04 的虛擬機(jī),并通過 Kind 啟動(dòng)多個(gè) Kubernetes 集群來進(jìn)行測(cè)試。

root@seven-demo:~# seven-demo
   Static hostname: seven-demo
         Icon name: computer-vm
           Chassis: vm
        Machine ID: f780bfec3c409135b11d1ceac73e2293
           Boot ID: e83e9a883800480f86d37189bdb09628
    Virtualization: kvm
  Operating System: Ubuntu 20.04.5 LTS
            Kernel: Linux 5.15.0-1030-gcp
      Architecture: x86-64

安裝相關(guān)軟件和命令行工具。

# 安裝 Docker,根據(jù)操作系統(tǒng)安裝 https://docs.docker.com/engine/install/ 
sudo apt-get update
sudo apt-get install -y \
    ca-certificates \
    curl \
    gnupg
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 安裝 Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.18.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

# 安裝 kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
mv kubectl /usr/local/bin
apt install -y bash-completion
echo 'source <(kubectl completion bash)' >>~/.bashrc

# 安裝 subctl
curl -Lo subctl-release-0.14-linux-amd64.tar.xz https://github.com/submariner-io/subctl/releases/download/subctl-release-0.14/subctl-release-0.14-linux-amd64.tar.xz
tar -xf subctl-release-0.14-linux-amd64.tar.xz
mv subctl-release-0.14/subctl-release-0.14-linux-amd64 /usr/local/bin/subctl
chmod +x /usr/local/bin/subctl

3 快速開始

3.1 創(chuàng)建集群

使用 Kind 創(chuàng)建一個(gè) 3 節(jié)點(diǎn)的集群,這里讀者需要將 SERVER_IP 替換成自己服務(wù)器的 IP。默認(rèn)情況下,Kind 將 Kubernetes API 服務(wù)器 IP:Port 設(shè)置為本地環(huán)回地址 (?127.0.0.1): 隨機(jī)端口,這對(duì)于從本機(jī)與集群交互來說很好,但是在本實(shí)驗(yàn)中多個(gè) Kind 集群之間需要通信,因此我們需要把 Kind 的 apiServerAddress 改成本機(jī) IP。

# 替換成服務(wù)器 IP
export SERVER_IP="10.138.0.11"

kind create cluster --config - <<EOF
kind: Cluster
name: broker
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
networking:
  apiServerAddress: $SERVER_IP
  podSubnet: "10.7.0.0/16"
  serviceSubnet: "10.77.0.0/16"
EOF

kind create cluster --config - <<EOF
kind: Cluster
name: c1
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
networking:
  apiServerAddress: $SERVER_IP
  podSubnet: "10.8.0.0/16"
  serviceSubnet: "10.88.0.0/16"
EOF
 
kind create cluster --config - <<EOF
kind: Cluster
name: c2
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
networking:
  apiServerAddress: $SERVER_IP
  podSubnet: "10.9.0.0/16"
  serviceSubnet: "10.99.0.0/16"
EOF

3.2 部署 Broker

在本次實(shí)驗(yàn)中,我們專門將一個(gè)集群配置為 Broker 集群。Broker 集群可以是專用集群,也可以是連接的集群之一。執(zhí)行 subctl deploy-broker 命令部署 Broker,Broker 只包含了一組 CRD,并沒有部署 Pod 或者 Service。

subctl --context kind-broker deploy-broker

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

部署完成后,會(huì)生成 broker-info.subm 文件,文件以 Base64 加密,其中包含了連接 Broker 集群 API Server 的地址以及證書信息,還有 IPsec 的密鑰信息。

{
  "brokerURL": "https://10.138.0.11:45681",
  "ClientToken": {
    "metadata": {
      "name": "submariner-k8s-broker-admin-token-f7b62",
      "namespace": "submariner-k8s-broker",
      "uid": "3f949d19-4f42-43d6-af1c-382b53f83d8a",
      "resourceVersion": "688",
      "creationTimestamp": "2023-04-05T02:50:02Z",
      "annotations": {
        "kubernetes.io/created-by": "subctl",
        "kubernetes.io/service-account.name": "submariner-k8s-broker-admin",
        "kubernetes.io/service-account.uid": "da6eeba1-b707-4d30-8e1e-e414e9eae817"
      },
      "managedFields": [
        {
          "manager": "kube-controller-manager",
          "operation": "Update",
          "apiVersion": "v1",
          "time": "2023-04-05T02:50:02Z",
          "fieldsType": "FieldsV1",
          "fieldsV1": {
            "f:data": {
              ".": {},
              "f:ca.crt": {},
              "f:namespace": {},
              "f:token": {}
            },
            "f:metadata": {
              "f:annotations": {
                "f:kubernetes.io/service-account.uid": {}
              }
            }
          }
        },
        {
          "manager": "subctl",
          "operation": "Update",
          "apiVersion": "v1",
          "time": "2023-04-05T02:50:02Z",
          "fieldsType": "FieldsV1",
          "fieldsV1": {
            "f:metadata": {
              "f:annotations": {
                ".": {},
                "f:kubernetes.io/created-by": {},
                "f:kubernetes.io/service-account.name": {}
              }
            },
            "f:type": {}
          }
        }
      ]
    },
    "data": {
      "ca.crt": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EUXdOVEF5TkRVMU1Wb1hEVE16TURRd01qQXlORFUxTVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSytXCmIzb0h1ZEJlbU5tSWFBNXQrWmI3TFhKNXRLWDB6QVc5a0tudjQzaGpoTE84NHlSaEpyY3ZSK29QVnNaUUJIclkKc01tRmx3aVltbU5ORzA4c2NLMTlyLzV0VkdFR2hCckdML3VKcTIybXZtYi80aHdwdmRTQjN0UDlkU2RzYUFyRwpYYllwOE4vUmlheUJvbTBJVy9aQjNvZ0MwK0tNcWM0NE1MYnBkZXViWnNSckErN2pwTElYczE3OGgxb25kdGNrClIrYlRnNGpjeS92NTkrbGJjamZSeTczbUllMm9DbVFIbE1XUFpSTkMveDhaTktGekl6UHc4SmZSOERjWk5Xc1YKa1NBUVNVUkpnTEhBbjY5MlhDSEsybmJuN21pcjYvYVZzVVpyTGdVNC9zcWg3QVFBdDFGQkk3NDRpcithTjVxSwpJRnRJenkxU3p2ZEpwMThza3EwQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZFQUhFbndHditwTXNVcHVQRXNqbkQwTEgvSFpNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQTFGckk1cGR1VTFsQzluVldNNwowYlc2VFRXdzYwUTlFVWdsRzc4bkRFZkNKb3ovY2xWclFNWGZrc2Zjc1VvcHZsaE5yWFlpbmd0UEE4aEMrTnRJCmdPZElDZDJGaWFOTjRCYkt3a1NmRkQvbmhjWDU1WmQ0UzN1SzZqb2JWVHIzaXVJRVhIdHg0WVIyS1ZuZitTMDUKQTFtbXdzSG1ZbkhtWEllOUEyL3hKdVhtSnNybWljWTlhMXhtSXVyYzhNalBsa1pZWVU1OFBvZHJFNi9XcnBaawpBbW9qcERIWWIrbnZxa0FuaG9hYUV3b2FEVGxYRjY0M3lVLy9MZE4wTmw5MWkvSHNwQ2tZdVFrQjJmQXNkSGNaCkMrdzQ4WVhYT21pSzZXcmJGYVJnaEVKdjB6UjdsZk50UEVZVWJHWEFxV0ZlSnFTdnM5aUYwbFV1NzZDNkt3YWIKbmdnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==",
      "namespace": "c3VibWFyaW5lci1rOHMtYnJva2Vy",
      "token": "ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklqaHZWVnBuZVVoZk1uVTFjSEJxU1hOdE1UTk1NbUY0TFRaSlIyVlZVRGd4VjI1dmMyNXBNMjFYZFhjaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUp6ZFdKdFlYSnBibVZ5TFdzNGN5MWljbTlyWlhJaUxDSnJkV0psY201bGRHVnpMbWx2TDNObGNuWnBZMlZoWTJOdmRXNTBMM05sWTNKbGRDNXVZVzFsSWpvaWMzVmliV0Z5YVc1bGNpMXJPSE10WW5KdmEyVnlMV0ZrYldsdUxYUnZhMlZ1TFdZM1lqWXlJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpYSjJhV05sTFdGalkyOTFiblF1Ym1GdFpTSTZJbk4xWW0xaGNtbHVaWEl0YXpoekxXSnliMnRsY2kxaFpHMXBiaUlzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG5WcFpDSTZJbVJoTm1WbFltRXhMV0kzTURjdE5HUXpNQzA0WlRGbExXVTBNVFJsT1dWaFpUZ3hOeUlzSW5OMVlpSTZJbk41YzNSbGJUcHpaWEoyYVdObFlXTmpiM1Z1ZERwemRXSnRZWEpwYm1WeUxXczRjeTFpY205clpYSTZjM1ZpYldGeWFXNWxjaTFyT0hNdFluSnZhMlZ5TFdGa2JXbHVJbjAub1JHM2d6Wno4MGVYQXk5YlZ5b1V2NmoyTERvdFJiNlJyOTF4d0ZiTDMwdFNJY3dnS3FYd3NZbVV1THhtcFdBb2M5LWRSMldHY0ZLYklORlZmUUttdVJMY2JsenlTUFFVMlB3WVVwN1oyNnlxYXFOMG1UQ3ZNWWxSeHp6cWY3LXlXUm8yNE9pWS1nMnNmNmNrRzRPMkdwa2MwTlNoOWRTUGY4dXJTbjZSVGJwbjFtcFZjTy1IQjJWeU5hTE9EdmtWS3RLVFJfVS1ZRGc1NzVtczM0OXM0X2xMZjljZjlvcjFaQXVvXzcyN0E5U0VvZ0JkN3BaSndwb0FEUHZRb1NGR0VLQWZYYTFXXzJWVE5PYXE4cUQxOENVbXVFRUFxMmtoNElBN0d5LVRGdUV2Q0JYUVlzRHYzUFJQTjZpOGlKSFBLVUN1WVNONS1NT3lGX19aNS1WdlhR"
    },
    "type": "kubernetes.io/service-account-token"
  },
  "IPSecPSK": {
    "metadata": {
      "name": "submariner-ipsec-psk",
      "creationTimestamp": null
    },
    "data": {
      "psk": "NL7dUK+RagDKPQZZj+7Q7wComj0/wLFbfvnHe12hHxR8+d/FnkEqXfmh8JMzLo6h"
    }
  },
  "ServiceDiscovery": true,
  "Components": [
    "service-discovery",
    "connectivity"
  ],
  "CustomDomains": null
}

3.3 c1, c2 加入集群

執(zhí)行 subctl join 命令將 c1 和 c2 兩個(gè)集群加入 Broker 集群。使用 --clusterid 參數(shù)指定集群 ID,每個(gè)集群 ID 需要唯一。提供上一步生成的 broker-info.subm 文件用于集群注冊(cè)。

subctl --context kind-c1 join broker-info.subm --clusterid c1
subctl --context kind-c2 join broker-info.subm --clusterid c2

會(huì)提示我們選擇一個(gè)節(jié)點(diǎn)作為 Gateway Node,c1 集群選擇 c1-worker 節(jié)點(diǎn)作為 Gateway,c2 集群選擇 c2-worker 節(jié)點(diǎn)作為 Gateway。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

兩個(gè) Gateway Node 的 IP 地址如下,之后會(huì)分別使用這兩個(gè)地址在兩個(gè)集群間建立隧道連接。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

3.4 查看集群連接

等待 c1 和 c2 集群中 Submariner 的相關(guān)組件都運(yùn)行成功后,執(zhí)行以下命令查看集群間連接情況。

subctl show connections --context kind-c1
subctl show connections --context kind-c2

可以看到 c1 和 c2 集群分別和對(duì)方建立的連接。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

查看 c1 gateway 日志,可以看到成功與 c2 集群建立了 IPsec 隧道。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

3.5 測(cè)試跨集群通信

至此,我們已經(jīng)成功在 c1 和 c2 集群間建立了跨集群的連接,接下來我們將創(chuàng)建服務(wù)并演示如何將其導(dǎo)出給其他集群進(jìn)行訪問。

在下面的示例中,我們?cè)?sample Namespace 中創(chuàng)建相關(guān)資源。請(qǐng)注意,必須在兩個(gè)集群中都創(chuàng)建 sample 命名空間,服務(wù)發(fā)現(xiàn)才能正常工作。

kubectl --context kind-c2 create namespace sample
# 需要確保 c1 集群上也有 sample Namespace,否則 Lighthouse agent 創(chuàng)建 Endpointslices 會(huì)失敗
kubectl --context kind-c1 create namespace sample
3.5.1 ClusterIP Service

首先測(cè)試 ClusterIP 類型的 Service。執(zhí)行以下命令在 c2 集群創(chuàng)建服務(wù)。本實(shí)驗(yàn)中 whereami 是一個(gè)用 Golang 編寫的 HTTP Server,它通過 Downward API 將 Kubernetes 的相關(guān)信息(Pod 名字,Pod 所在的 Namespace,Node)注入到容器的環(huán)境變量中,當(dāng)接收到請(qǐng)求時(shí)進(jìn)行輸出。另外 whereami 還會(huì)打印請(qǐng)求方的 IP 地址和端口信息。

kubectl --context kind-c2 apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whereami
  namespace: sample
spec:
  replicas: 3
  selector:
    matchLabels:
      app: whereami
  template:
    metadata:
      labels:
        app: whereami
    spec:
      containers:
      - name: whereami
        image: cr7258/whereami:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:
  name: whereami-cs
  namespace: sample
spec:
  selector:
    app: whereami
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
EOF

在 c2 集群查看服務(wù)。

root@seven-demo:~# kubectl --context kind-c2 get pod -n sample -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP          NODE        NOMINATED NODE   READINESS GATES
whereami-754776cdc9-28kgd   1/1     Running   0          19h   10.9.1.18   c2-control-plane   <none>           <none>
whereami-754776cdc9-8ccmc   1/1     Running   0          19h   10.9.1.17   c2-control-plane   <none>           <none>
whereami-754776cdc9-dlp55   1/1     Running   0          19h   10.9.1.16   c2-control-plane   <none>           <none>
root@seven-demo:~# kubectl --context kind-c2 get svc -n sample -o wide
NAME          TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
whereami-cs   ClusterIP   10.99.2.201   <none>        80/TCP    19h   app=whereami

在 c2 集群中使用 subctl export 命令將服務(wù)導(dǎo)出。

subctl --context kind-c2 export service --namespace sample whereami-cs

該命令會(huì)在創(chuàng)建一個(gè)和 Service 相同名字和 Namespace 的 ServiceExport 資源。

root@seven-demo:~# kubectl  get serviceexports --context kind-c2 -n sample whereami-cs -o yaml
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceExport
metadata:
  creationTimestamp: "2023-04-06T13:04:15Z"
  generation: 1
  name: whereami-cs
  namespace: sample
  resourceVersion: "327707"
  uid: d1da8953-3fa5-4635-a8bb-6de4cd3c45a9
status:
  conditions:
  - lastTransitionTime: "2023-04-06T13:04:15Z"
    message: ""
    reason: ""
    status: "True"
    type: Valid
  - lastTransitionTime: "2023-04-06T13:04:15Z"
    message: ServiceImport was successfully synced to the broker
    reason: ""
    status: "True"
    type: Synced

ServiceImport 資源會(huì)由 Submariner 自動(dòng)在 c1,c2 集群中創(chuàng)建,IP 地址是 Service 的 ClusterIP 地址。

kubectl --context kind-c1 get -n submariner-operator serviceimport
kubectl --context kind-c2 get -n submariner-operator serviceimport

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

在 c1 集群創(chuàng)建一個(gè) client Pod 來訪問 c2 集群的 whereami 服務(wù)。

kubectl --context kind-c1 run client --image=cr7258/nettool:v1
kubectl --context kind-c1 exec -it client -- bash

先嘗試下 DNS 解析,ClusterIP Service 類型的 Service 可以通過以下格式進(jìn)行訪問 <svc-name>.<namespace>.svc.clusterset.local

nslookup whereami-cs.sample.svc.clusterset.local

返回的 IP 是在 c2 集群 Service 的 ClusterIP 的地址。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

我們查看一下 CoreDNS 的配置文件,這個(gè) Configmap 會(huì)被 Submariner Operator 修改,將 clusterset.local 用于跨集群通信的域名交給 Lighthouse DNS 來解析。

root@seven-demo:~# kubectl get cm -n kube-system coredns -oyaml
apiVersion: v1
data:
  Corefile: |+
    #lighthouse-start AUTO-GENERATED SECTION. DO NOT EDIT
    clusterset.local:53 {
        forward . 10.88.78.89
    }
    #lighthouse-end
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }

kind: ConfigMap
metadata:
  creationTimestamp: "2023-04-05T02:47:34Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "1211"
  uid: 698f20a5-83ea-4a3e-8a1e-8b9438a6b3f8

Submariner 遵循以下邏輯來進(jìn)行跨集群集的服務(wù)發(fā)現(xiàn):

  • 如果導(dǎo)出的服務(wù)在本地集群中不可用,Lighthouse DNS 從服務(wù)導(dǎo)出的遠(yuǎn)程集群之一返回 ClusterIP 服務(wù)的 IP 地址。
  • 如果導(dǎo)出的服務(wù)在本地集群中可用,Lighthouse DNS 總是返回本地 ClusterIP 服務(wù)的 IP 地址。
  • 如果多個(gè)集群從同一個(gè)命名空間導(dǎo)出具有相同名稱的服務(wù),Lighthouse DNS 會(huì)以輪詢的方式在集群之間進(jìn)行負(fù)載均衡。
  • 可以在 DNS 查詢前加上 cluster-id 前綴來訪問特定集群的服務(wù),<cluster-id>.<svc-name>.<namespace>.svc.clusterset.local。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

通過 curl 命令發(fā)起 HTTP 請(qǐng)求。

curl whereami-cs.sample.svc.clusterset.local

返回結(jié)果如下,我們根據(jù)輸出的 node_name 字段可以確認(rèn)該 Pod 是在 c2 集群。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

這里結(jié)合下圖對(duì)流量進(jìn)行簡(jiǎn)單的說明:流量從 c1 集群的 client Pod 發(fā)出,首先經(jīng)過 veth-pair 到達(dá) Node 的 Root Network Namespace,然后經(jīng)過 Submariner Route Agent 設(shè)置的 vx-submariner 這個(gè) VXLAN 隧道將流量發(fā)往 Gateway Node 上(c1-worker)。接著經(jīng)過連接 c1 和 c2 集群的 IPsec 隧道到達(dá)對(duì)端,c2 集群的 Gateway Node(c2-worker)接收到流量后將,經(jīng)過 iptables 的反向代理規(guī)則(在這過程中根據(jù) ClusterIP 進(jìn)行了 DNAT)最終發(fā)送到后端的 whereami Pod 上。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

接下來我們?cè)?c1 集群也創(chuàng)建相同的服務(wù)。

kubectl --context kind-c1 apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whereami
  namespace: sample
spec:
  replicas: 3
  selector:
    matchLabels:
      app: whereami
  template:
    metadata:
      labels:
        app: whereami
    spec:
      containers:
      - name: whereami
        image: cr7258/whereami:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:
  name: whereami-cs
  namespace: sample
spec:
  selector:
    app: whereami
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
EOF

在 c1 集群上查看服務(wù)。

root@seven-demo:~# kubectl --context kind-c1 get pod -n sample -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP          NODE        NOMINATED NODE   READINESS GATES
whereami-754776cdc9-hq4m2   1/1     Running   0          45s   10.8.1.25   c1-worker   <none>           <none>
whereami-754776cdc9-rt84w   1/1     Running   0          45s   10.8.1.23   c1-worker   <none>           <none>
whereami-754776cdc9-v5zrk   1/1     Running   0          45s   10.8.1.24   c1-worker   <none>           <none>
root@seven-demo:~# kubectl --context kind-c1 get svc -n sample
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
whereami-cs   ClusterIP   10.88.132.102   <none>        80/TCP    50s

在 c1 集群導(dǎo)出服務(wù)。

subctl --context kind-c1 export service --namespace sample whereami-cs

查看 ServiceImport。

kubectl --context kind-c1 get -n submariner-operator serviceimport
kubectl --context kind-c2 get -n submariner-operator serviceimport

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

由于在 c1 集群本地也有相同的服務(wù),因此這次請(qǐng)求將會(huì)發(fā)給 c1 集群的服務(wù)。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

kubectl --context kind-c1 exec -it client -- bash
nslookup whereami-cs.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

curl whereami-cs.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

我們也可以通過 <cluster-id>.<svc-name>.<namespace>.svc.clusterset.local 來指定訪問訪問特定集群的 ClusterIP Service。例如我們指定訪問 c2 集群的 Service。

curl c2.whereami-cs.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

3.5.2 Headless Service + StatefulSet

Submariner 還支持帶有 StatefulSets 的 Headless Services,從而可以通過穩(wěn)定的 DNS 名稱訪問各個(gè) Pod。在單個(gè)集群中,Kubernetes 通過引入穩(wěn)定的 Pod ID 來支持這一點(diǎn),在單個(gè)集群中可以通過 <pod-name>.<svc-name>.<ns>.svc.cluster.local 格式來解析域名。跨集群場(chǎng)景下,Submariner 通過 <pod-name>.<cluster-id>.<svc-name>.<ns>.svc.clusterset.local 的格式來解析域名。

在 c2 集群創(chuàng)建 Headless Service 和 StatefulSet。

kubectl --context kind-c2 apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
 name: whereami-ss
 namespace: sample
 labels:
   app: whereami-ss
spec:
 ports:
 - port: 80
   name: whereami
 clusterIP: None
 selector:
   app: whereami-ss
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: whereami
 namespace: sample
spec:
 serviceName: "whereami-ss"
 replicas: 3
 selector:
   matchLabels:
       app: whereami-ss
 template:
   metadata:
     labels:
       app: whereami-ss
   spec:
     containers:
     - name: whereami-ss
       image: cr7258/whereami:v1
       ports:
       - containerPort: 80
         name: whereami
       env:
       - name: NAMESPACE
         valueFrom:
           fieldRef:
             fieldPath: metadata.namespace
       - name: NODE_NAME
         valueFrom:
           fieldRef:
             fieldPath: spec.nodeName
       - name: POD_NAME
         valueFrom:
           fieldRef:
             fieldPath: metadata.name
       - name: POD_IP
         valueFrom:
          fieldRef:
             fieldPath: status.podIP
EOF

在 c2 集群查看服務(wù)。

root@seven-demo:~# kubectl get pod -n sample --context kind-c2 -o wide -l app=whereami-ss
NAME                        READY   STATUS    RESTARTS   AGE   IP          NODE        NOMINATED NODE   READINESS GATES
whereami-0                  1/1     Running   0          38s   10.9.1.20   c2-control-plane   <none>           <none>
whereami-1                  1/1     Running   0          36s   10.9.1.21   c2-control-plane    <none>           <none>
whereami-2                  1/1     Running   0          31s   10.9.1.22   c2-control-plane    <none>           <none>
root@seven-demo:~# kubectl get svc -n sample --context kind-c2 -l app=whereami-ss
NAME          TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
whereami-ss   ClusterIP   None          <none>        80/TCP    4m58s

在 c2 集群導(dǎo)出服務(wù)。

subctl --context kind-c2 export service whereami-ss --namespace sample 

解析 Headless Service 的域名可以得到所有 Pod 的 IP。

kubectl --context kind-c1 exec -it client -- bash
nslookup whereami-ss.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

也可以指定單個(gè) Pod 進(jìn)行解析。

nslookup whereami-0.c2.whereami-ss.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

通過域名訪問指定的 Pod。

curl whereami-0.c2.whereami-ss.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

查看 ServiceImport,在 IP 地址的一欄是空的,因?yàn)閷?dǎo)出的服務(wù)類型是 Headless。

kubectl --context kind-c1 get -n submariner-operator serviceimport
kubectl --context kind-c2 get -n submariner-operator serviceimport

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

對(duì)于 Headless Service,Pod IP 是根據(jù) Endpointslice 來解析的。

kubectl --context kind-c1 get endpointslices -n sample
kubectl --context kind-c2 get endpointslices -n sample

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

4 使用 Globalnet 解決 CIDR 重疊問題

接下來將演示如何通過 Submariner 的 Globalnet 功能來解決多集群間 CIDR 重疊的問題,在本實(shí)驗(yàn)中,我們將會(huì)創(chuàng)建 3 個(gè)集群,并且將每個(gè)集群的 Service 和 Pod CIDR 都設(shè)置成相同的。

4.1 創(chuàng)建集群

# 替換成服務(wù)器 IP
export SERVER_IP="10.138.0.11"

kind create cluster --config - <<EOF
kind: Cluster
name: broker-globalnet
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
networking:
  apiServerAddress: $SERVER_IP
  podSubnet: "10.7.0.0/16"
  serviceSubnet: "10.77.0.0/16"
EOF

kind create cluster --config - <<EOF
kind: Cluster
name: g1
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
networking:
  apiServerAddress: $SERVER_IP
  podSubnet: "10.7.0.0/16"
  serviceSubnet: "10.77.0.0/16"
EOF
 
kind create cluster --config - <<EOF
kind: Cluster
name: g2
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
networking:
  apiServerAddress: $SERVER_IP
  podSubnet: "10.7.0.0/16"
  serviceSubnet: "10.77.0.0/16"
EOF

4.2 部署 Broker

使用 --globalnet=true 參數(shù)啟用 Globalnet 功能,使用 --globalnet-cidr-range 參數(shù)指定所有集群的全局 GlobalCIDR(默認(rèn) 242.0.0.0/8)。

subctl --context kind-broker-globalnet deploy-broker --globalnet=true --globalnet-cidr-range 120.0.0.0/8

4.3 g1, g2 加入集群

使用 --globalnet-cidr 參數(shù)指定本集群的 GlobalCIDR。

subctl --context kind-g1 join broker-info.subm --clusterid g1 --globalnet-cidr 120.1.0.0/24
subctl --context kind-g2 join broker-info.subm --clusterid g2 --globalnet-cidr 120.2.0.0/24

4.4 查看集群連接

subctl show connections --context kind-g1
subctl show connections --context kind-g2

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

4.5 測(cè)試跨集群通信

在兩個(gè)集群中都創(chuàng)建 sample 命名空間。

kubectl --context kind-g2 create namespace sample
kubectl --context kind-g1 create namespace sample
4.5.1 ClusterIP Service

在 g2 集群創(chuàng)建服務(wù)。

kubectl --context kind-g2 apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whereami
  namespace: sample
spec:
  replicas: 3
  selector:
    matchLabels:
      app: whereami
  template:
    metadata:
      labels:
        app: whereami
    spec:
      containers:
      - name: whereami
        image: cr7258/whereami:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:
  name: whereami-cs
  namespace: sample
spec:
  selector:
    app: whereami
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
EOF

在 g2 集群查看服務(wù)。

root@seven-demo:~/globalnet# kubectl --context kind-g2 get pod -n sample -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP         NODE        NOMINATED NODE   READINESS GATES
whereami-754776cdc9-72qd4   1/1     Running   0          19s   10.7.1.8   g2-control-plane    <none>           <none>
whereami-754776cdc9-jsnhk   1/1     Running   0          20s   10.7.1.7   g2-control-plane    <none>           <none>
whereami-754776cdc9-n4mm6   1/1     Running   0          19s   10.7.1.9   g2-control-plane    <none>           <none>
root@seven-demo:~/globalnet# kubectl --context kind-g2 get svc -n sample -o wide
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE   SELECTOR
whereami-cs   ClusterIP   10.77.153.172   <none>        80/TCP    26s   app=whereami

在 g2 集群導(dǎo)出服務(wù)。

subctl --context kind-g2 export service --namespace sample whereami-cs

導(dǎo)出服務(wù)后,我們?cè)俨榭匆幌?g2 集群的 Service,會(huì)發(fā)現(xiàn) Submariner 自動(dòng)在與導(dǎo)出的服務(wù)相同的命名空間中創(chuàng)建了一個(gè)額外的服務(wù),并且設(shè)置 externalIPs 為分配給相應(yīng)服務(wù)的 Global IP。

kubectl --context kind-g2 get svc -n sample

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

在g1 集群訪問 g2 集群的 whereami 服務(wù)。

kubectl --context kind-g1 run client --image=cr7258/nettool:v1
kubectl --context kind-g1 exec -it client -- bash

DNS 將會(huì)解析到分配給 c2 集群 whereami 服務(wù)的 Global IP 地址,而不是服務(wù)的 ClusterIP IP 地址。

nslookup whereami-cs.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

用 curl 命令發(fā)起 HTTP 請(qǐng)求,從輸出的結(jié)果可以發(fā)現(xiàn),在 g2 集群的 whereami 看來,請(qǐng)求的源 IP 是 120.1.0.5,也就是說當(dāng)流量從 g1 發(fā)往 g2 集群時(shí),在 g1 集群的 Gateway Node 上對(duì)流量進(jìn)行了 SNAT 源地址轉(zhuǎn)換。

curl whereami-cs.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

這里結(jié)合下圖對(duì)流量進(jìn)行簡(jiǎn)單的說明:流量從 c1 集群的 client Pod 發(fā)出,經(jīng)過 DNS 解析后應(yīng)該請(qǐng)求 IP 120.2.0.253。首先經(jīng)過 veth-pair 到達(dá) Node 的 Root Network Namespace,然后經(jīng)過 Submariner Route Agent 設(shè)置的 vx-submariner 這個(gè) VXLAN 隧道將流量發(fā)往 Gateway Node 上(c1-worker)。在 Gateway Node 上將源 IP 10.7.1.7 轉(zhuǎn)換成了 120.1.0.5, 然后通過 c1 和 c2 集群的 IPsec 隧道發(fā)送到對(duì)端,c2 集群的 Gateway Node(c2-worker)接收到流量后,經(jīng)過 iptables 的反向代理規(guī)則(在這過程中根據(jù) Global IP 進(jìn)行了 DNAT)最終發(fā)送到后端的 whereami Pod 上。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

我們可以分別查看 g1 和 g2 集群上 Gateway Node 的 Iptables 來驗(yàn)證 NAT 規(guī)則,首先執(zhí)行 docker exec -it g1-worker bashdocker exec -it g2-worker bash 進(jìn)入這兩個(gè)節(jié)點(diǎn),然后執(zhí)行 iptables-save 命令可以看到 iptables 配置,以下我篩選了相關(guān)的 iptables 配置。

g1-worker 節(jié)點(diǎn):

# 在出訪的時(shí)候?qū)⒃?IP 轉(zhuǎn)換為 120.1.0.1-120.1.0.8 中的一個(gè)
-A SM-GN-EGRESS-CLUSTER -s 10.7.0.0/16 -m mark --mark 0xc0000/0xc0000 -j SNAT --to-source 120.1.0.1-120.1.0.8

g2-worker 節(jié)點(diǎn):

# 訪問 120.2.0.253:80 的流量跳轉(zhuǎn)到 KUBE-EXT-ZTP7SBVPSRVMWSUN 鏈
-A KUBE-SERVICES -d 120.2.0.253/32 -p tcp -m comment --comment "sample/submariner-fzpkhsc5wssywpk5x3par6ceb6b2jinr external IP" -m tcp --dport 80 -j KUBE-EXT-ZTP7SBVPSRVMWSUN

# 跳轉(zhuǎn)到 KUBE-SVC-ZTP7SBVPSRVMWSUN 鏈
-A KUBE-EXT-ZTP7SBVPSRVMWSUN -j KUBE-SVC-ZTP7SBVPSRVMWSUN

# 隨機(jī)選擇 whereami 后端的一個(gè) Pod
-A KUBE-SVC-ZTP7SBVPSRVMWSUN -m comment --comment "sample/submariner-fzpkhsc5wssywpk5x3par6ceb6b2jinr -> 10.7.1.7:80" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-BB74OZOLBDYS7GHU

-A KUBE-SVC-ZTP7SBVPSRVMWSUN -m comment --comment "sample/submariner-fzpkhsc5wssywpk5x3par6ceb6b2jinr -> 10.7.1.8:80" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-MTZHPN36KRSHGEO6

-A KUBE-SVC-ZTP7SBVPSRVMWSUN -m comment --comment "sample/submariner-fzpkhsc5wssywpk5x3par6ceb6b2jinr -> 10.7.1.9:80" -j KUBE-SEP-UYVYXWJKZN2VHFJW

# DNAT 地址轉(zhuǎn)換
-A KUBE-SEP-BB74OZOLBDYS7GHU -p tcp -m comment --comment "sample/submariner-fzpkhsc5wssywpk5x3par6ceb6b2jinr" -m tcp -j DNAT --to-destination 10.7.1.7:80

-A KUBE-SEP-MTZHPN36KRSHGEO6 -p tcp -m comment --comment "sample/submariner-fzpkhsc5wssywpk5x3par6ceb6b2jinr" -m tcp -j DNAT --to-destination 10.7.1.8:80

-A KUBE-SEP-UYVYXWJKZN2VHFJW -p tcp -m comment --comment "sample/submariner-fzpkhsc5wssywpk5x3par6ceb6b2jinr" -m tcp -j DNAT --to-destination 10.7.1.9:80
4.5.2 Headless Service + StatefulSet

接下來測(cè)試 Globalnet 在 Headless Service + StatefulSet 場(chǎng)景下的應(yīng)用。在 g2 集群創(chuàng)建服務(wù)。

kubectl --context kind-g2 apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
 name: whereami-ss
 namespace: sample
 labels:
   app: whereami-ss
spec:
 ports:
 - port: 80
   name: whereami
 clusterIP: None
 selector:
   app: whereami-ss
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: whereami
 namespace: sample
spec:
 serviceName: "whereami-ss"
 replicas: 3
 selector:
   matchLabels:
       app: whereami-ss
 template:
   metadata:
     labels:
       app: whereami-ss
   spec:
     containers:
     - name: whereami-ss
       image: cr7258/whereami:v1
       ports:
       - containerPort: 80
         name: whereami
       env:
       - name: NAMESPACE
         valueFrom:
           fieldRef:
             fieldPath: metadata.namespace
       - name: NODE_NAME
         valueFrom:
           fieldRef:
             fieldPath: spec.nodeName
       - name: POD_NAME
         valueFrom:
           fieldRef:
             fieldPath: metadata.name
       - name: POD_IP
         valueFrom:
          fieldRef:
             fieldPath: status.podIP
EOF

在 g2 集群查看服務(wù)。

root@seven-demo:~# kubectl get pod -n sample --context kind-g2 -o wide -l app=whereami-ss
NAME         READY   STATUS    RESTARTS   AGE   IP          NODE        NOMINATED NODE   READINESS GATES
whereami-0   1/1     Running   0          62s   10.7.1.10   g2-worker   <none>           <none>
whereami-1   1/1     Running   0          56s   10.7.1.11   g2-worker   <none>           <none>
whereami-2   1/1     Running   0          51s   10.7.1.12   g2-worker   <none>           <none>
root@seven-demo:~# kubectl get svc -n sample --context kind-c2 -l app=whereami-ss
NAME          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
whereami-ss   ClusterIP   None         <none>        80/TCP    42h

在 g2 集群導(dǎo)出服務(wù)。

subctl --context kind-g2 export service whereami-ss --namespace sample 

在 g1 集群訪問 g2 集群服務(wù),Globalnet 會(huì)為每一個(gè) Headless Service 關(guān)聯(lián)的 Pod 分配一個(gè) Global IP,用于出向和入向的流量。

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

kubectl --context kind-g1 exec -it client -- bash
nslookup whereami-ss.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

指定解析某個(gè) Pod。

nslookup whereami-0.g2.whereami-ss.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

指定訪問某個(gè) Pod。

curl whereami-0.g2.whereami-ss.sample.svc.clusterset.local

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

查看 ServiceImport,在 IP 地址的一欄是空的,因?yàn)閷?dǎo)出的服務(wù)類型是 Headless。

kubectl --context kind-g1 get -n submariner-operator serviceimport
kubectl --context kind-g2 get -n submariner-operator serviceimport

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

對(duì)于 Headless Service,Pod IP 是根據(jù) Endpointslice 來解析的。

kubectl --context kind-g1 get endpointslices -n sample
kubectl --context kind-g2 get endpointslices -n sample

Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹

執(zhí)行 docker exec -it g2-worker bash 命令進(jìn)入 g2-worker 節(jié)點(diǎn),然后執(zhí)行 iptables-save 命令尋找相關(guān)的 Iptables 規(guī)則。

# SNAT
-A SM-GN-EGRESS-HDLS-PODS -s 10.7.1.12/32 -m mark --mark 0xc0000/0xc0000 -j SNAT --to-source 120.2.0.252

-A SM-GN-EGRESS-HDLS-PODS -s 10.7.1.11/32 -m mark --mark 0xc0000/0xc0000 -j SNAT --to-source 120.2.0.251

-A SM-GN-EGRESS-HDLS-PODS -s 10.7.1.10/32 -m mark --mark 0xc0000/0xc0000 -j SNAT --to-source 120.2.0.250

# DNAT
-A SUBMARINER-GN-INGRESS -d 120.2.0.252/32 -j DNAT --to-destination 10.7.1.12

-A SUBMARINER-GN-INGRESS -d 120.2.0.251/32 -j DNAT --to-destination 10.7.1.11

-A SUBMARINER-GN-INGRESS -d 120.2.0.250/32 -j DNAT --to-destination 10.7.1.10

5 清理環(huán)境

執(zhí)行以下命令刪除本次實(shí)驗(yàn)創(chuàng)建的 Kind 集群。

kind delete clusters broker c1 c2 g1 g2

6 總結(jié)

本文首先介紹了 Submariner 的架構(gòu),包括 Broker、Gateway Engine、Route Agent、Service Discovery、Globalnet 和 Submariner Operator。接著,通過實(shí)驗(yàn)向讀者展示了 Submariner 在跨集群場(chǎng)景中如何處理 ClusterIP 和 Headless 類型的流量。最后,演示了 Submariner 的 Globalnet 是如何通過 GlobalCIDR 支持不同集群間存在 CIDR 重疊的情況。文章來源地址http://www.zghlxwxcb.cn/news/detail-411362.html

7 歡迎關(guān)注

到了這里,關(guān)于Kubernetes 多集群網(wǎng)絡(luò)方案系列 1 -- Submariner 介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 一、Kubernetes介紹與集群架構(gòu)

    docker machine 主要用于準(zhǔn)備docker host 現(xiàn)已棄用 建議使用docker desktop docker compose Compose 是一個(gè)用于定義和運(yùn)行多容器 Docker 應(yīng)用程序的工具。 使用 Compose,您可以使用 YAML 文件來配置應(yīng)用程序的服務(wù)。 使用一個(gè)命令,您可以從您的配置中創(chuàng)建并啟動(dòng)所有服務(wù)。 docker swarm 內(nèi)置于d

    2024年02月13日
    瀏覽(23)
  • 【kubernetes】集群架構(gòu)介紹與基礎(chǔ)環(huán)境準(zhǔn)備

    【kubernetes】集群架構(gòu)介紹與基礎(chǔ)環(huán)境準(zhǔn)備

    前言 :二進(jìn)制部署kubernetes集群在企業(yè)應(yīng)用中扮演著非常重要的角色。無論是集群升級(jí),還是證書設(shè)置有效期都非常方便,也是從事云原生相關(guān)工作從入門到精通不得不邁過的坎。通過本系列文章,你將從虛擬機(jī)準(zhǔn)備開始,到使用二進(jìn)制方式從零到一搭建起安全穩(wěn)定的高可用

    2024年02月10日
    瀏覽(23)
  • 【云原生|探索 Kubernetes 系列 6】從 0 到 1,輕松搭建完整的 Kubernetes 集群

    【云原生|探索 Kubernetes 系列 6】從 0 到 1,輕松搭建完整的 Kubernetes 集群

    大家好,我是秋意零。 前面一篇中,我們介紹了 kubeadm 的工作流程。那么今天我們就實(shí)際操作一下,探索如何快速、高效地從 0 開始搭建一個(gè)完整的 Kubernetes 集群,讓你輕松駕馭容器化技術(shù)的力量?。??? 簡(jiǎn)介 ?? 個(gè)人主頁 : 秋意零 ?? 個(gè)人介紹 :在校期間參與眾多云計(jì)算

    2024年02月07日
    瀏覽(22)
  • 【云原生 | Kubernetes 系列】— Kubernetes存儲(chǔ)方案

    目錄 【云原生 | Kubernetes 系列】— Kubernetes存儲(chǔ)方案 ?? 一、基本存儲(chǔ) EmptyDir HostPath NFS 搭建nfs服務(wù)器 ?? 二、高級(jí)存儲(chǔ) PV和PVC pv pvc 演示 -NFS StorageClass(動(dòng)態(tài)存儲(chǔ)) StorageClass準(zhǔn)備 創(chuàng)建deployment應(yīng)用StorageClass 創(chuàng)建StatefulSet應(yīng)用StorageClass ??三、配置存儲(chǔ) ConfigMap ConfigMap 的創(chuàng)建

    2024年02月03日
    瀏覽(24)
  • 【探索 Kubernetes|集群搭建篇 系列 5】簡(jiǎn)化 Kubernetes 的部署,深入解析其工作流程

    【探索 Kubernetes|集群搭建篇 系列 5】簡(jiǎn)化 Kubernetes 的部署,深入解析其工作流程

    大家好,我是秋意零。 在前面 4 個(gè)章節(jié)中,我們充分了解了容器技術(shù)和 Kubernes 原生時(shí)代引擎的架構(gòu)和設(shè)計(jì)思想,今天分享的主要內(nèi)容是,探索 Kubernetes 部署,深入解析其工作流程 ?? 簡(jiǎn)介 ?? 個(gè)人主頁 : 秋意零 ?? 個(gè)人介紹 :在校期間參與眾多云計(jì)算相關(guān)比賽,如:??

    2024年02月08日
    瀏覽(28)
  • 【kubernetes系列】kubernetes之基礎(chǔ)組件高可用方案

    從前面的基礎(chǔ)章節(jié)了解到,kubernetes的mastere節(jié)點(diǎn)基礎(chǔ)組件大致包括kube-apiserver、kube-controller-manager、kube-scheduler,還有一個(gè)重要的數(shù)據(jù)存儲(chǔ)服務(wù)etcd。這些主件作為master節(jié)點(diǎn)的服務(wù)相當(dāng)重要,很多時(shí)候我們都需要保證其高可用。下面將分享在實(shí)際工作中的一些常見做法。 在使用私

    2024年02月16日
    瀏覽(21)
  • Kubernetes系列-部署pod到集群中的指定node

    Kubernetes系列-部署pod到集群中的指定node

    集群只有兩個(gè)節(jié)點(diǎn),這里打算將應(yīng)用部署在k8s-node2節(jié)點(diǎn)上,需要先記下這個(gè)節(jié)點(diǎn)的名稱:k8s-node2。 k8s編排文件中指定nodeName,只需這一行配置 完整配置如下:? 以上這段配置部署了一個(gè)Go服務(wù),指定節(jié)點(diǎn)在k8s-node2,并且限制了資源,同時(shí)暴露了一個(gè)30091外部訪問端口,看下服

    2024年02月06日
    瀏覽(17)
  • (【云原生 | Kubernetes 系列】— Kubernetes 1.28 存儲(chǔ)方案)

    EmptyDir 用途: 1: 緩存空間,例如基于磁盤的歸并排序。 2: 為耗時(shí)較長(zhǎng)的計(jì)算任務(wù)提供檢查點(diǎn),以便任務(wù)能方便地從崩潰前狀態(tài)恢復(fù)執(zhí)行。 3: 在 Web 服務(wù)器容器服務(wù)數(shù)據(jù)時(shí),保存內(nèi)容管理器容器獲取的文件。 HostPath 例如,hostPath 的一些用法有: 運(yùn)行一個(gè)需要訪問 Docker 內(nèi)部機(jī)

    2024年02月02日
    瀏覽(28)
  • Kubernetes系列-容器狀態(tài)介紹

    目錄 1. 概述 2. 狀態(tài)定義 Kubernetes 會(huì)跟蹤 Pod 中每個(gè)容器的狀態(tài),就像它跟蹤 Pod 總體上的階段一樣。 可以使用容器生命周期回調(diào)?來在容器生命周期中的特定時(shí)間點(diǎn)觸發(fā)事件。 一旦調(diào)度器將 Pod 分派給某個(gè)節(jié)點(diǎn),kubelet?就通過?容器運(yùn)行時(shí)?開始為 Pod 創(chuàng)建容器。 容器的狀態(tài)有

    2024年02月14日
    瀏覽(18)
  • Kubernetes 集群calico網(wǎng)絡(luò)故障排查思路

    報(bào)錯(cuò) calico/node is not ready: BIRD is not ready: BGP not established with 172.16.0.20,172.16.0.30 訪問k8s的dashboard界面無法訪問網(wǎng)站,查看pod,未知原因?qū)е耤alico的Pod資源重新創(chuàng)建后無法啟動(dòng),顯示的是0/1狀態(tài)? Calico的Pod報(bào)錯(cuò)內(nèi)容 原因:calico沒有發(fā)現(xiàn)實(shí)node節(jié)點(diǎn)實(shí)際的網(wǎng)卡名稱 解決方法 調(diào)整cal

    2024年02月07日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包