We all love stateless services but there is no rule without an exception. Both of Zookeeper and Broker service plays as storage to Ohara and we can't, unfortunately, keep the data consistently. This issue is about to include the container volume to ohara object that users are able to configure the volume and then mount it on specify services. Those volumes are alive until users kill them manually.
第一版的volume support目標是先能有基本的volume操作,因此有以下幾個限制:
Create a Volumn
POST /v0/volumns
{
"group": "group",
"name": "name",
"nodeNames": ["n0", "n1"],
"path": "/tmp/aaa"
}
Update a Volumn
PUT /v0/volumns/$name?gruop=$group
{
"path": "/tmp/aaa2"
}
Delete a Volumn
DELETE /v0/volumns/$name?gruop=$group
Get a Volumn
GET /v0/volumns/$name?gruop=$group
{
"group": "group",
"name": "name",
"nodeNames": ["n0", "n1"],
"path": "/tmp/aaa"
}
List Volumns
GET /v0/volumns
[
{
"group": "group",
"name": "name",
"nodeNames": ["n0", "n1"],
"path": "/tmp/aaa"
}
]
Definition會新增一個Reference為Volume,用來給作為目錄的key值設定,例如
SettingDef.builder()
.key(LOG_DIRS_KEY)
.optional(Type.OBJECT_KEY)
.reference(SettingDef.Reference.VOLUME)
.build
@jackyoh @vitojeng 麻煩你們看一下上述的限制以及APIs,
@chia7712
沒有 Get all Volumns Api,漏掉了嗎?
漏掉了XD
同一個 group 下的 path 是否要限制為 unique?
你是指同一個group + name吧? 如果是的話,那的確要做檢查
UI 如何知道一個 Volumn 被使用中?Get a Volumn Api 回傳的 data 沒有相關的訊息。
這是UI流程需要嗎? 現在我還沒列任何"runtime"的資訊,看UI流程需要哪些可以提出來討論
你是指同一個group + name吧? 如果是的話,那的確要做檢查
喔喔~ group + name 為 unique 應該是基本規則。不過,我問的是 path,因為在同一個 group 下有兩組 (path 相同, nodeNames 不同)的 Volumn ,使用者應該很容易混淆吧。我猜想使用者選擇 Volumn 時,應該會認 path 而不是 name。
這是UI流程需要嗎?現在我還沒列任何"runtime"的資訊,看UI流程需要哪些可以提出來討論
是的,UI 可以先阻擋使用者修改或刪除正在使用中的 Volumn
因為在同一個 group 下有兩組 (path 相同, nodeNames 不同)的 Volumn ,使用者應該很容易混淆吧。我猜想使用者選擇 Volumn 時,應該會認 path 而不是 name。
我覺得讓path不能重複使用故事比較單純,使用者在指定volume的時候應該還是會認名字,畢竟path可能會很難閱讀
是的,UI 可以先阻擋使用者修改或刪除正在使用中的 Volumn
那就加上一個runtime資訊顯示被誰使用? 例如
{
"references": [
{
"group": "g",
"name": "n",
"kind": "zookeeper"
}
]
}
@chia7712
1.那要限制在 node 建立資料夾的使用者權限為 root 嗎? 因為 container 執行的 user 為 ohara, node 建立的 user 為 root,我不太確定是否會發生 permission denied 的問題
那要限制在 node 建立資料夾的使用者權限為 root 嗎? 因為 container 執行的 user 為 ohara, node 建立的 user 為 root,我不太確定是否會發生 permission denied 的問題
Docker mode的話就是設定的使用者要有權限、k8s也是。現階段沒有權限就是拋錯
當 volume 使用的資料夾路徑不存在我們要幫使用者建立還是要丟 exception?
嘗試建立,否則拋錯
一個正在被使用的volume無法被更新或刪除
這是否意味著: 一個 service 擴充節點, 除了 service 本身的 definition 要修改外, 其對應的 volumn 也須要修改, 而且是必須的?(我們需要檢查?)
volume path不可以重複
是否指不同的 volumn 之間, path 不可重覆的意思?
討論: 另外一個可能容易會有的情境
由於不同的 node 配置的資源不一致, 例如 mount 的硬碟數量不同, 或是硬碟的容量不一樣.
這種情形下, 很有可能出現一個 volumn 裡在不同的 node 裡的 path "被迫" 無法一致.
不同時期買的硬體不盡相同, 我想這種不一致的情形很可能發生
這是否意味著: 一個 service 擴充節點, 除了 service 本身的 definition 要修改外, 其對應的 volumn 也須要修改, 而且是必須的?(我們需要檢查?)
擴充的部分會獨立成一組API,因為背後要做的動作比較適合由後端來處理而非前端
是否指不同的 volumn 之間, path 不可重覆的意思?
yep
討論: 另外一個可能容易會有的情境
由於不同的 node 配置的資源不一致, 例如 mount 的硬碟數量不同, 或是硬碟的容量不一樣.
這種情形下, 很有可能出現一個 volumn 裡在不同的 node 裡的 path "被迫" 無法一致.
不同時期買的硬體不盡相同, 我想這種不一致的情形很可能發生
以後才支援異質環境,否則無論是API或是UI都會有很大幅度的改動
擴充的部分會獨立成一組API,因為背後要做的動作比較適合由後端來處理而非前端
酷!
以後才支援異質環境,否則無論是API或是UI都會有很大幅度的改動
了解~
@jackyoh 歹勢 我剛剛注意到一些APIs的定義有些不恰當,我會很快發隻PR調整一下 :(
有,看到 PR 了。
volumes 回傳的值改成 Seq[ContainerVolume] 了。
@jackyoh 麻煩你有空先把k8s的實作補上,我會接著把它套用到route上面 感恩恩
OK, 我大概明天就可以開始實作了。
@chia7712
目前我把 K8S Volume 的部份 implement 完了 (volumeCreator, removeVolumes 和 volumes) 已經先開草稿的 PR 了 #4556 (我下午還會在看是否要補一些測試程式)。
目前我有遇到以下二個問題:
因此我覺得在 volume name 的部份我們應該要做設計,就像是我們的 zk, bk 和 wk 服務的 container name 一樣。這樣才能解決關於 volume name 衝突的問題
ContainerCreator#doCreate 是否要先接上 volume 的 mapping (像是 Docker Mode 的 docker run -v ${VOLUME_NAME}:${CONTAINER_PATH}), 還是要等到做 apply Volume on zookeeper service 再來實作 volume 的 mapping?
這會在別隻pr
關於 volume name 的部份,因為 k8s 的 persistent volume 是從整體性來看,因此如果 volume1 建立在 node1 ,之後 volume1 這個名稱就不能建立在 node2 會發生 already exists 的錯誤。但 Docker Mode 不會遇到此問題,因為直接在不同 node 建立相同的 volume name 不會有名稱衝到的問題。
這個名稱管理由collie來處理
了解, Thank you.
@chia7712
目前在寫 ContainerClient mount volume 的測試程式時遇到 Node 資料夾權限的問題,有遇到以下二個狀況描述如下:
1.當 Node 的資料夾不存在時,在 ohara 預設的情況下會先建立一個資料夾,然後在 mount 到 container (zk, bk) 裡執行。 K8S 有提供當資料夾不存在時會建立資料夾的參數(DirectoryOrCreate),但建立出來的資料夾 own 和 group 通常都會是 root 因為相依於 kubelet service (k8s 執行的 service)
If nothing exists at the given path, an empty directory will be created there as needed with permission set to 0755, having the same group and ownership with Kubelet.
因為目前 ohara 執行服務的 container (zk和 bk) 使用者都為 ohara(UID=1000) mount 到 node 的資料夾 root (UID=0) 會發生 permission denied 的問題。
2.觀察到在 node 建立資料夾的 UID 要和執行 container (zk, bk 和 wk 服務) 的 UID 相同,例如 container 執行的 UID 是 1000, mount 到 node 的資料夾 own 也要是 1000,不然會發生 permission denied 的問題。
因此目前有想到一個解決方法,就是在 QA 裡,測試前先連到 IT 環境建立要 mount 的資料夾並修改 UID 的權限,測試程式就會取得設定參數的路徑然後 mount 到 container 裡執行測試的動作,最後跑完測試之後再把 QA 建立的資料夾刪除掉。
@jackyoh 感謝提供的資訊
權限的部分考量我們目前還沒有要整合,因此目前比較適合的邏輯應該是使用者要事先準備好目錄給我們來mount(例如權限設定),以及我們在建立ohara volume的時候要先確認權限是否可行 (例如目錄的使用者名稱一定要等於ohara,以及目錄是否存在),簡單來說,在沒有整合權限的狀態下,我們不應該去做太多"猜測"的自動化
所以在 ContainerClient 測試程式的部份,應該要先在 IT 的 node 裡先建立資料夾,然後測試程式用 hard code 的方式指定 path 去檢查資料夾有沒有存在以及 own 是否為 ohara。
等做了權限管理之後再來整自動化的部份
檢查的部分,k8s的APis能做到嗎?
K8S Api 做不到檢查 remote node 的資料夾有沒有存在以及資料夾的 own,我常常忘掉資料夾是 remote 的操作。
K8S Api 做不到檢查 remote node 的資料夾有沒有存在以及資料夾的 own,我常常忘掉資料夾是 remote 的操作。
或許利用ssh來做操作?
我這邊會先去研究看 K8S 的 plugin 看能不能做到建立資料夾的部份,如果最後沒辦法只能透過 ssh 的方式來建立資料夾。
我很像有找到在 k8s 的 node 建立資料夾的方法了,如下連結:
https://serverfault.com/questions/906083/how-to-mount-volume-with-specific-uid-in-kubernetes-pod
它的概念是在啟動 pod (container)之前會有一個 init container 的動作,mount 資料夾到 container 裡,之後調整資料夾的 own 權限,這樣 node 資料夾的 own 也會跟著修改。
目前有使用 ohara 的 zookeeper container 做個簡單的實驗,看起來 zookeeper container 可以順利存取 node 的資料夾,啟動 zookeeper pod 的 k8s 設定如下:
kind: Pod
metadata:
labels:
createdByOhara: k8s
name: default-cnh754f214-zookeeper-3f0ea29
spec:
initContainers:
- name: volume-test-init
image: busybox
command: ["sh", "-c", "chown -R 1000:1000 /data"]
volumeMounts:
- name: volume1
mountPath: /data
containers:
- args:
- "--file"
- "/home/ohara/default/data/myid=0"
- "--file"
- "/home/ohara/default/conf/zoo.cfg=initLimit=10,dataDir=/home/ohara/default/data,server.0=14-zookeeper-ae40098:37505:42415,syncLimit=5,tickTime=2000,clientPort=42813"
- "--config"
- "/home/ohara/default/conf/zoo.cfg"
env:
- name: JMXDISABLE
value: 'true'
- name: JVMFLAGS
value: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=38259
-Dcom.sun.management.jmxremote.rmi.port=38259 -Djava.rmi.server.hostname=ohara-k8s-master
-Xmx1024M -Xms1024M"
image: oharastream/zookeeper:0.10.0-SNAPSHOT
volumeMounts:
- name: volume1
mountPath: "/home/ohara/default/data"
imagePullPolicy: IfNotPresent
name: ohara
ports:
- containerPort: 42813
hostPort: 42813
- containerPort: 37505
hostPort: 37505
- containerPort: 42415
hostPort: 42415
- containerPort: 38259
hostPort: 38259
hostAliases:
- hostnames:
- ohara-k8s-master
ip: 192.168.1.211
- hostnames:
- ohara-k8s-slave00
ip: 192.168.1.212
hostname: 14-zookeeper-ae40098
nodeSelector:
kubernetes.io/hostname: ohara-k8s-master
volumes:
- name: volume1
persistentVolumeClaim:
claimName: volume1
restartPolicy: Never
subdomain: default
我明天還會繼續做進一步的測試,如果沒問題的話就會把以上的設定整入 ohara k8s json 設定的部份,並且繼續把 ContainerClient 的測試寫完。
@chia7712
我後來想一想我上面寫的 sample 設定,只能用在 mount volume 並修改權限,讓 container 可以 mount volume 執行服務。而無法做到我們討論的直接在 node 上檢查資料夾存不存在和 own 的使用者。看來還是需要用 ssh 來做了。
@jackyoh 感謝測試,如果明天中午之前沒有特別的解法的話,我們就敲前端一起討論一下
@chia7712
我嘗試很多方法想要透過 K8S API 去檢查 remote node 資料夾是否存在以及資料夾的 own,但
都沒有辦法成功,有些問題是沒辦法拿到正確的 exception 訊息,有些是超出我的能力範圍太多。但我感覺到最後應該都會用到 ssh 來處裡 remote node 操作資料夾的需求。
因此需要前端的幫忙,看是否能把之前建立 k8s node 的帳號和密碼重新拿回來使用,這樣才有辦法透過 ssh 來檢查 remote node 的資料夾和 own
@oharastream/developer ping 前端 :)
如上面jack所提,目前在管理volume上不管是docker mode或是k8s mode都需要透過ssh來進行一些底層的操作和檢查,換言之,這邊需要前端調整讓使用者"需要"輸入可操作的帳密,這邊不知道你們有什麼想法?
如上面jack所提,目前在管理volume上不管是docker mode或是k8s mode都需要透過ssh來進行一些底層的操作和檢查,換言之,這邊需要前端調整讓使用者"需要"輸入可操作的帳密,這邊不知道你們有什麼想法?
以我目前的理解,這組帳密是為了"管理host volumes"所用的?
由於我們目前所有服務應該都是基於"ohara"這個使用者來啟動服務與操作,在我們的UI上需要使用者輸入一組可以"跳過ohara使用者來遠端操作host dir"是否怪怪的?
在我們的UI上需要使用者輸入一組可以"跳過ohara使用者來遠端操作host dir"是否怪怪的?
我不太清楚"跳過ohara使用者"的意思
該登入是方便後端針對volume的部分先進行一些基本的檢查(或是一些基本的自動化),由於docker模式具有帳密可以完成相關檢查,但k8s這邊缺乏相關支援。如果後端沒有能力去進行相關操作,會演變成使用者依然要自行登入到所有節點去幫我們完成事先檢查和操作,這樣就偏離我們的整合了
我不太清楚"跳過ohara使用者"的意思
我想我該解釋清楚點XD
該登入是方便後端針對volume的部分先進行一些基本的檢查(或是一些基本的自動化),由於docker模式具有帳密可以完成相關檢查
這裡其實不是完全正確。因為docker模式下的host帳密目的應該為"允許使用者可以登入到該台主機並且操作docker服務",而不是"操作資料夾"。我想我們應該會需要有控制資料夾的權限才有辦法達到此目的,對吧?
而K8S模式如果需要此支援,那這組帳密的權限要與K8S安裝的權限相同嗎? 抑或是足夠更改"想要操作的資料夾"的權限就夠了?
我想我們應該會需要有控制資料夾的權限才有辦法達到此目的,對吧?
權限的部分我們目前主要是做檢查,例如目錄權限或者存在與否,以linux的規則來說一般使用者"通常"都具備此等權限,至於更複雜的例子或許可以等我們要整security的時候再討論。
而K8S模式如果需要此支援,那這組帳密的權限要與K8S安裝的權限相同嗎? 抑或是足夠更改"想要操作的資料夾"的權限就夠了?
如上所述,k8s這邊要的只是一個能登入的帳密即可
權限的部分我們目前主要是做檢查
了解,那我的想像是:
Docker: 以目前的UI流程可能可以不用改? (對使用者來說需要針對每台host都要兩組帳密好像有點麻煩)
K8S: 感覺需要額外的步驟來設定 "可以登入有安裝K8S slave機器的帳密"
Docker: 以目前的UI流程可能可以不用改? (對使用者來說需要針對每台host都要兩組帳密好像有點麻煩)
你說的沒錯
K8S: 感覺需要額外的步驟來設定 "可以登入有安裝K8S slave機器的帳密"
沒錯,我一開始的想像是設定nodes的步驟可以兩個模式都走一樣的流程? 當然看前端你們的想法
另外如果這個變更會增加一定的時辰的話,或許我們要討論一下release時間往後延一下,否則volume的功能會有點難進行
我一開始的想像是設定nodes的步驟可以兩個模式都走一樣的流程?
K8S如果要走新增node的流程,我覺得可能會需要在畫面上多點提示使用者為何需要這組帳密...並且這個新增的步驟我們似乎需要另外用API來處理 (避免與現有的node objects衝突),或許可以用/objects這支API來儲存?
K8S如果要走新增node的流程,我覺得可能會需要在畫面上多點提示使用者為何需要這組帳密...並且這個新增的步驟我們似乎需要另外用API來處理 (避免與現有的node objects衝突),或許可以用/objects這支API來儲存?
或許讓使用者針對已經存在的node設定帳密就好? 因為k8s模式會自動去撈取nodes,可以提示使用者去為那些node設定帳密以利後續volume的使用?
或許讓使用者針對已經存在的node設定帳密就好?
聽起來可行,只是在建立workspace過程中這個步驟我們無法限制使用者"一定"要輸入 (因為列表會出現已撈取的nodes)
對於要如何"限制使用者不能勾選還未輸入帳密的node",畫面要如何呈現我沒什麼想法...XD
這邊應該是optional,所以只要有提示就好?
聽起來可行,只是在建立workspace過程中這個步驟我們無法限制使用者"一定"要輸入 (因為列表會出現已撈取的nodes)
細節可能還需要討論XD
這邊應該是optional,所以只要有提示就好?
沒錯
另外我剛剛想到一件事情,或許前端可以晚一點再實作,因為後端可以延後此錯誤直到使用者開始操作volume的時候才拋出需要帳密的錯誤? @jackyoh 你覺得呢? 這樣前端可以等到0.11再來實作,而後端我們可以封裝檢查的邏輯給docker 和 k8s使用,另外在IT的部分就是要求在測試volume的時候要輸入帳密 (或許可以沿用docker的參數)
測試volume的時候要輸入帳密
是指在 ContainerClient 的 ContainerVolume case class 新增 username 和 password 嗎?
我覺的帳號密碼的部份前端可以到 0.11 版再做,目前後端要先把 createVolume 做到能遠端檢查 node 的資料夾,讓 api 和整合測試能夠使用 volume。
是指在 ContainerClient 的 ContainerVolume case class 新增 username 和 password 嗎?
或許依然操作Node就好,當發現node沒有設定帳密的時候拋出錯誤就好
另外我剛剛想到一件事情,或許前端可以晚一點再實作
+1
前端目前的工作滿載...可能再加入 Volume 這個部份應該很困難
或許依然操作Node就好,當發現node沒有設定帳密的時候拋出錯誤就好
因為目前的 ContainerClient 設定 node 的方式是透過 string 傳入 node name, 那是否要改成傳入 Node case class, 不然 ContainerClient 在建立 volume 時沒有帳號和密碼資訊無法做 ssh 的登入,做檢查的動作。
因為目前的 ContainerClient 設定 node 的方式是透過 string 傳入 node name, 那是否要改成傳入 Node case class, 不然 ContainerClient 在建立 volume 時沒有帳號和密碼資訊無法做 ssh 的登入,做檢查的動作。
在agent裡面有一個介面稱之為DataCollie可以用來幫忙轉換hostname -> node,DockerClient底層仰賴它,或許k8s也可以有一樣的行為
不過考量到驗證的邏輯理論上是相同的,或許使用DataCollie建立一個新的專門用來做驗證的類別,然後讓DockerClient和K8sClient去呼叫它就好
@jackyoh 麻煩將未完成的議題移動到#4621,然後關閉此議題
OK, 我來移動。