千家信息网

k8s-ceph-rbd

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,k8s使用ceph实现动态持久化存储 https://juejin.im/post/5b766b5bf265da27e36efdfa96 CountingStars_2018.08.17 14:37*
千家信息网最后更新 2025年12月02日k8s-ceph-rbd

k8s使用ceph实现动态持久化存储 https://juejin.im/post/5b766b5bf265da27e36efdfa
96 CountingStars_
2018.08.17 14:37* 字数 435 阅读 3432评论 1喜欢 3
简介
本文章介绍如何使用ceph为k8s提供动态申请pv的功能。ceph提供底层存储功能,cephfs方式支持k8s的pv的3种访问模式ReadWriteOnce,ReadOnlyMany ,ReadWriteMany ,RBD支持ReadWriteOnce,ReadOnlyMany两种模式

访问模式只是能力描述,并不是强制执行的,对于没有按pvc声明的方式使用pv,存储提供者应该负责访问时的运行错误。例如如果设置pvc的访问模式为ReadOnlyMany ,pod挂载后依然可写,如果需要真正的不可写,申请pvc是需要指定 readOnly: true 参数

部署
部署k8s
centos7使用kubeadm安装k8s-1.11版本

部署ceph
centos7安装ceph分布式存储集群

在k8s集群中配置使用ceph
使用Ceph RBD
使用kubeadm安装集群的额外配置

如果使用kubeadm部署的集群需要这些额外的步骤

由于使用动态存储时 controller-manager 需要使用 rbd 命令创建 image

所以 controller-manager 需要使用 rbd 命令

由于官方controller-manager镜像里没有rbd命令

如果没使用如下方式会报错无法成功创建pvc

相关 issue https://github.com/kubernetes/kubernetes/issues/38923

cat >external-storage-rbd-provisioner.yaml<apiVersion: v1
kind: ServiceAccount
metadata:
name: rbd-provisioner
namespace: kube-system

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbd-provisioner
rules:

  • apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  • apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  • apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  • apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
  • apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  • apiGroups: [""]
    resources: ["services"]
    resourceNames: ["kube-dns"]
    verbs: ["list", "get"]

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: rbd-provisioner
    subjects:

  • kind: ServiceAccount
    name: rbd-provisioner
    namespace: kube-system
    roleRef:
    kind: ClusterRole
    name: rbd-provisioner
    apiGroup: rbac.authorization.k8s.io

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: rbd-provisioner
namespace: kube-system
rules:

  • apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
    name: rbd-provisioner
    namespace: kube-system
    roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: Role
    name: rbd-provisioner
    subjects:

  • kind: ServiceAccount
    name: rbd-provisioner
    namespace: kube-system

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: rbd-provisioner
namespace: kube-system
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: rbd-provisioner
spec:
containers:

  • name: rbd-provisioner
    image: "quay.io/external_storage/rbd-provisioner:v2.0.0-k8s1.11"
    env:
    • name: PROVISIONER_NAME
      value: ceph.com/rbd
      serviceAccount: rbd-provisioner
      EOF
      kubectl apply -f external-storage-rbd-provisioner.yaml

查看状态 等待running之后 再进行后续的操作

kubectl get pod -n kube-system
配置 storageclass

在k8s集群中所有节点安装 ceph-common

需要使用kubelet使用rdb命令map附加rbd创建的image

yum install -y ceph-common

创建 osd pool 在ceph的mon或者admin节点

ceph osd pool create kube 4096
ceph osd pool ls

创建k8s访问ceph的用户 在ceph的mon或者admin节点

ceph auth get-or-create client.kube mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=kube' -o ceph.client.kube.keyring

查看key 在ceph的mon或者admin节点

ceph auth get-key client.admin
ceph auth get-key client.kube

创建 admin secret

CEPH_ADMIN_SECRET 替换为 client.admin 获取到的key

export CEPH_ADMIN_SECRET='AQBBAnRbSiSOFxAAEZXNMzYV6hsceccYLhzdWw=='
kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \
--from-literal=key=$CEPH_ADMIN_SECRET \
--namespace=kube-system

在 default 命名空间创建pvc用于访问ceph的 secret

CEPH_KUBE_SECRET 替换为 client.kube 获取到的key

