すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:Jindo CLI 統合のベストプラクティス

最終更新日:Oct 09, 2025

Alibaba Cloud Jindo CLI は、OSS-HDFS サービスを管理するためのコマンドラインインターフェイス (CLI) です。このトピックでは、Java Spring Boot を使用して Jindo CLI コマンドを API 操作としてラップし、OSS-HDFS サービスをプログラムで管理する方法について説明します。このトピックでは、集中型デプロイメントと分離型デプロイメントの 2 つのアーキテクチャについて説明します。これらのアーキテクチャは、運用保守 (O&M) 制御システム、自動化スクリプト、継続的インテグレーションと継続的デリバリー (CI/CD) ツールなどのシナリオに適しています。

デプロイメントオプション

オプション 1: 集中型デプロイメント

業務アプリケーションと Jindo CLI ツールは同じサーバーにデプロイされ、ローカル呼び出しを介して統合されます。次の図に示すように、業務アプリケーションは業務サーバー上の Jindo CLI を直接呼び出して OSS-HDFS サービスにアクセスします。

image
  • 利点: ネットワークオーバーヘッドがなく、実装がシンプルです。

  • 欠点: CLI の実行は、主要な業務アプリケーションのリソースを消費します。

  • シナリオ: このオプションは、迅速な検証、内部自動化スクリプト、および単一の管理プラットフォームに適しています。

オプション 2: 分離型デプロイメント

業務アプリケーション (サーバー A) は Jindo CLI (サーバー B) から分離されています。CLI は独立した HTTP Agent サービスとしてラップされ、2 つのコンポーネントは RESTful API を介して通信します。次の図に示すように、業務アプリケーションは HTTP Agent をリモートで呼び出します。その後、Agent は Jindo CLI を呼び出して OSS-HDFS サービスにアクセスします。

image
  • 利点: AccessKey はツールサーバー上で分離されます。業務アプリケーションとツールは分離されています。これにより、独立したアップグレードとクロス言語呼び出しがサポートされます。このツールは、複数の業務プラットフォームに同時にサービスを提供できます。

  • 欠点: このオプションでは、Agent サービスの追加のメンテナンスが必要になり、ネットワークオーバーヘッドが発生します。RESTful API 呼び出しには、デフォルトで認証がありません。認証トークンメカニズムなど、独自のセキュリティチェックを実装する必要があります。

  • シナリオ: このオプションは、本番環境、特に拡張性の要件が高いシステムや、複数の業務プラットフォームにサービスを提供するシナリオに適しています。

準備

開始する前に、次の前提条件が満たされていることを確認してください:

  1. OSS-HDFS サービス: OSS-HDFS サービスが有効になっているバケット。詳細については、「OSS-HDFS サービスを有効にする」をご参照ください。

  2. 権限: Resource Access Management (RAM) ユーザーは、OSS-HDFS サービスにアクセスするための権限を持っている必要があります。最小権限の原則に従ってください。たとえば、読み取り権限のみが必要な場合は、書き込み権限や削除権限を付与しないでください。詳細については、「OSS-HDFS サービスへのアクセス権限を付与する」をご参照ください。

  3. サーバー環境: ECS インスタンスや自己管理サーバーなど、少なくとも 1 台のサーバーが必要です。このサーバーは、バケットと同じリージョンにあり、内部ネットワーク経由で OSS にアクセスでき、Java 開発キット (JDK) がインストールされている必要があります。

  4. Jindo SDK: Jindo ソフトウェア開発キット (SDK) がインストールされ、構成されている必要があります。

    • 集中型デプロイメント: SDK を業務サーバーにインストールします。

    • 分離型デプロイメント: SDK は Agent サーバー (サーバー B) にのみインストールします。

    クリックして展開: Jindo SDK のインストール手順 (インストール済みの場合はスキップ)

    1. SDK のダウンロードと解凍

      このトピックでは、Linux x86 プラットフォーム上の Jindo SDK 6.10.0 を例として使用します。

      # Jindo SDK パッケージをダウンロード
      wget https://jindodata-binary.oss-cn-shanghai.aliyuncs.com/release/6.10.0/jindosdk-6.10.0-linux.tar.gz
      
      # 現在のディレクトリに解凍
      tar zxvf jindosdk-6.10.0-linux.tar.gz
    2. 構成ファイルの作成

      解凍した SDK の /conf ディレクトリに移動します。

      cd jindosdk-6.10.0-linux/conf/
    3. 次の内容で jindosdk.cfg ファイルを作成します。プレースホルダーの値を実際の構成に置き換えてください。

      [common]
      # デフォルト設定を使用します。
      logger.dir = /tmp/jindo/
      logger.sync = false
      logger.consolelogger = false
      
      [jindosdk]
      # バケットが配置されているリージョンの OSS-HDFS エンドポイントに置き換えます。
      fs.oss.endpoint = cn-hangzhou.oss-dls.aliyuncs.com
      # AccessKey ID に置き換えます。
      fs.oss.accessKeyId = yourAccessKeyId
      # AccessKey シークレットに置き換えます。
      fs.oss.accessKeySecret = yourAccessKeySecret
    4. Jindo CLI 環境変数の構成

      次の例では、Jindo CLI が /usr/lib/jindosdk-6.10.0-linux ディレクトリにインストールされていることを前提としています:

      export JINDOSDK_HOME=/usr/lib/jindosdk-6.10.0-linux
      export JINDOSDK_CONF_DIR=${JINDOSDK_HOME}/conf
      export PATH=${PATH}:${JINDOSDK_HOME}/bin
      説明

      環境変数を永続的にするには、エクスポートコマンドを ~/.bashrc ファイルに追加します。

