Apache Hadoop OzoneがCSIに対応(=Kubernetesでも使える)してたのでお試してみる

qiita.com

qiita.com

遅れてしまいましたが、この記事は、 MicroAd Advent Calendar 2019 及び Distributed computing (Apache Spark, Hadoop, Kafka, ...) Advent Calendar 2019 - Qiita20日目の記事です。

f:id:yassan0627:20191217211032p:plain
公式ドキュメント より

TL;DR

Apache Hadoop Ozone1 で対応したCSIをつかってKubernetesでPVCをお試しようと思ったんですが、準備が間に合わなかった… S3を喋れるので、今回は、aws CLI使って、ファイル操作をしてみた。

hadoop.apache.org

Apache Hadoop Ozoneって?

Apache Hadoop Ozone(以下、Ozone)とは、Hadoopの為の分散オブジェクトストレージです。
平たく言うと SparkHiveHBase 等のHadoopエコシステムで使えるS3。

Documentation for Apache Hadoop Ozone によると以下の特徴があります。

Ozone is a scalable, redundant, and distributed object store for Hadoop.

Apart from scaling to billions of objects of varying sizes, Ozone can function effectively in containerized environments like Kubernetes.

Applications like Apache Spark, Hive and YARN, work without any modifications when using Ozone. Ozone comes with a Java client library, S3 protocol support, and a command line interface which makes it easy to use Ozone.

Ozone consists of volumes, buckets, and keys:

  • Volumes are similar to user accounts. Only administrators can create or delete volumes.
  • Buckets are similar to directories. A bucket can contain any number of keys, but buckets cannot contain other buckets.
  • Keys are similar to files.

Hadoop FSやS3インターフェイスを介しての利用だけかと思いきや、CSI2 に対応した事によりKubernetesのPodのVolumeとして割当ても可能になります(CSIって美味しいの?って人は こちら の素晴らしい解説を参照下さい)。

KubernetesCSIといえば、こないだのMeetup3 もあった Rook4 がありますが、、
Issue確認するとありました、Ozone🎉

Support Apache Hadoop Ozone as a storage provider in Rook · Issue #3235 · rook/rook
ozone: initial version of ozone operator by elek · Pull Request #4013 · rook/rook

v1.2のブランチには、 デザインドキュメント5 があるので、v1.2には出てくるかも?って期待していたんですが、、リリースに間に合わず入っていないようです。

Ozoneアーキテクチャ

Ozoneアーキテクチャは、Rookのデザインドキュメントにあった下図が分かりやすいです。

f:id:yassan0627:20191217213305p:plain
デザインドキュメントより

  • メタデータサーバ:
    • Storage Container Manager (SCM): ブロック領域の管理用 (DataNode間のレプリカ用の巨大なバイナリブロックの作成)
    • Ozone Manager (OM): キー領域の管理用 (Bucketの作成、SCMにより複製した上位のキー)
  • Datanodes: ストレージデーモン
  • S3 gateway (ステートレスなRESTサービスでS3互換のI/F)
  • Recon server (異常検知とか履歴データの閲覧用のUI)
  • Recon用のDB

また、CSIのI/Fは以下の2つのデーモンが必要

  • CSI Controller service
  • CSI Node service

そして、監視には以下にも対応しています。

  • すべてのメトリクスはPrometheusからの呼び出し可能
  • Grafanaのデフォルトのダッシュボードで表示可能

Ozone自体の登場背景とかベースとなる仕組みに関しては、バルセロナで行われた DataWorks Summit 2019の Losing Data in a Safe Way – Advanced Replication Strategies in Apache Hadoop Ozone が分りやすいです。

www.slideshare.net

開発状況については、ロードマップ6 によると、現状はでアルファ版。
最新の v0.4.1 にてOzoneがネイティブのACL対応と、CSIに対応してKubernetesからも使えるようなった。
v0.5.0でベータ版になってHAな対応を始め、ネイティブのCSIに対応したり、v0.6.0からHDSFからのマイグレーション用意したりとなかなか夢が広がります。

