Skip to content

Commit c773386

Browse files
committed
fix: split provider CRs from operator deployment
This commit splits the cluster-api-operator Helm chart into two separate charts to resolve flaky installations caused by webhook validation timing issues. Problem: - Provider Custom Resources (CoreProvider, BootstrapProvider, etc.) were applied at the same time as the operator deployment. - The webhook service was not yet ready, leading to validation errors: "no endpoints available for service 'capi-operator-webhook-service'". Solution: - Create two charts: 1. cluster-api-operator: contains only the operator deployment and its resources. 2. cluster-api-operator-providers: contains all provider Custom Resources. - Installing the operator first allows the webhook to start before provider CRs are applied. Installation now requires: 1. Install operator: helm install capi-operator capi-operator/cluster-api-operator \ --create-namespace -n capi-operator-system --wait --timeout 90s 2. Install providers: helm install capi-providers \ capi-operator/cluster-api-operator-providers \ -n capi-operator-system \ --set infrastructure.docker.enabled=true \ --set cert-manager.enabled=true \ --set configSecret.name=${CREDENTIALS_SECRET_NAME} \ --set configSecret.namespace=${CREDENTIALS_SECRET_NAMESPACE} Fixes: #534 Signed-off-by: kahirokunn <okinakahiro@gmail.com>
1 parent 95adca5 commit c773386

File tree

16 files changed

+314
-78
lines changed

16 files changed

+314
-78
lines changed

Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ endif
180180
RELEASE_ALIAS_TAG ?= $(PULL_BASE_REF)
181181
RELEASE_DIR := $(ROOT)/out
182182
CHART_DIR := $(RELEASE_DIR)/charts/cluster-api-operator
183+
CHART_PROVIDERS_DIR := $(RELEASE_DIR)/charts/cluster-api-operator-providers
183184
CHART_PACKAGE_DIR := $(RELEASE_DIR)/package
184185

185186
# Set --output-base for conversion-gen if we are not within GOPATH
@@ -455,6 +456,9 @@ $(CHART_DIR):
455456
$(CHART_PACKAGE_DIR):
456457
mkdir -p $(CHART_PACKAGE_DIR)
457458

459+
$(CHART_PROVIDERS_DIR):
460+
mkdir -p $(CHART_PROVIDERS_DIR)/templates
461+
458462
.PHONY: release
459463
release: clean-release $(RELEASE_DIR) ## Builds and push container images using the latest git tag for the commit.
460464
@if [ -z "${RELEASE_TAG}" ]; then echo "RELEASE_TAG is not set"; exit 1; fi
@@ -485,11 +489,16 @@ release-manifests: $(KUSTOMIZE) $(RELEASE_DIR) ## Builds the manifests to publis
485489
$(KUSTOMIZE) build ./config/default > $(RELEASE_DIR)/operator-components.yaml
486490

487491
.PHONY: release-chart
488-
release-chart: $(HELM) $(KUSTOMIZE) $(RELEASE_DIR) $(CHART_DIR) $(CHART_PACKAGE_DIR) ## Builds the chart to publish with a release
492+
release-chart: $(HELM) $(KUSTOMIZE) $(RELEASE_DIR) $(CHART_DIR) $(CHART_PROVIDERS_DIR) $(CHART_PACKAGE_DIR) ## Builds the chart to publish with a release
493+
# cluster-api-operator チャートの処理
489494
cp -rf $(ROOT)/hack/charts/cluster-api-operator/. $(CHART_DIR)
490495
$(KUSTOMIZE) build ./config/chart > $(CHART_DIR)/templates/operator-components.yaml
491496
$(HELM) package $(CHART_DIR) --app-version=$(HELM_CHART_TAG) --version=$(HELM_CHART_TAG) --destination=$(CHART_PACKAGE_DIR)
492497

