Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

基于Rook的Kubernetes存储方案

28
Feb
2018

基于Rook的Kubernetes存储方案

By Alex
/ in PaaS
/ tags Ceph, K8S
5 Comments
简介

Rook是专用于Cloud-Native环境的文件、块、对象存储服务。它实现了一个自我管理的、自我扩容的、自我修复的分布式存储服务。

Rook支持自动部署、启动、配置、分配(provisioning)、扩容/缩容、升级、迁移、灾难恢复、监控,以及资源管理。 为了实现所有这些功能,Rook依赖底层的容器编排平台。

Rook在初期专注于Kubernetes+Ceph。Ceph是一个分布式存储系统,支持文件、块、对象存储,在生产环境中被广泛应用。

Rook架构

Rook和K8S的交互关系如下图:

rook-architecture-0

 

rook-architecture-2

说明如下:

  1. Kubelet是K8S节点上运行的代理程序,负责挂载当前节点的Pod所需要的卷
  2. Rook提供了一种卷插件,扩展了K8S的存储系统。Pod可以挂载Rook管理的块设备或者文件系统
  3. Operator启动并监控:监控Ceph的Pods、OSD(提供基本的RADOS存储)的Daemonset。Operator还管理CRD、对象存储(S3/Swift)、文件系统。Operator通过监控存储守护程序,来保障集群的健康运行。Ceph监控Pod会自动启动和Failover。集群扩缩容时Operator会进行相应的调整
  4. Operator还负责创建Rook Agent。这些代理是部署在所有K8S节点上的Pod。每个代理都配置一个Flexvolume驱动,此驱动和K8S的卷控制框架集成。节点上的所有存储相关操作(例如添加网络存储设备、挂载卷、格式化文件系统)都Agent负责

Rook守护程序(Mons, OSDs, MGR, RGW, MDS)被编译到单体的程序rook中,并打包到一个很小的容器中。该容器还包含Ceph守护程序,以及管理、存储数据所需的工具。

Rook隐藏了Ceph的很多细节,而向它的用户暴露物理资源、池、卷、文件系统、Bucket等概念。

Ceph
前提条件

要使用rook-ceph,必须满足:

  1. Kubernetes 1.11+版本
  2. 节点提供以下本地存储之一:
    1. 裸设备(没有分区、文件系统)
    2. 裸分区(没有文件系统),可以 lsblk -f查看,如果 FSTYPE不为空说明有文件系统
    3. 来自block模式的StorageClass提供的PV
安装
快速起步

使用下面的命令,创建一个简单的Rook集群:

Shell
1
2
3
4
5
git clone --single-branch --branch release-1.4 https://github.com/rook/rook.git
cd rook/cluster/examples/kubernetes/ceph
kubectl create -f common.yaml
kubectl create -f operator.yaml
kubectl create -f cluster.yaml

集群启动后,你可以创建块/对象/文件系统存储。

Operator

一般情况下,使用Rook Operator来管理Rook集群,下面的命令安装此Operator: 

Shell
1
2
3
4
5
cd cluster/examples/kubernetes/ceph
kubectl create -f common.yaml
kubectl create -f operator.yaml
 
kubectl -n rook-ceph get pod

你也可以通过Helm Chart安装:

Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
helm repo add rook-release https://charts.rook.io/release
 
# Helm 3
helm install --namespace rook-ceph rook-ceph rook-release/rook-ceph
 
# Helm 2
helm install --namespace rook-ceph --name rook-ceph rook-release/rook-ceph
 
 
# 参数示例
helm install --namespace rook-ceph rook-ceph rook-release/rook-ceph \
  --set image.repository=docker.gmem.cc/rook/ceph,logLevel=DEBUG  \
  --set csi.cephcsi.image=docker.gmem.cc/cephcsi/cephcsi:v3.1.0  \
  --set csi.registrar.image=docker.gmem.cc/k8scsi/csi-node-driver-registrar:v1.2.0  \
  --set csi.resizer.image=docker.gmem.cc/k8scsi/csi-resizer:v0.4.0  \
  --set csi.provisioner.image=docker.gmem.cc/k8scsi/csi-provisioner:v1.6.0 \
  --set csi.snapshotter.image=docker.gmem.cc/k8scsi/csi-snapshotter:v2.1.1  \
  --set csi.attacher.image=docker.gmem.cc/k8scsi/csi-attacher:v2.1.0
创建集群
示例

使用自定义资源CephCluster来创建Rook Ceph集群: 

