티스토리 뷰

빅데이터

Ceph 오브젝트 스토리지

warpmemory 2016. 7. 26. 16:38

1. Ceph

  • 분산 오브젝트 파일 시스템으로 좋은 성능, 신뢰성, 확장성을 가지고 있다.

2. Block Device

2.1. 커널 모듈 사용

  • 커널에 Ceph 모듈이 포함되어야 있어야 한다.(CentOs 7 기본 탑재)

2.1.1. pool 생성

# rados mkpool dsan_block_device

successfully created pool dsan_block_device

2.1.2. 이미지 생성

# rdb create test-images --size 10240 --pool dsan_block_device

2.1.3. Device 맵핑 생성

# rbd map test-images --pool dsan_block_device

/dev/rbd0

# rbd ls -p dsan_block_device

test-images

# rbd showmapped

id pool              image       snap device

0  dsan_block_device test-images -    /dev/rbd0

2.1.4. 파일 시스템 생성

# mkfs.ext4 -m0 /de/rbd/dsan_block_device/test-images

mke2fs 1.42.9 (28-Dec-2013)

Discarding device blocks: done

Filesystem label=

OS type: Linux

Block size=4096 (log=2)

Fragment size=4096 (log=2)

Stride=1024 blocks, Stripe width=1024 blocks

655360 inodes, 2621440 blocks

0 blocks (0.00%) reserved for the super user

First data block=0

Maximum filesystem blocks=2151677952

80 block groups

32768 blocks per group, 32768 fragments per group

8192 inodes per group

Superblock backups stored on blocks:

        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done

Writing inode tables: done

Creating journal (32768 blocks):

done

Writing superblocks and filesystem accounting information: done

2.1.5. 마운트

# mkdir -p /var/lib/test/images

# mount /dev/rbd/dsan_block_device/test-images /var/lib/test/images

# mount |fgrep rbd0

/dev/rbd0 on /var/lib/test/images type ext4 (rw,relatime,seclabel,stripe=1024,data=ordered)

# cd /var/lib/test/images/

# ls

lost+found

2.1.6. 삭제

# cd /

# umount /var/lib/test/images

# rbd unmap /dev /rbd/dsan_block_device/test-images

# rbd -p dsan_block_device rm test-images

Removing image: 100% complete...done.

2.2. QEMU 사용

2.2.1. 이미지 생성

# qemu-img create -f raw rbd:dsan_block_device/test2-images 10240M

Formatting 'rbd:dsan_block_device/test2-images', fmt=raw size=10737418240 cluster_size=0

# rbd -p dsan_block_device ls

test2-images

# qemu-img info rbd:dsan_block_device/test2-images

image: rbd:dsan_block_device/test2-images

file format: raw

virtual size: 10G (10737418240 bytes)

disk size: unavailable

2.2.2. 기존 파일 이지미 복사

  • kvm 이미지를 가져와, convert 하여 rbd 이미지로 저장한다.

# qemu-img convert -f raw -O raw centos6.img rbd:dsan_block_device/test3-images

# qemu-img info rbd:dsan_block_device/test3-images

image: rbd:dsan_block_device/test3-images

file format: raw

virtual size: 40G (42949672960 bytes)

disk size: unavailable

2.2.3. VM 생성(KVM)

# cat > secret.xml <<EOF

<secret ephemeral='no' private='no'>

        <usage type='ceph'>

                <name>client.admin secret</name>

        </usage>

</secret>

EOF

# sudo virsh secret-define --file secret.xml

Secret 234a3f1a-fbd4-3585-18a4-12661d6ab0ab created

# ceph auth get-key client.admin | sudo tee client.admin.key

# sudo virsh secret-set-value --secret 234a3f1a-fbd4-3585-18a4-12661d6ab0ab --base64 $(cat client.admin.key) && rm client.admin.key secret.xml

# uuidgen

ae3d7cc0-4db6-43ef-8dfd-3e8dbe20e182

 

# cat > /etc/libvirt/qemu/centos6.xml <<EOF

<!--

WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE

OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:

  virsh edit centos6

or other application using the libvirt API.

-->