オプション 1: 集中型デプロイメント

業務アプリケーションと Jindo CLI は同じサーバー上にあります。業務アプリケーションは Jindo CLI コマンドを直接呼び出します。このオプションは、迅速な検証に適しています。

ステップ 1: バックエンド API 操作の開発

Spring Boot API 操作を作成して jindo fs -ls コマンドをラップします。

説明

メインコマンドは Jindo SDK のバージョンによって異なる場合があります。たとえば、一部の新しいバージョンでは jindo を使用し、一部の古いバージョンでは jindofs を使用します。

コードをコピーする前に、サーバーのコマンドラインで jindo -v または jindofs -v を実行して、環境に適した正しいコマンドを決定してください。このトピックの例では jindo を使用しています。

package com.example.jindotest;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

@RestController
public class JindoController {

    @PostMapping("/jindo-ls")
    public ResponseEntity<String> executeJindoLs(@RequestParam("path") String path) {
        // パス形式を検証
        if (path == null || !path.startsWith("oss://")) {
            return ResponseEntity.badRequest().body("Invalid OSS path");
        }

        try {
            // Jindo CLI コマンドをビルド
            ProcessBuilder processBuilder = new ProcessBuilder("jindo", "fs", "-ls", path);
            processBuilder.redirectErrorStream(true);

            // プロセスを開始
            Process process = processBuilder.start();

            // コマンド出力を読み取り
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder result = new StringBuilder();  
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line).append("\n");
            }

            // プロセスの終了を待機し、終了コードを確認
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                // コマンド実行結果を返す
                return ResponseEntity.ok(result.toString());
            } else {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Command failed with exit code: " + exitCode);
            }
        } catch (IOException | InterruptedException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Error executing command: " + e.getMessage());
        }
    }
}

ステップ 2: 結果の検証

デプロイメントが完了したら、次のいずれかの方法で統合を検証できます。

  1. Web インターフェイスでの検証:

    サンプル Web インターフェイスコードについては、「付録」をご参照ください。コード内のリクエストパスを /jindo-ls に変更します。http://<業務サーバーのパブリック IP>:8080 にアクセスして統合をテストできます。業務サーバーでインバウンドトラフィックに対してポート 8080 を開く必要があります。oss://my-bucket.cn-hangzhou.oss-dls.aliyuncs.com/ などのファイルパスを入力し、「List Files」ボタンをクリックします。インターフェイスに OSS ファイルリストが表示された場合、統合は成功です。

    image

  2. API 操作を使用した検証 (代替)

    フロントエンドをデプロイできない場合は、curl を使用してバックエンド API 操作をテストできます。

    curl -X POST "http://localhost:8080/jindo-ls?path=oss://bucket.endpoint/"

    ファイルリストが返された場合、統合は成功です。

検証が成功したら、他のコマンドをシステムに統合できます。詳細については、付録の「一般的な Jindo CLI コマンド」をご参照ください。

オプション 2: 分離型デプロイメント

