はじめに
この記事は実機検証前の手順書です。 コマンド出力や成功結果は記載していません。実機検証後に結果と修正点を追記します。
現在、次のような構成でApache IcebergのデータをHDFSへ保存しているとします。
これをオブジェクトストレージ中心の構成へ移行する場合、Apache Ozoneは候補の一つです。Ozoneは分散オブジェクトストアで、S3 Gatewayに加えてHadoop FileSystem APIも提供します。そのため、Hadoopエコシステムとの親和性を保ちながらHDFSからの移行を検討できる点が興味深いところです。
用途によって選択肢は変わります。
- AWS S3互換環境を手軽に用意することが主目的なら、MinIOなども有力
- HDFSからの移行やHadoop系処理基盤との統合を検証するなら、Apache Ozoneが有力候補
OzoneはHDFSの完全な置き換えを保証するものではありません。API、運用、性能、障害復旧をワークロードごとに検証する必要があります。
今回はIcebergの移行までは行わず、Kubernetes上にOzoneを構築し、S3互換APIで読み書きするところまでをゴールにします。
公式情報とバージョン方針
この記事は2026年9月20日時点で、次の公式情報を確認して作成しています。
- Apache Ozone Downloads
- Try Ozone With Kubernetes
- Apache Ozone公式Helm Chartリポジトリ
- 公式Chartのvalues.yaml
- S3 Gateway
- Securing S3
確認時点のOzone最新安定版は2.2.1です。一方、公式Helm repositoryの最新Chartは0.3.0で、appVersion、つまりChartが既定で利用するOzoneは2.1.1です。
この記事では、未検証のChartとイメージの組み合わせを避けるため、Chart 0.3.0とOzone 2.1.1を固定します。Ozone 2.2.1への更新は、公式Chartが対応した後、またはChart 0.3.0との互換性を別途検証した後に行います。「Ozoneの最新版」と「公式Chartが現在対象にする版」は同じとは限らない点に注意してください。
今回構築する構成
各コンポーネントの役割は次のとおりです。
| コンポーネント | 役割 |
|---|---|
| OM(Ozone Manager) | Volume、Bucket、Keyなど名前空間のメタデータを管理する |
| SCM(Storage Container Manager) | DataNode、Container、Pipeline、レプリカ配置を管理する |
| DataNode | オブジェクトのデータブロックをContainerとして保存する |
| S3 Gateway | S3互換REST APIをOzoneへ変換する。データ本体は保持しない |
| Recon | OM、SCM、DataNodeの情報を集約し、読み取り専用のUI/APIを提供する |
この検証ではDataNodeを3台に分散し、既定のRATIS/THREE、すなわち3レプリカを利用します。3レプリカは容量とネットワークに約200%の追加オーバーヘッドがあるため、本番では必要容量やECも含めて設計します。
前提環境
Kubernetesクラスタ自体の構築は扱いません。次の状態から開始します。
- Linux環境
-
kubectlで操作可能な既存クラスタ - Helm 3
- 複数のWorker Node
- 動的プロビジョニング可能なPersistentVolume
- AWS CLI
ノード構成のイメージは次のとおりですが、手順はホスト名に依存しません。
control-plane
worker1
worker2
worker3
最初に確認します。
kubectl get nodes -o wide
kubectl get storageclass
helm version
aws --version
DataNodeのPVCがReadWriteOnceで作成されるため、利用するStorageClassが各Worker Nodeでボリュームを提供できるか確認します。ローカルPVを使う場合は、Podの再スケジュール先とPVのNode Affinityにも注意が必要です。
Namespaceを作成する
kubectl create namespace ozone
以降、Ozoneのリソースをozone Namespaceにまとめます。
公式Helm repositoryを追加する
公式ドキュメントに記載されたrepositoryを追加します。
helm repo add ozone https://apache.github.io/ozone-helm-charts/
helm repo update ozone
helm search repo ozone/ozone --versions
この記事で固定するChartを確認します。
helm show chart ozone/ozone --version 0.3.0
helm show values ozone/ozone --version 0.3.0 > values-default.yaml
helm show valuesは、ブログ記事の例ではなく、現在取得できるChartに実在するキーを調べるために重要です。Chartを更新する場合は、この記事のvalues.yamlとの差分を必ず確認します。
検証用values.yamlを作成する
作業ディレクトリにvalues.yamlを作成します。まずStorageClass名を確認します。
kubectl get storageclass
次の<YOUR_STORAGE_CLASS>を実在する名前へ置き換えます。
image:
repository: apache/ozone
pullPolicy: IfNotPresent
tag: "2.1.1"
clusterId: cluster1
env:
- name: OZONE-SITE.XML_ozone.replication.type
value: RATIS
- name: OZONE-SITE.XML_ozone.replication
value: THREE
datanode:
replicas: 3
persistence:
enabled: true
accessModes:
- ReadWriteOnce
path: /data
size: 100Gi
storageClassName: <YOUR_STORAGE_CLASS>
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values: [ozone]
- key: app.kubernetes.io/instance
operator: In
values: [ozone]
- key: app.kubernetes.io/component
operator: In
values: [datanode]
topologyKey: kubernetes.io/hostname
om:
replicas: 3
persistence:
enabled: true
accessModes: [ReadWriteOnce]
path: /data
size: 20Gi
storageClassName: <YOUR_STORAGE_CLASS>
scm:
replicas: 1
persistence:
enabled: true
accessModes: [ReadWriteOnce]
path: /data
size: 20Gi
storageClassName: <YOUR_STORAGE_CLASS>
s3g:
replicas: 1
service:
rest:
type: ClusterIP
port: 9878
web:
type: ClusterIP
port: 19878
persistence:
enabled: false
recon:
enabled: true
service:
type: ClusterIP
port: 9888
OM、SCM、DataNodeにはPVCを割り当てます。S3 Gatewayはステートレスなプロトコル変換層なので、今回の構成では永続化しません。
Chart 0.3.0にはRecon用のpersistenceキーがありません。そのため、存在しないキーは追加していません。Reconは監視・調査用であり、データの正本はOM、SCM、DataNode側です。
DataNodeの必須Pod Anti-Affinityにより、同じreleaseの3 Podを異なるkubernetes.io/hostnameへ配置します。配置可能なWorker Nodeが3台未満ならPendingになるため、その環境ではrequired...をpreferred...へ緩めるか、ノードを増やす必要があります。
設定をインストール前にレンダリングして確認します。
helm lint ozone/ozone \
--version 0.3.0 \
--values values.yaml
helm template ozone ozone/ozone \
--namespace ozone \
--version 0.3.0 \
--values values.yaml > rendered.yaml
Ozoneをインストールする
helm install ozone ozone/ozone \
--namespace ozone \
--version 0.3.0 \
--values values.yaml
release名をozoneに固定しています。後続のラベルセレクタやAnti-Affinityもこの名前を前提にします。
Pod、Service、PVCを確認する
kubectl get pods -n ozone
kubectl get pods -n ozone -o wide
kubectl get svc -n ozone
kubectl get pvc -n ozone
すべてのPodがReadyになり、PVCがBoundになるかを確認する予定です。DataNodeだけを絞り込み、配置先を確認できます。
kubectl get pods -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=datanode \
-o custom-columns='POD:.metadata.name,NODE:.spec.nodeName,PHASE:.status.phase'
3つのDataNodeが異なるNodeに表示されることが期待値です。
Ozoneクラスタの状態を確認する
Pod名を決め打ちせず、Chartが付与するラベルから取得します。
SCM_POD=$(kubectl get pods -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=scm \
-o jsonpath='{.items[0].metadata.name}')
OM_POD=$(kubectl get pods -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=om \
-o jsonpath='{.items[0].metadata.name}')
kubectl exec -n ozone "$SCM_POD" -- ozone version
kubectl exec -n ozone "$SCM_POD" -- ozone admin safemode status
kubectl exec -n ozone "$SCM_POD" -- ozone admin datanode list
kubectl exec -n ozone "$OM_POD" -- ozone admin om roles -id cluster1 --table
ここでは次を確認する予定です。
- SCMがsafe modeを抜けている
- 3台のDataNodeが認識され、HEALTHYになっている
- 3台のOMにLEADER/FOLLOWERの役割が付いている
CLIのオプションはバージョン差分があり得るため、エラー時は対象コンテナ内のhelpを正とします。
kubectl exec -n ozone "$SCM_POD" -- ozone admin --help
kubectl exec -n ozone "$SCM_POD" -- ozone admin datanode --help
kubectl exec -n ozone "$OM_POD" -- ozone admin om roles --help
S3 Gatewayへport-forwardする
最初から外部公開せず、公式Chartが作成するラベルからService名を取得します。
kubectl get svc -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=s3g
S3G_SERVICE=$(kubectl get svc -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=s3g \
-o jsonpath='{range .items[?(@.spec.ports[*].name=="rest")]}{.metadata.name}{"\n"}{end}')
kubectl port-forward -n ozone "service/${S3G_SERVICE}" 9878:9878
Chart 0.3.0をrelease名ozoneで入れた場合、REST Serviceは通常ozone-s3g-restですが、上の手順なら名前を決め打ちせずに確認できます。port-forwardを実行したターミナルは開いたままにします。
NodePortでクラスタ外から接続する場合
継続的な検証で別PC、Spark、Flink、TrinoなどからS3 Gatewayへ接続する場合は、S3 API用ServiceをNodePortへ変更できます。ReconやS3 GatewayのWebポートまで外部公開する必要はないため、s3g.service.restだけを変更します。
values.yamlのS3 Gateway設定を次のように変更します。
s3g:
replicas: 1
service:
rest:
type: NodePort
port: 9878
nodePort: 30878
web:
type: ClusterIP
port: 19878
persistence:
enabled: false
30878は例です。一般的な既定NodePort範囲である30000〜32767のうち、クラスタ内で未使用かつネットワークポリシー上許可できる番号を指定します。クラスタ側でNodePort範囲を変更している場合は、その設定に合わせます。
変更を反映します。
helm upgrade ozone ozone/ozone \
--namespace ozone \
--version 0.3.0 \
--values values.yaml
ServiceとNodeのIPアドレスを確認します。
kubectl get svc -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=s3g
kubectl get nodes -o wide
ozone-s3g-restのTYPEがNodePort、PORT(S)が9878:30878/TCPのようになっていることを確認する予定です。外部クライアントから到達可能なNodeのIPアドレスを使い、疎通を確認します。
export OZONE_NODE_IP='<REACHABLE_NODE_IP>'
export OZONE_S3_ENDPOINT="http://${OZONE_NODE_IP}:30878"
curl -v "${OZONE_S3_ENDPOINT}/"
aws \
--endpoint-url "${OZONE_S3_ENDPOINT}" \
s3api list-buckets
NodePortは通常、どのKubernetes NodeのIPアドレスでも同じポートを受け付け、ServiceがS3 Gateway Podへ転送します。ただし、CNI、kube-proxyの構成、ファイアウォール、クラウドのSecurity Groupなどによって到達可能なNodeは異なります。少なくともクライアントから対象NodeのTCP 30878への通信を許可します。インターネット全体へ開放せず、接続元の管理ネットワークや利用ホストに限定します。
この検証構成はHTTPで、Ozone securityも無効です。そのため、任意のAccess Key / Secret Keyを使用でき、通信も暗号化されません。信頼できないネットワークへNodePortを公開してはいけません。本番利用では、次を別途設計します。
- TLS終端と証明書管理
- Kerberosを含むOzone securityとS3資格情報の発行・失効
- 接続元IPの制限とNetworkPolicy
- 複数S3 Gatewayとロードバランサー
- 固定DNS名と監視
一時的な動作確認だけならport-forwardを維持し、NodePortは閉じたままにする方が安全です。NodePortを使用する場合、以降のAWS CLIコマンドにあるhttp://localhost:9878は${OZONE_S3_ENDPOINT}へ読み替えます。
AWS CLIの認証情報を設定する
今回のChart既定構成はKerberosを有効にしていません。Ozone公式ドキュメントでは、security無効時は任意のAccess Key / Secret Keyペアを使用できます。検証専用の値を別ターミナルで環境変数へ設定します。
export AWS_ACCESS_KEY_ID='ozone-test-user'
export AWS_SECRET_ACCESS_KEY='ozone-test-secret'
export AWS_DEFAULT_REGION='us-east-1'
export AWS_EC2_METADATA_DISABLED='true'
これらは検証用のダミー値です。values.yaml、シェルスクリプト、.envなどへ実際の秘密情報を書いてGitへコミットしてはいけません。
本番向けにKerberosを含むsecurityを有効化した構成では任意値は使えません。kinit後に次の公式コマンドでユーザーの資格情報を取得します。
ozone s3 getsecret
管理者が対象ユーザーを指定する場合はozone s3 getsecret -u <username>です。取得したSecretはパスワード同様に保護します。なお、公式ChartにはS3資格情報を自動生成するvaluesキーは確認できないため、存在しない設定を追加していません。
バケットを作成して読み書きする
Ozone S3 Gatewayは既定でpath-styleを利用できます。AWS CLIでendpointを明示します。
aws \
--endpoint-url http://localhost:9878 \
s3api create-bucket \
--bucket ozone-test
テストファイルを作成し、アップロードします。
echo "Hello Apache Ozone" > test.txt
aws \
--endpoint-url http://localhost:9878 \
s3 cp test.txt s3://ozone-test/
一覧を確認します。
aws \
--endpoint-url http://localhost:9878 \
s3 ls s3://ozone-test/
別名でダウンロードし、内容を確認します。
aws \
--endpoint-url http://localhost:9878 \
s3 cp s3://ozone-test/test.txt downloaded.txt
cat downloaded.txt
実機検証では、次の表示になることを確認する予定です。
Hello Apache Ozone
Pod再作成後の永続性を確認する
PVCはPodとは別のライフサイクルを持ちます。StatefulSetのPodを1つ再作成しても、同じPVCが再接続されればデータは残ります。ただし、PVCやPVを削除すると話が変わるため、一括削除は行いません。
まず対象とPVCを確認します。
kubectl get pods -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=datanode \
-o wide
kubectl get pvc -n ozone
対象を1 Podだけ明示し、再作成します。次の値は、直前の一覧から選んだ実在するPod名に置き換えます。
TARGET_DATANODE=<ONE_DATANODE_POD_NAME>
kubectl delete pod -n ozone "$TARGET_DATANODE"
kubectl get pods -n ozone -w
再作成後、DataNodeの状態とS3上のファイルを確認します。
kubectl exec -n ozone "$SCM_POD" -- ozone admin datanode list
aws \
--endpoint-url http://localhost:9878 \
s3 ls s3://ozone-test/
aws \
--endpoint-url http://localhost:9878 \
s3 cp s3://ozone-test/test.txt -
RATIS/THREEではデータが3台へ複製されますが、PVC自体の耐障害性はStorageClassの実装にも依存します。このテストは「1 Podの再作成後にデータへアクセスできるか」の確認であり、ノード消失、複数障害、PV障害、災害復旧を証明するものではありません。
Reconを確認する
Recon Serviceをラベルで取得し、ローカルへ転送します。
RECON_SERVICE=$(kubectl get svc -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=recon \
-o jsonpath='{.items[0].metadata.name}')
kubectl port-forward -n ozone "service/${RECON_SERVICE}" 9888:9888
ブラウザでhttp://localhost:9888/を開き、Datanodes、Pipelines、Containers、容量などを確認する予定です。Reconは読み取り専用の可観測性サービスで、クラスタ状態を変更する管理画面ではありません。反映には同期時間がかかる場合があります。
APIの例として、まずレスポンスを確認します。
curl -fsS http://localhost:9888/api/v1/clusterState
APIパスはバージョンで変わり得るため、利用するOzone版の公式Recon REST APIも確認します。
HDFSとの違いを整理する
単純化すると、HDFSは次の構成です。
NameNode
|
DataNode
DataNode
DataNode
Ozoneではメタデータとストレージ管理の役割がOMとSCMへ分かれ、S3 Gatewayなど複数のプロトコルヘッドを利用できます。
OM
|
SCM
|
DataNode
DataNode
DataNode
+ S3 Gateway
| 観点 | HDFS | Apache Ozone |
|---|---|---|
| 主なモデル | 階層型ファイルシステム | Volume / Bucket / Keyを持つオブジェクトストア |
| メタデータ | 主にNameNode | OMが名前空間、SCMがContainerとDataNodeを管理 |
| アクセス | HDFS API中心 | S3 API、Hadoop FileSystem APIなど |
| S3互換API | 標準機能ではない | S3 Gatewayで提供 |
| 移行判断 | 既存Hadoop処理との実績が多い | 互換性、性能、運用を個別検証する必要がある |
OzoneがHDFSの完全な置き換えになると断定はできません。特にIcebergでは、S3 APIの実装差、rename前提の有無、multipart upload、整合性、認証、Spark/Flink/Trino側のS3A設定を検証します。
今後の構成
次の段階では、ログ処理からIceberg、Ozoneまでを接続します。
rsyslog
|
Fluentd
|
Kafka
|
Flink
|
Iceberg
|
Apache Ozone
|
S3 Gateway
さらに、ローカルのS3互換環境で検証したIcebergデータをAWSへ展開できるかも検討します。
今回はどちらも実施しません。
トラブルシューティング
PodがPendingになる
イベント、リソース、Anti-Affinity、taintを確認します。
kubectl get pods -n ozone -o wide
kubectl describe pod -n ozone <POD_NAME>
kubectl get events -n ozone --sort-by=.lastTimestamp
kubectl describe node <NODE_NAME>
DataNodeを異なる3ノードへ必須分散しているため、配置可能なWorker Nodeが不足するとPendingになるのは意図した動作です。
PVCがBoundにならない
kubectl get pvc -n ozone
kubectl describe pvc -n ozone <PVC_NAME>
kubectl get pv
kubectl get storageclass
kubectl describe storageclass <STORAGE_CLASS_NAME>
kubectl get events -n ozone --sort-by=.lastTimestamp
storageClassNameの誤り、プロビジョナー停止、容量不足、AccessMode、volumeBindingMode、PVのNode Affinityを調べます。
DataNodeがSCMへ登録されない
kubectl logs -n ozone <DATANODE_POD> -c datanode
kubectl logs -n ozone <SCM_POD> -c scm
kubectl exec -n ozone <SCM_POD> -- ozone admin datanode list
kubectl get svc,endpoints -n ozone
kubectl get events -n ozone --sort-by=.lastTimestamp
SCMの名前解決、ポート、NetworkPolicy、時刻ずれ、PVCの権限、DataNode IDディレクトリを確認します。
S3 Gatewayへ接続できない
kubectl get pods,svc,endpoints -n ozone \
-l app.kubernetes.io/instance=ozone,app.kubernetes.io/component=s3g
kubectl logs -n ozone <S3G_POD> -c s3g
curl -v http://localhost:9878/
port-forwardを使う場合は転送処理が継続中か、REST用Serviceの9878番へ転送しているかを確認します。NodePortを使う場合は、ServiceのnodePort、Nodeの到達可能なIPアドレス、OSファイアウォール、ルーター、Security Groupなどで対象TCPポートが許可されているかを確認します。19878番はChart上のS3 Gateway Webポートで、S3 APIの接続先ではありません。
AWS CLIで認証エラーになる
env | grep '^AWS_'
aws --endpoint-url http://localhost:9878 s3api list-buckets --debug
kubectl logs -n ozone <S3G_POD> -c s3g
別AWS profileの影響、空の環境変数、endpoint、時刻ずれを確認します。security有効時はダミー資格情報ではなく、Kerberos認証後にozone s3 getsecretで取得した値が必要です。
DataNodeが同じWorker Nodeへ偏る
kubectl get pods -n ozone \
-l app.kubernetes.io/component=datanode \
-o wide
kubectl get statefulset -n ozone ozone-datanode -o yaml
kubectl describe pod -n ozone <DATANODE_POD>
適用済みのAffinityとPodラベルが一致するかを確認します。Chartのrelease名を変えた場合、app.kubernetes.io/instanceも合わせて変更します。
Pod再作成後にデータが見えない
kubectl get pods,pvc -n ozone -o wide
kubectl get pv
kubectl describe pod -n ozone <RECREATED_POD>
kubectl describe pvc -n ozone <PVC_NAME>
kubectl logs -n ozone <RECREATED_POD>
kubectl exec -n ozone "$SCM_POD" -- ozone admin datanode list
同じStatefulSet ordinalへ元のPVCが接続されたか、PVが別Nodeへ接続可能か、OM/SCMのPVCも保持されているか、DataNodeがHEALTHYへ戻ったかを確認します。
アンインストール
まず、残す必要があるデータとPVのReclaimPolicyを確認します。
helm list -n ozone
kubectl get pvc -n ozone
kubectl get pv
kubectl get storageclass
releaseを削除します。
helm uninstall ozone -n ozone
StatefulSetのPVCは自動削除されず残る場合があります。さらに、PVCを削除したときのPVの動作はStorageClass/PVのreclaimPolicyがDeleteかRetainかで異なります。RetainならPVや実体データが残る可能性があります。
kubectl get pvc -n ozone
kubectl get pv \
-o custom-columns='NAME:.metadata.name,STATUS:.status.phase,CLAIM:.spec.claimRef.namespace/.spec.claimRef.name,RECLAIM:.spec.persistentVolumeReclaimPolicy,STORAGECLASS:.spec.storageClassName'
kubectl get storageclass \
-o custom-columns='NAME:.metadata.name,PROVISIONER:.provisioner,RECLAIM:.reclaimPolicy,BINDING:.volumeBindingMode'
不要であることを確認してからNamespaceを削除します。
kubectl delete namespace ozone
Namespace削除だけでPVやバックエンドのデータまで確実に消えるとは限りません。RetainのPVを削除する場合は、ストレージ実体を確認し、利用中でないことを確定してから個別に処理します。
まとめ
この記事では、公式Helm Chartの実在する設定項目に合わせて、次を検証する手順を整理しました。
- OM、SCM、3台のDataNodeをPVC付きで配置する
- DataNodeを異なるWorker Nodeへ分散する
- S3 Gatewayをport-forwardし、AWS CLIで作成・アップロード・一覧・ダウンロードを行う
- 必要な場合だけS3 API用ServiceをNodePortに変更し、接続元を制限してクラスタ外から利用する
- 1台のDataNode Pod再作成後にデータの永続性を確認する
- Recon UI/APIでクラスタ状態を確認する
現時点では実機検証前です。 「動作確認済み」ではなく、公式ドキュメントとChart
0.3.0を基にした検証計画です。実機検証後に、実際の出力、必要な修正、StorageClass固有の注意点を追記します。
「HDFSログ分析基盤をAWS S3へ段階移行する」シリーズへ組み込む場合
この内容を既存の「HDFSログ分析基盤をAWS S3へ段階移行する」シリーズへ組み込むなら、対象は次の記事です。
【第2編】HDFSのrawログとApache IcebergをローカルS3へ移行してみる
第2編は、HDFSからローカルS3互換ストレージであるApache OzoneへrawログとIcebergを移行する記事です。そのため、今回のKubernetes版Ozone構築は、第2編の「Apache Ozoneを構築する」から「S3 credentialを用意する」までを置き換える位置に相当します。
現在の第2編では、公式Docker Composeを使った単一ホストの検証用Ozoneを前提にしています。
今回の記事を使う場合は、次の流れへ変更できます。
つまり、置き換えるのは第2編全体ではなく、Docker ComposeでOzoneを用意している構築部分です。DistCp、Spark S3A、Icebergの論理コピー、Trino接続、HDFSとの比較およびrollbackは第2編の後半を引き続き利用できます。
接続先は、今回のport-forward用http://localhost:9878から、Kubernetesクラスタ内または運用ネットワークから到達できるS3 Gateway Serviceへ変更する必要があります。第2編で使用しているhttp://ozone1:9878をそのまま利用できるとは限りません。外部公開方法、DNS名、TLS、認証を決めてから、次の設定を同じendpointへ統一します。
- AWS CLIの
--endpoint-url - Hadoop S3Aの
fs.s3a.endpoint - SparkのS3A設定
- TrinoのS3 endpoint
- 移行用ツールの接続先
なお、「HDFSログ分析基盤をAWS S3へ段階移行する」シリーズの標準経路が既存のAmazon S3バックアップをそのまま利用する方針なら、第2編のOzone経由移行自体は任意手順のままです。ローカルS3互換性を検証する場合だけ、今回の記事を第1編と第2編後半の間へ差し込む構成が適しています。
