K8S 有狀態(tài)的應(yīng)用和示例:Cassandra

本教程描述拉如何在 Kubernetes 上運(yùn)行 Apache Cassandra佛嬉。 數(shù)據(jù)庫 Cassandra 需要永久性存儲提供數(shù)據(jù)持久性(應(yīng)用 狀態(tài))组题。 在此示例中蟆肆,自定義 Cassandra seed provider 使數(shù)據(jù)庫在加入 Cassandra 集群時發(fā)現(xiàn)新的 Cassandra 實(shí)例墩剖。

使用 StatefulSets 可以更輕松地將有狀態(tài)的應(yīng)用程序部署到你的 Kubernetes 集群中塘淑。 有關(guān)本教程中使用的功能的更多信息盐须, 參閱 StatefulSet画饥。

說明:

Cassandra 和 Kubernetes 都使用術(shù)語 node 來表示集群的成員衔瓮。 在本教程中,屬于 StatefulSet 的 Pod 是 Cassandra 節(jié)點(diǎn)抖甘,并且是 Cassandra 集群的成員(稱為 ring)热鞍。 當(dāng)這些 Pod 在你的 Kubernetes 集群中運(yùn)行時,Kubernetes 控制平面會將這些 Pod 調(diào)度到 Kubernetes 的 節(jié)點(diǎn)上。

當(dāng) Cassandra 節(jié)點(diǎn)啟動時薇宠,使用 seed列表 來引導(dǎo)發(fā)現(xiàn) ring 中其他節(jié)點(diǎn)偷办。 本教程部署了一個自定義的 Cassandra seed provider,使數(shù)據(jù)庫可以發(fā)現(xiàn)新的 Cassandra Pod 出現(xiàn)在 Kubernetes 集群中澄港。

一椒涯、教程目標(biāo)

  • 創(chuàng)建并驗(yàn)證 Cassandra 無頭(headless)Service..
  • 使用 StatefulSet 創(chuàng)建一個 Cassandra ring。
  • 驗(yàn)證 StatefulSet回梧。
  • 修改 StatefulSet废岂。
  • 刪除 StatefulSet 及其 Pod.

二、準(zhǔn)備開始

你必須擁有一個 Kubernetes 的集群漂辐,同時你的 Kubernetes 集群必須帶有 kubectl 命令行工具。

如果你還沒有集群棕硫,參考 用 kubeadm 在 Debian 或 Ubuntu 中創(chuàng)建 k8s 集群髓涯。

要完成本教程,你應(yīng)該已經(jīng)熟悉 Pod哈扮, ServiceStatefulSet纬纪。

三、教程

1 為 Cassandra 創(chuàng)建無頭(headless) Services

在 Kubernetes 中滑肉,一個 Service 描述了一組執(zhí)行相同任務(wù)的 Pod包各。

以下 Service 用于在 Cassandra Pod 和集群中的客戶端之間進(jìn)行 DNS 查找:

cassandra-service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: cassandra
  name: cassandra
spec:
  clusterIP: None
  ports:
  - port: 9042
  selector:
    app: cassandra

創(chuàng)建一個 Service 來跟蹤 cassandra-service.yaml 文件中的所有 Cassandra StatefulSet:

kubectl apply -f ./cassandra-service.yaml

1.1 驗(yàn)證(可選)

獲取 Cassandra Service劈愚。

kubectl get svc cassandra
NAME        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
cassandra   ClusterIP   None         <none>        9042/TCP   3s

如果沒有看到名為 cassandra 的服務(wù)扭仁,則表示創(chuàng)建失敗有缆。 請閱讀Debug Services略号,以解決常見問題肚菠。

2 使用 StatefulSet 創(chuàng)建 Cassandra Ring

下面包含的 StatefulSet 清單創(chuàng)建了一個由三個 Pod 組成的 Cassandra ring揩环。

cassandra-statefulset.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: cassandra-pv-1
  labels:
    type: local
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp"
apiVersion: v1
kind: PersistentVolume
metadata:
  name: cassandra-pv-3
  labels:
    type: local
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cassandra
  labels:
    app: cassandra
