Kubernetes Handbook
  • Kubernetes 中文指南/云原生应用架构实践手册
  • 前言
    • 序言
  • 云原生
    • 云原生(Cloud Native)的定义
    • 云原生的设计哲学
    • Play with Kubernetes
    • 快速部署一个云原生本地实验环境
    • 使用Rancher在阿里云上部署Kubenretes集群
    • Kubernetes与云原生应用概览
    • 云原生应用之路——从Kubernetes到Cloud Native
    • 云原生编程语言
      • 云原生编程语言Ballerina
      • 云原生编程语言Pulumi
    • 云原生的未来
  • 概念与原理
    • Kubernetes架构
      • 设计理念
      • Etcd解析
      • 开放接口
        • CRI - Container Runtime Interface(容器运行时接口)
        • CNI - Container Network Interface(容器网络接口)
        • CSI - Container Storage Interface(容器存储接口)
    • Kubernetes中的网络
      • Kubernetes中的网络解析——以flannel为例
      • Kubernetes中的网络解析——以calico为例
      • 具备API感知的网络和安全性管理开源软件Cilium
        • Cilium架构设计与概念解析
    • 资源对象与基本概念解析
    • Pod状态与生命周期管理
      • Pod概览
      • Pod解析
      • Init容器
      • Pause容器
      • Pod安全策略
      • Pod的生命周期
      • Pod Hook
      • Pod Preset
      • Pod中断与PDB(Pod中断预算)
    • 集群资源管理
      • Node
      • Namespace
      • Label
      • Annotation
      • Taint和Toleration(污点和容忍)
      • 垃圾收集
    • 控制器
      • Deployment
      • StatefulSet
      • DaemonSet
      • ReplicationController和ReplicaSet
      • Job
      • CronJob
      • Horizontal Pod Autoscaling
        • 自定义指标HPA
      • 准入控制器(Admission Controller)
    • 服务发现
      • Service
      • Ingress
        • Traefik Ingress Controller
    • 身份与权限控制
      • ServiceAccount
      • RBAC——基于角色的访问控制
      • NetworkPolicy
    • 存储
      • Secret
      • ConfigMap
        • ConfigMap的热更新
      • Volume
      • Persistent Volume(持久化卷)
      • Storage Class
      • 本地持久化存储
    • 集群扩展
      • 使用自定义资源扩展API
      • 使用CRD扩展Kubernetes API
      • Aggregated API Server
      • APIService
      • Service Catalog
    • 资源调度
      • QoS(服务质量等级)
  • 用户指南
    • 用户指南
    • 资源对象配置
      • 配置Pod的liveness和readiness探针
      • 配置Pod的Service Account
      • Secret配置
      • 管理namespace中的资源配额
    • 命令使用
      • Docker用户过渡到kubectl命令行指南
      • kubectl命令概览
      • kubectl命令技巧大全
      • 使用etcdctl访问kubernetes数据
    • 集群安全性管理
      • 管理集群中的TLS
      • kubelet的认证授权
      • TLS bootstrap
      • 创建用户认证授权的kubeconfig文件
      • IP伪装代理
      • 使用kubeconfig或token进行用户身份认证
      • Kubernetes中的用户与身份认证授权
      • Kubernetes集群安全性配置最佳实践
    • 访问Kubernetes集群
      • 访问集群
      • 使用kubeconfig文件配置跨集群认证
      • 通过端口转发访问集群中的应用程序
      • 使用service访问群集中的应用程序
      • 从外部访问Kubernetes中的Pod
      • Cabin - Kubernetes手机客户端
      • Kubernetic - Kubernetes桌面客户端
      • Kubernator - 更底层的Kubernetes UI
    • 在Kubernetes中开发部署应用
      • 适用于kubernetes的应用开发部署流程
      • 迁移传统应用到Kubernetes中——以Hadoop YARN为例
      • 使用StatefulSet部署用状态应用
  • 最佳实践
    • 最佳实践概览
    • 在CentOS上部署Kubernetes集群
      • 创建TLS证书和秘钥
      • 创建kubeconfig文件
      • 创建高可用etcd集群
      • 安装kubectl命令行工具
      • 部署master节点
      • 安装flannel网络插件
      • 部署node节点
      • 安装kubedns插件
      • 安装dashboard插件
      • 安装heapster插件
      • 安装EFK插件
    • 生产级的Kubernetes简化管理工具kubeadm
      • 使用kubeadm在Ubuntu Server 16.04上快速构建测试集群
    • 服务发现与负载均衡
      • 安装Traefik ingress
      • 分布式负载测试
      • 网络和集群性能测试
      • 边缘节点配置
      • 安装Nginx ingress
      • 安装配置DNS
        • 安装配置Kube-dns
        • 安装配置CoreDNS
    • 运维管理
      • Master节点高可用
      • 服务滚动升级
      • 应用日志收集
      • 配置最佳实践
      • 集群及应用监控
      • 数据持久化问题
      • 管理容器的计算资源
      • 集群联邦
    • 存储管理
      • GlusterFS
        • 使用GlusterFS做持久化存储
        • 使用Heketi作为Kubernetes的持久存储GlusterFS的external provisioner
        • 在OpenShift中使用GlusterFS做持久化存储
      • GlusterD-2.0
      • Ceph
        • 用Helm托管安装Ceph集群并提供后端存储
        • 使用Ceph做持久化存储
        • 使用rbd-provisioner提供rbd持久化存储
      • OpenEBS
        • 使用OpenEBS做持久化存储
      • Rook
      • NFS
        • 利用NFS动态提供Kubernetes后端存储卷
    • 集群与应用监控
      • Heapster
        • 使用Heapster获取集群和对象的metric数据
      • Prometheus
        • 使用Prometheus监控kubernetes集群
        • Prometheus查询语言PromQL使用说明
      • 使用Vistio监控Istio服务网格中的流量
    • 分布式跟踪
      • OpenTracing
    • 服务编排管理
      • 使用Helm管理Kubernetes应用
      • 构建私有Chart仓库
    • 持续集成与发布
      • 使用Jenkins进行持续集成与发布
      • 使用Drone进行持续集成与发布
    • 更新与升级
      • 手动升级Kubernetes集群
      • 升级dashboard
  • 领域应用
    • 领域应用概览
    • 微服务架构
      • 微服务中的服务发现
      • 使用Java构建微服务并发布到Kubernetes平台
        • Spring Boot快速开始指南
    • Service Mesh 服务网格
      • 企业级服务网格架构
        • Service Mesh基础
        • Service Mesh技术对比
        • 采纳和演进
        • 定制和集成
        • 总结
      • Istio
        • 安装并试用Istio service mesh
        • 配置请求的路由规则
        • 安装和拓展Istio service mesh
        • 集成虚拟机
        • Istio中sidecar的注入规范及示例
        • 如何参与Istio社区及注意事项
        • Istio教程
        • Istio免费学习资源汇总
        • 深入理解Istio Service Mesh中的Envoy Sidecar注入与流量劫持
        • 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由转发
      • Linkerd
        • Linkerd 使用指南
      • Conduit
        • Condiut概览
        • 安装Conduit
      • Envoy
        • Envoy的架构与基本术语
        • Envoy作为前端代理
        • Envoy mesh教程
      • SOFAMesh
        • SOFAMesh中的Dubbo on x-protocol
      • MOSN
        • 使用 MOSN 构建 SOFAMesh
    • 大数据
      • Spark standalone on Kubernetes
      • 运行支持Kubernetes原生调度的Spark程序
    • Serverless架构
      • 理解Serverless
      • FaaS-函数即服务
        • OpenFaaS快速入门指南
    • 边缘计算
    • 人工智能
  • 开发指南
    • 开发指南概览
    • SIG和工作组
    • 开发环境搭建
      • 本地分布式开发环境搭建(使用Vagrant和Virtualbox)
    • 单元测试和集成测试
    • client-go示例
    • Operator
      • operator-sdk
    • kubebuilder
    • 高级开发指南
    • 社区贡献
    • Minikube
  • CNCF(云原生计算基金会)
    • CNCF - 云原生计算基金会简介
    • CNCF章程
    • CNCF特别兴趣小组(SIG)说明
    • 开源项目加入CNCF Sandbox的要求
    • CNCF中的项目治理
    • CNCF Ambassador
  • 附录
    • 附录说明
    • Kubernetes中的应用故障排查
    • Kubernetes相关资讯和情报链接
    • Docker最佳实践
    • 使用技巧
    • 问题记录
    • Kubernetes版本更新日志
      • Kubernetes1.7更新日志
      • Kubernetes1.8更新日志
      • Kubernetes1.9更新日志
      • Kubernetes1.10更新日志
      • Kubernetes1.11更新日志
      • Kubernetes1.12更新日志
      • Kubernetes1.13更新日志
      • Kubernetes1.14更新日志
      • Kubernetes1.15更新日志
    • Kubernetes及云原生年度总结及展望
      • Kubernetes与云原生2017年年终总结及2018年展望
      • Kubernetes与云原生2018年年中总结及2019年展望
    • CNCF年度报告解读
      • CNCF 2018年年度报告解读
    • Kubernetes认证服务提供商(KCSP)说明
    • 认证Kubernetes管理员(CKA)说明