このオプションは、本番環境に推奨されます。このアーキテクチャでは、Jindo CLI は独立した Agent サービスとしてラップされ、責任を分離します。このアーキテクチャは、内部ネットワーク環境やセキュリティ要件が比較的低いシナリオに適しています。セキュリティ要件が高いシナリオでは、独自の API アクセス検証メカニズムを実装する必要があります。

ステップ 1: サーバー B で Agent サービスを開始する

  1. Agent スクリプトの作成

    JindoCliHttpAgent.py ファイルを作成します。スクリプトは Python 3 で実装されています。他の技術スタックでも同様のアプローチを使用できます。

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    import http.server
    import json
    import subprocess
    import socketserver
    import shlex  
    
    class CommandHandler(http.server.SimpleHTTPRequestHandler):
        def do_POST(self):
            if self.path == '/execute':
                # リクエスト本文を読み取り
                content_length = int(self.headers.get('Content-Length', 0))
                post_data = self.rfile.read(content_length)
                try:
                    # JSON リクエストを解析
                    data = json.loads(post_data)
                    command = data.get('command', '')
    
                    # command パラメーターを検証
                    if not command:
                        self.send_response(400)
                        self.send_header('Content-Type', 'application/json')
                        self.end_headers()
                        self.wfile.write(json.dumps({'error': 'Missing "command" parameter'}).encode('utf-8'))
                        return
    
                    # コマンドを安全に実行
                    command_list = shlex.split(command)
                    output = subprocess.check_output(command_list, stderr=subprocess.STDOUT)
                    output_str = output.decode('utf-8').strip()
    
                    # 実行結果を返す
                    self.send_response(200)
                    self.send_header('Content-Type', 'application/json')
                    self.end_headers()
                    self.wfile.write(json.dumps({'output': output_str}).encode('utf-8'))
                except Exception as e:
                    # エラーメッセージを返す
                    self.send_response(500)
                    self.send_header('Content-Type', 'application/json')
                    self.end_headers()
                    self.wfile.write(json.dumps({'error': str(e)}).encode('utf-8'))
            else:
                self.send_error(404, 'Not Found')
    
    # マルチスレッド HTTP サーバー
    class ThreadedHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
        pass
    
    if __name__ == '__main__':
        # HTTP Agent サービスを開始
        server_address = ('0.0.0.0', 8000)
        httpd = ThreadedHTTPServer(server_address, CommandHandler)
        print('Starting secure HTTP Agent on port 8000...')
        httpd.serve_forever()
    
  2. ファイアウォールの構成

    サーバー B のインバウンドトラフィックに対してポート 8000 を開きます。業務サーバー (サーバー A) のプライベート IP アドレスからのアクセスのみを許可し、パブリックネットワークアクセスを拒否します。

  3. 実行権限の追加

    chmod +x JindoCliHttpAgent.py
  4. HTTP Agent サービスの開始

    python3 JindoCliHttpAgent.py

    サービスが開始されると、ポート 8000 でリクエストをリッスンします。次の図は、起動結果の例を示しています。

    image.png

  5. Agent サービスの検証

    新しいターミナルを開き、Agent が正しく動作しているかテストします。 と を実際の値に置き換えます。例: oss://my-bucket.cn-hangzhou.oss-dls.aliyuncs.com/

    curl -X POST http://localhost:8000/execute \
       -H "Content-Type: application/json" \
       -d '{"command": "jindo fs -ls oss://<Bucketname>.<EndPoint>/"}'

    次の図に示すように、JSON 形式のファイルリストが返された場合、Agent は正常にデプロイされています。

    image

ステップ 2: サーバー A に業務システムを統合する

説明

メインコマンドは Jindo SDK のバージョンによって異なる場合があります。たとえば、一部の新しいバージョンでは jindo を使用し、一部の古いバージョンでは jindofs を使用します。

サーバーのコマンドラインで jindo -v または jindofs -v を実行して、環境に適した正しいコマンドを確認してください。このトピックのすべての例では jindo を使用しています。

Java API 操作を作成して Agent サービスを呼び出します。コード内の <サーバー B のプライベート IP> をサーバー B の実際のプライベート IP アドレスに置き換えます。

package com.example.jindotest;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

@RestController
public class JindoAgentController {
    