<domain type='qemu'>

  <name>centos6</name>

  <uuid>ae3d7cc0-4db6-43ef-8dfd-3e8dbe20e182</uuid>

  <memory unit='KiB'>524288</memory>

  <currentMemory unit='KiB'>524288</currentMemory>

  <vcpu placement='static'>2</vcpu>

  <os>

    <type arch='x86_64' machine='rhel6.2.0'>hvm</type>

    <boot dev='hd'/>

  </os>

  <features>

    <acpi/>

    <apic/>

    <pae/>

  </features>

  <clock offset='utc'/>

  <on_poweroff>destroy</on_poweroff>

  <on_reboot>restart</on_reboot>

  <on_crash>restart</on_crash>

  <devices>

    <emulator>/usr/libexec/qemu-kvm</emulator>

    <disk type='network' device='disk'>

      <driver name='qemu' type='raw' cache='none'/>

      <auth username='admin'>

        <secret type='ceph' uuid='234a3f1a-fbd4-3585-18a4-12661d6ab0ab'/>

      </auth>

      <source protocol='rbd' name='dsan_block_device/test3-images'>

        <host name='192.168.49.73' port='6789'/>

      </source>

      <target dev='hda' bus='ide'/>

      <address type='drive' controller='0' bus='0' target='0' unit='0'/>

    </disk>

    <disk type='block' device='cdrom'>

      <driver name='qemu' type='raw'/>

      <target dev='hdc' bus='ide'/>

      <readonly/>

      <address type='drive' controller='0' bus='1' target='0' unit='0'/>

    </disk>

    <controller type='usb' index='0' model='ich9-ehci1'>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>

    </controller>

    <controller type='usb' index='0' model='ich9-uhci1'>

      <master startport='0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>

    </controller>

    <controller type='usb' index='0' model='ich9-uhci2'>

      <master startport='2'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>

    </controller>

    <controller type='usb' index='0' model='ich9-uhci3'>

      <master startport='4'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>

    </controller>

    <controller type='ide' index='0'>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>

    </controller>

    <interface type='bridge'>

      <mac address='52:54:00:88:4f:e5'/>

      <source bridge='virbr0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>

    </interface>

    <serial type='pty'>

      <target port='0'/>

    </serial>

    <console type='pty'>

      <target type='serial' port='0'/>

    </console>

    <input type='mouse' bus='ps2'/>

    <graphics type='vnc' port='-1' autoport='yes'/>

    <video>

      <model type='cirrus' vram='9216' heads='1'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>

    </video>

    <memballoon model='virtio'>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>

    </memballoon>

  </devices>

</domain>

EOF

# virsh define /etc/libvirt/qemu/centos6.xml

# virsh list --all

 Id    Name                           State

----------------------------------------------------

 -     centos6            shut off

# virsh start centos6

# virsh list

 Id    Name                           State

----------------------------------------------------

 20    centos6            running

2.3. Snapshot 생성/복원

# rbd snap create dsan_block_device/test3-images@snap1

# rbd snap ls dsan_block_device/test3-images

SNAPID NAME      SIZE

     2 snap1 40960 MB

# rbd snap rollback dsan_block_device/test3-images@snap1

Rolling back to snapshot: 100% complete...done.

# rbd snap rm dsan_block_device/test3-images@snap1

# rbd snap purge dsan_block_device/test3-images

Removing all snapshots: 100% complete...done.

2.4. Layering

  • 레이어링은 베이스가 되는 스냅샷을 사용하고, 실제 이미지에서는 변경된 데이터만 가지도록 하게 한다.
  • 반드시 protection 된 스냅샷을 사용해야한다.(flatten 하기 전엔, protection을 유지 해야함)
  • copy-on-write(COW) 를 지원하는 이미지만 가능하다.

# rbd snap protect {pool-name}/{image-name}@{snapshot-name}

# rbd clone {pool-name}/{parent-image}@{snap-name} {pool-name}/{child-image-name}

# rbd snap unprotect rbd/my-image@my-snapshot

# rbd children {pool-name}/{image-name}@{snapshot-name}

# rbd flatten rbd/my-image 

3. File System

  • Ceph File System은 메타데이터 pool, 데이터 pool 두개의 풀을 사용하고, mds(메타데이터서버) 를 이용하여 File System 서비스가 이루어지게 된다.(mds 가 1개 이상 있어야함)
  • newfs 명령어를 사용하게 되면, pool 데이터가 모두 사라지게 되므로 주의 하여야한다.
  • 또한, 여러개의 fs 생성하여 사용하지 못하는 것으로 보이고, 오로지 한쌍의 메타데이터 pool, 데이터 pool만 지정 할 수 있는 것으로 보인다.
  • newfs를 하게되면, 해당 pool로 바로 대체 되기 때문에, 절대 서비스 운영중에는 newfs 를 하면 안된다.
  • Ceph File System을 마운트 하려면, 커널에 Ceph 모듈이 포함 되어있어야한다.(CentOS 7 기본 탑재)

# rados mkpool dsan2_cephfs_data

successfully created pool dsan2_cephfs_data

# rados mkpool dsan2_cephfs_metadata

successfully created pool dsan2_cephfs_metadata

# ceph osd lspools

0 data,1 metadata,2 rbd,3 cephfs_data,4 cephfs_metadata,12 .rgw.root,13 .rgw.control,14 .rgw,15 .rgw.gc,16 .users.uid,17 .users,18 .users.swift,19 .rgw.buckets.index,20 .rgw.buckets,21 proxmox_img,23 ecTempPool,25 .usage,26 .users.email,27 .rgw.buckets.extra,35 .rgw.buckets.custom,37 .rgw.buckets.custom.index,38 .rgw.buckets.custom.extra,39 dsan_cephfs_data,40 dsan_cephfs_metadata,41 dsan2_cephfs_data,42 dsan2_cephfs_metadata,

# ceph mds newfs 42 41 --yes-i-really-mean-it

new fs with metadata pool 42 and data pool 41


3.1. mount/umount

  • mount 는 fs 안에 디렉토리로 구분하여, 마운트가 가능하다.