Powered by GitBook
On this page
  • 部署rbd-provisioner
  • 创建storageclass
  • 测试ceph rbd自动分配
  • 总结
  • 参考

Was this helpful?

  1. 最佳实践
  2. 存储管理
  3. Ceph

使用rbd-provisioner提供rbd持久化存储

Previous使用Ceph做持久化存储NextOpenEBS

Last updated 5 years ago

Was this helpful?

rbd-provisioner为kubernetes 1.5+版本提供了类似于kubernetes.io/rbd的ceph rbd持久化存储动态配置实现。

一些用户会使用kubeadm来部署集群,或者将kube-controller-manager以容器的方式运行。这种方式下,kubernetes在创建使用ceph rbd pv/pvc时没任何问题,但使用dynamic provisioning自动管理存储生命周期时会报错。提示"rbd: create volume failed, err: failed to create rbd image: executable file not found in $PATH:"。

问题来自gcr.io提供的kube-controller-manager容器镜像未打包ceph-common组件,缺少了rbd命令,因此无法通过rbd命令为pod创建rbd image,查了github的相关文章,目前kubernetes官方在kubernetes-incubator/external-storage项目通过External Provisioners的方式来解决此类问题。

本文主要针对该问题,通过rbd-provisioner的方式,解决ceph rbd的dynamic provisioning问题。

  • 参考链接