    @PostMapping("/jindo-agent-ls")
    public ResponseEntity<String> executeJindoLs(@RequestParam String path) {
        // パス形式を検証
        if (path == null || !path.startsWith("oss://")) {
            return ResponseEntity.badRequest().body("Invalid OSS path");
        }

        try {
            // JSON リクエスト本文を構築
            String requestBody = String.format("{\"command\": \"jindo fs -ls %s\"}", path);
      
            // curl を使用して Agent サービスを呼び出し
            ProcessBuilder processBuilder = new ProcessBuilder(
                "curl", "-X", "POST", "http://<サーバー B のプライベート IP>:8000/execute", 
                "-H", "Content-Type: application/json",
                "-d", requestBody
            );
          
            // プロセスを開始
            Process process = processBuilder.start();

            // 出力ストリームを読み取り
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder result = new StringBuilder();  
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line).append("\n");
            }

            // 実行結果を確認
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                
                return ResponseEntity.ok(result.toString());
            } else {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Command failed with exit code: " + exitCode);
            }
        } catch (IOException | InterruptedException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error executing command: " + e.getMessage());
        }
    }
}
説明

本番環境では、パフォーマンスとエラー処理を向上させるために、curl の代わりに RestTemplate や WebClient などの HTTP クライアントライブラリを使用してください。

ステップ 3: 結果の検証

  1. ネットワーク接続の確認

    分離型デプロイメントを使用する場合、サーバーが相互に接続できることを確認してください。サーバー A で ping <サーバー B のプライベート IP> を実行できます。パケット損失なしで安定した ping 応答を受信した場合、2 つのサーバーは接続されています。image

  2. Web インターフェイスでの検証

    サンプル Web インターフェイスコードについては、「付録」をご参照ください。コード内のリクエストパスを /jindo-agent-ls に変更します。http://<サーバー A のパブリック IP>:8080 にアクセスして統合をテストできます。サーバー A でインバウンドトラフィックに対してポート 8080 を開く必要があります。oss://my-bucket.cn-hangzhou.oss-dls.aliyuncs.com/ などのファイルパスを入力し、「List Files」ボタンをクリックします。インターフェイスに OSS ファイルリストが表示された場合、統合は成功です。

    image

  3. API 操作を使用した検証 (代替)

    フロントエンドをデプロイできない場合は、curl を使用してバックエンド API 操作をテストできます。

    curl -X POST "http://localhost:8080/jindo-agent-ls?path=oss://<bucket>.<Endpoint>/"

    ファイルリストが返された場合、統合は成功です。

検証が成功したら、他のコマンドをシステムに統合できます。詳細については、付録の「一般的な Jindo CLI コマンド」をご参照ください。

セキュリティに関する推奨事項

Jindo CLI は、OSS-HDFS サービスの構成管理とデータ削除機能を提供します。不適切な使用は深刻な結果を招く可能性があります。本番環境にサービスをデプロイする前に、テスト環境で徹底的なテストを実施する必要があります。

コア原則

  • 最小権限: タスクを完了するために必要な最小限の権限のみを付与します。過剰な権限付与は避けてください。

  • アクセス制御: クライアント側で厳格な ID 検証と権限付与メカニズムを実装します。

  • 同時実行制御: 同時操作の数を制限して、構成の競合やデータ管理の問題を防ぎます。

ネットワークセキュリティ

  • 分離型デプロイメント: 分離型デプロイメントでは、Agent サーバーへのアクセスを業務サーバーのプライベート IP アドレスからのみ許可します。Agent サーバーをインターネットに公開しないでください。

  • ポート管理: セキュリティグループまたはファイアウォールを使用して、ポートへのアクセスを正確に制御します。

リファレンス

付録

一般的な Jindo CLI コマンド

コマンド

説明

stat

ファイルのステータスを表示します。

jindo fs -stat oss://<bucket-name>.<oss-hdfs-endpoint>/<file>

ls

ディレクトリ内のファイルを一覧表示します。オプションの -R パラメーターは再帰的な一覧表示を示します。

jindo fs -ls [-R] oss://<bucket-name>.<oss-hdfs-endpoint>/<dir>

du

ディレクトリ内のすべてのファイルのサイズを表示します。次のパラメーターはオプションです:

  • -s: 宛先フォルダの合計サイズを計算します。

  • -h: 人間が読める形式でサイズを表示します。

jindo fs -du oss://<bucket-name>.<oss-hdfs-endpoint>/<dir>

