0. 说明

要求Kubernetes的版本在1.11及以上,k8s集群必须允许特权Pod(privileged pods),即apiserver和kubelet需要设置--allow-privilegedtrue。节点的Docker daemon需要允许挂载共享卷。

涉及镜像

  • quay.io/k8scsi/csi-provisioner:v0.3.0
  • quay.io/k8scsi/csi-attacher:v0.3.0
  • quay.io/k8scsi/driver-registrar:v0.3.0
  • quay.io/cephcsi/cephfsplugin:v0.3.0

1. 部署RBAC

部署service accounts, cluster rolescluster role bindings,这些可供RBDCephFS CSI plugins共同使用,他们拥有相同的权限。

  1. $ kubectl create -f csi-attacher-rbac.yaml
  2. $ kubectl create -f csi-provisioner-rbac.yaml
  3. $ kubectl create -f csi-nodeplugin-rbac.yaml

1.1. csi-attacher-rbac.yaml

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: csi-attacher
  5. ---
  6. kind: ClusterRole
  7. apiVersion: rbac.authorization.k8s.io/v1
  8. metadata:
  9. name: external-attacher-runner
  10. rules:
  11. - apiGroups: [""]
  12. resources: ["events"]
  13. verbs: ["get", "list", "watch", "update"]
  14. - apiGroups: [""]
  15. resources: ["persistentvolumes"]
  16. verbs: ["get", "list", "watch", "update"]
  17. - apiGroups: [""]
  18. resources: ["nodes"]
  19. verbs: ["get", "list", "watch"]
  20. - apiGroups: ["storage.k8s.io"]
  21. resources: ["volumeattachments"]
  22. verbs: ["get", "list", "watch", "update"]
  23. ---
  24. kind: ClusterRoleBinding
  25. apiVersion: rbac.authorization.k8s.io/v1
  26. metadata:
  27. name: csi-attacher-role
  28. subjects:
  29. - kind: ServiceAccount
  30. name: csi-attacher
  31. namespace: default
  32. roleRef:
  33. kind: ClusterRole
  34. name: external-attacher-runner
  35. apiGroup: rbac.authorization.k8s.io

1.2. csi-provisioner-rbac.yaml

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: csi-provisioner
  5. ---
  6. kind: ClusterRole
  7. apiVersion: rbac.authorization.k8s.io/v1
  8. metadata:
  9. name: external-provisioner-runner
  10. rules:
  11. - apiGroups: [""]
  12. resources: ["secrets"]
  13. verbs: ["get", "list"]
  14. - apiGroups: [""]
  15. resources: ["persistentvolumes"]
  16. verbs: ["get", "list", "watch", "create", "delete"]
  17. - apiGroups: [""]
  18. resources: ["persistentvolumeclaims"]
  19. verbs: ["get", "list", "watch", "update"]
  20. - apiGroups: ["storage.k8s.io"]
  21. resources: ["storageclasses"]
  22. verbs: ["get", "list", "watch"]
  23. - apiGroups: [""]
  24. resources: ["events"]
  25. verbs: ["list", "watch", "create", "update", "patch"]
  26. ---
  27. kind: ClusterRoleBinding
  28. apiVersion: rbac.authorization.k8s.io/v1
  29. metadata:
  30. name: csi-provisioner-role
  31. subjects:
  32. - kind: ServiceAccount
  33. name: csi-provisioner
  34. namespace: default
  35. roleRef:
  36. kind: ClusterRole
  37. name: external-provisioner-runner
  38. apiGroup: rbac.authorization.k8s.io

1.3. csi-nodeplugin-rbac.yaml

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: csi-nodeplugin
  5. ---
  6. kind: ClusterRole
  7. apiVersion: rbac.authorization.k8s.io/v1
  8. metadata:
  9. name: csi-nodeplugin
  10. rules:
  11. - apiGroups: [""]
  12. resources: ["nodes"]
  13. verbs: ["get", "list", "update"]
  14. - apiGroups: [""]
  15. resources: ["namespaces"]
  16. verbs: ["get", "list"]
  17. - apiGroups: [""]
  18. resources: ["persistentvolumes"]
  19. verbs: ["get", "list", "watch", "update"]
  20. - apiGroups: ["storage.k8s.io"]
  21. resources: ["volumeattachments"]
  22. verbs: ["get", "list", "watch", "update"]
  23. ---
  24. kind: ClusterRoleBinding
  25. apiVersion: rbac.authorization.k8s.io/v1
  26. metadata:
  27. name: csi-nodeplugin
  28. subjects:
  29. - kind: ServiceAccount
  30. name: csi-nodeplugin
  31. namespace: default
  32. roleRef:
  33. kind: ClusterRole
  34. name: csi-nodeplugin
  35. apiGroup: rbac.authorization.k8s.io

