本文发布已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已失效。
使用 Kubeadm 部署外部 OpenStack Cloud Provider
本文介绍如何使用 kubeadm 在 CentOS 上安装一个单控制平面 Kubernetes v1.15 集群,然后部署一个外部 OpenStack 云提供商和 Cinder CSI 插件,以便在 Kubernetes 中使用 Cinder 卷作为持久卷。
在 OpenStack 中准备
此集群运行在 OpenStack 虚拟机上,所以我们首先在 OpenStack 中创建一些东西。
- 为此 Kubernetes 集群创建一个项目/租户
- 在此项目中为 Kubernetes 创建一个用户,用于查询节点信息和挂载卷等
- 一个私有网络和子网
- 为此私有网络创建一个路由器,并将其连接到公共网络以获取浮动 IP
- 为所有 Kubernetes 虚拟机创建一个安全组
- 一个虚拟机作为控制平面节点,以及几个虚拟机作为工作节点
安全组将包含以下规则,用于为 Kubernetes 开放端口。
控制平面节点
协议 | 端口号 | 描述 |
---|---|---|
TCP | 6443 | Kubernetes API 服务器 |
TCP | 2379-2380 | etcd 服务器客户端 API |
TCP | 10250 | Kubelet API |
TCP | 10251 | kube-scheduler |
TCP | 10252 | kube-controller-manager |
TCP | 10255 | 只读 Kubelet API |
工作节点
协议 | 端口号 | 描述 |
---|---|---|
TCP | 10250 | Kubelet API |
TCP | 10255 | 只读 Kubelet API |
TCP | 30000-32767 | NodePort 服务 |
控制平面节点和工作节点上的 CNI 端口
协议 | 端口号 | 描述 |
---|---|---|
TCP | 179 | Calico BGP 网络 |
TCP | 9099 | Calico felix (健康检查) |
UDP | 8285 | Flannel |
UDP | 8472 | Flannel |
TCP | 6781-6784 | Weave Net |
UDP | 6783-6784 | Weave Net |
只有使用特定的 CNI 插件时,才需要开放相应的 CNI 端口。在本指南中,我们将使用 Weave Net。因此,只需要在安全组中开放 Weave Net 端口(TCP 6781-6784 和 UDP 6783-6784)。
控制平面节点至少需要 2 个核心和 4GB 内存。虚拟机启动后,请验证其主机名,并确保它与 Nova 中的节点名称相同。如果主机名无法解析,请将其添加到 /etc/hosts
中。
例如,如果虚拟机名为 master1,且其内部 IP 为 192.168.1.4。将其添加到 /etc/hosts
中,并将主机名设置为 master1。
echo "192.168.1.4 master1" >> /etc/hosts
hostnamectl set-hostname master1
安装 Docker 和 Kubernetes
接下来,我们将按照官方文档使用 kubeadm 安装 docker 和 Kubernetes。
按照容器运行时文档中的步骤安装 Docker。
请注意,使用 systemd 作为 Kubernetes 的 cgroup 驱动程序是最佳实践。如果使用内部容器镜像仓库,请将其添加到 docker 配置中。
# Install Docker CE
## Set up the repository
### Install required packages.
yum install yum-utils device-mapper-persistent-data lvm2
### Add Docker repository.
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
## Install Docker CE.
yum update && yum install docker-ce-18.06.2.ce
## Create /etc/docker directory.
mkdir /etc/docker
# Configure the Docker daemon
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# Restart Docker
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
按照安装 Kubeadm 文档中的步骤安装 kubeadm。
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
# Set SELinux in permissive mode (effectively disabling it)
# Caveat: In a production environment you may not want to disable SELinux, please refer to Kubernetes documents about SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
# check if br_netfilter module is loaded
lsmod | grep br_netfilter
# if not, load it explicitly with
modprobe br_netfilter
关于如何使用 kubeadm 创建单控制平面集群的官方文档可参阅使用 kubeadm 创建单控制平面集群文档。
我们将主要遵循该文档,但也会为云提供商添加额外内容。为了更清楚,我们将为控制平面节点使用一个 kubeadm-config.yml
文件。在此配置中,我们指定使用外部 OpenStack 云提供商,以及查找其配置的位置。我们还启用 API 服务器的运行时配置中的 storage API,这样我们就可以在 Kubernetes 中使用 OpenStack 卷作为持久卷。
apiVersion: kubeadm.k8s.io/v1beta1
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
cloud-provider: "external"
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: "v1.15.1"
apiServer:
extraArgs:
enable-admission-plugins: NodeRestriction
runtime-config: "storage.k8s.io/v1=true"
controllerManager:
extraArgs:
external-cloud-volume-plugin: openstack
extraVolumes:
- name: "cloud-config"
hostPath: "/etc/kubernetes/cloud-config"
mountPath: "/etc/kubernetes/cloud-config"
readOnly: true
pathType: File
networking:
serviceSubnet: "10.96.0.0/12"
podSubnet: "10.224.0.0/16"
dnsDomain: "cluster.local"
现在我们将创建 OpenStack 的云配置 /etc/kubernetes/cloud-config
。请注意,这里的租户是我们一开始为所有 Kubernetes 虚拟机创建的那个。所有虚拟机都应该在此项目/租户中启动。此外,您需要在该租户中为 Kubernetes 创建一个用户以执行查询。ca-file 是 OpenStack API 端点的 CA 根证书,例如 https://openstack.cloud:5000/v3
在撰写本文时,云提供商不允许不安全的连接(跳过 CA 检查)。
[Global]
region=RegionOne
username=username
password=password
auth-url=https://openstack.cloud:5000/v3
tenant-id=14ba698c0aec4fd6b7dc8c310f664009
domain-id=default
ca-file=/etc/kubernetes/ca.pem
[LoadBalancer]
subnet-id=b4a9a292-ea48-4125-9fb2-8be2628cb7a1
floating-network-id=bc8a590a-5d65-4525-98f3-f7ef29c727d5
[BlockStorage]
bs-version=v2
[Networking]
public-network-name=public
ipv6-support-disabled=false
接下来运行 kubeadm 初始化控制平面节点
kubeadm init --config=kubeadm-config.yml
初始化完成后,将 admin config 复制到 .kube
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
在此阶段,控制平面节点已创建但尚未就绪。所有节点都有污点 node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule
,并等待由 cloud-controller-manager 初始化。
# kubectl describe no master1
Name: master1
Roles: master
......
Taints: node-role.kubernetes.io/master:NoSchedule
node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule
node.kubernetes.io/not-ready:NoSchedule
......
现在将 OpenStack 云控制器管理器部署到集群中,请遵循使用 kubeadm 部署控制器管理器。
为 OpenStack 云提供商创建一个包含云配置的 Secret。
kubectl create secret -n kube-system generic cloud-config --from-literal=cloud.conf="$(cat /etc/kubernetes/cloud-config)" --dry-run -o yaml > cloud-config-secret.yaml
kubectl apply -f cloud-config-secret.yaml
获取 OpenStack API 端点的 CA 证书,并将其放入 /etc/kubernetes/ca.pem
。
创建 RBAC 资源。
kubectl apply -f https://github.com/kubernetes/cloud-provider-openstack/raw/release-1.15/cluster/addons/rbac/cloud-controller-manager-roles.yaml
kubectl apply -f https://github.com/kubernetes/cloud-provider-openstack/raw/release-1.15/cluster/addons/rbac/cloud-controller-manager-role-bindings.yaml
我们将以 DaemonSet 而非 Pod 的形式运行 OpenStack 云控制器管理器。该管理器将仅在控制平面节点上运行,因此如果存在多个控制平面节点,将运行多个 Pod 以实现高可用性。创建包含以下 manifests 的 openstack-cloud-controller-manager-ds.yaml
文件,然后应用它。
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cloud-controller-manager
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: openstack-cloud-controller-manager
namespace: kube-system
labels:
k8s-app: openstack-cloud-controller-manager
spec:
selector:
matchLabels:
k8s-app: openstack-cloud-controller-manager
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
k8s-app: openstack-cloud-controller-manager
spec:
nodeSelector:
node-role.kubernetes.io/master: ""
securityContext:
runAsUser: 1001
tolerations:
- key: node.cloudprovider.kubernetes.io/uninitialized
value: "true"
effect: NoSchedule
- key: node-role.kubernetes.io/master
effect: NoSchedule
- effect: NoSchedule
key: node.kubernetes.io/not-ready
serviceAccountName: cloud-controller-manager
containers:
- name: openstack-cloud-controller-manager
image: docker.io/k8scloudprovider/openstack-cloud-controller-manager:v1.15.0
args:
- /bin/openstack-cloud-controller-manager
- --v=1
- --cloud-config=$(CLOUD_CONFIG)
- --cloud-provider=openstack
- --use-service-account-credentials=true
- --address=127.0.0.1
volumeMounts:
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/config
name: cloud-config-volume
readOnly: true
- mountPath: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
name: flexvolume-dir
- mountPath: /etc/kubernetes
name: ca-cert
readOnly: true
resources:
requests:
cpu: 200m
env:
- name: CLOUD_CONFIG
value: /etc/config/cloud.conf
hostNetwork: true
volumes:
- hostPath:
path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
type: DirectoryOrCreate
name: flexvolume-dir
- hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
name: k8s-certs
- hostPath:
path: /etc/ssl/certs
type: DirectoryOrCreate
name: ca-certs
- name: cloud-config-volume
secret:
secretName: cloud-config
- name: ca-cert
secret:
secretName: openstack-ca-cert
当控制器管理器运行时,它将查询 OpenStack 以获取节点信息并移除污点。在节点信息中,您将看到虚拟机在 OpenStack 中的 UUID。
# kubectl describe no master1
Name: master1
Roles: master
......
Taints: node-role.kubernetes.io/master:NoSchedule
node.kubernetes.io/not-ready:NoSchedule
......
sage:docker: network plugin is not ready: cni config uninitialized
......
PodCIDR: 10.224.0.0/24
ProviderID: openstack:///548e3c46-2477-4ce2-968b-3de1314560a5
现在安装您喜欢的 CNI,控制平面节点将变为就绪状态。
例如,要安装 Weave Net,运行此命令
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
接下来我们将设置工作节点。
首先,以与在控制平面节点上安装 docker 和 kubeadm 相同的方式安装它们。要将它们加入集群,我们需要控制平面节点安装输出中的 token 和 ca cert hash。如果 token 或 hash 已过期或丢失,我们可以使用这些命令重新创建它们。
# check if token is expired
kubeadm token list
# re-create token and show join command
kubeadm token create --print-join-command
为工作节点创建包含上述 token 和 ca cert hash 的 kubeadm-config.yml
。
apiVersion: kubeadm.k8s.io/v1beta2
discovery:
bootstrapToken:
apiServerEndpoint: 192.168.1.7:6443
token: 0c0z4p.dnafh6vnmouus569
caCertHashes: ["sha256:fcb3e956a6880c05fc9d09714424b827f57a6fdc8afc44497180905946527adf"]
kind: JoinConfiguration
nodeRegistration:
kubeletExtraArgs:
cloud-provider: "external"
apiServerEndpoint 是控制平面节点,token 和 caCertHashes 可以从 'kubeadm token create' 命令输出中打印的 join 命令中获取。
运行 kubeadm,工作节点将加入集群。
kubeadm join --config kubeadm-config.yml
在此阶段,我们将拥有一个运行正常的 Kubernetes 集群,并带有外部 OpenStack 云提供商。该提供商将 Kubernetes 节点与 OpenStack 虚拟机之间的映射关系告知 Kubernetes。如果 Kubernetes 想要将持久卷挂载到 Pod,它可以从映射中找到 Pod 运行在哪个 OpenStack 虚拟机上,并相应地将底层 OpenStack 卷挂载到该虚拟机。
部署 Cinder CSI
Cinder 集成由一个外部的 Cinder CSI 插件提供,如Cinder CSI 文档所述。
我们将执行以下步骤来安装 Cinder CSI 插件。首先,为 OpenStack API 端点创建一个包含 CA 证书的 Secret。该证书文件与我们在上面云提供商配置中使用的文件相同。
kubectl create secret -n kube-system generic openstack-ca-cert --from-literal=ca.pem="$(cat /etc/kubernetes/ca.pem)" --dry-run -o yaml > openstack-ca-cert.yaml
kubectl apply -f openstack-ca-cert.yaml
然后创建 RBAC 资源。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/release-1.15/manifests/cinder-csi-plugin/cinder-csi-controllerplugin-rbac.yaml
kubectl apply -f https://github.com/kubernetes/cloud-provider-openstack/raw/release-1.15/manifests/cinder-csi-plugin/cinder-csi-nodeplugin-rbac.yaml
Cinder CSI 插件包含一个控制器插件和一个节点插件。控制器与 Kubernetes API 和 Cinder API 通信,用于创建/挂载/卸载/删除 Cinder 卷。节点插件则运行在每个工作节点上,将存储设备(已挂载的卷)绑定到 Pod,并在删除时解绑。创建包含以下 manifests 的 cinder-csi-controllerplugin.yaml
文件,并应用它来创建 csi controller。
kind: Service
apiVersion: v1
metadata:
name: csi-cinder-controller-service
namespace: kube-system
labels:
app: csi-cinder-controllerplugin
spec:
selector:
app: csi-cinder-controllerplugin
ports:
- name: dummy
port: 12345
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: csi-cinder-controllerplugin
namespace: kube-system
spec:
serviceName: "csi-cinder-controller-service"
replicas: 1
selector:
matchLabels:
app: csi-cinder-controllerplugin
template:
metadata:
labels:
app: csi-cinder-controllerplugin
spec:
serviceAccount: csi-cinder-controller-sa
containers:
- name: csi-attacher
image: quay.io/k8scsi/csi-attacher:v1.0.1
args:
- "--v=5"
- "--csi-address=$(ADDRESS)"
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
- name: csi-provisioner
image: quay.io/k8scsi/csi-provisioner:v1.0.1
args:
- "--provisioner=csi-cinderplugin"
- "--csi-address=$(ADDRESS)"
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
- name: csi-snapshotter
image: quay.io/k8scsi/csi-snapshotter:v1.0.1
args:
- "--connection-timeout=15s"
- "--csi-address=$(ADDRESS)"
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
imagePullPolicy: Always
volumeMounts:
- mountPath: /var/lib/csi/sockets/pluginproxy/
name: socket-dir
- name: cinder-csi-plugin
image: docker.io/k8scloudprovider/cinder-csi-plugin:v1.15.0
args :
- /bin/cinder-csi-plugin
- "--v=5"
- "--nodeid=$(NODE_ID)"
- "--endpoint=$(CSI_ENDPOINT)"
- "--cloud-config=$(CLOUD_CONFIG)"
- "--cluster=$(CLUSTER_NAME)"
env:
- name: NODE_ID
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: CSI_ENDPOINT
value: unix://csi/csi.sock
- name: CLOUD_CONFIG
value: /etc/config/cloud.conf
- name: CLUSTER_NAME
value: kubernetes
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /csi
- name: secret-cinderplugin
mountPath: /etc/config
readOnly: true
- mountPath: /etc/kubernetes
name: ca-cert
readOnly: true
volumes:
- name: socket-dir
hostPath:
path: /var/lib/csi/sockets/pluginproxy/
type: DirectoryOrCreate
- name: secret-cinderplugin
secret:
secretName: cloud-config
- name: ca-cert
secret:
secretName: openstack-ca-cert
创建包含以下 manifests 的 cinder-csi-nodeplugin.yaml
文件,并应用它来创建 csi node。
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: csi-cinder-nodeplugin
namespace: kube-system
spec:
selector:
matchLabels:
app: csi-cinder-nodeplugin
template:
metadata:
labels:
app: csi-cinder-nodeplugin
spec:
serviceAccount: csi-cinder-node-sa
hostNetwork: true
containers:
- name: node-driver-registrar
image: quay.io/k8scsi/csi-node-driver-registrar:v1.1.0
args:
- "--v=5"
- "--csi-address=$(ADDRESS)"
- "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)"
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "rm -rf /registration/cinder.csi.openstack.org /registration/cinder.csi.openstack.org-reg.sock"]
env:
- name: ADDRESS
value: /csi/csi.sock
- name: DRIVER_REG_SOCK_PATH
value: /var/lib/kubelet/plugins/cinder.csi.openstack.org/csi.sock
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /csi
- name: registration-dir
mountPath: /registration
- name: cinder-csi-plugin
securityContext:
privileged: true
capabilities:
add: ["SYS_ADMIN"]
allowPrivilegeEscalation: true
image: docker.io/k8scloudprovider/cinder-csi-plugin:v1.15.0
args :
- /bin/cinder-csi-plugin
- "--nodeid=$(NODE_ID)"
- "--endpoint=$(CSI_ENDPOINT)"
- "--cloud-config=$(CLOUD_CONFIG)"
env:
- name: NODE_ID
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: CSI_ENDPOINT
value: unix://csi/csi.sock
- name: CLOUD_CONFIG
value: /etc/config/cloud.conf
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /csi
- name: pods-mount-dir
mountPath: /var/lib/kubelet/pods
mountPropagation: "Bidirectional"
- name: kubelet-dir
mountPath: /var/lib/kubelet
mountPropagation: "Bidirectional"
- name: pods-cloud-data
mountPath: /var/lib/cloud/data
readOnly: true
- name: pods-probe-dir
mountPath: /dev
mountPropagation: "HostToContainer"
- name: secret-cinderplugin
mountPath: /etc/config
readOnly: true
- mountPath: /etc/kubernetes
name: ca-cert
readOnly: true
volumes:
- name: socket-dir
hostPath:
path: /var/lib/kubelet/plugins/cinder.csi.openstack.org
type: DirectoryOrCreate
- name: registration-dir
hostPath:
path: /var/lib/kubelet/plugins_registry/
type: Directory
- name: kubelet-dir
hostPath:
path: /var/lib/kubelet
type: Directory
- name: pods-mount-dir
hostPath:
path: /var/lib/kubelet/pods
type: Directory
- name: pods-cloud-data
hostPath:
path: /var/lib/cloud/data
type: Directory
- name: pods-probe-dir
hostPath:
path: /dev
type: Directory
- name: secret-cinderplugin
secret:
secretName: cloud-config
- name: ca-cert
secret:
secretName: openstack-ca-cert
当它们都运行后,为 Cinder 创建一个 StorageClass。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-sc-cinderplugin
provisioner: csi-cinderplugin
然后我们可以使用此类创建一个 PVC。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myvol
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-sc-cinderplugin
当 PVC 创建后,将相应地创建一个 Cinder 卷。
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myvol Bound pvc-14b8bc68-6c4c-4dc6-ad79-4cb29a81faad 1Gi RWO csi-sc-cinderplugin 3s
在 OpenStack 中,卷名称将匹配 Kubernetes 生成的持久卷名称。在此示例中为:pvc-14b8bc68-6c4c-4dc6-ad79-4cb29a81faad
现在我们可以使用此 PVC 创建一个 Pod。
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
hostPort: 8081
protocol: TCP
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myvol
当 Pod 运行时,该卷将挂载到 Pod。如果回到 OpenStack,我们可以看到 Cinder 卷已挂载到 Pod 运行的工作节点上。
# openstack volume show 6b5f3296-b0eb-40cd-bd4f-2067a0d6287f
+--------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+--------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| attachments | [{u'server_id': u'1c5e1439-edfa-40ed-91fe-2a0e12bc7eb4', u'attachment_id': u'11a15b30-5c24-41d4-86d9-d92823983a32', u'attached_at': u'2019-07-24T05:02:34.000000', u'host_name': u'compute-6', u'volume_id': u'6b5f3296-b0eb-40cd-bd4f-2067a0d6287f', u'device': u'/dev/vdb', u'id': u'6b5f3296-b0eb-40cd-bd4f-2067a0d6287f'}] |
| availability_zone | nova |
| bootable | false |
| consistencygroup_id | None |
| created_at | 2019-07-24T05:02:18.000000 |
| description | Created by OpenStack Cinder CSI driver |
| encrypted | False |
| id | 6b5f3296-b0eb-40cd-bd4f-2067a0d6287f |
| migration_status | None |
| multiattach | False |
| name | pvc-14b8bc68-6c4c-4dc6-ad79-4cb29a81faad |
| os-vol-host-attr:host | rbd:volumes@rbd#rbd |
| os-vol-mig-status-attr:migstat | None |
| os-vol-mig-status-attr:name_id | None |
| os-vol-tenant-attr:tenant_id | 14ba698c0aec4fd6b7dc8c310f664009 |
| properties | attached_mode='rw', cinder.csi.openstack.org/cluster='kubernetes' |
| replication_status | None |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | in-use |
| type | rbd |
| updated_at | 2019-07-24T05:02:35.000000 |
| user_id | 5f6a7a06f4e3456c890130d56babf591 |
+--------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
总结
在本教程中,我们在 OpenStack 虚拟机上部署了一个 Kubernetes 集群,并使用外部 OpenStack 云提供商将其与 OpenStack 集成。然后在此 Kubernetes 集群上,我们部署了 Cinder CSI 插件,该插件可以在 Kubernetes 中创建 Cinder 卷并将其公开为持久卷。