export CEPH_KUBE_SECRET='AQBZK3VbTN/QOBAAIYi6CRLQcVevW5HM8lunOg=='
kubectl create secret generic ceph-user-secret --type="kubernetes.io/rbd" \
--from-literal=key=$CEPH_KUBE_SECRET \
--namespace=default

查看 secret

kubectl get secret ceph-user-secret -o yaml
kubectl get secret ceph-secret -n kube-system -o yaml

配置 StorageClass

如果使用kubeadm创建的集群 provisioner 使用如下方式

provisioner: ceph.com/rbd

cat >storageclass-ceph-rdb.yaml<kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: dynamic-ceph-rdb
provisioner: ceph.com/rbd

provisioner: kubernetes.io/rbd

parameters:
monitors: 11.11.11.111:6789,11.11.11.112:6789,11.11.11.113:6789
adminId: admin
adminSecretName: ceph-secret
adminSecretNamespace: kube-system
pool: kube
userId: kube
userSecretName: ceph-user-secret
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
EOF

创建

kubectl apply -f storageclass-ceph-rdb.yaml

查看

kubectl get sc
测试使用

创建pvc测试

cat >ceph-rdb-pvc-test.yaml<kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: ceph-rdb-claim
spec:
accessModes:

  • ReadWriteOnce
    storageClassName: dynamic-ceph-rdb
    resources:
    requests:
    storage: 2Gi
    EOF
    kubectl apply -f ceph-rdb-pvc-test.yaml

查看

kubectl get pvc
kubectl get pv

创建 nginx pod 挂载测试

cat >nginx-pod.yaml<apiVersion: v1
kind: Pod
metadata:
name: nginx-pod1
labels:
name: nginx-pod1
spec:
containers:

  • name: nginx-pod1
    image: nginx:alpine
    ports:
    • name: web
      containerPort: 80
      volumeMounts:
    • name: ceph-rdb
      mountPath: /usr/share/nginx/html
      volumes:
  • name: ceph-rdb
    persistentVolumeClaim:
    claimName: ceph-rdb-claim
    EOF
    kubectl apply -f nginx-pod.yaml

查看

kubectl get pods -o wide

修改文件内容

kubectl exec -ti nginx-pod1 -- /bin/sh -c 'echo Hello World from Ceph RBD!!! > /usr/share/nginx/html/index.html'

访问测试

POD_ID=$(kubectl get pods -o wide | grep nginx-pod1 | awk '{print $(NF-1)}')
curl http://$POD_ID

清理

kubectl delete -f nginx-pod.yaml
kubectl delete -f ceph-rdb-pvc-test.yaml
使用 CephFS
linux内核需要4.10+,否则会出现无法正常使用的问题,详细issue信息 https://github.com/kubernetes-incubator/external-storage/issues/345
centos7升级内核

在ceph集群创建CephFS

如下操作在ceph的mon或者admin节点

CephFS需要使用两个Pool来分别存储数据和元数据

ceph osd pool create fs_data 128
ceph osd pool create fs_metadata 128
ceph osd lspools

创建一个CephFS

ceph fs new cephfs fs_metadata fs_data

查看

ceph fs ls
部署cephfs-provisioner

官方没有cephfs动态卷支持

使用社区提供的cephfs-provisioner

cat >external-storage-cephfs-provisioner.yaml<apiVersion: v1
kind: ServiceAccount
metadata:
name: cephfs-provisioner
namespace: kube-system

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cephfs-provisioner
rules:

  • apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  • apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  • apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  • apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
  • apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  • apiGroups: [""]
    resources: ["secrets"]
    verbs: ["create", "get", "delete"]

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: cephfs-provisioner
    subjects:

  • kind: ServiceAccount
    name: cephfs-provisioner
    namespace: kube-system
    roleRef:
    kind: ClusterRole
    name: cephfs-provisioner
    apiGroup: rbac.authorization.k8s.io

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: cephfs-provisioner
namespace: kube-system
rules:

  • apiGroups: [""]
    resources: ["secrets"]
    verbs: ["create", "get", "delete"]

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
    name: cephfs-provisioner
    namespace: kube-system
    roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: Role
    name: cephfs-provisioner
    subjects:

    • kind: ServiceAccount
      name: cephfs-provisioner
      namespace: kube-system

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: cephfs-provisioner
namespace: kube-system
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: cephfs-provisioner
spec:
containers:

  • name: cephfs-provisioner
    image: "quay.io/external_storage/cephfs-provisioner:v2.0.0-k8s1.11"
    env:
    • name: PROVISIONER_NAME
      value: ceph.com/cephfs
      command:
    • "/usr/local/bin/cephfs-provisioner"
      args:
    • "-id=cephfs-provisioner-1"
      serviceAccount: cephfs-provisioner
      EOF
      kubectl apply -f external-storage-cephfs-provisioner.yaml