# mkdir /root/cephfs

# mount -t ceph ceph-001.test.com:6789:/ /root/cephfs \

-o name=admin,secret=`ceph-authtool \

-p /etc/ceph/ceph.client.admin.keyring`

# ls -al /root/cephfs

total 4

drwxr-xr-x  1 root root    0 May 21  2015 .

dr-xr-x---. 9 root root 4096 May 21 17:04 ..

# mkdir /root/cephfs/ceph-hosting-001

# touch /root/cephfs/ceph-hosting-001/file1

# touch /root/cephfs/ceph-hosting-001/file2

# mkdir /root/cephfs/ceph-hosting-001/dir1

# mkdir /root/cephfs/ceph-hosting-001/dir2

# ls -al /root/cephfs/ceph-hosting-001

total 0

drwxr-xr-x 1 root root 0 May 21 17:08 .

drwxr-xr-x 1 root root 0 May 21 17:07 ..

drwxr-xr-x 1 root root 0 May 21 17:08 dir1

drwxr-xr-x 1 root root 0 May 21 17:08 dir2

-rw-r--r-- 1 root root 0 May 21 17:08 file1

-rw-r--r-- 1 root root 0 May 21 17:08 file2

# mkdir /root/cephfs-ceph-hosting-001

# mount -t ceph ceph-001.test.com:6789:/ceph-hosting-001 /root/cephfs-ceph-hosting-001 \

-o name=admin,secret=`ceph-authtool \

-p /etc/ceph/ceph.client.admin.keyring`

# ls -al /root/cephfs-ceph-hosting-001

total 4

drwxr-xr-x   1 root root    0 May 21 17:08 .

dr-xr-x---. 10 root root 4096 May 21 17:10 ..

drwxr-xr-x   1 root root    0 May 21 17:08 dir1

drwxr-xr-x   1 root root    0 May 21 17:08 dir2

-rw-r--r--   1 root root    0 May 21 17:08 file1

-rw-r--r--   1 root root    0 May 21 17:08 file2

# mount |fgrep ceph

192.168.49.73:6789:/ on /root/cephfs type ceph (rw,relatime,name=admin,secret=<hidden>,nodcache)

192.168.49.73:6789:/ceph-hosting-001 on /root/cephfs-ceph-hosting-001 type ceph (rw,relatime,name=admin,secret=<hidden>,nodcache)

# umount /root/cephfs-ceph-hosting-001

# umount /root/cephfs


3.2. fuse

# ceph-fuse -m ceph-001.test.com:6789 /root/cephfs

# ls -al /root/cephfs

total 5

drwxr-xr-x  1 root root    0 May 21 17:30 .

dr-xr-x--- 21 root root 4096 May 21 17:51 ..

drwxr-xr-x  1 root root    0 May 21 17:31 ceph-hosting-001

# ceph-fuse -m ceph-001.test.com:6789 -r /ceph-hosting-001 /root/cephfs-ceph-hosting-001

# ls -al /root/cephfs-ceph-hosting-001

total 6

drwxr-xr-x  1 root root    0 May 21 17:31 .

dr-xr-x--- 21 root root 4096 May 21 17:51 ..

drwxr-xr-x  1 root root    0 May 21 17:30 dir1

drwxr-xr-x  1 root root    0 May 21 17:31 dir2

-rw-r--r--  1 root root    0 May 21 17:30 file1

-rw-r--r--  1 root root    0 May 21 17:30 file2

