Ceph分布式存储实践应用之Swift Api配置使用

178 阅读6分钟

1. Ceph Swift Api 说明

在ceph的使用上, 之前采用的是fs文件系统, 并编写了相应的api来操作演示。 但在互联网大规模的文件场景下, fs并不能满足生产的使用要求,rados本地化操作也不便于服务的接入与使用, 这里就需要采用Ceph Swift Api 来实现文件的存储管理。

2. Ceph Swift Api 特点

Swift是由Rackspace开发,用来为云计算提供可扩展存储的项目。专注于对象存储, 并提供一套REST风格的Api来访问, 与Ceph强一致性不同, 它是最终一致性。两者都是优秀的开源项目, 并无明显优劣之分,在使用场景上有所不同, 如果是专注于对象存储, 那么可以选择swift即可满足需要, 如果还有块存储要求, 那么选择Ceph更为合适。这里选择Ceph, 因为通过网关可以适配兼容swift api, 同时在数据访问上具有较强的扩展性:

  • Ceph可通过Rados网关用兼容S3的RESTful API访问,对AWS云环境下的其他内容也能很好的兼容, 比如OpenStack Swift的对象存储访问接口。
  • CephFS:是一个POSIX兼容的文件系统,可以在任何Linux发行版上运行,操作系统可直接访问Ceph存储。
  • RDB:RBD是一个Linux内核级的块设备,允许用户像任何其他Linux块设备一样访问Ceph。
  • ISCSI 网关: 这一增加的功能是SUSE加上去的,它允许管理员在Ceph之上运行iSCSI网关,从而将其转变为任何操作系统都可以访问的SAN文件管理器。

3. Ceph RGW 介绍

Ceph可以提供块、文件和对象三种形态的存储。RGW就是提供对象存储的网关,也即对象存储网关。所谓对象存储网关,也就是对象存储的入口,本质上是一个HTTP服务器,与Nginx和Apache无特殊差别。通过这个网关入口,用户可以采用HTTP协议,以RESTful的方式访问Ceph的对象存储。

4. Ceph 存储结构

在使用对象存储之前, 先要了解桶(container容器)概念及其存储结构:

Ceph Swift Api的调用, 需要先创建相应用户进行认证才能操作, 每个用户下面可以创建多个桶, 桶里面可以存储对象,对象就是各种数据文件, 包括文档, 图片等。传统上传文件的使用, 我们往往会指定路径信息, 在这里, 桶和对象的关系好比文件夹与文件的概念, 不同之处是桶不能再嵌套桶, 也就是没有层级路径的概念。

Ceph存储结构: file