498+
# cluster-api-operator-providers チャートの処理
499+
cp -rf $(ROOT)/hack/charts/cluster-api-operator-providers/. $(CHART_PROVIDERS_DIR)
500+
$(HELM) package $(CHART_PROVIDERS_DIR) --app-version=$(HELM_CHART_TAG) --version=$(HELM_CHART_TAG) --destination=$(CHART_PACKAGE_DIR)
501+
493502
.PHONY: release-staging
494503
release-staging: ## Builds and push container images and manifests to the staging bucket.
495504
$(MAKE) docker-build-all
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v2
2+
name: cluster-api-operator-providers
3+
description: Cluster API Provider Custom Resources
4+
type: application
5+
version: 0.0.0
6+
appVersion: "0.0.0"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{{/* vim: set filetype=mustache: */}}
2+
{{/*
3+
Expand the name of the chart.
4+
*/}}
5+
{{- define "capi-operator.name" -}}
6+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
7+
{{- end -}}
8+
9+
{{/*
10+
Create a default fully qualified app name.
11+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12+
*/}}
13+
{{- define "capi-operator.fullname" -}}
14+
{{- if .Values.fullnameOverride -}}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
16+
{{- else -}}
17+
{{- $name := default .Chart.Name .Values.nameOverride -}}
18+
{{- if contains $name .Release.Name -}}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
20+
{{- else -}}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
22+
{{- end -}}
23+
{{- end -}}
24+
{{- end -}}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"core": {
6+
"oneOf": [
7+
{ "type": "object" },
8+
{ "type": "null" }
9+
]
10+
},
11+
"bootstrap": {
12+
"type": "object",
13+
"oneOf": [
14+
{ "type": "object" },
15+
{ "type": "null" }
16+
]
17+
},
18+
"controlPlane": {
19+
"type": "object",
20+
"oneOf": [
21+
{ "type": "object" },
22+
{ "type": "null" }
23+
]
24+
},
25+
"infrastructure": {
26+
"type": "object",
27+
"oneOf": [
28+
{ "type": "object" },
29+
{ "type": "null" }
30+
]
31+
},
32+
"addon": {
33+
"type": "object",
34+
"oneOf": [
35+
{ "type": "object" },
36+
{ "type": "null" }
37+
]
38+
},
39+
"ipam": {
40+
"type": "object",
41+
"oneOf": [
42+
{ "type": "object" },
43+
{ "type": "null" }
44+
]
45+
},
46+
"manager": {
47+
"type": "object",
48+
"properties": {
49+
"featureGates": {
50+
"type": "object"
51+
}
52+
}
53+
},
54+
"fetchConfig": {
55+
"type": "object"
56+
},
57+
"configSecret": {
58+
"type": "object"
59+
},
60+
"enableHelmHook": {
61+
"type": "boolean",
62+
"default": false
63+
}
64+
}
65+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
# Cluster API provider options
3+
core: {}
4+
# cluster-api: {} # Name, required
5+
# namespace: "" # Optional
6+
# version: "" # Optional
7+
# createNamespace: true # Optional
8+
bootstrap: {}
9+
# kubeadm: {} # Name, required
10+
# namespace: "" # Optional
11+
# version: "" # Optional
12+
# createNamespace: true # Optional
13+
controlPlane: {}
14+
# kubeadm: {} # Name, required
15+
# namespace: "" # Optional
16+
# version: "" # Optional
17+
# createNamespace: true # Optional
18+
infrastructure: {}
19+
# docker: {} # Name, required
20+
# namespace: "" # Optional
21+
# version: "" # Optional
22+
# createNamespace: true # Optional
23+
addon: {}
24+
# helm: {} # Name, required
25+
# namespace: "" # Optional
26+
# version: "" # Optional
27+
# createNamespace: true # Optional
28+
ipam: {}
29+
# in-cluster: {} # Name, required
30+
# namespace: "" # Optional
31+
# version: "" # Optional
32+
# createNamespace: true # Optional
33+
manager:
34+
featureGates: {}
35+
# Configuration for enabling feature gates in different providers
36+
# manager:
37+
# featureGates:
38+
# proxmox: # Name of the provider
39+
# ClusterTopology: true
40+
# core:
41+
# ClusterTopology: true
42+
# kubeadm:
43+
# ClusterTopology: true
44+
fetchConfig: {}
45+
# ---
46+
# Common configuration secret options
47+
configSecret: {}
48+
enableHelmHook: false # Provider CRsではHookは不要

hack/charts/cluster-api-operator/values.schema.json