3.3. 제약 사항

  • fsck 등 복구 기능들이 정상적으로 동작 하지 않는다.
  • 커널에 대한 제약 사항이 존재한다.(http://docs.ceph.com/docs/master/start/os-recommendations/)
  • 현재 도 개발중이다.

4. Object Storage

4.1. Ceph 사용자 관리

4.1.1. radosgw-admin

  • radosgw-admin 명령어를 이용하여, ceph cluster를 관리 한다.
  • http://ceph.com/docs/master/radosgw/admin/

기능

명령어

코멘트

 사용자 추가

 radosgw-admin user create --uid="dsan" --display-name="dsan"

 

 swift 사용자 추가 radosgw-admin subuser create --uid="dsan" --subuser=dsan:swift --access=full --key-type=swift --gen-secret 기본 사용자 추가 후 swift 사용자 추가 가능
 swift 사용자 키 생성 radosgw-admin key create --uid=dsan --subuser=dsan:swift --gen-secret --key-type=swift swfit 사용자 시크릿 키 생성
 사용자 권한 추가 radosgw-admin caps add --uid=dsan --caps="usage=read,write;users=read,write;buckets=read,write;metadata=read,write;zone=read,write" Admin Ops API 사용시 필요, 관리자 계정에만 권한 추가

 swift 사용자 삭제

 radosgw-admin subuser rm --uid=dsan --subuser=dsan:swift 
 swift 사용자 access 키 삭제 radosgw-admin key rm --uid=dsan --subuser=dsan:swift --access-key=0A864YJ639X4Q12K4NLP 
 swift 사용자 secret 키 삭제

 

 
 사용자 삭제 radosgw-admin user rm --uid=dsan --purge-data --purge_keys 

 사용자 차단

 radosgw-admin user suspend --uid=dsan 
 사용자 차단 해제 radosgw-admin user enable --uid=dsan 
 사용자 키 변경  
 사용자 쿼터 제한 radosgw-admin quota set --uid=dsan --quota-scope=user --max-size=1000000000 1G 사용자 용량 제한
 사용자 쿼터 사용 radosgw-admin quota enable --uid=dsan 
 사용자 쿼터 해제 radosgw-admin quota disable --uid=dsan 
 사용자 쿼터 확인 radosgw-admin user stats --uid=dsan --sync-stats 
 사용자 트래픽 사용량 확인 radosgw-admin usage show --uid=dsan --start-date='2015-04-21 15:00:00' --end-date='2015-04-22 14:59:59' UTC 를 사용하기 때문에 9시간을 더한 값을 사용
 버켓 생성 radosgw-admin 


# radosgw-admin user create --uid="dsan" --display-name="dsan"

{ "user_id": "dsan",

  "display_name": "dsan",

  "email": "",

  "suspended": 0,

  "max_buckets": 1000,

  "auid": 0,

  "subusers": [],

  "keys": [

        { "user": "dsan",

          "access_key": "HITN5QX9EJ89VMDTTQBN",

          "secret_key": "dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"}],

  "swift_keys": [],

  "caps": [],

  "op_mask": "read, write, delete",

  "default_placement": "",

  "placement_tags": [],

  "bucket_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "user_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "temp_url_keys": []}

 

 

# radosgw-admin subuser create --uid=dsan --subuser=dsan:swift --access=full

{ "user_id": "dsan",

  "display_name": "dsan",

  "email": "",

  "suspended": 0,

  "max_buckets": 1000,

  "auid": 0,

  "subusers": [

        { "id": "dsan:swift",

          "permissions": "full-control"}],

  "keys": [

        { "user": "dsan",

          "access_key": "HITN5QX9EJ89VMDTTQBN",

          "secret_key": "dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"},

        { "user": "dsan:swift",

          "access_key": "LBRXJPSGRFWF04S440HU",

          "secret_key": ""}],

  "swift_keys": [],

  "caps": [],

  "op_mask": "read, write, delete",

  "default_placement": "",

  "placement_tags": [],

  "bucket_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "user_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "temp_url_keys": []}

 

 

# radosgw-admin key create --uid=dsan --subuser=dsan:swift --gen-secret --key-type=swift

{ "user_id": "dsan",

  "display_name": "dsan",

  "email": "",

  "suspended": 0,

  "max_buckets": 1000,

  "auid": 0,

  "subusers": [

        { "id": "dsan:swift",

          "permissions": "full-control"}],

  "keys": [

        { "user": "dsan",

          "access_key": "HITN5QX9EJ89VMDTTQBN",

          "secret_key": "dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"},

        { "user": "dsan:swift",

          "access_key": "LBRXJPSGRFWF04S440HU",

          "secret_key": ""}],

  "swift_keys": [

        { "user": "dsan:swift",

          "secret_key": "tdMDDayBg78UWc2g+0hcykAShCJ4PbnPGjM1C1B5"}],

  "caps": [],

  "op_mask": "read, write, delete",

  "default_placement": "",

  "placement_tags": [],

  "bucket_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "user_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "temp_url_keys": []}

 

 

# radosgw-admin caps add --uid=dsan --caps="usage=read,write;users=read,write;buckets=read,write"

{ "user_id": "dsan",

  "display_name": "dsan",

  "email": "",

  "suspended": 0,

  "max_buckets": 1000,

  "auid": 0,

  "subusers": [

        { "id": "dsan:swift",

          "permissions": "full-control"}],

  "keys": [

        { "user": "dsan",

          "access_key": "HITN5QX9EJ89VMDTTQBN",

          "secret_key": "dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"},

        { "user": "dsan:swift",

          "access_key": "LBRXJPSGRFWF04S440HU",

          "secret_key": ""}],

  "swift_keys": [

        { "user": "dsan:swift",

          "secret_key": "tdMDDayBg78UWc2g+0hcykAShCJ4PbnPGjM1C1B5"}],

  "caps": [

        { "type": "buckets",

          "perm": "*"},

        { "type": "usage",

          "perm": "*"},

        { "type": "users",

          "perm": "*"}],

  "op_mask": "read, write, delete",

  "default_placement": "",

  "placement_tags": [],

  "bucket_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "user_quota": { "enabled": false,

      "max_size_kb": -1,

      "max_objects": -1},

  "temp_url_keys": []}

4.1.2. Admin Ops API

  • 관리자 API 로 사용자 추가/삭제/관리, 쿼터 설정/조회 등의 API를 제공한다.
  • AWS S3 에서 사용하는 인증 방식과 동일 한 방식으로 인증한다.
  • http://ceph.com/docs/master/radosgw/adminops/
