Skip to content

Commit

Permalink
Provide --cluster-name flag to the OpenStack external CCM
Browse files Browse the repository at this point in the history
Signed-off-by: Marko Mudrinić <mudrinic.mare@gmail.com>
  • Loading branch information
xmudrii committed Nov 15, 2021
1 parent c936e10 commit 00ee956
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 2 deletions.
3 changes: 3 additions & 0 deletions addons/ccm-openstack/ccm-openstack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ spec:
- --cloud-provider=openstack
- --use-service-account-credentials=true
- --bind-address=127.0.0.1
{{ if .CCMClusterName }}
- --cluster-name={{ .CCMClusterName }}
{{ end }}
{{ if .Config.CABundle }}
env:
{{ caBundleEnvVar | indent 12 }}
Expand Down
2 changes: 2 additions & 0 deletions pkg/addons/applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type templateData struct {
Config *kubeoneapi.KubeOneCluster
Certificates map[string]string
Credentials map[string]string
CCMClusterName string
CSIMigration bool
CSIMigrationFeatureGates string
MachineControllerCredentialsEnvVars string
Expand Down Expand Up @@ -155,6 +156,7 @@ func newAddonsApplier(s *state.State) (*applier, error) {
"KubernetesCA": mcCertsMap[resources.KubernetesCACertName],
},
Credentials: creds,
CCMClusterName: s.LiveCluster.CCMClusterName,
CSIMigration: csiMigration,
CSIMigrationFeatureGates: csiMigrationFeatureGates,
MachineControllerCredentialsEnvVars: string(credsEnvVars),
Expand Down
1 change: 1 addition & 0 deletions pkg/state/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Cluster struct {
StaticWorkers []Host
ExpectedVersion *semver.Version
EncryptionConfiguration *EncryptionConfiguration
CCMClusterName string
CCMStatus *CCMStatus
Lock sync.Mutex
}
Expand Down
84 changes: 82 additions & 2 deletions pkg/tasks/probes.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ const (

kubeletInitializedCMD = `test -f /etc/kubernetes/kubelet.conf`

k8sAppLabel = "k8s-app"
k8sAppLabel = "k8s-app"
openstackCCMAppLabelValue = "openstack-cloud-controller-manager"
)

var KubeProxyObjectKey = dynclient.ObjectKey{
Expand Down Expand Up @@ -158,6 +159,14 @@ func runProbes(s *state.State) error {
}
}

clusterName, cnErr := detectClusterName(s)
if cnErr != nil {
return errors.Wrap(cnErr, "failed to detect the ccm --cluster-name flag value")
}
s.LiveCluster.Lock.Lock()
s.LiveCluster.CCMClusterName = clusterName
s.LiveCluster.Lock.Unlock()

switch {
case s.Cluster.ContainerRuntime.Containerd != nil:
return nil
Expand Down Expand Up @@ -612,7 +621,7 @@ func detectCCMMigrationStatus(s *state.State) (*state.CCMStatus, error) {
case s.Cluster.CloudProvider.Azure != nil:
ccmLabelValue = "azure-cloud-controller-manager"
case s.Cluster.CloudProvider.Openstack != nil:
ccmLabelValue = "openstack-cloud-controller-manager"
ccmLabelValue = openstackCCMAppLabelValue
case s.Cluster.CloudProvider.Vsphere != nil:
ccmLabelValue = "vsphere-cloud-controller-manager"
default:
Expand All @@ -636,3 +645,74 @@ func detectCCMMigrationStatus(s *state.State) (*state.CCMStatus, error) {

return status, nil
}

// detectClusterName is used to detect the value that should be passed to the
// external CCM via the --cluster-name flag.
//
// This function is currently used for OpenStack clusters, because we initially
// didn't set this flag, in which case it defaults to `kubernetes`.
//
// Not setting the flag can cause issues if there are multiple clusters in the
// same tenant. For example, Load Balancers with the same name in different
// clusters will share the same Octavia LB.
//
// Changing the --cluster-name causes the CCM to lose all references to the
// Load Balancers on OpenStack, because the cluster name is used as part of
// the reference to the LB. Therefore, we need this function to ensure the
// backwards compatibility.
//
// The function works in the following way:
// * if the cluster is not provisioned, or if the cluster is not an OpenStack
// cluster, return the KubeOne cluster name
// * if it's an existing OpenStack cluster:
// * if cluster is running in-tree cloud provider: return the KubeOne
// cluster name because the in-tree provider already has the
// --cluster-name flag set
// * if cluster is running external cloud provider: check if there is
// `--cluster-name` flag on the OpenStack CCM. If there is, read the
// value and return it, otherwise don't set the OpenStack cluster name,
// in which case it defaults to `kubernetes`
// * if cluster is migrated to external CCM, return the KubeOne cluster name
//
// If an operator wants to change the --cluster-name flag on OpenStack external
// CCM, they need to edit the CCM DaemonSet manually. KubeOne will
// automatically pick up the provided value when reconciling the cluster.
func detectClusterName(s *state.State) (string, error) {
if !s.LiveCluster.IsProvisioned() ||
s.LiveCluster.CCMStatus == nil ||
s.Cluster.CloudProvider.Openstack == nil {
return s.Cluster.Name, nil
}

if s.LiveCluster.CCMStatus.InTreeCloudProviderEnabled && !s.LiveCluster.CCMStatus.ExternalCCMDeployed {
return s.Cluster.Name, nil
}

pods := corev1.PodList{}
err := s.DynamicClient.List(s.Context, &pods, &dynclient.ListOptions{
Namespace: metav1.NamespaceSystem,
LabelSelector: labels.SelectorFromSet(map[string]string{
k8sAppLabel: openstackCCMAppLabelValue,
}),
})
if err != nil {
return "", err
}
if len(pods.Items) == 0 || len(pods.Items[0].Spec.Containers) == 0 {
return "", errors.New("unable to detect ccm pod/container")
}
for _, container := range pods.Items[0].Spec.Containers {
if container.Name != openstackCCMAppLabelValue {
continue
}
for _, flag := range container.Command {
if strings.HasPrefix(flag, "--cluster-name") {
return strings.Split(flag, "=")[1], nil
}
}
}

// If we got here, the cluster is running external CCM, but we didn't
// find the --cluster-name flag, therefore assume default value.
return "", nil
}

0 comments on commit 00ee956

Please sign in to comment.