7 minute read
Using the OpenStack provider extension with Gardener as end-user
core.gardener.cloud/v1beta1.Shoot resource declares a few fields that are meant to contain provider-specific configuration.
In this document we are describing how this configuration looks like for OpenStack and provide an example
Shoot manifest with minimal configuration that you can use to create an OpenStack cluster (modulo the landscape-specific information like cloud profile names, secret binding names, etc.).
Provider Secret Data
Every shoot cluster references a
SecretBinding which itself references a
Secret, and this
Secret contains the provider credentials of your OpenStack tenant.
Secret must look as follows:
apiVersion: v1 kind: Secret metadata: name: core-openstack namespace: garden-dev type: Opaque data: domainName: base64(domain-name) tenantName: base64(tenant-name) # either use username/password username: base64(user-name) password: base64(password) # or application credentials #applicationCredentialID: base64(app-credential-id) #applicationCredentialName: base64(app-credential-name) # optional #applicationCredentialSecret: base64(app-credential-secret)
Please look up https://docs.openstack.org/keystone/pike/admin/identity-concepts.html as well.
For authentication with username/password see Keystone username/password
Alternatively, for authentication with application credentials see Keystone Application Credentials. Application Credentials are not supported for shoots with kubernetes versions less than v1.19.
⚠️ Depending on your API usage it can be problematic to reuse the same provider credentials for different Shoot clusters due to rate limits. Please consider spreading your Shoots over multiple credentials from different tenants if you are hitting those limits.
The infrastructure configuration mainly describes how the network layout looks like in order to create the shoot worker nodes in a later step, thus, prepares everything relevant to create VMs, load balancers, volumes, etc.
InfrastructureConfig for the OpenStack extension looks as follows:
apiVersion: openstack.provider.extensions.gardener.cloud/v1alpha1 kind: InfrastructureConfig floatingPoolName: MY-FLOATING-POOL # floatingPoolSubnetName: my-floating-pool-subnet-name networks: # id: 12345678-abcd-efef-08af-0123456789ab # router: # id: 1234 workers: 10.250.0.0/19
floatingPoolName is the name of the floating pool you want to use for your shoot.
If you don’t know which floating pools are available look it up in the respective
floatingPoolSubnetName you can explicitly define to which subnet in the floating pool network (defined via
floatingPoolName) the router should be attached to.
networks.id is an optional field. If it is given, you can specify the uuid of an existing private Neutron network (created manually, by other tooling, …) that should be reused. A new subnet for the Shoot will be created in it.
networks.router section describes whether you want to create the shoot cluster in an already existing router or whether to create a new one:
networks.router.idis given then you have to specify the router id of the existing router that was created by other means (manually, other tooling, …). If you want to get a fresh router for the shoot then just omit the
In any case, the shoot cluster will be created in a new subnet.
networks.workers section describes the CIDR for a subnet that is used for all shoot worker nodes, i.e., VMs which later run your applications.
You can freely choose these CIDRs and it is your responsibility to properly design the network layout to suit your needs.
Apart from the router and the worker subnet the OpenStack extension will also create a network, router interfaces, security groups, and a key pair.
The control plane configuration mainly contains values for the OpenStack-specific control plane components.
Today, the only component deployed by the OpenStack extension is the
ControlPlaneConfig for the OpenStack extension looks as follows:
apiVersion: openstack.provider.extensions.gardener.cloud/v1alpha1 kind: ControlPlaneConfig loadBalancerProvider: haproxy loadBalancerClasses: - name: lbclass-1 purpose: default floatingNetworkID: fips-1-id floatingSubnetName: internet-* - name: lbclass-2 floatingNetworkID: fips-1-id floatingSubnetTags: internal,private - name: lbclass-3 purpose: private subnetID: internal-id cloudControllerManager: featureGates: CustomResourceValidation: true
loadBalancerProvider is the provider name you want to use for load balancers in your shoot.
If you don’t know which types are available look it up in the respective
loadBalancerClasses field contains an optional list of load balancer classes which will be available in the cluster. Each entry can have the following fields:
nameto select the load balancer class via the kubernetes service annotations
- The configuration of the
defaultload balancer class will be used as default for all other kubernetes loadbalancer services without a class annotation
- The configuration of the
privateload balancer class will be also set to the global loadbalancer configuration of the cluster, but will be overridden by the
- The configuration of the
floatingNetworkIDcan be specified to receive an ip from an floating/external network, additionally the subnet in this network can be selected via
floatingSubnetNamecan be either a full subnet name or a regex/glob to match subnet name
floatingSubnetTagsa comma seperated list of subnet tags
floatingSubnetIDthe id of a specific subnet
subnetIDcan be specified by to receive an ip from an internal subnet (will not have an effect in combination with floating/external network configuration)
cloudControllerManager.featureGates contains a map of explicitly enabled or disabled feature gates.
For production usage it’s not recommended to use this field at all as you can enable alpha features or disable beta/stable features, potentially impacting the cluster stability.
If you don’t want to configure anything for the
cloudControllerManager simply omit the key in the YAML specification.
Each worker group in a shoot may contain provider-specific configurations and options. These are contained in the
providerConfig section of a worker group and can be configured using a
An example of a
WorkerConfig looks as follows:
apiVersion: openstack.provider.extensions.gardener.cloud/v1alpha1 kind: WorkerConfig serverGroup: policy: soft-anti-affinity
When you specify the
serverGroup section in your worker group configuration, a new server group will be created with the configured policy for each worker group that enabled this setting and all machines managed by this worker group will be assigned as members of the created server group.
For users to have access to the server group feature, it must be enabled on the
CloudProfile by your operator.
Existing clusters can take advantage of this feature by updating the server group configuration of their respective worker groups. Worker groups that are already configured with server groups can update their setting to change the policy used, or remove it altogether at any time.
Users must be aware that any change to the server group settings will result in a rolling deployment of new nodes for the affected worker group.
Please note the following restrictions when deploying workers with server groups:
serverGroupsection is optional, but if it is included in the worker configuration, it must contain a valid policy value.
- The available
policyvalues that can be used, are defined in the provider specific section of
CloudProfileby your operator.
- Certain policy values may induce further constraints. Using the
affinitypolicy is only allowed when the worker group utilizes a single zone.
Shoot manifest (one availability zone)
Please find below an example
Shoot manifest for one availability zone:
apiVersion: core.gardener.cloud/v1alpha1 kind: Shoot metadata: name: johndoe-openstack namespace: garden-dev spec: cloudProfileName: openstack region: europe-1 secretBindingName: core-openstack provider: type: openstack infrastructureConfig: apiVersion: openstack.provider.extensions.gardener.cloud/v1alpha1 kind: InfrastructureConfig floatingPoolName: MY-FLOATING-POOL networks: workers: 10.250.0.0/19 controlPlaneConfig: apiVersion: openstack.provider.extensions.gardener.cloud/v1alpha1 kind: ControlPlaneConfig loadBalancerProvider: haproxy workers: - name: worker-xoluy machine: type: medium_4_8 minimum: 2 maximum: 2 zones: - europe-1a networking: nodes: 10.250.0.0/16 type: calico kubernetes: version: 1.16.1 maintenance: autoUpdate: kubernetesVersion: true machineImageVersion: true addons: kubernetes-dashboard: enabled: true nginx-ingress: enabled: true
CSI volume provisioners
Every OpenStack shoot cluster that has at least Kubernetes v1.19 will be deployed with the OpenStack Cinder CSI driver.
It is compatible with the legacy in-tree volume provisioner that was deprecated by the Kubernetes community and will be removed in future versions of Kubernetes.
End-users might want to update their custom
StorageClasses to the new
Shoot clusters with Kubernetes v1.18 or less will use the in-tree
kubernetes.io/cinder volume provisioner in the kube-controller-manager and the kubelet.
Kubernetes Versions per Worker Pool
This extension supports
WorkerPoolKubernetesVersion feature gate, i.e., having worker pools with overridden Kubernetes versions since
Note that this feature is only usable for
.spec.kubernetes.version is greater or equal than the CSI migration version (
Shoot CA Certificate and
ServiceAccount Signing Key Rotation
This extension supports
ShootSARotation feature gates since