部署rbd-provisioner

首先得在kubernetes集群中安装rbd-provisioner,github仓库链接

[root@k8s01 ~]# git clone https://github.com/kubernetes-incubator/external-storage.git
[root@k8s01 ~]# cd external-storage/ceph/rbd/deploy
[root@k8s01 deploy]# NAMESPACE=kube-system
[root@k8s01 deploy]# sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./rbac/clusterrolebinding.yaml ./rbac/rolebinding.yaml
[root@k8s01 deploy]# kubectl -n $NAMESPACE apply -f ./rbac
  • 根据自己需要,修改rbd-provisioner的namespace;

部署完成后检查rbd-provisioner deployment,确保已经正常部署;

[root@k8s01 ~]# kubectl describe deployments.apps -n kube-system rbd-provisioner
Name:               rbd-provisioner
Namespace:          kube-system
CreationTimestamp:  Sat, 13 Oct 2018 20:08:45 +0800
Labels:             app=rbd-provisioner
Annotations:        deployment.kubernetes.io/revision: 1
                    kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{},"name":"rbd-provisioner","namespace":"kube-system"},"s...
Selector:           app=rbd-provisioner
Replicas:           1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:       Recreate
MinReadySeconds:    0
Pod Template:
  Labels:           app=rbd-provisioner
  Service Account:  rbd-provisioner
  Containers:
   rbd-provisioner:
    Image:      quay.io/external_storage/rbd-provisioner:latest
    Port:       <none>
    Host Port:  <none>
    Environment:
      PROVISIONER_NAME:  ceph.com/rbd
    Mounts:              <none>
  Volumes:               <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  <none>