2. 部署CSI sidecar containers

通过StatefulSet的方式部署external-attacherexternal-provisionerCSI CephFS使用。

  1. $ kubectl create -f csi-cephfsplugin-attacher.yaml
  2. $ kubectl create -f csi-cephfsplugin-provisioner.yaml

2.1. csi-cephfsplugin-provisioner.yaml

  1. kind: Service
  2. apiVersion: v1
  3. metadata:
  4. name: csi-cephfsplugin-provisioner
  5. labels:
  6. app: csi-cephfsplugin-provisioner
  7. spec:
  8. selector:
  9. app: csi-cephfsplugin-provisioner
  10. ports:
  11. - name: dummy
  12. port: 12345
  13. ---
  14. kind: StatefulSet
  15. apiVersion: apps/v1beta1
  16. metadata:
  17. name: csi-cephfsplugin-provisioner
  18. spec:
  19. serviceName: "csi-cephfsplugin-provisioner"
  20. replicas: 1
  21. template:
  22. metadata:
  23. labels:
  24. app: csi-cephfsplugin-provisioner
  25. spec:
  26. serviceAccount: csi-provisioner
  27. containers:
  28. - name: csi-provisioner
  29. image: quay.io/k8scsi/csi-provisioner:v0.3.0
  30. args:
  31. - "--provisioner=csi-cephfsplugin"
  32. - "--csi-address=$(ADDRESS)"
  33. - "--v=5"
  34. env:
  35. - name: ADDRESS
  36. value: /var/lib/kubelet/plugins/csi-cephfsplugin/csi.sock
  37. imagePullPolicy: "IfNotPresent"
  38. volumeMounts:
  39. - name: socket-dir
  40. mountPath: /var/lib/kubelet/plugins/csi-cephfsplugin
  41. volumes:
  42. - name: socket-dir
  43. hostPath:
  44. path: /var/lib/kubelet/plugins/csi-cephfsplugin
  45. type: DirectoryOrCreate

2.2. csi-cephfsplugin-attacher.yaml

  1. kind: Service
  2. apiVersion: v1
  3. metadata:
  4. name: csi-cephfsplugin-attacher
  5. labels:
  6. app: csi-cephfsplugin-attacher
  7. spec:
  8. selector:
  9. app: csi-cephfsplugin-attacher
  10. ports:
  11. - name: dummy
  12. port: 12345
  13. ---
  14. kind: StatefulSet
  15. apiVersion: apps/v1beta1
  16. metadata:
  17. name: csi-cephfsplugin-attacher
  18. spec:
  19. serviceName: "csi-cephfsplugin-attacher"
  20. replicas: 1
  21. template:
  22. metadata:
  23. labels:
  24. app: csi-cephfsplugin-attacher
  25. spec:
  26. serviceAccount: csi-attacher
  27. containers:
  28. - name: csi-cephfsplugin-attacher
  29. image: quay.io/k8scsi/csi-attacher:v0.3.0
  30. args:
  31. - "--v=5"
  32. - "--csi-address=$(ADDRESS)"
  33. env:
  34. - name: ADDRESS
  35. value: /var/lib/kubelet/plugins/csi-cephfsplugin/csi.sock
  36. imagePullPolicy: "IfNotPresent"
  37. volumeMounts:
  38. - name: socket-dir
  39. mountPath: /var/lib/kubelet/plugins/csi-cephfsplugin
  40. volumes:
  41. - name: socket-dir
  42. hostPath:
  43. path: /var/lib/kubelet/plugins/csi-cephfsplugin
  44. type: DirectoryOrCreate

3. 部署CSI-CephFS-driver(plugin)

csi-cephfs-plugin 的作用类似nfs-client,部署在所有node节点上,执行ceph的挂载等相关任务。

通过DaemonSet的方式部署,其中包括两个容器:CSI driver-registrarCSI CephFS driver

  1. $ kubectl create -f csi-cephfsplugin.yaml