YAML
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# 使用宿主机上的块设备
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: ceph/ceph:v15.2.4
  dataDirHostPath: /var/lib/rook
  mon:
    count: 3
    allowMultiplePerNode: true
  storage:
    useAllNodes: true
    useAllDevices: true
 
 
# 使用PVC创建块设备
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: ceph/ceph:v15.2.4
  dataDirHostPath: /var/lib/rook
  mon:
    count: 3
    volumeClaimTemplate:
      spec:
        storageClassName: local-storage
        resources:
          requests:
            storage: 10Gi
  storage:
   storageClassDeviceSets:
    - name: set1
      count: 3
      portable: false
      tuneDeviceClass: false
      encrypted: false
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          resources:
            requests:
              storage: 10Gi
          storageClassName: local-storage
          volumeMode: Block
          accessModes:
            - ReadWriteOnce
 
# 使用特定设备
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: ceph/ceph:v15.2.4
  dataDirHostPath: /var/lib/rook
  mon:
    count: 3
    allowMultiplePerNode: true
  dashboard:
    enabled: true
  # cluster level storage configuration and selection
  storage:
    useAllNodes: false
    useAllDevices: false
    deviceFilter:
    config:
      metadataDevice:
      databaseSizeMB: "1024" # this value can be removed for environments with normal sized disks (100 GB or larger)
    nodes:
    - name: "172.17.4.201"
      devices:             # specific devices to use for storage can be specified for each node
      - name: "sdb" # Whole storage device
      - name: "sdc1" # One specific partition. Should not have a file system on it.
      - name: "/dev/disk/by-id/ata-ST4000DM004-XXXX" # both device name and explicit udev links are supported
      config:         # configuration can be specified at the node level which overrides the cluster level config
        storeType: bluestore
    - name: "172.17.4.301"
      deviceFilter: "^sd."
CephCluster
YAML
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  # 内部名称,一般使用命名空间的名字,因为同一个命名空间仅仅支持一个集群
  name: rook-ceph
  namespace: rook-ceph