さっそくお試ししてみる

Apache Hadoop Ozoneの公式ドキュメントにある Getting Started を使って進めます。

クラスタの用意

今回はMicroK8sを使ってクラスタを用意します。 MicroK8sって何?って方は簡単な紹介記事があるのでそちらを参照下さい。

yassan.hatenablog.jp

昔使っててまっさらにしても良いなら以下を実行
$ microk8s.reset

ダッシュボード、DNS、ストレージを有効にしておく
$ microk8s.enable dashboard dns storage

状態確認

$ microk8s.status --wait-ready
※ここでエラーでたら、再起動

ダッシュボードの準備

$ token=$(microk8s.kubectl -n kube-system get secret | grep default-token | cut -d " " -f1)
$ microk8s.kubectl -n kube-system describe secret $token
Name:         default-token-fqhb4
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: da83710d-2921-4717-b96e-394a4e6ea1d6

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1103 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IjY2UGV0RlZESTdpTzhQTHpzay16Y3JiMGVreURiaGVvN3RTMnlaNEZFZ2sifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLWZxaGI0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkYTgzNzEwZC0yOTIxLTQ3MTctYjk2ZS0zOTRhNGU2ZWExZDYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.dzlWWmtUl2afSlw3MePNcUntJpmxHHCn_h-5RrVPq3_ni3yl9y8pjAV2YBKa60PtzZ3kyJvhZTzaV8aVpG4CEvJ3P8Fgc_XJVW9VGVyUtq-DVAB8O_UdstW68H3z46pz7nV0zFeKWiCdF2UuacHliTIHUve2bn_vDENOFeZwy2LtLF2W7vr_fz3jBGqwjD30Ea5ShS5GzPCkPFICeeFvd06wO3xy__JKMQdacpPs1vsuVR9frBzc3DpIoDnvTOK_08MBlG9-bZgTQ3vLOoJgKKZtSjoMzJyz3G5lA_MlFmY8oXJSHIA7ijBz0Qt-WW3I0YEBg6wCO4e0CFWAyVeVHw

※↑のtokenを使う(…★)

proxyしてブラウザからアクセス出来るようにしておく

$ microk8s.kubectl proxy

ブラウザで以下にアクセス
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login

★のtokenをいれるとダッシュボード出てきます。

f:id:yassan0627:20191226071006p:plain

kubectlからMicroK8sのクラスタを触れる様にようにする

microk8s.kubectl でも良いし、以下のようにalias指定しても良いのですが、他でも使いたいときにめんどくさいので今回は別の方法を取ります。

sudo snap alias microk8s.kubectl kubectl

kubectlがない場合、特にこだわり無いならaptでinstall。

$ sudo apt install kubectl

MicroK8sで構築したクラスタ設定情報の書き出し

$ microk8s.kubectl config view --raw > microk8s.kubeconfig

kubectlでMicroK8sのクラスターを参照するようにする

$ export KUBECONFIG=$(pwd)/microk8s.kubeconfig

動作確認

$ kubectl get no
NAME             STATUS   ROLES    AGE   VERSION
microad-pc-752   Ready    <none>   97m   v1.17.0

Ozoneのデプロイ

Apache OzoneのDL DLサイト にアクセスして、 0.4.1-alphaのbinary をDL。

その後、適当な場所に展開。

$ wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/hadoop/ozone/ozone-0.4.1-alpha/hadoop-ozone-0.4.1-alpha.tar.gz
$ tar xvf hadoop-ozone-0.4.1-alpha.tar.gz
$ cd hadoop-ozone-0.4.1-alpha

公式ドキュメントの Minikube & Ozone [^MinikubeOzone] を元に進める 進める前に以下に、マニフェストを書き換え。 コンテナイメージをDockerHubから取得するのだけれど、イメージTagが存在していない 0.4.1-alpha になっている7 ので、まとめて 0.4.1 に置換する。