# python
>>> import requests
>>> from awsauth import S3Auth
>>> aws_key = "HITN5QX9EJ89VMDTTQBN"
>>> secret = "dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"
>>> server = "ceph-hosting-001.test.com"
>>> url = 'http://%s/admin/user?format=json&uid=dsan' % server
>>> r = requests.get(url, auth=S3Auth(aws_key, secret, server))
>>> print r.text
{"user_id":"dsan","display_name":"dsan","email":"","suspended":0,"max_buckets":1000,"subusers":[{"id":"dsan:swift","permissions":"full-control"}],"keys":[{"user":"dsan","access_key":"HITN5QX9EJ89VMDTTQBN","secret_key":"dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"},{"user":"dsan:swift","access_key":"LBRXJPSGRFWF04S440HU","secret_key":""}],"swift_keys":[{"user":"dsan:swift","secret_key":"tdMDDayBg78UWc2g+0hcykAShCJ4PbnPGjM1C1B5"}],"caps":[{"type":"buckets","perm":"*"},{"type":"usage","perm":"*"},{"type":"users","perm":"*"}]}

4.2. Ceph 사용자 Pool 관리

  • .rgw.buckets 풀에 디폴트로 데이터가 저장된다. 용도에 따라 pool을 생성 하여 사용자 데이터를 저장 할 수 있다.

4.2.1. pool생성

# rados mkpool .rgw.buckets.custom
successfully created pool .rgw.buckets.custom

4.2.2. region 등록

# radosgw-admin region get > region.conf.json
# vim region.conf.json
  • region.conf.json 파일에서 placement_targets 에 custom-placement 추가

{ "name": "default",

  "api_name": "",

  "is_master": "true",

  "endpoints": [],

  "master_zone": "",

  "zones": [

        { "name": "default",

          "endpoints": [],

          "log_meta": "false",

          "log_data": "false"}],

  "placement_targets": [

        { "name": "default-placement",

          "tags": []},

        { "name": "custom-placement",

          "tags": []}],

  "default_placement": "default-placement"}


# radosgw-admin region set < region.conf.json

4.2.3. zone 등록

# radosgw-admin zone get > zone.conf.json
# vim zone.conf.json
  • zone.conf.json 파일에서 placement_pools 추가
{ "domain_root": ".rgw",
  "control_pool": ".rgw.control",
  "gc_pool": ".rgw.gc",
  "log_pool": ".log",
  "intent_log_pool": ".intent-log",
  "usage_log_pool": ".usage",
  "user_keys_pool": ".users",
  "user_email_pool": ".users.email",
  "user_swift_pool": ".users.swift",
  "user_uid_pool": ".users.uid",
  "system_key": { "access_key": "",
      "secret_key": ""},
  "placement_pools": [
        { "key": "default-placement",
          "val": { "index_pool": ".rgw.buckets.index",
              "data_pool": ".rgw.buckets",
              "data_extra_pool": ".rgw.buckets.extra"}},
        { "key": "custom-placement",
          "val": { "index_pool": ".rgw.buckets.index",
              "data_pool": ".rgw.buckets.custom",
              "data_extra_pool": ".rgw.buckets.extra"}}]}


# radosgw-admin zone set < zone.conf.json

4.2.4. regionmap 업데이트

# radosgw-admin regionmap update
{ "regions": [
        { "key": "default",
          "val": { "name": "default",
              "api_name": "",
              "is_master": "true",
              "endpoints": [],
              "master_zone": "",
              "zones": [
                    { "name": "default",
                      "endpoints": [],
                      "log_meta": "false",
                      "log_data": "false"}],
              "placement_targets": [
                    { "name": "custom-placement",
                      "tags": []},
                    { "name": "default-placement",
                      "tags": []}],
              "default_placement": "default-placement"}}],
  "master_region": "default",
  "bucket_quota": { "enabled": false,
      "max_size_kb": -1,
      "max_objects": -1},
  "user_quota": { "enabled": false,
      "max_size_kb": -1,
      "max_objects": -1}}

4.2.5. 사용자 정보 업데이트

# radosgw-admin metadata get user:dsan > user.md.json
# vim user.md.json
  • user.md.json 파일에서 default_placement 변경
{ "key": "user:dsan",
  "ver": { "tag": "_BjzlbkKq8DaYeR0rm7bYvjf",
      "ver": 3},
  "mtime": 1431932547,
  "data": { "user_id": "dsan",
      "display_name": "dsan",
      "email": "",
      "suspended": 0,
      "max_buckets": 1000,
      "auid": 0,
      "subusers": [
            { "id": "dsan:swift",
              "permissions": "full-control"}],
      "keys": [
            { "user": "dsan",
              "access_key": "IKCKXOAL4BPMCNCY4DB5",
              "secret_key": "8SdsLI256QKgWljT6RJWQwg61XE84ByX9SJY5ChP"}],
      "swift_keys": [
            { "user": "dsan:swift",
              "secret_key": "PXWXRJe87wld7gXkotxEkhW1nwl7rM7ikzvq5Gv+"}],
      "caps": [
            { "type": "buckets",
              "perm": "*"},
            { "type": "metadata",
              "perm": "*"},
            { "type": "usage",
              "perm": "*"},
            { "type": "users",
              "perm": "*"}],
      "op_mask": "read, write, delete",
      "default_placement": "custom-placement",
      "placement_tags": [],
      "bucket_quota": { "enabled": false,
          "max_size_kb": -1,
          "max_objects": -1},
      "user_quota": { "enabled": false,
          "max_size_kb": -1,
          "max_objects": -1},
      "temp_url_keys": []}}