spec:
  # Rook可以连接到外部Ceph集群,而不是在K8S集群中创建自己管理的Ceph集群
  external:
    # 使用外部集群(最低luminous 12.2.x),仅仅作为集群消费者。这种情况下,Rook仍然能够在K8S中创建
    # 对象网关、MDS、NFS组件
    # 除了cephVersion.image、dataDirHostPath之外的其它选项,都被忽略
    #
    # Rook特性要求的Ceph版本
    #   动态分配RBD:12.2.X
    #   配置额外的CR(object,file,nfs):13.2.3
    #   动态分配CephFS:14.2.3
    enabled: true
  # Ceph守护程序的版本信息
  cephVersion:
    # 用于运行Ceph守护进程的镜像
    image: ceph/ceph:v15.2.4
    # 如果true则允许使用不支持的major Ceph版本
    # 目前支持nautilus( 14.2.0 )、octopus( 15.2.0 )
    allowUnsupported: true
  # 宿主机上的路径,在此路径下存储各Ceph服务的配置和数据
  dataDirHostPath: /var/lib/rook
  # 如果设置为true,则升级时不会检查Ceph守护程序的新版本
  skipUpgradeChecks: false
  # Ceph仪表盘设置
  dashboard:
    # 启用仪表盘,以查看集群状态
    enabled: true
    # URL前缀,反向代理场景下有用
    urlPrefix:
    # 仪表盘端口
    port:
    # 使用使用SSL,13.2.2+
    ssl: true
  # 基于Prometheus的监控配置
  monitoring:
    enabled: true
    # 部署PrometheusRule的命名空间,默认此CR所在命名空间
    rulesNamespace:
  # 集群网络设置,如果不指定,使用默认的SDN
  network:
    # 可选 host multus(为Pod添加多个接口的开源项目,试验性支持)
    provider: host
    # 网络选择器,选择器的值必须匹配Multus的NetworkAttachmentDefinition对象
    selectors
      # 客户端通信(读写)使用的网络
      public:
      # 集群内部流量使用的网络
      cluster:
  mon:
    # mon pod的数量
    count: 3
    # 允许在单个节点上部署多个mon pod
    allowMultiplePerNode: true
    # 用于创建mon存储的PersistentVolumeSpec,如果不支持,使用HostPath卷
    volumeClaimTemplate:
  mgr:
    # 启用的mgr模块列表
    modules:
  crashCollector:
    # 禁用crash collector,不再每个运行了Ceph守护进程的节点上创建crash collector pod
    disable: true
  # 针对所有节点的存储设备选择和配置,各节点可以覆盖
  storage:
    # 是否将集群中所有节点作为Ceph节点。如果你使用nodes字段,必须设置为false
    useAllNodes: true
    # 按节点配置存储
    nodes:
      # 匹配kubernetes.io/hostname的节点名
      - name: xenial-100
        devices:
         - name: sdb
         - name: sdc1
        config:
          # 用于存放OSD元数据的设备名,使用低延迟设备例如SSD/NVMe可以提升性能
          metadataDevice:
          # OSD的底层存储格式
          storeType: bluestore
          # Bluestore WAL日志大小
          walSizeMB:
          # Bluestore 数据库的大小
          databaseSizeMB:
          # CRUSH设备类,如果不指定,Ceph会自动设置为hdd ssd nvme之一
          deviceClass:
          # 设置各设备运行OSD的数量,NVMe这样的高性能设备可以运行多个OSD
          osdsPerDevice**:
          # 设置各设备是否使用dmcrypt加密
          encryptedDevice**:
    # 是否自动将所有发现的裸设备/分区作为OSD
    useAllDevices: true
    # 参与OSD的设备,过滤表达式:
    # sdb      仅仅sdb
    # ^sd.     任何sd开头的设备
    # ^[^r]    任何不以r开头的设备
    # ^sd[a-d] sda sdb sdc sdd
    # ^s       任何s开头的设备
    deviceFilter: sdb
    # 参与OSD的设备
    devices:
        # sdb这样的设备名,或者udev的完整路径,例如/dev/disk/by-id/ata-ST4000DM004-XXXX
      - name:
        # 参见上面的config
        config:
    # 参见上面的config
    config:
  # 为各种Ceph组件添加的注解
  annotations:
    all:
    mgr:
    mon:
    osd:
  # 为各种Ceph组件添加的亲和性设置
  placement:
    mgr:
      nodeAffinity:
      podAffinity:
      podAntiAffinity:
      tolerations:
      topologySpreadConstraints:
    mon:
    osd:
    cleanup:
    all:
  # 为各种Ceph组件进行资源配额
  resources:
    mon:
      requests:
        cpu:
        memory:
      limits:
    mgr:
    osd:
    mds:
    prepareosd:
    crashcollector:
  # 健康检查配置
  healthCheck:
    daemonHealth:
      mon:
        disabled: false
        interval: 45s
        timeout: 600s
      osd:
        disabled: false
        interval: 60s
      status:
        disabled: false
    livenessProbe:
      mon:
        disabled: false
      mgr:
        disabled: false
      osd:
        disabled: false
 
  # 各组件的优先级类别名
  priorityClassNames:
  # 删除CephCluster对象是,如何清理数据
  cleanupPolicy:
    # kubectl -n rook-ceph patch cephcluster rook-ceph --type merge \
    #   -p '{"spec":{"cleanupPolicy":{"confirmation":"yes-really-destroy-data"}}}'
    # 仅仅当你要删除CephCluster时,才设置该字段。可选空值或者yes-really-destroy-data
    #   空值:仅仅删除Ceph元数据,除非你手工清理主机,否则无法重新安装CephCluster
    #   yes-really-destroy-data:RookOperator回自动删除宿主机上的目录,清理宿主机上的块设备
    confirmation: yes-really-destroy-data
    # yes-really-destroy-data时如何清理磁盘
    sanitizeDisks:
      # 仅仅清理元数据,还是消毒整个磁盘
      method: quick | complete
      # 消毒磁盘使用的随机字节来源
      dataSource: zero | random
      # 反复消毒多次
      iteration: 1
使用外部Ceph集群

为了使用外部Ceph集群,Rook需要知道如何连接到Ceph。你可以通过脚本导入Rook需要的信息:

Shell
1
2
3
4
5
6
7
8
9
10
11
# 信息导入到什么命名空间
export NAMESPACE=rook-ceph-external
# 外部集群的FSID
export ROOK_EXTERNAL_FSID=3240b4aa-ddbc-42ee-98ba-4ea7b2a61514
# 外部集群的MON信息
export ROOK_EXTERNAL_CEPH_MON_DATA=a=172.17.0.4:6789
# 外部集群的管理Keyring
export ROOK_EXTERNAL_ADMIN_SECRET=AQC6Ylxdja+NDBAAB7qy9MEAr4VLLq4dCIvxtg==
 
