Use OCCM and Cinder CSI in Kubernetes
Connect a Kubernetes cluster that runs on your instances to load balancers and volumes with the OpenStack cloud controller manager and Cinder CSI.
A Kubernetes cluster that runs on your instances can use the cloud's load balancers and volumes. Two upstream components do this: the OpenStack cloud controller manager (OCCM) creates a load balancer for each Service of type LoadBalancer, and the Cinder CSI driver creates volumes for persistent volume claims. Both read the same configuration file, cloud.conf, which the console generates for an application credential.
Before you begin
- Create a service account for the cluster, with the Owner or Contributor role, or a custom role with Manage access to compute, networking, storage, and load balancers in the project. See Service accounts and API tokens.
- Create an application credential for that service account with the Full access profile, and download
cloud-config-secret.yaml. See Create an application credential. - You need
kubectlaccess to the cluster and the openstack CLI. See Use the openstack CLI.
Use one service account credential per cluster. A personal credential stops working when its owner leaves your organization or loses their role in the project, and the cluster would then lose control of its load balancers and volumes. Creating load balancers needs the Keystone role load-balancer_member, which only the Full access profile includes.
Set the network for public load balancers
Find the external network that provides public addresses:
openstack network list --external -c ID -c NameIn cloud-config-secret.yaml, uncomment the floating-network-id line in the [LoadBalancer] section, and set it to the network's ID.
You can also set the network per Service with an annotation instead. See Expose a Service through a load balancer.
Install the components
Create the Secret kube-system/cloud-config that both components read:
kubectl apply -f cloud-config-secret.yamlInstall OCCM from the upstream manifests of cloud-provider-openstack, with a cluster name that's unique among the clusters in the project:
BASE=https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/release-1.31/manifests
kubectl apply -f $BASE/controller-manager/cloud-controller-manager-roles.yaml
kubectl apply -f $BASE/controller-manager/cloud-controller-manager-role-bindings.yaml
curl -fsSL $BASE/controller-manager/openstack-cloud-controller-manager-ds.yaml \
| sed 's/value: kubernetes$/value: <cluster-name>/' | kubectl apply -f -Replace <cluster-name> with your cluster's name.
In the same shell, so that BASE is still set, install Cinder CSI:
for f in cinder-csi-controllerplugin-rbac cinder-csi-controllerplugin \
cinder-csi-nodeplugin-rbac cinder-csi-nodeplugin csi-cinder-driver; do
kubectl apply -f $BASE/cinder-csi-plugin/$f.yaml
doneThe commands use the release-1.31 manifests of cloud-provider-openstack, the release that the console's guide was checked against.
The cluster name is part of the name of every load balancer that OCCM creates, so it must be unique among the clusters in the project.
Create volumes
Create a StorageClass for Cinder CSI, and request a volume with a persistent volume claim:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: cinder
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: cinder.csi.openstack.org
allowVolumeExpansion: true
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: cinder
resources:
requests:
storage: 1GiThe volumes appear in the project's Block Storage, and they're billed like volumes that you create in the console.
Expose a Service through a load balancer
apiVersion: v1
kind: Service
metadata:
name: web
annotations:
# Optional when floating-network-id is set in cloud.conf:
loadbalancer.openstack.org/floating-network-id: "<external-network-id>"
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 8080Replace <external-network-id> with the ID of the external network, or remove the annotation if you set floating-network-id in the Secret. OCCM creates a load balancer in the project, which appears in the console like any other load balancer.
Rotate the cluster's credential
After you rotate the credential, download the new cloud-config-secret.yaml, set floating-network-id in it again, and restart the components before the overlap window ends:
kubectl apply -f cloud-config-secret.yaml
kubectl -n kube-system rollout restart daemonset/openstack-cloud-controller-manager
kubectl -n kube-system rollout restart deployment/csi-cinder-controllerplugin daemonset/csi-cinder-nodepluginSee Rotate and revoke credentials.