ozone-0.4.1-alpha/kubernetes/ 以下の

image: 'apache/ozone:0.4.1-alpha'

image: 'apache/ozone:0.4.1'

に一括で置換してしまう。

Getting Started の Minikube & Ozone で使う場所へ移動

$ cd ozone-0.4.1-alpha/kubernetes/examples/minikube

Dashboardトークンの有効期限切れになってアクセス出来なくなっていないか確認し、アクセス出来ない場合は、以下のようにしてトークンを取得してアクセス出来るようにしておく

kubectl -n kube-system describe secret   $(kubectl -n kube-system get secret | grep kubernetes-dashboard-token | awk '{print $1}')

マニフェストをデプロイ

$ kubectl apply -f .

結果をダッシュボードとかで確認。しばらくすると以下の様にすべて Running になっている。

$ kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
datanode-0   1/1     Running   0          87s
datanode-1   1/1     Running   0          105s
datanode-2   1/1     Running   0          103s
om-0         1/1     Running   0          28s
s3g-0        1/1     Running   0          57s
scm-0        1/1     Running   0          3m49s

※動いていない場合は、イメージタグの置換漏れだったりするので、 Dashboardから直接マニフェストを編集しても良いかも

$ kubectl get svc
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
datanode          ClusterIP   None             <none>        9870/TCP         82m
datanode-public   NodePort    10.152.183.152   <none>        9870:31869/TCP   82m
kubernetes        ClusterIP   10.152.183.1     <none>        443/TCP          125m
om                ClusterIP   None             <none>        9874/TCP         82m
om-public         NodePort    10.152.183.226   <none>        9874:31824/TCP   82m
s3g               ClusterIP   None             <none>        9878/TCP         82m
s3g-public        NodePort    10.152.183.101   <none>        9878:32165/TCP   82m
scm               ClusterIP   None             <none>        9876/TCP         82m
scm-public        NodePort    10.152.183.164   <none>        9876:30995/TCP   82m

f:id:yassan0627:20191226071143p:plain

管理画面(SCM)の確認

$ kubectl get svc
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
:
scm-public        NodePort    10.152.183.164   <none>        9876:30995/TCP   82m

となっているので、ブラウザで以下にアクセス

http://127.0.0.1:30995/static/

f:id:yassan0627:20191226071222p:plain

awsコマンド使ってファイルをputしてみる

S3 gatewayが以下の通り、32165ポートからアクセス出来るようになっている

$ kubectl get svc
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
:
s3g-public        NodePort    10.152.183.101   <none>        9878:32165/TCP   82m
:

S3 gatewayの画面(http://127.0.0.1:30995/)にアクセス f:id:yassan0627:20191226071521p:plain

バケットの作成

testバケットを作ってみる。

$ aws s3api --endpoint http://127.0.0.1:32165 create-bucket --bucket=test
{
    "Location": "http://127.0.0.1:32165/test"
}

適当にputしてみる

$ aws s3api --endpoint http://127.0.0.1:32165 put-object --bucket test --key key1 --body ./om-service.yaml

確認

$ aws s3 --endpoint http://127.0.0.1:32165 ls s3://test
2019-12-26 06:34:53        941 key1

ブラウザで以下にアクセス http://127.0.0.1:32165/test?browser=true

f:id:yassan0627:20191226071950p:plain

key1のリンクを押下するとputしたファイルが見えます f:id:yassan0627:20191226072004p:plain

その他、S3 APIは以下を参照

Documentation for Apache Hadoop Ozone

最後に

如何でしたでしょうか?

CSIはどこいった?
Minikubeじゃ出来ないってのを終わってから気がついたので、また今度。。。。良い子はexampleのマニフェストをちゃんと読もう。

また、 Ozone File System で、HDFSコマンドでファイルのput出来るらしいのでこっちも試したいところです。

以上、20日目の記事でした。

補足

スライド

動画

Youtubeで「Apache Ozone」で検索するとチュートリアルとかもあります

その他