# 执行导入
bash cluster/examples/kubernetes/ceph/import-external-cluster.sh

然后,创建使用外部集群的CephCluster对象:

YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph-external
  # 命名空间和上面对应
  namespace: rook-ceph-external
spec:
  external:
    enable: true
  crashCollector:
    disable: true
  # 可选的,使用外部ceph-mgr暴露的Prometheus Exporter
  monitoring:
    enabled: true
    rulesNamespace: rook-ceph
    externalMgrEndpoints:
      - ip: 192.168.39.182 
使用块存储
示例 
YAML
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
31
32
33
34
35
36
37
38
39
40
41
42
43
# 定义一个块存储池
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  # 池的名字
  name: replicapool
  namespace: rook-ceph
spec:
  failureDomain: host
  replicated:
    size: 3
 
---
 
# 定义一个StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: rook-ceph-block
# 该SC的Provisioner标识,rook-ceph前缀即当前命名空间
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
    # clusterID 就是集群所在的命名空间名
    clusterID: rook-ceph
    # RBD镜像在哪个池中创建
    pool: replicapool
    # RBD镜像格式,默认2
    imageFormat: "2"
    # RBD镜像格式为2时,指定镜像特性,CSI RBD目前仅仅支持layering
    imageFeatures: layering
    # Ceph管理凭证配置
    csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
    csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
    csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
    csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
    csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
    csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
 
    # 卷的文件系统类型,默认ext4,不建议xfs,因为存在潜在的死锁问题(超融合设置下卷被挂载到相同节点作为OSD时)
    # will set default as `ext4`. Note that `xfs` is not recommended due to potential deadlock
    csi.storage.k8s.io/fstype: ext4
# PVC被删除后,删除对应的RBD卷
reclaimPolicy: Delete
CephBlockPool
YAML
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
31
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  # 存储池的名称,会反映到底层Ceph
  name: replicapool
  namespace: rook-ceph
spec:
  # 每个数据副本必须跨越不同的故障域分布,如果设置为host,则保证每个副本在不同机器上
  failureDomain: host
  # 复制/纠删码,二选一
  replicated:
    # 副本数量
    size: 3
    # 如果需要设置副本数量为1,则必须将该字段置为false
    requireSafeReplicaSize: false
  erasureCoded:
    dataChunks: 2
    codingChunks: 1
  # CRUSH设备类别,说明该池中的数据可以存放在哪些设备上
  deviceClass: hdd
  # 该池使用的CRUSH map中的根节点
  crushRoot:
  # 通过启用动态OSD性能计数器,从而实现per-rbd的IO统计
  enableRBDStats:
  # 为存储池传递参数
  # 可用参数参考 https://docs.ceph.com/docs/master/rados/operations/pools/#set-pool-values
  parameters:
    # 给Ceph一个提示,说明该池期望消耗集群的最大多少容量
    target_size_ratio:
    # Bluestore压缩模式
    compression_mode: 
使用文件系统

目前,对多文件系统的支持仍然处于试验阶段,需要通过Rook Operator的环境变量 ROOK_ALLOW_MULTIPLE_FILESYSTEMS开启。默认情况下,一个Ceph集群仅仅支持单个文件系统。

示例
YAML
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 定义文件系统
apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
  name: myfs
  namespace: rook-ceph
spec:
  # 元数据池配置
  metadataPool:
    replicated:
      size: 3
  # 数据池配置
  dataPools:
    - replicated:
        size: 3
  # 该对象删除后,Ceph存储池怎么办
  preservePoolsOnDelete: true
  # 元数据服务器一主一备
  metadataServer:
    activeCount: 1
    activeStandby: true
 
---
 
# 定义一个StorageClass
 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-cephfs
#            注意前缀匹配Operator的命名空间
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
  # Operator所在命名空间,就是Ceph集群的ID
  clusterID: rook-ceph
 
  # CephFS 文件系统名
  fsName: myfs
 
  # CephFS卷在哪个存储池中创建,如果provisionVolume: "true" 则此字段必须
  pool: myfs-data0
 
  # 可以使用既有的CephFS卷,需要指定卷的根路径
  # 如果 provisionVolume: "false" 则此字段必须
  rootPath: /absolute/path
 
  # 这些Ceph管理凭证由Operator自动生成
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
 
reclaimPolicy: Delete
关于PV配额