spec:
  serviceName: cassandra
  replicas: 3
  selector:
    matchLabels:
      app: cassandra
  template:
    metadata:
      labels:
        app: cassandra
    spec:
      terminationGracePeriodSeconds: 1800
      containers:
      - name: cassandra
        image: registry.cn-hangzhou.aliyuncs.com/google_samples_thepoy/cassandra:v13
        imagePullPolicy: Always
        ports:
        - containerPort: 7000
          name: intra-node
        - containerPort: 7001
          name: tls-intra-node
        - containerPort: 7199
          name: jmx
        - containerPort: 9042
          name: cql
        resources:
          limits:
            cpu: "500m"
            memory: 1Gi
          requests:
            cpu: "500m"
            memory: 1Gi
        securityContext:
          capabilities:
            add:
              - IPC_LOCK
        lifecycle:
          preStop:
            exec:
              command: 
              - /bin/sh
              - -c
              - nodetool drain
        env:
          - name: MAX_HEAP_SIZE
            value: 512M
          - name: HEAP_NEWSIZE
            value: 100M
          - name: CASSANDRA_SEEDS
            value: "cassandra-0.cassandra.default.svc.cluster.local"
          - name: CASSANDRA_CLUSTER_NAME
            value: "K8Demo"
          - name: CASSANDRA_DC
            value: "DC1-K8Demo"
          - name: CASSANDRA_RACK
            value: "Rack1-K8Demo"
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
        readinessProbe:
          exec:
            command:
            - /bin/bash
            - -c
            - /ready-probe.sh
          initialDelaySeconds: 15
          timeoutSeconds: 5
        # These volume mounts are persistent. They are like inline claims,
        # but not exactly because the names need to match exactly one of
        # the stateful pod volumes.
        volumeMounts:
        - name: cassandra-data
          mountPath: /cassandra_data
  # These are converted to volume claims by the controller
  # and mounted at the paths mentioned above.
  # do not use these in production until ssd GCEPersistentDisk or other ssd pd
  volumeClaimTemplates:
  - metadata:
      name: cassandra-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

3 驗(yàn)證 Cassandra StatefulSet

  1. 獲取 Cassandra StatefulSet:
kubectl get statefulset cassandra

結(jié)果:

NAME        READY   AGE
cassandra   3/3     14m

StatefulSet 資源會按順序部署 Pod诉探。

  1. 獲取 Pod 查看已排序的創(chuàng)建狀態(tài):

    kubectl get pods -l app=cassandra
    

    三個 Pod 要花幾分鐘的時間才能部署先较。部署之后掏击,相同的命令將返回類似于以下的輸出:

    NAME          READY   STATUS    RESTARTS   AGE
    cassandra-0   1/1     Running   0          15m
    cassandra-1   1/1     Running   0          14m
    cassandra-2   1/1     Running   0          13m
    
  2. 運(yùn)行第一個 Pod 中的 Cassandra nodetool卵皂,以顯示 ring 的狀態(tài)。

    kubectl exec -it cassandra-0 -- nodetool status
    

    結(jié)果:

    Datacenter: DC1-K8Demo
    ======================
    Status=Up/Down
    |/ State=Normal/Leaving/Joining/Moving
    --  Address      Load       Tokens       Owns (effective)  Host ID                               Rack
    UN  10.244.1.20  70.88 KiB  32           65.9%             2c20de58-2680-4edd-b651-d83e73219a05  Rack1-K8Demo
    UN  10.244.2.16  108.87 KiB  32           69.6%             7fb488d6-5fce-4e82-bfb7-0ac34ddea61d  Rack1-K8Demo
    UN  10.244.3.17  104.55 KiB  32           64.5%             fc9be49a-5fbc-454e-b244-cc7e8b736ca2  Rack1-K8Demo
    

4 修改 Cassandra StatefulSet

