Ohara: 研究 K8S 的 volume 功能

Created on 14 Apr 2020  ·  8Comments  ·  Source: oharastream/ohara

目前 ohara 的 zookeeper, broker 和 worker 都是使用 container 在建立服務,因此如果要長時間的保留資料就需要整合 volume 的功能,細節在 issue #4460。

在 K8S Client 的部份使用 hostPath 來做 container 做資料保留, 因為知道服務(zooker, broker 和 worker) 在哪台的 node 上執行, 所以使用 hostPath 是最簡單和方便的方式。

以下是一個簡單的 example, 有做 volume 功能的 pod:

apiVersion: v1
kind: Pod
metadata:
  name: test-volume
spec:
  containers:
  - name: test-volume
    image: nginx
    volumeMounts:
    - mountPath: /tmp/testVolume
      name: volume1
    imagePullPolicy: Always
  volumes:
  - name: volume1
    hostPath:
      path: /home/ohara/testVolume
      type: DirectoryOrCreate

在這個 sample 裡,hostPath 下面 path 是指執行 pod (container) 的 Node 的資料夾路徑, 當 node 不存在 /home/ohara/testVolume 的資料夾會做自動建立的動作。另外在執行 pod 時,會把 volume mount 到 test-volume container 的 /tmp/testVolume 路徑裡。

All 8 comments

目前 ohara 的 zookeeper, broker 和 worker 都是使用 container 在建立服務,因此如果要長時間的保留資料就需要整合 volume 的功能

想確認 worker container 有需要用到 volume 嗎?

worker 應該不會用到 volume

@chia7712 我有去測試 k8s 的 volume name,它是透過 k8s 的 pod API 來查詢。volume name 是固定的名稱不會被 hash。

查詢的 JSON 如下:

volumes: [
  {
       name: "volume1",
       hostPath: {
           path: "/home/ohara/testVolume",
           type: "DirectoryOrCreate"
      }
  }
]

再麻煩妳看看能否接上ohara volume的介面,如果有任何不符合實際面的地方我們在討論如何修訂介面

好,我今天已經有先看介面和 Docker Client 實做的部份了。

K8S 的部份主要會去實做 volumeCreator, volumes 和 removeVolume 這三個方法。原本我以為是在建立 container 的時候 (zk, bk),才會建立 volume 像是 docker run -v nodePath:containerPath 在這個議題的 description 才會寫使用 K8S 的 hostPath。但是仔細看程式碼之後發現 ohara 有做完整的 volume 管理,像是 docker volume create 和 docker volume delete 的界面,因此 K8S 的部份我會改成使用 Persistent Volume 的方式來實做, 今天有去做簡單的測試在 k8s 建立 persistent volume 看起來應該是可以跟我們的介面串起來, 明天我會嘗試實做看看。

另外我來確認有關於 ohara 的 Docker mode volume 機制,如果 broker container 在 node1 的情況下,volume 應該不會跑到 node2 去建立 (docker volume create) 吧, 因為目前沒有支援 NFS 的機制。

K8S 的部份主要會去實做 volumeCreator, volumes 和 removeVolume 這三個方法。原本我以為是在建立 container 的時候 (zk, bk),才會建立 volume 像是 docker run -v nodePath:containerPath 在這個議題的 description 才會寫使用 K8S 的 hostPath。但是仔細看程式碼之後發現 ohara 有做完整的 volume 管理,像是 docker volume create 和 docker volume delete 的界面,因此 K8S 的部份我會改成使用 Persistent Volume 的方式來實做, 今天有去做簡單的測試在 k8s 建立 persistent volume 看起來應該是可以跟我們的介面串起來, 明天我會嘗試實做看看。

ohara volume會是一個獨立的元件可以被管理,0.11+之後應該會有支援相關的介面...

另外我來確認有關於 ohara 的 Docker mode volume 機制,如果 broker container 在 node1 的情況下,volume 應該不會跑到 node2 去建立 (docker volume create) 吧, 因為目前沒有支援 NFS 的機制。

我們現在先支援local volume就好,換言之你講的狀況會直接扔出錯誤,就是使用者指定了volume (on n2)然後希望container開在n1的話

了解,我明天就開始嘗試 K8S 實作的部份。

目前已經大概找到實作 ohara volume 介面要對應 K8S 的 API,分別介紹如下:

ContainerClient#volumeCreator:

使用 k8s 的 /api/v1/persistentvolumes 和 /api/v1/namespaces/default/persistentvolumeclaims 二個 API來建立 ohara 服務的 volume。

persistentvolume 和 persistentvolumeclaims 主要是 K8S 的架構設計,希望系統管理者和系統開發者能夠切開,系統開發者在建立 pod (container) 時只要針對 persistentvolumeclaims 做 volume 的 mount。系統管理者在維護 volume 時是針對 persistentvolume 來做檔案系統的管理。persistentvolumeclaims 和 persistentvolume 的連結是透過 storageClassName,因此persistentvolumeclaims 如果修改 storageClassName 就可以連到底層不同的persistentvolumes。

以下是建立 persistentvolume 和 persistentvolumeclaims 的 json 格式:

persistentvolume:

{
  "apiVersion": "v1",
  "kind": "PersistentVolume",
  "metadata": {
    "name": "volume1"
  },
  "spec": {
    "capacity": {
      "storage": "500Gi"
    },
    "accessModes": [
      "ReadWriteOnce"
    ],
    "persistentVolumeReclaimPolicy": "Retain",
    "storageClassName": "volume1",
    "hostPath": {
      "path": "/tmp/PVDATA-100",
      "type": "DirectoryOrCreate"
    },
    "nodeAffinity": {
      "required": {
        "nodeSelectorTerms": [
          {
            "matchExpressions": [
              {
                "key": "kubernetes.io/hostname",
                "operator": "In",
                "values": [
                  "ohara-k8s-master"
                ]
              }
            ]
          }
        ]
      }
    }
  }
}

persistentvolume claim:

{
  "apiVersion": "v1",
  "kind": "PersistentVolumeClaim",
  "metadata": {
    "name": "volume1"
  },
  "spec": {
    "storageClassName": "volume1",
    "accessModes": [
      "ReadWriteOnce"
    ],
    "resources": {
      "requests": {
        "storage": "500Gi"
      }
    }
  }
}

ContainerClient#removeVolumes:

刪除 volume 時會使用 /api/v1/namespaces/${namespaces}/persistentvolumeclaims/${volumeName} 和 /api/v1/namespaces/default/persistentvolumeclaims/${volumeName} 這二個 api 來刪除 ohara 服務的 volume

ContainerClient#volumes:

查看 volume 資訊會使用 /api/v1/persistentvolumes 的 k8s api 來做查詢的動作。

在建立 pod (container) 的 json 簡單設定如下:

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "nginx1"
  },
  "spec": {
    "containers": [
      {
        "name": "nginx1",
        "image": "nginx",
        "volumeMounts": [
          {
            "name": "volume1",
            "mountPath": "/usr/share/nginx/html"
          }
         ]
       }
     ],
     "nodeSelector": {
        "kubernetes.io/hostname": "ohara-k8s-master"
     },
     "volumes": [
       {
         "name": "volume1",
         "persistentVolumeClaim": {
           "claimName": "volume1"
         }
       }
     ]
  }
}

volumes 會指定 persistentVolumeClaim, 然後 volume mount 到 pod (container) 裡。

Was this page helpful?
0 / 5 - 0 ratings