5. Ceph Swift Api 服务端的配置

  1. 确保集群正常安装并启动:

    [root@CENTOS7-1 ceph-cluster]# ceph -s
      cluster:
        id:     0ec99aa9-e97e-43d3-b5b9-90eb21c4abff
        health: HEALTH_OK
     
      services:
        mon: 3 daemons, quorum CENTOS7-1,CENTOS7-2,CENTOS7-3
        mgr: centos7-1(active), standbys: centos7-3, centos7-2
        mds: fs_test-1/1/1 up  {0=centos7-1=up:active}
        osd: 3 osds: 3 up, 3 in
        rgw: 3 daemons active
     
      data:
        pools:   9 pools, 128 pgs
        objects: 257  objects, 166 KiB
        usage:   3.0 GiB used, 57 GiB / 60 GiB avail
        pgs:     128 active+clean
    

    如果rgw没有显示, 检查服务状态:

    [root@CENTOS7-1 ceph-cluster]#  systemctl list-unit-files|grep enabled|grep ceph
    ceph-crash.service                            enabled        
    ceph-mds@.service                             enabled        
    ceph-mgr@.service                             enabled        
    ceph-mon@.service                             enabled        
    ceph-osd@.service                             enabled-runtime
    ceph-radosgw@.service                         enabled        
    ceph-volume@.service                          enabled        
    ceph-mds.target                               enabled        
    ceph-mgr.target                               enabled        
    ceph-mon.target                               enabled        
    ceph-osd.target                               enabled        
    ceph-radosgw.target                           enabled        
    ceph.target                                   enabled        
    

    重启RGW服务:

    systemctl restart ceph-radosgw@*.service
    
  2. 验证网关是否正常

    访问地址,http://{服务器IP}:7480

    出现以下提示代表正常

    file

  3. 创建Swift用户, 用于接口请求认证

    sudo radosgw-admin user create --subuser="cephtester:subtester" --uid="cephtester" --display-name="cephtester" --key-type=swift --secret="654321" --access=full
    
    

    uid 为主用户, subuser为子用户信息, secret指定密钥, 不指定则随机生成, access拥有权限设定。

    返回结果:

    {
        "user_id": "cephtester",
        "display_name": "cephtester",
        "email": "",
        "suspended": 0,
        "max_buckets": 1000,
        "auid": 0,
        "subusers": [
            {
                "id": "cephtester:subtester",
                "permissions": "full-control"
            }
        ],
        "keys": [],
        "swift_keys": [
            {
                "user": "cephtester:subtester",
                "secret_key": "654321"
            }
        ],
        "caps": [],
        "op_mask": "read, write, delete",
        "default_placement": "",
        "placement_tags": [],
        "bucket_quota": {
            "enabled": false,
            "check_on_raw": false,
            "max_size": -1,
            "max_size_kb": 0,
            "max_objects": -1
        },
        "user_quota": {
            "enabled": false,
            "check_on_raw": false,
            "max_size": -1,
            "max_size_kb": 0,
            "max_objects": -1
        },
        "temp_url_keys": [],
        "type": "rgw",
        "mfa_ids": []
    }
    

    记住swift_keys下面的user和secret_key信息, 代码中需使用。

  4. 激活管理后台的对象存储模块:

  5. 创建一个管理用户:

     radosgw-admin user create --uid=mgruser --display-name=mgruser  --system
    

    返回结果:

       {
           "user_id": "mgruser",
           "display_name": "mgruser",
           "email": "",
           "suspended": 0,
           "max_buckets": 1000,
           "auid": 0,
           "subusers": [],
           "keys": [
               {
                   "user": "mgruser",
                   "access_key": "XZDC4Y0AORE01NMYU3VV",
                   "secret_key": "me0Z80HLvctkzzBs74ufXS0Wi947NBe6Wpj3MxKP"
               }
           ],
           "swift_keys": [],
           "caps": [],
           "op_mask": "read, write, delete",
           "system": "true",
           "default_placement": "",
           "placement_tags": [],
           "bucket_quota": {
               "enabled": false,
               "check_on_raw": false,
               "max_size": -1,
               "max_size_kb": 0,
               "max_objects": -1
           },
           "user_quota": {
               "enabled": false,
               "check_on_raw": false,
               "max_size": -1,
               "max_size_kb": 0,
               "max_objects": -1
           },
           "temp_url_keys": [],
           "type": "rgw",
           "mfa_ids": []
       }
    

    根据生成的access_key与secret_key, 执行:

       ceph dashboard set-rgw-api-access-key XZDC4Y0AORE01NMYU3VV
       ceph dashboard set-rgw-api-secret-key me0Z80HLvctkzzBs74ufXS0Wi947NBe6Wpj3MxKP
    

    打开管理界面,https://10.10.20.11:8443 可以查看到我们刚才创建的两个用户: file

