1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Docker】Ceph+AWS-CLI検証環境を作成する

1
Last updated at Posted at 2026-01-30

はじめに

概要

本記事はCephの検証用環境をDockerで作成してみようという試みになります。また作成したCephのテストのためAWS-CLIの環境も一緒に用意しています。
本来Cephは各サービスが複数あることと、物理的に分けられた記憶領域が複数あることが求められます。ですが個人環境にそのような環境を用意することは難易度が高いです。そのためDockerを使って環境を作ることが真っ先に思い浮かびますが、ネット上に参考となる記事があまり見当たりませんでした。
そんな中Apache Polarisの公式リポジトリに非常に参考になるdocker-compose.ymlがありましたので、それをベースに作成してみました。

お断り

概要で述べた通り、本来cephの性能や利点を引き出すための構成になっていません。
とりあえずクリティカルなエラーがなく起動できるようにカスタムし、バケットの作成という簡単なテストしか行っていないため動作が安定しない可能性があります。
UUIDを.envに固定していたり、起動するとkeyringがホストPCに保存されるためセキュリティ面に留意してください。

TLDR

こちらのリポジトリをクローンしてcephフォルダで、docker compose upすると、環境が立ち上がります。

ディレクトリおよびファイル構成

以下のようにディレクトリとファイルを用意しています。

./
├ .env
├ docker-compose.yml
├ ceph/
│  └ ceph.conf
└ dockerfiles/
   ├ mgr/
   │  └ Dockerfile
   ├ mon1/
   │  ├ Dockerfile
   │  └ entrypoint.sh
   ├ osd1/
   │  └ Dockerfile
   └ rgw1/
      └ Dockerfile

Dockerfileおよび関連ファイル

各コンテナのビルドについて解説します。

mon1

mon向けのkeyringを作成しておきます。
entrypointではadmin向けとosdで使うkeyringの有無を確認したのち作成します。

mon1/Dockerfile
FROM quay.io/ceph/ceph:v20.2.0

USER ceph

RUN ceph-authtool \
    --create-keyring /var/lib/ceph/tmp/ceph.mon.keyring \
    --gen-key -n mon. \
    --cap mon 'allow *'

COPY entrypoint.sh /entrypoint.sh
mon1/entrypoint.sh
#!/bin/sh

if [ ! -f "/etc/ceph/ceph.client.admin.keyring" ]; then
    echo "Start creating keyrings (Frist time only)"

    ceph-authtool \
    --create-keyring /etc/ceph/ceph.client.admin.keyring \
    --gen-key -n client.admin \
    --cap mon 'allow *' \
    --cap osd 'allow *' \
    --cap mgr 'allow *' \
    --cap mds 'allow *'

    ceph-authtool \
    --create-keyring /etc/ceph/ceph.client.bootstrap-osd.keyring \
    --gen-key -n client.bootstrap-osd \
    --cap mon 'profile bootstrap-osd' \
    --cap mgr 'allow r'
else
    echo "Skipping to create keyrings"
fi

exec "$@"

mgr

mgr/Dockerfile
FROM quay.io/ceph/ceph:v20.2.0

RUN mkdir -p /var/lib/ceph/mgr/ceph-mgr

osd1

osd向けのkeyringを作成しておきます。

osd1/Dockerfile
FROM quay.io/ceph/ceph:v20.2.0

USER ceph

RUN mkdir -p /var/lib/ceph/osd/ceph-0
RUN ceph-authtool \
    --create-keyring /var/lib/ceph/osd/ceph-0/keyring \
    --gen-key -n osd.0 \
    --cap osd 'allow *' \
    --cap mon 'allow profile osd'

rgw1

rgw向けのkeyringを作成しておきます。

rgw1/Dockerfile
FROM quay.io/ceph/ceph:v20.2.0

RUN mkdir -p /var/lib/ceph/radosgw/ceph-rgw1
RUN ceph-authtool \
    --create-keyring /var/lib/ceph/radosgw/ceph-rgw1/keyring \
    --gen-key -n client.rgw1 \
    --cap osd 'allow *' \
    --cap mon 'allow *'

docker-compose.ymlおよび関連ファイル

docker-compose.yml

長いですが、以下がdocker-compose.ymlです。
各コンテナにマウントしているcephフォルダには、ceph.confと、初回起動時に作成されるceph.client.admin.keyring, ceph.client.bootstrap-osd.keyringが入ります。
ceph.conf内のmon_hostにコンテナ名を指定すると、うまく起動しなかったのでnetworkを構成してコンテナ同士で使えるIPアドレスを割り当ててます。