NewReplicaSet:   rbd-provisioner-db574c5c (1/1 replicas created)
Events:          <none>

创建storageclass

部署完rbd-provisioner,还需要创建StorageClass。创建SC前,我们还需要创建相关用户的secret;

[root@k8s01 ~]# vi secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: ceph-admin-secret
  namespace: kube-system
type: "kubernetes.io/rbd"
data:
  # ceph auth get-key client.admin | base64
  key: QVFCdng4QmJKQkFsSFJBQWl1c1o0TGdOV250NlpKQ1BSMHFCa1E9PQ==
---
apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret
  namespace: kube-system
type: "kubernetes.io/rbd"
data:
  # ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=kube'
  # ceph auth get-key client.kube | base64
  key: QVFCTHdNRmJueFZ4TUJBQTZjd1MybEJ2Q0JUcmZhRk4yL2tJQVE9PQ==

[root@k8s01 ~]#  kubectl create -f secrets.yaml

[root@k8s01 ~]# vi secrets-default.yaml
apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret
type: "kubernetes.io/rbd"
data:
  # ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=kube'
  # ceph auth get-key client.kube | base64
  key: QVFCTHdNRmJueFZ4TUJBQTZjd1MybEJ2Q0JUcmZhRk4yL2tJQVE9PQ==

[root@k8s01 ~]#  kubectl create -f secrets-default.yaml -n default
  • 创建secret保存client.admin和client.kube用户的key,client.admin和client.kube用户的secret可以放在kube-system namespace,但如果其他namespace需要使用ceph rbd的dynamic provisioning功能的话,要在相应的namespace创建secret来保存client.kube用户key信息;

[root@k8s01 ~]# vi ceph-rbd-sc.yaml
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  name: ceph-rbd
  annotations:
     storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: ceph.com/rbd
parameters:
  monitors: 172.16.16.81,172.16.16.82,172.16.16.83
  adminId: admin
  adminSecretName: ceph-admin-secret
  adminSecretNamespace: kube-system
  pool: rbd
  userId: kube
  userSecretName: ceph-secret
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"

[root@k8s01 ~]#  kubectl create -f  ceph-rbd-sc.yaml
  • 其他设置和普通的ceph rbd StorageClass一致,但provisioner需要设置为ceph.com/rbd,不是默认的kubernetes.io/rbd,这样rbd的请求将由rbd-provisioner来处理;

  • 考虑到兼容性,建议尽量关闭rbd image feature,并且kubelet节点的ceph-common版本尽量和ceph服务器端保持一致,我的环境都使用的L版本;

测试ceph rbd自动分配

在kube-system和default namespace分别创建pod,通过启动一个busybox实例,将ceph rbd镜像挂载到/usr/share/busybox;

[root@k8s01 ~]# vi test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: ceph-pod1
spec:
  containers:
  - name: ceph-busybox
    image: busybox
    command: ["sleep", "60000"]
    volumeMounts:
    - name: ceph-vol1
      mountPath: /usr/share/busybox
      readOnly: false
  volumes:
  - name: ceph-vol1
    persistentVolumeClaim:
      claimName: ceph-claim
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: ceph-claim
spec:
  accessModes:  
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

[root@k8s01 ~]# kubectl create -f test-pod.yaml -n kube-system
pod/ceph-pod1 created
persistentvolumeclaim/ceph-claim created
[root@k8s01 ~]# kubectl create -f test-pod.yaml -n default
pod/ceph-pod1 created
persistentvolumeclaim/ceph-claim created

检查pv和pvc的创建状态,是否都已经创建;