6. Ceph Swift Api 调用验证

  1. 修改ceph-demo工程:

    增加SwiftOperator接口:

    @Component
    @Log4j2
    public class SwiftOperator {   
        /**
         * 用户名信息, 格式: 主用户名:子用户名
         */
        private String username ="cephtester:subtester";   
        /**
         * 用户密码
         */
        private String password = "654321";   
        /**
         * 接口访问地址
         */
        private String authUrl = "http://10.10.20.11:7480/auth/1.0";
    
        /**
         * 默认存储的容器名称(bucket)
         */
        private String defaultContainerName = "user_datainfo";
    
        /**
         * Ceph的账户信息
         */
        private Account account = null;
    
        /**
         * Ceph的容器信息
         */
        private Container container;   
        /**
         * 进行Ceph的初始化配置
         */
        public SwiftOperator() {
            // 1. Ceph的账户信息配置
            AccountConfig config = new AccountConfig();
            config.setUsername(username);
            config.setPassword(password);
            config.setAuthUrl(authUrl);
            config.setAuthenticationMethod(AuthenticationMethod.BASIC);
            account = new AccountFactory(config).createAccount();   
            // 2.获取容器信息
            Container newContainer = account.getContainer(defaultContainerName);
            if(!newContainer.exists()) {
                container = newContainer.create();
                log.info("container create ==> " + defaultContainerName);
            }else {
                container = newContainer;
            }
    
        }   
        /**
         * 文件上传处理
         * @param remoteName
         * @param filePath
         */
        public void createObject(String remoteName, String filePath) {
            // 1. 从容器当中获取远程存储对象信息
            StoredObject object = container.getObject(remoteName);
            // 2. 执行文件上传处理
            object.uploadObject(new File(filePath));
        }   
        /**
         * 文件的下载处理
         * @param objectName
         * @param outPath
         */
        public void retrieveObject(String objectName, String outPath) {
            // 1. 从容器当中获取远程存储对象信息
            StoredObject object = container.getObject(objectName);
            // 2. 执行文件的下载方法
            object.downloadObject(new File(outPath));
    
        }   
        /**
         * 获取用户下面的所有容器信息
         * @return
         */
        public List listContainer() {
            List list = new ArrayList();
            Collection<Container> containers = account.list();
            for(Container container : containers) {
                list.add(container.getName());
                log.info("current container name : " + container.getName());
         }
            return list;
        }      
    }
    

    这里的用户名和密码填写上面我们所生成的信息。注意路径地址后缀为: /auth/1.0

    CephDemoApplication启动类,测试验证:

    @SpringBootApplication                
    @ComponentScan(basePackages = {"com.swift"})
    public class CephDemoApplication {   
    
        public static void main(String[] args) throws Exception  {
    
            // Swift Api接口调用验证
            swiftApi();
        }
    
        /**
         *  Rados Api的封装处理
         * @throws Exception
         */
        public static void radosApi(String[] args) throws Exception  {
            System.out.println("start....");
            String username = "admin";
            String monIp = "10.10.20.11:6789;10.10.20.12:6789;10.10.20.13:6789";
            String userKey = "AQBZBypdMchvBRAAbWVnIGyYNvxWQZ2UkuiYew==";
            String mountPath = "/";
            CephOperator cephOperate = null;
            try {
                String opt = (args == null || args.length < 1)? "" : args[0];
                cephOperate = new CephOperator(username, monIp, userKey, mountPath);
                if("upload".equals(opt)) {
                    cephOperate.uploadFileByPath("/temp_upload_fs", args[1]);
                }else if("download".equals(opt)) {
                    cephOperate.downloadFileByPath("/temp_download_fs", args[1]);
                }else {
                    System.out.println("Unrecognized Command! Usage  opt[upload|download] filename[path]!");
                }
            }catch(Exception e) {
                e.printStackTrace();
            }finally {
                if(null != cephOperate) {
                    cephOperate.umount();
                }
            }
            System.out.println("end....");
    
        }   
    
        /**
         * 通过Swift接口操作ceph集群
         * @throws Exception
         */
        public static void swiftApi() throws Exception  {
    
            ConfigurableApplicationContext appContext =  SpringApplication.run(CephDemoApplication.class);
            // 1. 先打印出用户的容器信息
            SwiftOperator swiftOperator = appContext.getBean(SwiftOperator.class);
            swiftOperator.listContainer();
    
            String objName = "test_ceph";
            // 2. 上传指定的文件
            swiftOperator.createObject(objName, "d:/test_swift_ceph.txt");
            // 3. 从ceph下载文件到指定的路径下面
            swiftOperator.retrieveObject(objName, "e:/test.txt");
    
            System.out.println("complete");
    
        }
    }
    
  2. 测试验证

    测试思路步骤: 先创建一个文件, 并上传到ceph系统, 然后从ceph系统下载到指定路径下面。

    这里要注意,我们默认的容器配置的是”user_datainfo“, 从ceph系统上传和下载的文件名称要一致, 启动打印"complete" , 无异常则代表执行成功。


本文由mirson创作分享,如需进一步交流,请加QQ群:19310171或访问www.softart.cn