3.1. csi-cephfsplugin.yaml

  1. kind: DaemonSet
  2. apiVersion: apps/v1beta2
  3. metadata:
  4. name: csi-cephfsplugin
  5. spec:
  6. selector:
  7. matchLabels:
  8. app: csi-cephfsplugin
  9. template:
  10. metadata:
  11. labels:
  12. app: csi-cephfsplugin
  13. spec:
  14. serviceAccount: csi-nodeplugin
  15. hostNetwork: true
  16. # to use e.g. Rook orchestrated cluster, and mons' FQDN is
  17. # resolved through k8s service, set dns policy to cluster first
  18. dnsPolicy: ClusterFirstWithHostNet
  19. containers:
  20. - name: driver-registrar
  21. image: quay.io/k8scsi/driver-registrar:v0.3.0
  22. args:
  23. - "--v=5"
  24. - "--csi-address=$(ADDRESS)"
  25. - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)"
  26. env:
  27. - name: ADDRESS
  28. value: /var/lib/kubelet/plugins/csi-cephfsplugin/csi.sock
  29. - name: DRIVER_REG_SOCK_PATH
  30. value: /var/lib/kubelet/plugins/csi-cephfsplugin/csi.sock
  31. - name: KUBE_NODE_NAME
  32. valueFrom:
  33. fieldRef:
  34. fieldPath: spec.nodeName
  35. volumeMounts:
  36. - name: socket-dir
  37. mountPath: /var/lib/kubelet/plugins/csi-cephfsplugin
  38. - name: registration-dir
  39. mountPath: /registration
  40. - name: csi-cephfsplugin
  41. securityContext:
  42. privileged: true
  43. capabilities:
  44. add: ["SYS_ADMIN"]
  45. allowPrivilegeEscalation: true
  46. image: quay.io/cephcsi/cephfsplugin:v0.3.0
  47. args :
  48. - "--nodeid=$(NODE_ID)"
  49. - "--endpoint=$(CSI_ENDPOINT)"
  50. - "--v=5"
  51. - "--drivername=csi-cephfsplugin"
  52. env:
  53. - name: NODE_ID
  54. valueFrom:
  55. fieldRef:
  56. fieldPath: spec.nodeName
  57. - name: CSI_ENDPOINT
  58. value: unix://var/lib/kubelet/plugins/csi-cephfsplugin/csi.sock
  59. imagePullPolicy: "IfNotPresent"
  60. volumeMounts:
  61. - name: plugin-dir
  62. mountPath: /var/lib/kubelet/plugins/csi-cephfsplugin
  63. - name: pods-mount-dir
  64. mountPath: /var/lib/kubelet/pods
  65. mountPropagation: "Bidirectional"
  66. - mountPath: /sys
  67. name: host-sys
  68. - name: lib-modules
  69. mountPath: /lib/modules
  70. readOnly: true
  71. - name: host-dev
  72. mountPath: /dev
  73. volumes:
  74. - name: plugin-dir
  75. hostPath:
  76. path: /var/lib/kubelet/plugins/csi-cephfsplugin
  77. type: DirectoryOrCreate
  78. - name: registration-dir
  79. hostPath:
  80. path: /var/lib/kubelet/plugins/
  81. type: Directory
  82. - name: pods-mount-dir
  83. hostPath:
  84. path: /var/lib/kubelet/pods
  85. type: Directory
  86. - name: socket-dir
  87. hostPath:
  88. path: /var/lib/kubelet/plugins/csi-cephfsplugin
  89. type: DirectoryOrCreate
  90. - name: host-sys
  91. hostPath:
  92. path: /sys
  93. - name: lib-modules
  94. hostPath:
  95. path: /lib/modules
  96. - name: host-dev
  97. hostPath:
  98. path: /dev

4. 确认部署结果

  1. $ kubectl get all
  2. NAME READY STATUS RESTARTS AGE
  3. pod/csi-cephfsplugin-attacher-0 1/1 Running 0 26s
  4. pod/csi-cephfsplugin-provisioner-0 1/1 Running 0 25s
  5. pod/csi-cephfsplugin-rljcv 2/2 Running 0 24s
  6. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  7. service/csi-cephfsplugin-attacher ClusterIP 10.104.116.218 <none> 12345/TCP 27s
  8. service/csi-cephfsplugin-provisioner ClusterIP 10.101.78.75 <none> 12345/TCP 26s
  9. ...

参考文档: