<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在 K8s 中部署企業(yè)級(jí)發(fā)布訂閱消息系統(tǒng) Apache Pulsar

          共 29889字,需瀏覽 60分鐘

           ·

          2022-01-14 22:22


          時(shí)間過得比較久了,在開始今天的學(xué)習(xí)之前先回顧一下前面已經(jīng)學(xué)習(xí)的 13 節(jié)的內(nèi)容。

          階段復(fù)習(xí)

          Pulsar 是一個(gè)支持多租戶的、高性能的、分布式的 Pub-Sub 消息系統(tǒng)。

          • 了解 Pulsar 的架構(gòu)。Pulsar 提供了一個(gè)比 Cluster 更高級(jí)別的抽象 Instance。
            • 一個(gè) Pulsar Instance 由多個(gè) Pulsar Cluster 組成
            • 一個(gè) Instance 中的 Cluster 之間可以相互跨地域復(fù)制數(shù)據(jù)
          • 單個(gè) Pulsar 集群由以下部分組成:
            • Pulsar Proxy: 是無狀態(tài)的,Proxy 作為集群的智能路由層,是負(fù)責(zé) Pulsar 客戶端與 Pulsar 集群交互的統(tǒng)一網(wǎng)關(guān)
            • Pulsar Brokers: 也是無狀態(tài)的,是集群的服務(wù)層,Proxy 會(huì)將客戶端的訪問請求轉(zhuǎn)發(fā)到正確的 Broker 上。Broker 作為服務(wù)層與 Pulsar 的存儲(chǔ)層進(jìn)行交互
            • Bookies: 一個(gè)集群有多個(gè) Bookie 節(jié)點(diǎn)(組成 Bookeeper 集群)負(fù)責(zé)消息的持久化存儲(chǔ)
            • Zookeeper: 用于集群級(jí)別的配置和協(xié)調(diào),并存儲(chǔ) Pulsar 集群的所有元數(shù)據(jù)
          • 以 docker 容器運(yùn)行單機(jī) Pulsar
            • 學(xué)習(xí)使用命令行工具pulsar-admin創(chuàng)建 tenant、namespace、topic
            • 了解 Pulsar Admin REST API
          • tenant、namespace、topic 的基本概念
            • Pulsar 基于租戶、命名空間、主題的邏輯層次結(jié)構(gòu)支持多租戶
            • 分區(qū) Topic 的概念
            • Topic URL 格式
            • 持久化 Topic 和非持久化 Topic 的概念
          • 生產(chǎn)者和消費(fèi)者、訂閱和訂閱模式
            • Pulsar 支持: exclusive(獨(dú)占), failover(故障轉(zhuǎn)移/災(zāi)備), shared(共享), key-shared(基于 key 的共享模式) 4 中訂閱模式
            • 使用命令行工具 pulsar-client 進(jìn)行生產(chǎn)者和消費(fèi)者測試
          • 使用 Pulsar Java 客戶端庫創(chuàng)建生產(chǎn)者、消費(fèi)者、Reader
            • 消費(fèi)者端可以使用"同步接收消息", “異步接收消息”, “MessageListener 接收” 3 種模式,其中 MessageListener 自帶線程池
            • 創(chuàng)建消費(fèi)者時(shí)可以設(shè)置消費(fèi)者的批量接收策略
            • 多主題訂閱: 設(shè)置單個(gè)消費(fèi)者訂閱多個(gè)主題
            • 消費(fèi)異常處理可以使用"無限重試", “捕獲并忽略異?!? “死信主題(Dead Letter Topic)“三種方式
            • 使用消息 Reader 可以由用戶自己手動(dòng)在 Topic 中定位,讀取想要讀取的消息
          • 使用 Pulsar Go 客戶端庫
            • 消費(fèi)者端支持consumer.Receive()consumer.Chan()兩種方式消費(fèi)消息。前者對 channel 關(guān)閉和 context cancel 的情況做了封裝,后者要我們自己處理和 channel 的交互,但也提供了最大的靈活性。
            • 多主題訂閱
            • 死信策略和死信主題
            • 使用消息 Reader
          • 使用 Pulsar Schema 管理消息數(shù)據(jù)的類型安全性
          • Web 圖形化管理工具 Pulsar Manager
          • 延遲消息投遞特性
            • 指定多長時(shí)間后投遞 deliverAfter
            • 指定在將來某個(gè)時(shí)間點(diǎn)投遞 deliverAt
          • 分區(qū) Topic 和路由模式
          • 認(rèn)證和授權(quán)
            • 開啟 JWT 身份認(rèn)證
            • 授權(quán)和權(quán)限管理

          前面的學(xué)習(xí)一直是基于以 docker 容器啟動(dòng)的單機(jī) Pulsar。今天將學(xué)習(xí)使用 Helm 在 Kubernetes 集群中部署 Pulsar 集群。

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

          這里使用的 Kubernetes 集群的版本是 1.22.4,Helm 的版本是 3.7.1。

          Pulsar 集群組件和 K8S Node 節(jié)點(diǎn)規(guī)劃

          下面做一下 Pulsar 集群各個(gè)組件部署節(jié)點(diǎn)的規(guī)劃。使用 Pulsar 官方的 Helm Chart 部署時(shí),可選擇部署各個(gè)組件。在后邊的配置中將禁用監(jiān)控相關(guān)的組件(promethues, grafana 等),我們這里選擇以后嘗試使用外部的全局 Prometheus 實(shí)現(xiàn)對 Pulsar 集群的監(jiān)控。

          本節(jié)選擇部署的集群組件如下:

          • proxy: 無狀態(tài), 但 pulsar 的 helm chart 使用 StatefulSet 部署
          • broker: 無狀態(tài), 但 pulsar 的 helm chart 使用 StatefulSet 部署
          • bookie: 有狀態(tài), pulsar 的 helm chart 使用 StatefulSet 部署
          • zookeeper: 有狀態(tài), pulsar 的 helm chart 使用 StatefulSet 部署
          • recovery: 無狀態(tài), 但 pulsar 的 helm chart 使用 StatefulSet 部署
          • toolset: 無狀態(tài), 但 pulsar 的 helm chart 使用 StatefulSet 部署
          • pulsar-manager: 無狀態(tài), pulsar 的 helm chart 使用 Deployment 部署

          注意, pulsar-managers 雖然是無狀態(tài)的,但因?yàn)樗枰褂?PostgreSQL 數(shù)據(jù)庫,pulsar-managers 的 docker 鏡像中內(nèi)置一個(gè) PostgreSQL, 這個(gè)我們在后邊的配置中將改為使用集群外部的 PostgreSQL。

          下面說一下以上各個(gè)組件的部署節(jié)點(diǎn)選擇。

          • 對于 proxy, broker, recovery, toolset, pulsar-manager 這 5 個(gè)無狀態(tài)組件,可以讓 k8s 將其調(diào)度到任意節(jié)點(diǎn)上。
          • 對于 bookie, zookeeper 這 2 個(gè)有狀態(tài)組件,需要我們根據(jù)其存儲(chǔ)卷的類型,將其規(guī)劃到合適的 k8s 節(jié)點(diǎn)。

          我們在線上環(huán)境對于有狀態(tài)服務(wù)的部署,在存儲(chǔ)卷的選擇上,為了更好的性能,一般都是選擇 Local Persistent Volumes 在。因此,如果你在規(guī)劃一個(gè)線上版本的 Pulsar 集群部署的話,對于 bookie 和 zookeeper 肯定需要單獨(dú)的獨(dú)立的 k8s 節(jié)點(diǎn),并使用這些節(jié)點(diǎn)上創(chuàng)建的 Local PV。例如,一個(gè)線上生產(chǎn)可用的 Pulsar 集群可能規(guī)劃如下:

          • pulsar zookeeper 集群至少需要 3 個(gè)獨(dú)立的 k8s 節(jié)點(diǎn), 在這些節(jié)點(diǎn)上創(chuàng)建 zookeeper 的 local pv
          • pulsar bookeeper 集群(bookie 節(jié)點(diǎn)組成)根據(jù)規(guī)劃的容量需要 N 個(gè)獨(dú)立的 k8s 節(jié)點(diǎn), 在這些節(jié)點(diǎn)上創(chuàng)建 bookie 的 local pv。如果后續(xù)需要擴(kuò)容增加 bookie 節(jié)點(diǎn)時(shí),只需要有新的創(chuàng)建好 local pv 的 k8s 節(jié)點(diǎn),并對 bookie 的 StatefulSet 擴(kuò)容即可。
          • pulsar proxy, broker 等無狀態(tài)服務(wù),只需要有足夠的數(shù)量的 k8s 節(jié)點(diǎn),并在需要時(shí)按需擴(kuò)容即可

          因本文這里用于實(shí)驗(yàn)的 k8s 集群資源有限,所以盡量將上面各組件在 3 個(gè) k8s 節(jié)點(diǎn)上混部,將一個(gè)用于測試環(huán)境的的 Pulsar 集群規(guī)劃如下:

          k8s 節(jié)點(diǎn)部署 pulsar 組件備注
          node1zookeeper-0, bookie-0, broker-0, proxy-0線上環(huán)境 bookie 和 zookeeper 一定要在單獨(dú)的節(jié)點(diǎn)上
          node2zookeeper-1, bookie-1, broker-1, proxy-1線上環(huán)境 bookie 和 zookeeper 一定要在單獨(dú)的節(jié)點(diǎn)上
          node3zookeeper-2, bookie-2, broker-2, proxy-2線上環(huán)境 bookie 和 zookeeper 一定要在單獨(dú)的節(jié)點(diǎn)上
          node1 或 node2 或 node3recovery-0, toolset-0, pulsar-manager

          基于上面測試環(huán)境的規(guī)劃,我們將 node1~node3 三個(gè)節(jié)點(diǎn)打上 Label 和 Taint:

          $?kubectl?label?node?node1?node-role.kubernetes.io/pulsar=pulsar
          $?kubectl?label?node?node2?node-role.kubernetes.io/pulsar=pulsar
          $?kubectl?label?node?node3?node-role.kubernetes.io/pulsar=pulsar
          $?kubectl?taint?nodes?node1?dedicated=pulsar:NoSchedule
          $?kubectl?taint?nodes?node2?dedicated=pulsar:NoSchedule
          $?kubectl?taint?nodes?node3?dedicated=pulsar:NoSchedule
          • Label node-role.kubernetes.io/pulsar=pulsar用于標(biāo)記節(jié)點(diǎn)是專門用于運(yùn)行 pulsar 集群組件的 k8s 節(jié)點(diǎn)。
          • Taint dedicated=pulsar:NoSchedule被打到節(jié)點(diǎn)上后,默認(rèn)配置下 k8s 集群中的其他不屬于 pulsar 集群組件的 pod 將不會(huì)被調(diào)度到這 3 個(gè)節(jié)點(diǎn)上,而后邊我們將要部署的 pulsar 組件上將會(huì)使用 Toleration 配置允許dedicated=pulsar:NoSchedule的 Taint。
          • 注意這里只是根據(jù)測試環(huán)境 Pulsar 集群的規(guī)劃,做了上面的 Label 和 Taint 的設(shè)置,如果是生產(chǎn)環(huán)境,這里的 Label 和 Taint 應(yīng)該做更合理和細(xì)粒度的規(guī)劃,確保實(shí)現(xiàn)上面生產(chǎn)可用 Pulsar 集群的 Node 節(jié)點(diǎn)規(guī)劃

          Pulsar 集群組件容器鏡像準(zhǔn)備

          前面我們選擇要部署 Pulsar 集群的 proxy, broker, bookie, zookeeper, recovery, toolset, pulsar-manager 7 大組件。

          其中 proxy, broker, bookie, zookeeper, recovery, toolset 的官方容器鏡像都是apachepulsar/pulsar-all[1]。pulsar-manager 的官方鏡像是apachepulsar/pulsar-manager[2]

          本文使用的 pulsar 官方的 helm chart https://github.com/apache/pulsar-helm-chart/releases。

          pulsar-helm-chart 的版本為 2.7.7,該版本中 pulsar 的版本為 2.7.4, pulsar-manager 版本為 v0.1.0:

          • apachepulsar/pulsar-all:2.7.4
          • apachepulsar/pulsar-manager:v0.1.0

          注意因?yàn)?code style="font-size: 14px;padding: 2px 5px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background: rgb(249, 242, 244);border-radius: 4px;color: rgb(21, 166, 117);">pulsar-manager:v0.1.0有這個(gè) ISSUE https://github.com/apache/pulsar-helm-chart/issues/133中描述的問題,所以在后邊的部署將鏡像pulsar-manager:v0.1.0更換成了pulsar-manager:v0.2.0。

          為了提高效率,這里將 apachepulsar/pulsar-all:2.7.4 和 apachepulsar/pulsar-manager:v0.2.0 這兩個(gè)鏡像轉(zhuǎn)存到了 k8s 集群所使用的私有鏡像倉庫中,例如:

          • harbor.example.com/library/apachepulsar/pulsar-all:2.7.4
          • harbor.example.com/library/apachepulsar/pulsar-manager:v0.2.0

          創(chuàng)建 JWT 認(rèn)證所需的 K8S Secret

          這里部署的 Pulsar 集群需要在安全上開通 JWT 認(rèn)證。根據(jù)前面學(xué)習(xí)的內(nèi)容,JWT 支持通過兩種不同的秘鑰生成和驗(yàn)證 Token:

          • 對稱秘鑰:
            • 使用單個(gè) Secret key 來生成和驗(yàn)證 Token
          • 非對稱秘鑰:包含由私鑰和公鑰組成的一對密鑰
          • 使用 Private key 生成 Token
          • 使用 Public key 驗(yàn)證 Token

          推薦使用非對稱密鑰的方式,需要先生成密鑰對,再用秘鑰生成 token。因?yàn)?Pulsar 被部署在 K8S 集群中,在 K8S 集群中存儲(chǔ)這些秘鑰和 Token 的最好的方式是使用 K8S 的 Secret。

          pulsar-helm-chart 專門提供了一個(gè)prepare_helm_release.sh腳本,可以用來生成這些 Secret。

          下面我們將 pulsar-helm-chart 的源碼 clone 到 K8S 的控制節(jié)點(diǎn)上(kubectl 和 helm 可用的節(jié)點(diǎn)):

          $?git?clone?-b?pulsar-2.7.7?--depth?1?https://github.com/apache/pulsar-helm-chart.git
          $?cd?pulsar-helm-chart/

          執(zhí)行下面的命令生成秘鑰對和 Token 的 Secret 的 Manifest:

          $?./scripts/pulsar/prepare_helm_release.sh?\
          ????-n?pulsar?\
          ????-k?pulsar?\
          ????-l

          上面的命令中:

          • -n指定的生成 Secret Manifest 中安裝的命名空間,這里我是將其部署到 K8S 中的 pulsar namespace 中,所以指定為 pulsar,當(dāng)然也可以指定部署到其他的 namespace 中。
          • -k指定的是使用 helm 部署時(shí)的 helm release 名稱,這里指定為 pulsar。
          • -l指定只將生成的內(nèi)容輸出達(dá)到本地,而不會(huì)自動(dòng)部署到 K8S 中。比較喜歡這種手動(dòng)的方式,因?yàn)橐磺斜容^可控。
          • 注意這個(gè)腳本還有一個(gè)-s,--symmetric參數(shù),如果給這個(gè)參數(shù)的話,JWT 認(rèn)證將使用對稱秘鑰的方式,這里沒有給這個(gè)參數(shù),就使用非對稱秘鑰的方式。

          執(zhí)行上面的腳本會(huì)輸出以下內(nèi)容:

          generate?the?token?keys?for?the?pulsar?cluster
          ---
          The?private?key?and?public?key?are?generated?to?...?successfully.
          apiVersion:?v1
          data:
          ??PRIVATEKEY:?<...>
          ??PUBLICKEY:?<...>
          kind:?Secret
          metadata:
          ??creationTimestamp:?null
          ??name:?pulsar-token-asymmetric-key
          ??namespace:?pulsar
          generate?the?tokens?for?the?super-users:?proxy-admin,broker-admin,admin
          generate?the?token?for?proxy-admin
          ---
          pulsar-token-asymmetric-key
          apiVersion:?v1
          data:
          ??TOKEN:?<...>
          ??TYPE:?YXN5bW1ldHJpYw==
          kind:?Secret
          metadata:
          ??creationTimestamp:?null
          ??name:?pulsar-token-proxy-admin
          ??namespace:?pulsar
          generate?the?token?for?broker-admin
          ---
          pulsar-token-asymmetric-key
          apiVersion:?v1
          data:
          ??TOKEN:?<...>
          ??TYPE:?YXN5bW1ldHJpYw==
          kind:?Secret
          metadata:
          ??creationTimestamp:?null
          ??name:?pulsar-token-broker-admin
          ??namespace:?pulsar
          generate?the?token?for?admin
          ---
          pulsar-token-asymmetric-key
          apiVersion:?v1
          data:
          ??TOKEN:??<...>
          ??TYPE:?YXN5bW1ldHJpYw==
          kind:?Secret
          metadata:
          ??creationTimestamp:?null
          ??name:?pulsar-token-admin
          ??namespace:?pulsar
          -------------------------------------

          The?jwt?token?secret?keys?are?generated?under:
          ????-?'pulsar-token-asymmetric-key'

          The?jwt?tokens?for?superusers?are?generated?and?stored?as?below:
          ????-?'proxy-admin':secret('pulsar-token-proxy-admin')
          ????-?'broker-admin':secret('pulsar-token-broker-admin')
          ????-?'admin':secret('pulsar-token-admin')

          從輸出可以看出,該腳本生成了 4 個(gè) K8S Secret 的 Manifest:

          • pulsar-token-asymmetric-key 這個(gè) Secret 中是用于生成 Token 和驗(yàn)證 Token 的私鑰和公鑰
          • pulsar-token-proxy-admin 這個(gè) Secret 中是用于 proxy 的超級(jí)用戶角色 Token
          • pulsar-token-broker-admin 這個(gè) Secret 中是用于 broker 的超級(jí)用戶角色 Token
          • pulsar-token-admin 這個(gè) Secret 中是用于管理客戶端的超級(jí)用戶角色 Token

          接下來手動(dòng)將這 4 個(gè) Secret 使用kubectl apply創(chuàng)建到 K8S 的 pulsar 命名空間中。創(chuàng)建完成后,可以使用 kubectl 找到它們:

          $?kubectl?get?secret?-n?pulsar?|?grep?pulsar-token
          pulsar-token-admin????????????????????????Opaque????????????????????2??????5m
          pulsar-token-asymmetric-key???????????????Opaque????????????????????2??????5m
          pulsar-token-broker-admin?????????????????Opaque????????????????????2??????5m
          pulsar-token-proxy-admin??????????????????Opaque????????????????????2??????5m

          創(chuàng)建 Zookeeper 和 Bookie 的 Local PV

          根據(jù)部署 Pulsar 的 K8S 節(jié)點(diǎn)的規(guī)劃,下面需要為 zookeeper, bookie 所在的節(jié)點(diǎn)在 K8S 上創(chuàng)建 Local Persistent Volume。

          注意每個(gè) zookeeper 節(jié)點(diǎn)需要一個(gè) data 的 local volume,每個(gè) bookie 節(jié)點(diǎn)需要 journal 和 ledgers 共兩個(gè) local volume。

          在創(chuàng)建 Local PV 之前,需要確認(rèn)一下 k8s 中存在 StorageClasslocal-storage,如果沒有可以使用下面的 manifest 創(chuàng)建。

          apiVersion:?storage.k8s.io/v1
          kind:?StorageClass
          metadata:
          ??name:?local-storage
          provisioner:?kubernetes.io/no-provisioner
          volumeBindingMode:?WaitForFirstConsumer
          reclaimPolicy:?Retain

          注意現(xiàn)在的 K8S 中不在直接提供 local volume 的 provisioner,這里也沒有使用 provisioner,因此后續(xù)對 local volume 的創(chuàng)建和管理都是需要 K8S 集群管理員的手動(dòng)進(jìn)行。也是說目前 Kubernetes 核心中不包含對對本地卷進(jìn)行動(dòng)態(tài)發(fā)放和管理的 provisioner,如果想要體驗(yàn)動(dòng)態(tài)發(fā)放和管理的功能,可以試一下由 Rancher 提供的Local Path Provisioner[3]

          我這里依然使用手動(dòng)管理的方式,即通過手動(dòng)在 K8S 節(jié)點(diǎn)上創(chuàng)建 Local Volume,手動(dòng)綁定 Local Volume 與 Pulsar Zookeeper 和 Bookie 的 PVC(PersistentVolumeClaim)之間的關(guān)系。

          下面,先手動(dòng)在 node1, node2, node3 上創(chuàng)建 local volume 對應(yīng)的數(shù)據(jù)目錄:

          $?mkdir?-p?/home/puslar/data/zookeeper-data
          $?mkdir?-p?/home/puslar/data/bookie-data/ledgers
          $?mkdir?-p?/home/puslar/data/bookie-data/journal

          zookeeper data 的 local pv 的 manifest 如下:

          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-zookeeper-data-pulsar-zookeeper-0
          spec:
          ??capacity:
          ????storage:?20Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/zookeeper-data
          ??claimRef:
          ????name:?pulsar-zookeeper-data-pulsar-zookeeper-0
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node1

          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-zookeeper-data-pulsar-zookeeper-1
          spec:
          ??capacity:
          ????storage:?20Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/zookeeper-data
          ??claimRef:
          ????name:?pulsar-zookeeper-data-pulsar-zookeeper-1
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node2


          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-zookeeper-data-pulsar-zookeeper-2
          spec:
          ??capacity:
          ????storage:?20Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/zookeeper-data
          ??claimRef:
          ????name:?pulsar-zookeeper-data-pulsar-zookeeper-2
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node3

          上面的 manifest 仍中將 3 個(gè) Local PV 通過nodeAffinity創(chuàng)建并關(guān)聯(lián)到到 node1~node3 上,同時(shí)使用claimRef將這 3 個(gè) Local PV 與即將在 K8S 集群中部署的 zookeeper SatefulSet 中的 PVC 綁定。使用kubectl apply創(chuàng)建上面的 manifest。

          bookie ledgers 和 journal 的 local pv 的 manifest 如下:

          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-bookie-ledgers-pulsar-bookie-0
          spec:
          ??capacity:
          ????storage:?50Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/bookie-data/ledgers
          ??claimRef:
          ????name:?pulsar-bookie-ledgers-pulsar-bookie-0
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node1
          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-bookie-journal-pulsar-bookie-0
          spec:
          ??capacity:
          ????storage:?50Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/bookie-data/journal
          ??claimRef:
          ????name:?pulsar-bookie-journal-pulsar-bookie-0
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node1



          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-bookie-ledgers-pulsar-bookie-1
          spec:
          ??capacity:
          ????storage:?50Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/bookie-data/ledgers
          ??claimRef:
          ????name:?pulsar-bookie-ledgers-pulsar-bookie-1
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node2
          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-bookie-journal-pulsar-bookie-1
          spec:
          ??capacity:
          ????storage:?50Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/bookie-data/journal
          ??claimRef:
          ????name:?pulsar-bookie-journal-pulsar-bookie-1
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node2




          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-bookie-ledgers-pulsar-bookie-2
          spec:
          ??capacity:
          ????storage:?50Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/bookie-data/ledgers
          ??claimRef:
          ????name:?pulsar-bookie-ledgers-pulsar-bookie-2
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node3
          ---
          apiVersion:?v1
          kind:?PersistentVolume
          metadata:
          ??name:?pulsar-bookie-journal-pulsar-bookie-2
          spec:
          ??capacity:
          ????storage:?50Gi
          ??accessModes:
          ??-?ReadWriteOnce
          ??persistentVolumeReclaimPolicy:?Retain
          ??storageClassName:?local-storage
          ??local:
          ????path:?/home/puslar/data/bookie-data/journal
          ??claimRef:
          ????name:?pulsar-bookie-journal-pulsar-bookie-2
          ????namespace:?pulsar
          ??nodeAffinity:
          ????required:
          ??????nodeSelectorTerms:
          ??????-?matchExpressions:
          ????????-?key:?kubernetes.io/hostname
          ??????????operator:?In
          ??????????values:
          ??????????-?node3

          上面的 manifest 仍中將 6 個(gè) Local PV 通過nodeAffinity創(chuàng)建并關(guān)聯(lián)到到 node1~node3 上,同時(shí)使用claimRef將這 3 個(gè) Local PV 與即將在 K8S 集群中部署的 zookeeper SatefulSet 中的 PVC 綁定。使用kubectl apply創(chuàng)建上面的 manifest。

          準(zhǔn)備 Pulsar Manager 的 PostgreSQL 數(shù)據(jù)庫

          這里準(zhǔn)備讓 Pulsar Manager 使用外部數(shù)據(jù)庫,需要提前在外部的 PostgreSQL 中創(chuàng)建好用戶和數(shù)據(jù)庫表結(jié)構(gòu)。

          創(chuàng)建數(shù)據(jù)庫和用戶:

          CREATE?USER?pulsar_manager?WITH?PASSWORD?'';

          CREATE?DATABASE?pulsar_manager?OWNER?pulsar_manager;

          GRANT?ALL?PRIVILEGES?ON?DATABASE?pulsar_manager?to?pulsar_manager;
          GRANT?ALL?PRIVILEGES?ON?ALL?TABLES?IN?SCHEMA?pulsar_manager?TO?pulsar_manager;
          ALTER?SCHEMA?public?OWNER?to?pulsar_manager;
          GRANT?ALL?PRIVILEGES?ON?ALL?TABLES?IN?SCHEMA?public?TO?pulsar_manager;
          GRANT?ALL?PRIVILEGES?ON?ALL?SEQUENCES?IN?SCHEMA?public?TO?pulsar_manager;

          創(chuàng)建表結(jié)構(gòu)(建表腳本可以在 pulsar-manager 的鏡像中找到):

          CREATE?TABLE?IF?NOT?EXISTS?environments?(
          ??name?varchar(256)?NOT?NULL,
          ??broker?varchar(1024)?NOT?NULL,
          ??CONSTRAINT?PK_name?PRIMARY?KEY?(name),
          ??UNIQUE?(broker)
          );

          CREATE?TABLE?IF?NOT?EXISTS?topics_stats?(
          ??topic_stats_id?BIGSERIAL?PRIMARY?KEY,
          ??environment?varchar(255)?NOT?NULL,
          ??cluster?varchar(255)?NOT?NULL,
          ??broker?varchar(255)?NOT?NULL,
          ??tenant?varchar(255)?NOT?NULL,
          ??namespace?varchar(255)?NOT?NULL,
          ??bundle?varchar(255)?NOT?NULL,
          ??persistent?varchar(36)?NOT?NULL,
          ??topic?varchar(255)?NOT?NULL,
          ??producer_count?BIGINT,
          ??subscription_count?BIGINT,
          ??msg_rate_in?double?precision??,
          ??msg_throughput_in?double?precision????,
          ??msg_rate_out?double?precision?,
          ??msg_throughput_out?double?precision???,
          ??average_msg_size?double?precision?????,
          ??storage_size?double?precision?,
          ??time_stamp?BIGINT
          );

          CREATE?TABLE?IF?NOT?EXISTS?publishers_stats?(
          ??publisher_stats_id?BIGSERIAL?PRIMARY?KEY,
          ??producer_id?BIGINT,
          ??topic_stats_id?BIGINT?NOT?NULL,
          ??producer_name?varchar(255)?NOT?NULL,
          ??msg_rate_in?double?precision??,
          ??msg_throughput_in?double?precision????,
          ??average_msg_size?double?precision?????,
          ??address?varchar(255),
          ??connected_since?varchar(128),
          ??client_version?varchar(36),
          ??metadata?text,
          ??time_stamp?BIGINT,
          ??CONSTRAINT?fk_publishers_stats_topic_stats_id?FOREIGN?KEY?(topic_stats_id)?References?topics_stats(topic_stats_id)
          );

          CREATE?TABLE?IF?NOT?EXISTS?replications_stats?(
          ??replication_stats_id?BIGSERIAL?PRIMARY?KEY,
          ??topic_stats_id?BIGINT?NOT?NULL,
          ??cluster?varchar(255)?NOT?NULL,
          ??connected?BOOLEAN,
          ??msg_rate_in?double?precision??,
          ??msg_rate_out?double?precision?,
          ??msg_rate_expired?double?precision?????,
          ??msg_throughput_in?double?precision????,
          ??msg_throughput_out?double?precision???,
          ??msg_rate_redeliver?double?precision???,
          ??replication_backlog?BIGINT,
          ??replication_delay_in_seconds?BIGINT,
          ??inbound_connection?varchar(255),
          ??inbound_connected_since?varchar(255),
          ??outbound_connection?varchar(255),
          ??outbound_connected_since?varchar(255),
          ??time_stamp?BIGINT,
          ??CONSTRAINT?FK_replications_stats_topic_stats_id?FOREIGN?KEY?(topic_stats_id)?References?topics_stats(topic_stats_id)
          );

          CREATE?TABLE?IF?NOT?EXISTS?subscriptions_stats?(
          ??subscription_stats_id?BIGSERIAL?PRIMARY?KEY,
          ??topic_stats_id?BIGINT?NOT?NULL,
          ??subscription?varchar(255)?NULL,
          ??msg_backlog?BIGINT,
          ??msg_rate_expired?double?precision?????,
          ??msg_rate_out?double?precision?,
          ??msg_throughput_out?double?precision???,
          ??msg_rate_redeliver?double?precision???,
          ??number_of_entries_since_first_not_acked_message?BIGINT,
          ??total_non_contiguous_deleted_messages_range?BIGINT,
          ??subscription_type?varchar(16),
          ??blocked_subscription_on_unacked_msgs?BOOLEAN,
          ??time_stamp?BIGINT,
          ??UNIQUE?(topic_stats_id,?subscription),
          ??CONSTRAINT?FK_subscriptions_stats_topic_stats_id?FOREIGN?KEY?(topic_stats_id)?References?topics_stats(topic_stats_id)
          );

          CREATE?TABLE?IF?NOT?EXISTS?consumers_stats?(
          ??consumer_stats_id?BIGSERIAL?PRIMARY?KEY,
          ??consumer?varchar(255)?NOT?NULL,
          ??topic_stats_id?BIGINT?NOT?NUll,
          ??replication_stats_id?BIGINT,
          ??subscription_stats_id?BIGINT,
          ??address?varchar(255),
          ??available_permits?BIGINT,
          ??connected_since?varchar(255),
          ??msg_rate_out?double?precision?,
          ??msg_throughput_out?double?precision???,
          ??msg_rate_redeliver?double?precision???,
          ??client_version?varchar(36),
          ??time_stamp?BIGINT,
          ??metadata?text
          );

          CREATE?TABLE?IF?NOT?EXISTS?tokens?(
          ??token_id?BIGSERIAL?PRIMARY?KEY,
          ??role?varchar(256)?NOT?NULL,
          ??description?varchar(128),
          ??token?varchar(1024)?NOT?NUll,
          ??UNIQUE?(role)
          );

          CREATE?TABLE?IF?NOT?EXISTS?users?(
          ??user_id?BIGSERIAL?PRIMARY?KEY,
          ??access_token?varchar(256),
          ??name?varchar(256)?NOT?NULL,
          ??description?varchar(128),
          ??email?varchar(256),
          ??phone_number?varchar(48),
          ??location?varchar(256),
          ??company?varchar(256),
          ??expire?BIGINT,
          ??password?varchar(256),
          ??UNIQUE?(name)
          );

          CREATE?TABLE?IF?NOT?EXISTS?roles?(
          ??role_id?BIGSERIAL?PRIMARY?KEY,
          ??role_name?varchar(256)?NOT?NULL,
          ??role_source?varchar(256)?NOT?NULL,
          ??description?varchar(128),
          ??resource_id?BIGINT?NOT?NULL,
          ??resource_type?varchar(48)?NOT?NULL,
          ??resource_name?varchar(48)?NOT?NULL,
          ??resource_verbs?varchar(256)?NOT?NULL,
          ??flag?INT?NOT?NULL
          );

          CREATE?TABLE?IF?NOT?EXISTS?tenants?(
          ??tenant_id?BIGSERIAL?PRIMARY?KEY,
          ??tenant?varchar(255)?NOT?NULL,
          ??admin_roles?varchar(255),
          ??allowed_clusters?varchar(255),
          ??environment_name?varchar(255),
          ??UNIQUE(tenant)
          );

          CREATE?TABLE?IF?NOT?EXISTS?namespaces?(
          ??namespace_id?BIGSERIAL?PRIMARY?KEY,
          ??tenant?varchar(255)?NOT?NULL,
          ??namespace?varchar(255)?NOT?NULL,
          ??UNIQUE(tenant,?namespace)
          );

          CREATE?TABLE?IF?NOT?EXISTS?role_binding(
          ??role_binding_id?BIGSERIAL?PRIMARY?KEY,
          ??name?varchar(256)?NOT?NULL,
          ??description?varchar(256),
          ??role_id?BIGINT?NOT?NULL,
          ??user_id?BIGINT?NOT?NULL
          );

          上面已經(jīng)做好了部署的準(zhǔn)備工作,下面將使用 Helm 在 K8S 集群中部署 Pulsar 集群。

          使用 Helm 在 K8S 中部署 Pulsar

          從https://github.com/apache/pulsar-helm-chart/releases下載pulsar helm chart 2.7.7 到 K8S 的控制節(jié)點(diǎn)上(kubectl 和 helm 可用)。

          • https://github.com/apache/pulsar-helm-chart/releases/download/pulsar-2.7.7/pulsar-2.7.7.tgz

          定制編寫 helm chart 的 values.yaml

          定制編寫 helm chart 的 values.yaml 文件如下, 定制的內(nèi)容比較多,具體見下面文件的注釋:

          auth:
          ??authentication:
          ????enabled:?true??#?開啟jwt認(rèn)證
          ????provider:?"jwt"
          ????jwt:
          ??????usingSecretKey:?false?#?jwt認(rèn)證使用非對稱秘鑰對
          ??authorization:
          ????enabled:?true?#?開啟授權(quán)
          ??superUsers:
          ????#?broker?to?broker?communication
          ????broker:?"broker-admin"
          ????#?proxy?to?broker?communication
          ????proxy:?"proxy-admin"
          ????#?pulsar-admin?client?to?broker/proxy?communication
          ????client:?"admin"


          components:?#?啟用的組件
          ??autorecovery:?true
          ??bookkeeper:?true
          ??broker:?true
          ??functions:?true
          ??proxy:?true
          ??pulsar_manager:?true
          ??toolset:?true
          ??zookeeper:?true

          monitoring:?#?關(guān)閉監(jiān)控組件,?后續(xù)嘗試使用外部Prometheus對pulsar集群進(jìn)行監(jiān)控
          ??grafana:?false
          ??prometheus:?false
          ??node_exporter:?false


          volumes:
          ??local_storage:?true?#?數(shù)據(jù)卷使用local?storage



          proxy:?#?proxy的配置(這里是測試環(huán)境,?將proxy也調(diào)度到node1或node2或node3)
          ??nodeSelector:
          ????node-role.kubernetes.io/pulsar:?pulsar
          ??tolerations:
          ??-?key:?"dedicated"
          ????operator:?"Equal"
          ????value:?"pulsar"
          ????effect:?"NoSchedule"
          ??configData:
          ?????PULSAR_PREFIX_authenticateMetricsEndpoint:?"false"


          broker:?#?broker的配置(這里是測試環(huán)境,?將proxy也調(diào)度到node1或node2或node3)
          ??nodeSelector:
          ????node-role.kubernetes.io/pulsar:?pulsar
          ??tolerations:
          ??-?key:?"dedicated"
          ????operator:?"Equal"
          ????value:?"pulsar"
          ????effect:?"NoSchedule"


          zookeeper:?#?broker的配置
          ??replicaCount:?3
          ??tolerations:
          ??-?key:?"dedicated"
          ????operator:?"Equal"
          ????value:?"pulsar"
          ????effect:?"NoSchedule"
          ??volumes:
          ????data:?#?配置使用local?pv,?需要與前面手動(dòng)創(chuàng)建的local?pv信息一致
          ??????local_storage:?true
          ??????size:?20Gi


          bookkeeper:?#?bookkeeper的配置
          ??replicaCount:?3
          ??tolerations:
          ??-?key:?"dedicated"
          ????operator:?"Equal"
          ????value:?"pulsar"
          ????effect:?"NoSchedule"
          ??volumes:
          ????journal:?#?配置使用local?pv,?需要與前面手動(dòng)創(chuàng)建的local?pv信息一致
          ??????local_storage:?true
          ??????size:?50Gi
          ??ledgers:??#?配置使用local?pv,?需要與前面手動(dòng)創(chuàng)建的local?pv信息一致
          ??????local_storage:?true
          ??????size:?50Gi

          pulsar_manager:?#?pulsar_manager的配置(這里是測試環(huán)境,?將pulsar_manager也調(diào)度到node1或node2或node3)
          ??replicaCount:?1
          ??admin:
          ????#?文檔中描述這里是pulsar?manager?web界面登錄用戶密碼,但實(shí)際上當(dāng)使用外部PostgreSQL數(shù)據(jù)庫時(shí),這里需要指定PostgreSQL的數(shù)據(jù)庫和密碼,不知道是否是pulsar-helm-chart?2.7.7的問題
          ????user:?pulsar_manager
          ????password:?05aM3Braz_M4RWpn
          ??configData:
          ????DRIVER_CLASS_NAME:?org.postgresql.Driver
          ????URL:?jdbc:postgresql://:5432/pulsar_manager
          ????#?文檔中描述這里PostgreSQL數(shù)據(jù)庫的密碼,但實(shí)際上這里不能指定USERNAME和PASSWORD,?不知道是否是pulsar-helm-chart?2.7.7的問題
          ????#?USERNAME:?pulsar_manager
          ????#?PASSWORD:?05aM3Braz_M4RWpn
          ????LOG_LEVEL:?INFO
          ????##?開啟JWT認(rèn)證后,?這里需要指定pulsar-token-admin這個(gè)Secret中的JWT?Token
          ????JWT_TOKEN:??token...>


          autorecovery:?#?autorecovery的配置(這里是測試環(huán)境,?將autorecovery也調(diào)度到node1或node2或node3)
          ??replicaCount:?1
          ??nodeSelector:
          ????node-role.kubernetes.io/pulsar:?pulsar
          ??tolerations:
          ??-?key:?"dedicated"
          ????operator:?"Equal"
          ????value:?"pulsar"
          ????effect:?"NoSchedule"

          toolset:?#?toolset的配置(這里是測試環(huán)境,?將toolset也調(diào)度到node1或node2或node3)
          ??replicaCount:?1
          ??nodeSelector:
          ????node-role.kubernetes.io/pulsar:?pulsar
          ??tolerations:
          ??-?key:?"dedicated"
          ????operator:?"Equal"
          ????value:?"pulsar"
          ????effect:?"NoSchedule"


          images:?#?對個(gè)組件使用私有鏡像倉庫的配置
          ??imagePullSecrets:
          ??-?regsecret?#?私有鏡像倉庫的image?pull?secret,?需要提前在k8s命名空間中創(chuàng)建
          ??autorecovery:
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-all
          ????tag:?2.7.4
          ??bookie:
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-all
          ????tag:?2.7.4
          ??broker:
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-all
          ????tag:?2.7.4
          ??functions:
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-all
          ????tag:?2.7.4
          ??proxy:
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-all
          ????tag:?2.7.4
          ??pulsar_manager:
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-manager
          ????tag:?v0.2.0
          ??zookeeper:
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-all
          ????tag:?2.7.4

          pulsar_metadata:
          ??component:?pulsar-init
          ??image:
          ????#?the?image?used?for?running?`pulsar-cluster-initialize`?job
          ????repository:?harbor.example.com/library/apachepulsar/pulsar-all
          ????tag:?2.7.4

          因?yàn)楫?dāng)前在 pulsar-helm-chart 2.7.7 中好像不支持為 pulsar-init 設(shè)置私有倉庫的 imagePullSecret,所以下面為 pulsar namespace 中的 default servcieaccount 添加上 imagePullSecret。

          $?kubectl?patch?serviceaccount?default?-p?'{"imagePullSecrets":?[{"name":?"regsecret"}]}'?-n?pulsar

          使用 helm install 安裝 pulsar

          定制完 value.yaml 之后,使用下面的命令向 K8S 集群部署 pulsar。

          $?helm?install?\
          ????--values?values.yaml?\
          ????--set?initialize=true?\
          ????--namespace?pulsar?\
          ????pulsar?pulsar-2.7.7.tgz

          安裝完成后使用下面的命令查看一下兩個(gè)初始化 job pulsar-pulsar-init 和 pulsar-bookie-init 的 pod 狀態(tài)為 Complete:

          $?kubectl?get?pod?-n?pulsar??|?grep?init
          pulsar-bookie-init--1-h65bp??????????????0/1?????Completed???0???????????????5m14s
          pulsar-pulsar-init--1-t4thq??????????????0/1?????Completed???0???????????????5m5s

          使用下面的命令查看一下 pulsar 集群各個(gè)組件的 Pod 狀態(tài)全部都為 Running:

          $?kubectl?get?pod?-n?pulsar?-l?cluster=pulsar?-o?wide
          NAME?????????????????????????????????????READY???STATUS????RESTARTS??????AGE???IP??????????????NODE???NOMINATED?NODE???READINESS?GATES
          pulsar-bookie-0??????????????????????????1/1?????Running???0?????????????14m???10.244.226.91???node1???????????????
          pulsar-bookie-1??????????????????????????1/1?????Running???0?????????????14m???10.244.63.90????node2???????????????
          pulsar-bookie-2??????????????????????????1/1?????Running???0?????????????14m???10.244.46.92????node3???????????????
          pulsar-broker-0??????????????????????????1/1?????Running???0?????????????14m???10.244.226.90???node1???????????????
          pulsar-broker-1??????????????????????????1/1?????Running???0?????????????14m???10.244.63.89????node2???????????????
          pulsar-broker-2??????????????????????????1/1?????Running???0?????????????14m???10.244.46.90????node3???????????????
          pulsar-proxy-0???????????????????????????1/1?????Running???0?????????????14m???10.244.226.93???node1???????????????
          pulsar-proxy-1???????????????????????????1/1?????Running???0?????????????14m???10.244.63.91????node2???????????????
          pulsar-proxy-2???????????????????????????1/1?????Running???0?????????????14m???10.244.46.93????node3???????????????
          pulsar-pulsar-manager-7b98666cff-5626f???1/1?????Running???0?????????????14m???10.244.63.88????node2???????????????
          pulsar-recovery-0????????????????????????1/1?????Running???0?????????????14m???10.244.46.89????node3???????????????
          pulsar-toolset-0?????????????????????????1/1?????Running???0?????????????14m???10.244.46.91????node3???????????????
          pulsar-zookeeper-0???????????????????????1/1?????Running???0?????????????14m???10.244.226.92???node1???????????????
          pulsar-zookeeper-1???????????????????????1/1?????Running???0?????????????14m???10.244.63.92????node2???????????????
          pulsar-zookeeper-2???????????????????????1/1?????Running???0?????????????13m???10.244.46.94????node3???????????????

          如果后邊調(diào)整了 values.yaml,需要更新部署時(shí),使用下面的命令:

          $?helm?upgrade?pulsar?pulsar-2.7.7.tgz?\
          ????--namespace?pulsar?\
          ????-f?values.yaml

          在 toolset pod 中測試創(chuàng)建 tenant, namespace 和 topic

          toolset pod 中包含了各種管理和測試 pulsar 的命令行工具,例如 pulsar-admin, pulsar-client 等。

          下面進(jìn)入 toolset pod 中,使用 pulsar-admin 命令行工具測試一下 tenant, namespace 和 topic 的創(chuàng)建,進(jìn)一步確認(rèn) pulsar 集群工作正常。

          $?kubectl?exec?-it?-n?pulsar?pulsar-toolset-0?--?/bin/bash

          bin/pulsar-admin?tenants?create?test-tenant

          bin/pulsar-admin?tenants?list
          "public"
          "pulsar"
          "test-tenant"


          bin/pulsar-admin?namespaces?create?test-tenant/test-ns

          bin/pulsar-admin?namespaces?list?test-tenant
          "test-tenant/test-ns"

          bin/pulsar-admin?topics?create-partitioned-topic?test-tenant/test-ns/test-topic?-p?3

          bin/pulsar-admin?topics?list-partitioned-topics?test-tenant/test-ns
          "persistent://test-tenant/test-ns/test-topic"

          創(chuàng)建 pulsar-manager 的管理員用戶并登錄查看

          下面測試一下 pulsar manager 是否可以使用。

          前面使用 helm chart 部署的 pulsar 集群,在 k8s 中創(chuàng)建了下面 7 個(gè) Service。

          $?kubectl?get?svc?-l?app=pulsar?-n?pulsar
          NAME????????????????????TYPE???????????CLUSTER-IP???????EXTERNAL-IP???PORT(S)???????????????????????????????AGE
          pulsar-bookie???????????ClusterIP??????None?????????????????????3181/TCP,8000/TCP?????????????????????40m
          pulsar-broker???????????ClusterIP??????None?????????????????????8080/TCP,6650/TCP?????????????????????40m
          pulsar-proxy????????????LoadBalancer???10.104.105.137????????80:31970/TCP,6650:32631/TCP???????????40m
          pulsar-pulsar-manager???LoadBalancer???10.110.207.9??????????9527:32764/TCP????????????????????????40m
          pulsar-recovery?????????ClusterIP??????None?????????????????????8000/TCP??????????????????????????????40m
          pulsar-toolset??????????ClusterIP??????None?????????????????????????????????????????????????????40m
          pulsar-zookeeper????????ClusterIP??????None?????????????????????8000/TCP,2888/TCP,3888/TCP,2181/TCP???40m

          從上面命令的輸出可以看出,bookie, broker, recovery, toolset, zookeeper 這 5 個(gè) Service 的類型都是 ClusterIP 的,并且 cluser-ip 為 None,都是 Headless 的 Service,因?yàn)樗鼈冎恍枰?k8s 集群內(nèi)部使用。

          pulsar-proxy 和 pulsar-pulsar-manager 為 LoadBalancer 類型,并且都配置了 NodePort,提供了從 K8S 集群外部訪問的能力。

          從集群外部訪問 pulsar-manager 的地址是http://node1:32764,第一次訪問 pulsar manager 之前,需要為其創(chuàng)建一個(gè)管理用戶:

          $?CSRF_TOKEN=$(curl?http://node1:32764/pulsar-manager/csrf-token)
          $?curl?\
          ???-H?'X-XSRF-TOKEN:?$CSRF_TOKEN'?\
          ???-H?'Cookie:?XSRF-TOKEN=$CSRF_TOKEN;'?\
          ???-H?"Content-Type:?application/json"?\
          ???-X?PUT?http://node1:32764/pulsar-manager/users/superuser?\
          ???-d?'{"name":?"admin",?"password":?"pulsar",?"description":?"test",?"email":?"[email protected]"}'

          上面的命令為 pulsar-manager 創(chuàng)建用戶名為 admin, 密碼為 pulsar 的管理用戶。使用該用戶就可以登錄 pulsar manager。

          備注, 在線上使用時(shí),盡量避免以 NodePort 暴露服務(wù),這里的 pulsar-manager 的 Service 可以修改為 CluserIP 類型,并關(guān)閉 NodePort,同時(shí)創(chuàng)建 Ingress,以 Ingress+域名的形式暴露出來。看了一下 pulsar-helm-chart 也是支持的,只是目前 pulsar-helm-chart 2.7.7 中創(chuàng)建 Ingress 時(shí),使用的是apiVersion: extensions/v1beta1 API,這個(gè) API 從 k8s 1.19 被標(biāo)記為廢棄,在 k8s 1.22 已被移除。所以要直接是使用 pulsar-helm-chart 創(chuàng)建 Ingress 的話,需要等待 pulsar-helm-chart 的更新。

          參考

          • https://github.com/apache/pulsar-helm-chart
          • https://pulsar.apache.org/docs/zh-CN/kubernetes-helm/
          • https://github.com/apache/pulsar-helm-chart/issues/133
          • https://github.com/rancher/local-path-provisioner
          • https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/

          引用鏈接

          [1]

          apachepulsar/pulsar-all: https://hub.docker.com/r/apachepulsar/pulsar-all

          [2]

          apachepulsar/pulsar-manager: https://hub.docker.com/r/apachepulsar/pulsar-manager

          [3]

          Local Path Provisioner: https://github.com/rancher/local-path-provisioner

          原文鏈接:https://blog.frognew.com/2021/12/learning-apache-pulsar-14.html


          你可能還喜歡

          點(diǎn)擊下方圖片即可閱讀

          eBPF 和 Wasm:探索服務(wù)網(wǎng)格數(shù)據(jù)平面的未來

          云原生是一種信仰???

          關(guān)注公眾號(hào)

          后臺(tái)回復(fù)?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!



          點(diǎn)擊?"閱讀原文"?獲取更好的閱讀體驗(yàn)!


          發(fā)現(xiàn)朋友圈變“安靜”了嗎?


          瀏覽 70
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久草手机视频在线 | 亚洲午夜精品视频 | 欧美日韩高清 | 国产变态AV | 欧美亚洲日本在线 |