查看状态 等待running之后 再进行后续的操作

kubectl get pod -n kube-system
配置 storageclass

查看key 在ceph的mon或者admin节点

ceph auth get-key client.admin

创建 admin secret

CEPH_ADMIN_SECRET 替换为 client.admin 获取到的key

如果在测试 ceph rbd 方式已经添加 可以略过此步骤

export CEPH_ADMIN_SECRET='AQBBAnRbSiSOFxAAEZXNMzYV6hsceccYLhzdWw=='
kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \
--from-literal=key=$CEPH_ADMIN_SECRET \
--namespace=kube-system

查看 secret

kubectl get secret ceph-secret -n kube-system -o yaml

配置 StorageClass

cat >storageclass-cephfs.yaml<kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: dynamic-cephfs
provisioner: ceph.com/cephfs
parameters:
monitors: 11.11.11.111:6789,11.11.11.112:6789,11.11.11.113:6789
adminId: admin
adminSecretName: ceph-secret
adminSecretNamespace: "kube-system"
claimRoot: /volumes/kubernetes
EOF

创建

kubectl apply -f storageclass-cephfs.yaml

查看

kubectl get sc
测试使用

创建pvc测试

cat >cephfs-pvc-test.yaml<kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: cephfs-claim
spec:
accessModes:

  • ReadWriteOnce
    storageClassName: dynamic-cephfs
    resources:
    requests:
    storage: 2Gi
    EOF
    kubectl apply -f cephfs-pvc-test.yaml

查看

kubectl get pvc
kubectl get pv

创建 nginx pod 挂载测试

cat >nginx-pod.yaml<apiVersion: v1
kind: Pod
metadata:
name: nginx-pod1
labels:
name: nginx-pod1
spec:
containers:

  • name: nginx-pod1
    image: nginx:alpine
    ports:
    • name: web
      containerPort: 80
      volumeMounts:
    • name: cephfs
      mountPath: /usr/share/nginx/html
      volumes:
  • name: cephfs
    persistentVolumeClaim:
    claimName: cephfs-claim
    EOF
    kubectl apply -f nginx-pod.yaml

查看

kubectl get pods -o wide

修改文件内容

kubectl exec -ti nginx-pod1 -- /bin/sh -c 'echo Hello World from CephFS!!! > /usr/share/nginx/html/index.html'

访问测试

POD_ID=$(kubectl get pods -o wide | grep nginx-pod1 | awk '{print $(NF-1)}')
curl http://$POD_ID

清理

kubectl delete -f nginx-pod.yaml
kubectl delete -f cephfs-pvc-test.yaml

测试 集群 节点 存储 配置 方式 动态 命令 模式 支持 内容 内核 功能 官方 数据 文件 步骤 状态 成功 两个 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 如何搭建英国服务器 网络违法犯罪是我国网络安全 数据库技术是软件技术 英灵神殿为什么进不去好友服务器 网络安全类手抄报简单 服务器保留地址只能百分之5么 杨浦区媒体软件开发厂家报价 嘉兴软件开发自学步骤 智谷科技移动互联网 北京蜗牛好房互联网科技 中兴通讯服务器 泰兴购买网络技术厂家价格 为什么服务器搭建好了没有网 如何将软件所有数据库拷到硬盘 长沙学习软件开发需要多少钱 长宁区工商软件开发值得推荐 软件开发培训学校一对 小游戏租云服务器费用 有网络安全的图片 强类型 数据库 财经网站和经济研究数据库网站 银行软件开发是什么意思 杭州西奥服务器参数表 网络违法犯罪是我国网络安全 学习网络安全对数学的要求 redis是键值数据库吗 wpf调用数据库 程序员做服务器开发能做多少年 全国大学生网络安全攻防比赛 共享跑步机软件开发
0