# radosgw-admin metadata put user:dsan < user.md.json

4.3. 스냅샷 생성 복원

4.3.1. 스냅샷 생성

  • 스냅샷 생성은 주기적으로 생성해야 하고, bucket 인덱스 pool 과 bucket pool을 쌍으로 하여야한다.
# rados -p .rgw.buckets mksnap .rgw.buckets.20150519
created pool .rgw.buckets snap .rgw.buckets.20150519
# rados -p .rgw.buckets.index mksnap .rgw.buckets.index.20150519
created pool .rgw.buckets.index snap .rgw.buckets.index.20150519

4.3.2. 스냅샷 확인

# rados -p .rgw.buckets lssnap
1       .rgw.buckets.20150519   2015.05.19 11:35:55
1 snaps
# rados -p .rgw.buckets.index lssnap
1       .rgw.buckets.index.20150519     2015.05.19 11:46:51
1 snaps

4.3.3. 복원할 bucket 정보 확인

# radosgw-admin bucket stats --bucket=test1
{ "bucket": "test1",
  "pool": ".rgw.buckets",
  "index_pool": ".rgw.buckets.index",
  "id": "default.1673017.1",
  "marker": "default.1673017.1",
  "owner": "dsan",
  "ver": 35,
  "master_ver": 0,
  "mtime": 1431664412,
  "max_marker": "",
  "usage": { "rgw.main": { "size_kb": 1019504,
          "size_kb_actual": 1019540,
          "num_objects": 15}},
  "bucket_quota": { "enabled": false,
      "max_size_kb": -1,
      "max_objects": -1}}

# radosgw-admin bucket list --bucket=test1
....
    { "name": "Ch5r.ppt",
      "namespace": "",
      "owner": "dsan",
      "owner_display_name": "dsan",
      "size": 1499136,
      "mtime": "2015-05-15 04:39:17.000000Z",
      "etag": "c0c022e12ce952eb9126ac16b2f8146e",
      "content_type": "application\/vnd.ms-powerpoint",
      "tag": "default.1673017.38"},
....

# rados -p .rgw.buckets ls |egrep '^default.1673017.1_' |egrep -v '^default.1673017.1__shadow_.'
....
default.1673017.1_Ch5r.ppt
....

4.3.4. 스냅샷 복원

  • 우선적으로 복원할 bucket index를 rollback하고, 복구된 bucket index 로 복원 bucket 리스트를 가져와서 object를 rollback 한다.
# rados -p .rgw.buckets.index rollback dir.default.1673017.1 .rgw.buckets.index.20150519
rolled back pool .rgw.buckets.index to snapshot .rgw.buckets.index.20150519
# rados -p .rgw.buckets rollback default.1673017.1_Ch5r.ppt .rgw.buckets.20150519
rolled back pool .rgw.buckets to snapshot .rgw.buckets.20150519

4.3.5. 스냅샷 삭제

# rados -p .rgw.buckets rmsnap .rgw.buckets.20150519
removed pool .rgw.buckets snap .rgw.buckets.20150519
# rados -p .rgw.buckets.index rmsnap .rgw.buckets.index.20150519
removed pool .rgw.buckets.index snap .rgw.buckets.index.20150519

4.4. Ceph 데이터 접근 API

4.4.1. Swift API

  • Swift API의 데이터 접근 모델을 사용한 API로 파일 오브젝트 추가/삭제/관리 등의 API를 제공한다.
# python
>>> import swiftclient
>>> user = 'dsan:swift'
>>> key = 'tdMDDayBg78UWc2g+0hcykAShCJ4PbnPGjM1C1B5'
>>> conn = swiftclient.Connection(user=user,key=key,authurl='http://ceph-001.est.com/auth')
>>> for container in conn.get_account()[1]:
...         print container['name']
...
>>> # 버킷 생성
>>> container_name = 'my-new-container'
>>> conn.put_container(container_name)
>>>
>>> # 오브젝트 생성
>>> with open('hello.txt', 'r') as hello_file:
...         conn.put_object(container_name, 'hello.txt',
...                                         contents= hello_file.read(),
...                                         content_type='text/plain')
...
'd8e8fca2dc0f896fd7cb4cb0031ba249'
>>> # 버킷 이름 확인
>>> for container in conn.get_account()[1]:
...         print container['name']
...
my-new-container
>>> # 버킷 오브젝트 확인
>>> for data in conn.get_container(container_name)[1]:
...         print '{0}\t{1}\t{2}'.format(data['name'], data['bytes'], data['last_modified'])
...
hello.txt       5       2015-04-17T01:25:57.000Z
>>> # 오브젝트 가져오기
>>> obj_tuple = conn.get_object(container_name, 'hello.txt')
>>> with open('my_hello.txt', 'w') as my_hello:
...         my_hello.write(obj_tuple[1])
...
>>> # 오브젝트 삭제
>>> conn.delete_object(container_name, 'hello.txt')
>>> # 버킷 삭제
>>> conn.delete_container(container_name)
>>>