CephFS的CSI驱动使用Quotas来强制应用PVC声明的大小,仅仅4.17+内核才能支持CephFS quotas。

如果内核不支持,而且你需要配额管理,配置Operator环境变量 CSI_FORCE_CEPHFS_KERNEL_CLIENT: false来启用FUSE客户端。

使用FUSE客户端时,升级Ceph集群时应用Pod会断开mount,需要重启才能再次使用PV。

CephFilesystem
YAML
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
  name: myfs
  namespace: rook-ceph
spec:
  # 存放元数据的池的配置
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  # 存放数据的池的配置
  dataPools:
    - failureDomain: host
      replicated:
        size: 3
  # 删除该对象后,底层的存储池是否保留
  preservePoolsOnDelete: true
  # 元数据服务器配置
  metadataServer:
    # 主备元数据服务器数量
    activeCount: 1
    activeStandby: true
    # 注解
    annotations:
      key: value
    # 亲和性
    placement:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: role
              operator: In
              values:
              - mds-node
      tolerations:
      - key: mds-node
        operator: Exists
      podAffinity:
      podAntiAffinity:
      topologySpreadConstraints:
    # 配额
    resources:
      limits:
        cpu: "500m"
        memory: "1024Mi"
      requests:
        cpu: "500m"
        memory: "1024Mi" 
使用对象存储 
集群内对象存储

Rook支持在集群内部创建一个支持S3接口的RGW网关:

YAML
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
# 这个示例需要3个位于不同节点的Bluestore OSD
apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: my-store
  namespace: rook-ceph
spec:
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  dataPool:
    # 故障域设置为host,则意味着三个副本必须位于不同节点,也就是说需要3个节点
    failureDomain: host
    # 使用纠删码方式,三副本中2个用作dataChunks,一个用于codingChunks
    erasureCoded:
      dataChunks: 2
      codingChunks: 1
  preservePoolsOnDelete: true
  gateway:
    type: s3
    sslCertificateRef:
    port: 80
    securePort:
    instances: 1
  healthCheck:
    bucket:
      disabled: false
      interval: 60s
使用外部Ceph集群

Rook也可以直接连接到外部的RGW网关:

YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: external-store
  namespace: rook-ceph
spec:
  gateway:
    port: 8080
    externalRgwEndpoints:
      - ip: 192.168.39.182
  healthCheck:
    bucket:
      enabled: true
      interval: 60s
创建Bucket

有了对象存储后,还需要创建Bucket,以便客户端读写数据。

你需要定义一个StorageClass,定义了基于此StorageClass创建的桶的回收策略、所依赖的对象网关:

YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: rook-ceph-bucket
# rook-ceph前缀必须和命名空间对应
provisioner: rook-ceph.ceph.rook.io/bucket
# ObjectBucketClaim被删除后,删除RGW中的桶
reclaimPolicy: Delete
parameters:
  # 底层对象存储的信息
  objectStoreName: my-store
  objectStoreNamespace: rook-ceph
  region: us-east-1

有了上述StorageClass后,就可以使用下面的CR来创建Bucket: 

YAML
1
2
3
4
5
6
7
8
9
10
apiVersion: objectbucket.io/v1alpha1
kind: ObjectBucketClaim
metadata:
  name: ceph-bucket
  namespace: default
spec:
  # 生成的桶的名称
  generateBucketName: ceph-bkt
  # 基于的StorageClass
  storageClassName: rook-ceph-bucket

Rook Operator会创建名为ceph-bkt的桶,还会在ObjectBucketClaim所在命名空间下,创建和ObjectBucketClaim名字相同的:

  1. Configmap:包含Bucket的地址
  2. Secret:包含访问Bucket所需要的凭证信息

其中,Configmap内容如下:

YAML
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
data:
  BUCKET_HOST: rook-ceph-rgw-rgw.rook-ceph
  BUCKET_NAME: tcnp-5aca27d8-f74f-4687-b979-e336f4203459
  BUCKET_PORT: "9000"
  BUCKET_REGION: ""
  BUCKET_SUBREGION: ""
kind: ConfigMap
metadata:
  name: ceph-bucket
  namespace: default

Secret的内容如下:

YAML
1
2
3
4
5
6
7
8
9
apiVersion: v1
data:
  AWS_ACCESS_KEY_ID: RjZFRVUyTkUwWEZCWDRJVFgwWkE=
  AWS_SECRET_ACCESS_KEY: TUVPVU1panBFekM5emNQaDR2UkE3bHRwcFlaSnEzeGxFMmRmUFBQbw==