[root@k8s01 ~]# kubectl get pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
ceph-claim   Bound    pvc-ee0f1c35-cef7-11e8-8484-005056a33f16   2Gi        RWO            ceph-rbd       25s
[root@k8s01 ~]# kubectl get pvc -n kube-system
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
ceph-claim   Bound    pvc-ea377cad-cef7-11e8-8484-005056a33f16   2Gi        RWO            ceph-rbd       36s
[root@k8s01 ~]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGE
pvc-ea377cad-cef7-11e8-8484-005056a33f16   2Gi        RWO            Delete           Bound    kube-system/ceph-claim   ceph-rbd                40s
pvc-ee0f1c35-cef7-11e8-8484-005056a33f16   2Gi        RWO            Delete           Bound    default/ceph-claim       ceph-rbd                32s

在ceph服务器上,检查rbd镜像创建情况和镜像的信息;

[root@k8s01 ~]# rbd ls --pool rbd
kubernetes-dynamic-pvc-ea390cbf-cef7-11e8-aa22-0a580af40202
kubernetes-dynamic-pvc-eef5814f-cef7-11e8-aa22-0a580af40202

[root@k8s01 ~]# rbd info rbd/kubernetes-dynamic-pvc-ea390cbf-cef7-11e8-aa22-0a580af40202
rbd image 'kubernetes-dynamic-pvc-ea390cbf-cef7-11e8-aa22-0a580af40202':
    size 2048 MB in 512 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.456876b8b4567
    format: 2
    features: layering
    flags:
    create_timestamp: Sat Oct 13 22:54:41 2018
[root@k8s01 ~]# rbd info rbd/kubernetes-dynamic-pvc-eef5814f-cef7-11e8-aa22-0a580af40202
rbd image 'kubernetes-dynamic-pvc-eef5814f-cef7-11e8-aa22-0a580af40202':
    size 2048 MB in 512 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.ad6c6b8b4567
    format: 2
    features: layering
    flags:
    create_timestamp: Sat Oct 13 22:54:49 2018

检查busybox内的文件系统挂载和使用情况,确认能正常工作;

[root@k8s01 ~]# kubectl exec -it ceph-pod1 mount |grep rbd
/dev/rbd0 on /usr/share/busybox type ext4 (rw,seclabel,relatime,stripe=1024,data=ordered)
[root@k8s01 ~]# kubectl exec -it -n kube-system ceph-pod1 mount |grep rbd
/dev/rbd0 on /usr/share/busybox type ext4 (rw,seclabel,relatime,stripe=1024,data=ordered)

[root@k8s01 ~]# kubectl exec -it -n kube-system ceph-pod1 df |grep rbd
/dev/rbd0              1998672      6144   1976144   0% /usr/share/busybox
[root@k8s01 ~]# kubectl exec -it ceph-pod1 df |grep rbd
/dev/rbd0              1998672      6144   1976144   0% /usr/share/busybox

测试删除pod能否自动删除pv和pvc,生产环境中谨慎,设置好回收策略;

[root@k8s01 ~]# kubectl delete -f test-pod.yaml
pod "ceph-pod1" deleted
persistentvolumeclaim "ceph-claim" deleted

[root@k8s01 ~]# kubectl delete -f test-pod.yaml -n kube-system
pod "ceph-pod1" deleted
persistentvolumeclaim "ceph-claim" deleted

[root@k8s01 ~]# kubectl get pv
No resources found.
[root@k8s01 ~]# kubectl get pvc
No resources found.
[root@k8s01 ~]# kubectl get pvc -n kube-system
No resources found.

ceph服务器上的rbd image也已清除,自动回收成功;

[root@k8s01 ~]# rbd ls --pool rbd
  • 确认之前创建的rbd images都已经删除;

总结

大部分情况下,我们无需使用rbd provisioner来提供ceph rbd的dynamic provisioning能力。经测试,在OpenShift、Rancher、SUSE CaaS以及本Handbook的二进制文件方式部署,在安装好ceph-common软件包的情况下,定义StorageClass时使用kubernetes.io/rbd即可正常使用ceph rbd provisioning功能。

参考

RBD Volume Provisioner for Kubernetes 1.5+
https://github.com/kubernetes-incubator/external-storage
RBD Volume Provisioner for Kubernetes 1.5+