docker-compose.yml
networks:
  ceph_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.0.0/16

services:
  mon1:
    build: dockerfiles/mon1
    user: ceph
    entrypoint: ["/entrypoint.sh"]
    command:
      - "/bin/sh"
      - "-c"
      - >-
        ceph-authtool /var/lib/ceph/tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring;
        ceph-authtool /var/lib/ceph/tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.bootstrap-osd.keyring;
        monmaptool --create --add mon1 ${MON_IP} --fsid ${FSID} /var/lib/ceph/tmp/monmap --clobber;
        ceph-mon --mkfs -i mon1 --monmap /var/lib/ceph/tmp/monmap --keyring /var/lib/ceph/tmp/ceph.mon.keyring;
        ceph-mon -i mon1 -f -d;
    environment:
      MON_IP: ${MON_IP}
      FSID: ${FSID}
    volumes:
      - ./ceph:/etc/ceph
    networks:
      ceph_network:
        ipv4_address: 172.30.0.2

  mgr:
    build: dockerfiles/mgr
    command:
      - "/bin/sh"
      - "-c"
      - >-
        ceph auth get-or-create mgr.mgr mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-mgr/keyring;
        ceph-mgr -f -i mgr;
    volumes:
      - ./ceph:/etc/ceph
    depends_on:
      - mon1
    ports:
      - 8443:8443
    networks:
      ceph_network:

  osd1:
    pid: host
    privileged: true
    build: dockerfiles/osd1
    environment:
      OSD_UUID_1: ${OSD_UUID_1}
    user: ceph
    command:
      - "/bin/sh"
      - "-c"
      - >-
        ceph auth add osd.0 -i /var/lib/ceph/osd/ceph-0/keyring;
        ceph osd new ${OSD_UUID_1} -n client.bootstrap-osd;
        ceph-osd -i 0 --mkfs \
          --osd-data /var/lib/ceph/osd/ceph-0 \
          --osd-uuid ${OSD_UUID_1} \
          --keyring /var/lib/ceph/osd/ceph-0/keyring;
        ceph-osd -f -i 0;
    volumes:
      - ./ceph:/etc/ceph
    depends_on:
      - mon1
    networks:
      ceph_network:

  rgw1:
    build: dockerfiles/rgw1
    environment:
      MON_IP: ${MON_IP}
      AWS_ACCESS_KEY_ID: ${RGW_ACCESS_KEY}
      AWS_SECRET_ACCESS_KEY: ${RGW_SECRET_KEY}
    command:
      - "/bin/sh"
      - "-c"
      - >-
        ceph auth get-or-create client.rgw1 mon 'allow rw' osd 'allow rwx';
        ceph auth caps client.rgw1 mon 'allow rw' osd 'allow rwx';
        ceph auth del client.rgw1;
        ceph auth add client.rgw1 -i /var/lib/ceph/radosgw/ceph-rgw1/keyring;
        radosgw-admin user create \
          --uid="polaris-user" \
          --display-name="Polaris User" \
          --access-key="${RGW_ACCESS_KEY}" \
          --secret-key="${RGW_SECRET_KEY}";
        echo ">>> RGW user created (access=${RGW_ACCESS_KEY}, secret=${RGW_SECRET_KEY})";
        radosgw -n client.rgw1 --rgw-frontends="beast port=7480" --foreground;
    ports:
      - "7480:7480"   # RGW HTTP endpoint (S3)
      - "7481:7481"
    volumes:
      - ./ceph:/etc/ceph
    depends_on:
      - osd1
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7480"]
      interval: 2s
      timeout: 10s
      retries: 10
      start_period: 10s
    networks:
      ceph_network:

  aws-cli:
    image: amazon/aws-cli:2.33.8
    depends_on:
      rgw1:
        condition: service_healthy
    environment:
      AWS_ACCESS_KEY_ID: ${RGW_ACCESS_KEY}
      AWS_SECRET_ACCESS_KEY: ${RGW_SECRET_KEY}
      AWS_ENDPOINT_URL: ${S3_ENDPOINT_URL}
      AWS_REGION: ${S3_REGION}
    entrypoint: "/bin/sh"
    command:
      - "-c"
      - >-
        tail -f /dev/null;
    networks:
      ceph_network:

ceph/ceph.conf

mon1コンテナに割り当てたIPアドレスをmon_hostに記載しています。

ceph.conf
[global]
fsid = b2f59c4b-5f14-4f8c-a9b7-3b7998c76a0e
mon_initial_members = mon1
mon_host = 172.30.0.2
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
osd_pool_default_size = 1
osd_pool_default_min_size = 1
osd_pool_default_pg_num = 333
osd_crush_chooseleaf_type = 1
mon_allow_pool_size_one= true

[mon.mon1]
mon_data = /var/lib/ceph/mon/ceph-mon1
mon_rocksdb_min_wal_logs = 1
mon_rocksdb_max_total_wal_size = 64M
mon_rocksdb_options = max_background_compactions=4;max_background_flushes=2

[client.rgw1]
host = ceph-rgw1
rgw_frontends = civetweb port=7480

.env

参考元のコメントにある通り、本来UUID等は再作成したほうがよいのですが、そのまま使っています。
S3_REGIONはcephにおいては動作に関係ないのですが、aws-cliコンテナの動作に関係する可能性があるため残しております。

.env
LANG=en_US.utf8                                     # Default system locale used inside containers
TZ=UTC                                              # Timezone used inside containers
MON_IP=172.30.0.2                                   # IP address of the monitor
RGW_ACCESS_KEY=POLARIS123ACCESS                     # Access key for Polaris S3 user
RGW_SECRET_KEY=POLARIS456SECRET                     # Secret key for Polaris S3 user
FSID=b2f59c4b-5f14-4f8c-a9b7-3b7998c76a0e           # Unique cluster identifier (use `uuidgen` to regenerate)
OSD_UUID_1=80505106-0d32-4777-bac9-3dfc901b1273     # Unique OSD identifier (use `uuidgen` to regenerate)
S3_ENDPOINT_URL=http://rgw1:7480                    # Internal endpoint for S3-compatible RGW service
S3_REGION=us-east-1                                 # S3 region name

動作確認

ビルドと初回起動

まずはビルドしましょう。

$ docker compose build

起動します。

$ docker compose up -d

初回起動ののち、cephフォルダに以下の2ファイルが作成されます。

- ceph.client.admin.keyring
- ceph.client.bootstrap-osd.keyring

起動状態を確認します。

$ docker ps
CONTAINER ID   IMAGE                                            COMMAND                  CREATED          STATUS                    PORTS                                                             NAMES
14ddce9f5e87   amazon/aws-cli:2.33.8                            "/bin/sh -c 'tail -f…"   26 seconds ago   Up 3 seconds                                                                                iceberg-with-polaris-ceph-spark-in-docker-aws-cli-1
29706bc123bc   iceberg-with-polaris-ceph-spark-in-docker-rgw1   "/bin/sh -c 'ceph au…"   26 seconds ago   Up 25 seconds (healthy)   0.0.0.0:7480-7481->7480-7481/tcp, [::]:7480-7481->7480-7481/tcp   iceberg-with-polaris-ceph-spark-in-docker-rgw1-1
386c3c640132   iceberg-with-polaris-ceph-spark-in-docker-mgr    "/bin/sh -c 'ceph au…"   27 seconds ago   Up 25 seconds             0.0.0.0:8443->8443/tcp, [::]:8443->8443/tcp                       iceberg-with-polaris-ceph-spark-in-docker-mgr-1
d9e2ec9bb1d1   iceberg-with-polaris-ceph-spark-in-docker-osd1   "/bin/sh -c 'ceph au…"   27 seconds ago   Up 25 seconds                                                                               iceberg-with-polaris-ceph-spark-in-docker-osd1-1
06492fac38d8   iceberg-with-polaris-ceph-spark-in-docker-mon1   "/entrypoint.sh /bin…"   27 seconds ago   Up 25 seconds                                                                               iceberg-with-polaris-ceph-spark-in-docker-mon1-1

動作確認

AWL-CLIコンテナに入ります。

docker exec -it 14ddce9f5e87 sh

バケットの作成をします。

$ aws s3 mb s3://test-bucket
make_bucket: test-bucket

作成したバケットを確認します。

$ aws s3 ls
2026-01-30 13:54:20 test-bucket

終わりに

次はSparkとPolarisも追加して、Iceberg環境を作ってみたいなと思っています。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?