Lines changed: 138 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,154 @@
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"type": "object",
44
"properties": {
5-
"core": {
6-
"oneOf": [
7-
{ "type": "object" },
8-
{ "type": "null" }
9-
]
5+
"logLevel": {
6+
"type": "integer",
7+
"default": 2
108
},
11-
"bootstrap": {
9+
"replicaCount": {
10+
"type": "integer",
11+
"default": 1
12+
},
13+
"leaderElection": {
1214
"type": "object",
13-
"oneOf": [
14-
{ "type": "object" },
15-
{ "type": "null" }
16-
]
15+
"properties": {
16+
"enabled": {
17+
"type": "boolean",
18+
"default": true
19+
},
20+
"leaseDuration": {
21+
"type": "string"
22+
},
23+
"renewDeadline": {
24+
"type": "string"
25+
},
26+
"retryPeriod": {
27+
"type": "string"
28+
}
29+
}
1730
},
18-
"controlPlane": {
31+
"image": {
1932
"type": "object",
20-
"oneOf": [
21-
{ "type": "object" },
22-
{ "type": "null" }
23-
]
33+
"properties": {
34+
"manager": {
35+
"type": "object",
36+
"properties": {
37+
"repository": {
38+
"type": "string"
39+
},
40+
"tag": {
41+
"type": "string"
42+
},
43+
"pullPolicy": {
44+
"type": "string",
45+
"enum": ["Always", "IfNotPresent", "Never"]
46+
},
47+
"registry": {
48+
"type": "string"
49+
},
50+
"digest": {
51+
"type": "string"
52+
}
53+
}
54+
}
55+
}
2456
},
25-
"infrastructure": {
57+
"env": {
2658
"type": "object",
27-
"oneOf": [
28-
{ "type": "object" },
29-
{ "type": "null" }
30-
]
59+
"properties": {
60+
"manager": {
61+
"type": "array"
62+
}
63+
}
64+
},
65+
"diagnosticsAddress": {
66+
"type": "string",
67+
"default": ":8443"
68+
},
69+
"healthAddr": {
70+
"type": "string",
71+
"default": ":9440"
72+
},
73+
"profilerAddress": {
74+
"type": "string",
75+
"default": ":6060"
76+
},
77+
"contentionProfiling": {
78+
"type": "boolean",
79+
"default": false
80+
},
81+
"insecureDiagnostics": {
82+
"type": "boolean",
83+
"default": false
3184
},
32-
"addon": {
85+
"watchConfigSecret": {
86+
"type": "boolean",
87+
"default": false
88+
},
89+
"imagePullSecrets": {
90+
"type": "object"
91+
},
92+
"resources": {
3393
"type": "object",
34-
"oneOf": [
35-
{ "type": "object" },
36-
{ "type": "null" }
37-
]
94+
"properties": {
95+
"manager": {
96+
"type": "object"
97+
}
98+
}
99+
},
100+
"containerSecurityContext": {
101+
"type": "object"
102+
},
103+
"affinity": {
104+
"type": "object"
105+
},
106+
"tolerations": {
107+
"type": "array"
108+
},
109+
"volumes": {
110+
"type": "array"
38111
},
39-
"ipam": {
112+
"volumeMounts": {
40113
"type": "object",
41-
"oneOf": [
42-
{ "type": "object" },
43-
{ "type": "null" }
44-
]
114+
"properties": {
115+
"manager": {
116+
"type": "array"
117+
}
118+
}
119+
},
120+
"enableHelmHook": {
121+
"type": "boolean",
122+
"default": true
123+
},
124+
"deploymentLabels": {
125+
"type": "object"
126+
},
127+
"deploymentAnnotations": {
128+
"type": "object"
129+
},
130+
"podLabels": {
131+
"type": "object"
132+
},
133+
"podAnnotations": {
134+
"type": "object"
135+
},
136+
"securityContext": {
137+
"type": "object"
138+
},
139+
"strategy": {
140+
"type": "object"
141+
},
142+
"nodeSelector": {
143+
"type": "object"
144+
},
145+
"topologySpreadConstraints": {
146+
"type": "array"
147+
},
148+
"podDnsPolicy": {
149+
"type": "string"
150+
},
151+
"podDnsConfig": {
152+
"type": "object"
45153
}
46154
}
47155
}

0 commit comments

Comments
 (0)