使用 kubectl edit 修改 Cassandra StatefulSet 的大小砚亭。

  1. 運(yùn)行以下命令:

    kubectl edit statefulset cassandra
    

    此命令你的終端中打開一個編輯器灯变,修改的就是你之前 apply 的那個配置文件。如果你沒有修改過捅膘,那么需要更改的是第 51 行的 replicas 字段添祸,將其值修改為 4,:x保存退出寻仗。

    集群會自動應(yīng)用以此方法修改的配置文件膝捞,StatefulSet 將會擴(kuò)展為 4 個 Pod。

    但之前只創(chuàng)建了 3 個 PersistentVolume,每個 Pod 都需要綁定一個 PersistentVolume蔬咬,所以還需要再手動創(chuàng)建一個 PersistentVolume:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: cassandra-pv-4
      labels:
        type: local
    spec:
      capacity:
        storage: 1Gi
      accessModes:
        - ReadWriteOnce
      hostPath:
        path: "/tmp"
    
  2. 獲取 Cassandra StatefulSet 驗(yàn)證更改:

    kubectl get statefulset cassandra
    

    結(jié)果:

    NAME        DESIRED   CURRENT   AGE
    cassandra   4         4         36m
    

5 刪除本示例

出于安全考慮鲤遥,在刪除或縮小 StatefulSet 時不會刪除與 StatefulSet 關(guān)聯(lián)的卷,因?yàn)槟愕臄?shù)據(jù)更有價值林艘。

:warning:警告: 根據(jù)存儲類和回收策略盖奈,刪除 PersistentVolumeClaims 可能導(dǎo)致關(guān)聯(lián)的卷也被刪除。 千萬不要認(rèn)為其容量聲明被刪除狐援,你就能訪問數(shù)據(jù)钢坦。

運(yùn)行以下命令(連在一起成為一個單獨(dú)的命令)刪除 Cassandra StatefulSet 中的所有內(nèi)容:

grace=$(kubectl get pod cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}') \
  && kubectl delete statefulset -l app=cassandra \
  && echo "Sleeping ${grace} seconds" 1>&2 \
  && sleep $grace \
  && kubectl delete persistentvolumeclaim -l app=cassandra

運(yùn)行以下命令,刪除你為 Cassandra 設(shè)置的 Service:

kubectl delete service -l app=cassandra

6 Cassandra 容器環(huán)境變量

本教程中的 Pod 使用來自 Google container registrygcr.io/google-samples/cassandra:v13 鏡像(我把這個鏡像 Push 到了阿里云容器鏡像)啥酱。 上面的 Docker 鏡像基于 debian-base爹凹,并且包含 OpenJDK 8。

該鏡像包括來自 Apache Debian 存儲庫的標(biāo)準(zhǔn) Cassandra 安裝镶殷。 通過使用環(huán)境變量禾酱,您可以更改插入到 cassandra.yaml 中的值。

Environment variable Default value
CASSANDRA_CLUSTER_NAME 'Test Cluster'
CASSANDRA_NUM_TOKENS 32
CASSANDRA_RPC_ADDRESS 0.0.0.0
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绘趋,一起剝皮案震驚了整個濱河市颤陶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌陷遮,老刑警劉巖滓走,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異帽馋,居然都是意外死亡搅方,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門绽族,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腰懂,“玉大人,你說我怎么就攤上這事项秉⌒辶铮” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵娄蔼,是天一觀的道長怖喻。 經(jīng)常有香客問我,道長岁诉,這世上最難降的妖魔是什么锚沸? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮涕癣,結(jié)果婚禮上哗蜈,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好距潘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布炼列。 她就那樣靜靜地躺著,像睡著了一般音比。 火紅的嫁衣襯著肌膚如雪俭尖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天洞翩,我揣著相機(jī)與錄音稽犁,去河邊找鬼。 笑死骚亿,一個胖子當(dāng)著我的面吹牛已亥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播来屠,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼虑椎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了的妖?” 一聲冷哼從身側(cè)響起绣檬,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤足陨,失蹤者是張志新(化名)和其女友劉穎嫂粟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墨缘,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡星虹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了镊讼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宽涌。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蝶棋,靈堂內(nèi)的尸體忽然破棺而出卸亮,到底是詐尸還是另有隱情,我是刑警寧澤玩裙,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布兼贸,位于F島的核電站,受9級特大地震影響吃溅,放射性物質(zhì)發(fā)生泄漏溶诞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一决侈、第九天 我趴在偏房一處隱蔽的房頂上張望螺垢。 院中可真熱鬧,春花似錦、人聲如沸枉圃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讯蒲。三九已至痊土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間墨林,已是汗流浹背赁酝。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旭等,地道東北人酌呆。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像搔耕,于是被迫代替她去往敵國和親隙袁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容