count

ファイルサイズとファイル数を表示します。オプションの -h パラメーターは、ファイルサイズを人間が読める形式で表示します。

jindo fs -count -h oss://<bucket-name>.<oss-hdfs-endpoint>/<dir>

listUserGroupsMappings

すべてのユーザーとグループの関係を一覧表示します。

jindo admin -listUserGroupsMappings -dlsUri oss://<bucket-name>.<oss-hdfs-endpoint> [-maxKeys <value>] [-marker <value>]

dumpInventory

ファイルメタデータをエクスポートします。

jindo admin -dumpInventory oss://<bucket-name>.<oss-hdfs-endpoint>/<dir>

putConfig

ディレクトリ保護などのサービス属性を設定します。

jindo admin putConfig -dlsUri oss://<bucket-name>.<oss-hdfs-endpoint> -conf <key1=value1> -conf <key2=value2> ...]

getConfig

ディレクトリ保護情報などの構成情報を取得します。

jindo admin getConfig -dlsUri oss://<bucket-name>.<oss-hdfs-endpoint> -name <keys>

サンプル Web インターフェイスコード

次のコードを index.html として保存し、Spring Boot プロジェクトの src/main/resources/static/ ディレクトリに配置します:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Jindo CLI 管理インターフェイス</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1000px;
            margin: 50px auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            background-color: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            text-align: center;
            border-bottom: 2px solid #007bff;
            padding-bottom: 10px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }
        input[type="text"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 16px;
            box-sizing: border-box;
        }
        button {
            background-color: #007bff;
            color: white;
            padding: 12px 24px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            margin-right: 10px;
        }
        button:hover {
            background-color: #0056b3;
        }
        button:disabled {
            background-color: #6c757d;
            cursor: not-allowed;
        }
        .result {
            margin-top: 20px;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background-color: #f8f9fa;
            min-height: 100px;
            font-family: monospace;
            white-space: pre-wrap;
            font-size: 14px;
        }
        .loading {
            color: #007bff;
            font-style: italic;
        }
        .error {
            color: #dc3545;
            background-color: #f8d7da;
            border-color: #f5c6cb;
        }
        .success {
            color: #155724;
            background-color: #d4edda;
            border-color: #c3e6cb;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1> Jindo CLI 管理インターフェイス</h1>
        
        <div class="form-group">
            <label for="ossPath">OSS パス:</label>
            <input type="text" id="ossPath" 
                   value="oss://your-bucket-name.cn-hangzhou.oss-dls.aliyuncs.com/" 
                   placeholder="OSS パスを入力 (例: oss://bucket-name.endpoint/)">
        </div>
        
        <div class="form-group">
            <button onclick="listFiles()">ファイルの一覧表示 (ls)</button>
            <button onclick="clearResult()">結果をクリア</button>
        </div>
        
        <div id="result" class="result">
            Jindo CLI コマンドを実行する準備ができました...
        </div>
    </div>

    <script>
        function listFiles() {
            const path = document.getElementById('ossPath').value;
            const resultDiv = document.getElementById('result');
            
            if (!path || !path.startsWith('oss://')) {
                resultDiv.innerHTML = 'エラー: "oss://" で始まる有効な OSS パスを入力してください';
                resultDiv.className = 'result error';
                return;
            }
            
            // ロード中を表示
            resultDiv.innerHTML = 'ロード中... お待ちください';
            resultDiv.className = 'result loading';
            
            // バックエンド API を呼び出し
            fetch('/jindo-ls', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'path=' + encodeURIComponent(path)
            })
            .then(response => {
                if (response.ok) {
                    return response.text();
                } else {
                    throw new Error('HTTP ' + response.status + ': ' + response.statusText);
                }
            })
            .then(data => {
                resultDiv.innerHTML = '成功:\n\n' + data;
                resultDiv.className = 'result success';
            })
            .catch(error => {
                resultDiv.innerHTML = 'エラー:\n\n' + error.message;
                resultDiv.className = 'result error';
            });
        }
        
        function clearResult() {
            document.getElementById('result').innerHTML = 'Jindo CLI コマンドを実行する準備ができました...';
            document.getElementById('result').className = 'result';
        }
        
        // Enter キーで listFiles をトリガーできるようにする
        document.getElementById('ossPath').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                listFiles();
            }
        });
    </script>
</body>
</html>