4.4.2. S3 SPI

  • 아마존 S3 API의 데이터 접근 모델을 사용한 API로 파일 오브젝트 추가/삭제/관리 등의 API를 제공한다.
  • http://ceph.com/docs/master/radosgw/adminops/
# python
>>> import requests
>>> from awsauth import S3Auth
>>> aws_key = "HITN5QX9EJ89VMDTTQBN"
>>> secret = "dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"
>>> server = "ceph-hosting-001.test.com"
>>>
>>> # 버킷 생성
>>> url = 'http://%s/my-new-container2?uid=dsan' % server
>>> r = requests.put(url, auth=S3Auth(aws_key, secret, server))
>>> print r
<Response [200]>
>>> # 버킷 이름 확인
>>> url = 'http://%s/?uid=dsan' % server
>>> r = requests.get(url, auth=S3Auth(aws_key, secret, server))
>>> print r.text
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>dsan</ID><DisplayName>dsan</DisplayName></Owner><Buckets><Bucket><Name>my-new-bucket</Name><CreationDate>2015-04-22T01:17:30.000Z</CreationDate></Bucket><Bucket><Name>my-new-container</Name><CreationDate>2015-04-20T03:56:07.000Z</CreationDate></Bucket><Bucket><Name>my-new-container2</Name><CreationDate>2015-04-22T06:57:37.000Z</CreationDate></Bucket><Bucket><Name>my-new-container3</Name><CreationDate>2015-04-22T06:47:22.000Z</CreationDate></Bucket></Buckets></ListAllMyBucketsResult>
>>> # 오브젝트 생성
>>> data="test"
>>> url = 'http://%s/my-new-container2/file.txt' % server
>>> r = requests.put(url, data=data, auth=S3Auth(aws_key, secret, server))
>>> print r
<Response [200]>
>>> # 오브젝트 확인
>>> url = 'http://%s/my-new-container2' % server
>>> r = requests.get(url, auth=S3Auth(aws_key, secret, server))
>>> print r.text
<?xml version="1.0" encoding="UTF-8"?><ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>my-new-container2</Name><Prefix></Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>file.txt</Key><LastModified>2015-04-22T06:58:22.000Z</LastModified><ETag>&quot;098f6bcd4621d373cade4e832627b4f6&quot;</ETag><Size>4</Size><StorageClass>STANDARD</StorageClass><Owner><ID>dsan</ID><DisplayName>dsan</DisplayName></Owner></Contents></ListBucketResult>
>>> # 오브젝트 삭제
>>> url = 'http://%s/my-new-container2/file.txt' % server
>>> r = requests.delete(url, auth=S3Auth(aws_key, secret, server))
>>> print r
<Response [204]>
>>> # 버킷 삭제
>>> url = 'http://%s/my-new-container2' % server
>>> r = requests.delete(url, auth=S3Auth(aws_key, secret, server))
>>> print r
<Response [204]>
>>>

4.5. Ceph 데이터 접근 클라이언트

4.5.1. Object Gateway

4.5.1.1. Cyberduck

  • 프리웨어로 S3, Swift 등을 지원 하는 FTP 클라이언트로 오브젝트 스토리지를 FTP 클라이언트 처럼 사용가능하게 한다.
  • ceph 는 S3, Swift 인터페이스를 제공하기때문에, 해당 클라이언트로 파일 오브젝트에 대한 접근 및 제어가 가능하다.

4.5.1.2. CloudBerry Explorer

  • 프리웨어로 S3 지원 하는 클라이언트로, S3 컴포터블한 ceph의 오브젝트 스토리지에 접속하여, 오브젝트에 대한 접근 및 제어가 가능하다.

4.5.1.3. WebDrive

  • 유료 소프트웨어로 22일간 무료로 사용가능하고, 오브젝트 스토리지를 웹드라이브 처럼 연결하여, 사용 가능하게 한다.

4.5.2. Ftp Server + Object Gateway

  • wiftclient + python ftpdlib 를 이용한 ftp-cloudfs를 ftp server 로 하여 오브젝트 스토리지 데이터를 일반 파일 처럼 ftp클라이언트를 이용하여 접근한다.
  • https://github.com/cloudfs/ftp-cloudfs