kind: Secret
metadata:
  name: ceph-bucket
  namespace: default
type: Opaque 
创建用户

如果你希望创建独立的访问S3端点的用户,可以使用下面的CR:

YAML
1
2
3
4
5
6
7
8
9
apiVersion: ceph.rook.io/v1
kind: CephObjectStoreUser
metadata:
  name: my-user
  namespace: rook-ceph
spec:
  # 对象存储的名字
  store: my-store
  displayName: "my display name"

Access Key和Secret Key 会创建到相同命名空间。

从集群外访问

将rook-ceph-rgw-**服务暴露出去即可。

CephObjectStore
YAML
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  # 对象存储的名字,影响相关Pod、其它资源的命名
  name: rgw
  namespace: rook-ceph
spec:
  # 用于对象存储元数据的池,必须使用replicated方式
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  # 用于对象存储数据的池,可以使用纠删码方式
  dataPool:
    failureDomain: host
    erasureCoded:
      dataChunks: 2
      codingChunks: 1
  # 当前对象删除时,用于支持对象存储的池,是否被删除
  preservePoolsOnDelete: true
  gateway:
    # 目前仅仅支持s3
    type: s3
    # 必须指定证书才能配置SSL,包含SSL证书的Secret名称
    sslCertificateRef:
    # RGW Pod的HTTP端口
    port: 80
    # RGW Pod的HTTPS端口
    securePort:
    # RGW Pod的数量
    instances: 1
    # 添加到RGW Pod的注解
    annotations:
      key: value
    # 亲和性配置
    placement:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: role
              operator: In
              values:
              - rgw-node
      tolerations:
      - key: rgw-node
        operator: Exists
      podAffinity:
      podAntiAffinity:
      topologySpreadConstraints:
    # 资源配额
    resources:
      limits:
        cpu: "500m"
        memory: "1024Mi"
      requests:
        cpu: "500m"
        memory: "1024Mi"

 

常见问题
rook-ceph-osd无法启动
failed to configure devices

报错信息:failed to configure devices. failed to config osd 65. failed format/partition of osd 65. failed to partion device vdc. failed to partition /dev/vdc. Failed to complete partition vdc: exit status 4 

报错原因:在我的环境下是节点(本身是KVM虚拟机)的虚拟磁盘太小导致,分配32G的磁盘没有问题,20G则出现上述报错

activate容器失败

重启后出现,原因是逻辑卷没有激活,lsblk看到的块设备列表中没有Ceph管理的逻辑卷。执行:

Shell
1
2
3
4
5
6
7
# yum install lvm2
 
modprobe dm-mod
# 扫描可用的卷组
vgscan
# 激活逻辑卷
vgchange -ay

进行激活,然后可以在/dev/mapper、/dev/VGNAME下看到块设备了,OSD也可以启动了。

已存在文件系统

如果块设备上已经有了文件系统,则无法prepare OSD。这个在重装Rook的情况下容易出现。需要手工清除磁盘:

Shell
1
2
3
4
5
6
wipefs --all  /dev/vdb
dmsetup remove  ceph--164d13ee--d820--4da3--ac66--d1b2d83d8a28-osd--data--c29cedc6--f8ce--4e4b--b88b--4c7272866180
 
# 或者更优雅的
vgremove ceph-1fd08944-b4e0-4839-82a9-62ecc6f5861e
wipefs --all /dev/vdb

 

← OpenResty学习笔记
使用Eclipse Memory Analyzer分析JVM堆Dump →
5 Comments On This Topic
  1. 回复
    朱海峰
    2018/06/10

    rook 现在已经被cncf认证了

    • 回复
      Alex
      2018/06/10

      前些日子试验觉得不是很稳定,因此我们直接使用Ceph作为存储了。相信rook会很快完善。

  2. 回复
    General
    2018/12/20

    请问,在Kubernetes集群中添加了node节点以后,怎么实现添加rook-ceph-agent和rook-discover

    • 回复
      Alex
      2018/12/20

      不好意思,由于rook不太成熟,我们直接使用ceph了,因此最近没有跟进rook。

      • 回复
        General
        2018/12/25

        我打算把rook应用到测试环境中去,等rook在CNCF中毕业之后实现正式落地

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • 如何在Pod中执行宿主机上的命令
  • Istio学习笔记
  • Flexvolume学习笔记
  • Envoy学习笔记
  • 基于Helm的Kubernetes资源管理

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2