# /home/apps/python2.7/bin/ftpcloudfs -f -p 21 -b 192.168.51.169 -a http://ceph-hosting-001.test.com/auth
[I 15-04-29 15:44:07] >>> starting FTP server on 192.168.51.169:21, pid=24573 <<<
[24573] 2015-04-29 15:44:07,387 - INFO - >>> starting FTP server on 192.168.51.169:21, pid=24573 <<<
[I 15-04-29 15:44:07] poller: <class 'pyftpdlib.ioloop.Epoll'>
[24573] 2015-04-29 15:44:07,387 - INFO - poller: <class 'pyftpdlib.ioloop.Epoll'>
[I 15-04-29 15:44:07] masquerade (NAT) address: None
[24573] 2015-04-29 15:44:07,388 - INFO - masquerade (NAT) address: None
[I 15-04-29 15:44:07] passive ports: None
[24573] 2015-04-29 15:44:07,388 - INFO - passive ports: None
[I 15-04-29 15:44:07] use sendfile(2): False
[24573] 2015-04-29 15:44:07,388 - INFO - use sendfile(2): False
[I 15-04-29 15:44:07] dispatcher: <class pyftpdlib.servers.MultiprocessFTPServer at 0x7f8966826f58>
[24573] 2015-04-29 15:44:07,388 - INFO - dispatcher: <class pyftpdlib.servers.MultiprocessFTPServer at 0x7f8966826f58>
[I 15-04-29 15:44:59] 123.140.248.73:64867-[] FTP session opened (connect)
[24573] 2015-04-29 15:44:59,927 - INFO - 123.140.248.73:64867-[] FTP session opened (connect)
[I 15-04-29 15:44:59] 123.140.248.73:64867-[] FTP session closed (disconnect).
[24573] 2015-04-29 15:44:59,929 - INFO - 123.140.248.73:64867-[] FTP session closed (disconnect).
[24740] 2015-04-29 15:44:59,949 - INFO - Starting new HTTP connection (1): ceph-hosting-001.test.com
[I 15-04-29 15:44:59] 123.140.248.73:64867-[dsan:swift] Authentication validated for user dsan:swift
[24740] 2015-04-29 15:44:59,952 - INFO - 123.140.248.73:64867-[dsan:swift] Authentication validated for user dsan:swift
[I 15-04-29 15:44:59] 123.140.248.73:64867-[dsan:swift] USER 'dsan:swift' logged in.
[24740] 2015-04-29 15:44:59,952 - INFO - 123.140.248.73:64867-[dsan:swift] USER 'dsan:swift' logged in.
[24740] 2015-04-29 15:44:59,981 - INFO - Starting new HTTP connection (1): ceph-hosting-001.test.com
[24740] 2015-04-29 15:44:59,994 - INFO - Starting new HTTP connection (1): ceph-hosting-001.test.com

4.5.3. 웹브라우저

  • 파일 오브젝트의 ACL 설정이 모든 사용자에 대해 Read 권한이 되어있다면, 웹브라우저를 통해서, 오브젝트에 바로 접근 가능하다.
# python
>>> import requests
>>> from awsauth import S3Auth
>>> aws_key = "HITN5QX9EJ89VMDTTQBN"
>>> secret = "dxHGZyZJqSoGcK7aj+xdqXfxs7Ahw5Px9zpxEkzU"
>>> server = "ceph-hosting-001.test.com"
>>> url = 'http://%s%s?acl' % (server, self.obj_path)
>>> acl_data = '<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>dsan</ID><DisplayName>dsan</DisplayName></Owner><AccessControlList><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group"><URI>http://acs.amazonaws.com/groups/global/AllUsers</URI></Grantee><Permission>READ</Permission></Grant><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>dsan</ID><DisplayName>dsan</DisplayName></Grantee><Permission>READ</Permission></Grant><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>dsan</ID><DisplayName>dsan</DisplayName></Grantee><Permission>WRITE</Permission></Grant><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>dsan</ID><DisplayName>dsan</DisplayName></Grantee><Permission>READ_ACP</Permission></Grant><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>dsan</ID><DisplayName>dsan</DisplayName></Grantee><Permission>WRITE_ACP</Permission></Grant><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>dsan</ID><DisplayName>dsan</DisplayName></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>'
>>> print requests.put(url, auth=S3Auth(aws_key, secret, server), data=acl_data)
>>> r = requests.get(url, auth=S3Auth(aws_key, secret, server))
>>> print r
<Response [200]>

4.6. 호스팅 제약 사항

  • 사용자별로 버켓을 따로 생성해야, 독립된 사용자 공간이 확보됨
  • 사용자 아이디 이름으로 버켓 생성을 하고 사용자는 버켓 생성을 하면 안됨
  • http://도메인/버켓/오브젝트 형식으로 웹서비스 제공
  • 단, dns 설정을 통해서 http://버켓.도메인/오브젝트 형식으로 서비스 가능하지만,
  • *.도메인이 radosgw 서버를 가르켜야하고(무료 도메인 처리 안됨), 예약된 서브도메인으로는 버켓생성 하면 안됨
  • 버켓안에 들어있는 오브젝트는 모든 사용자에게 Read권한(웹서비스)이 들어가면 된다.

5. 용어 정리

ODS : Object  Storage Device Server

MON : Ceph 모니터 소프트웨어

MDS : Metadata Server

RADOS : Reliable Autonomic Distributed Object Store

RGW : RADOS(S3/Swift) 게이트 웨이

RBD : Block Device 컴포넌트

CephFS: Ceph POSIC 파일시스템 컴포넌트

cephx : Ceph 인증 프로토콜로 Kerberos 와 유사하게 동작

6. 레퍼런스

http://docs.ceph.com/docs/master/glossary/#term-osd



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
페이지
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함