Sitelet https://github.com/kubernetes/kops/commit/21489be4764a3e95795d3f573d57bde0768a7567
Skip to content

Commit 21489be

Browse files
committed
Adding flag to enable machine type for APIServer only.
Added flag --api-server-size to be consistent with other machine type flags. Added doc on the flag reflecting my testing. Adding GCE test for APIServer only option. Fixed comment from previous PR. apiserver only DNS check for AWS comment is now correct.
1 parent f54e1d7 commit 21489be

7 files changed

Lines changed: 433 additions & 5 deletions

File tree

‎cmd/kops/create_cluster.go‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ var (
157157
--node-count 3 \
158158
--yes
159159
160+
# Create a cluster in GCE with a dedicated APIServer-Only front-end.
161+
export KOPS_FEATURE_FLAGS="+APIServerNodes"
162+
export ZONES="us-west1-a,us-west1-b,us-west1-c"
163+
export PROJECT="my-project"
164+
export KOPS_STATE_STORE="gs://${PROJECT}-kops-state"
165+
export KOPS_CLUSTER_NAME="k8s-cluster.example.com"
166+
kops create cluster --name=${KOPS_CLUSTER_NAME} \
167+
--cloud=gce \
168+
--zones=${ZONES} \
169+
--project=${PROJECT} \
170+
--node-count=3 --node-size=e2-standard-2 \
171+
--api-server-count=2 --api-server-size=e2-standard-2 \
172+
--control-plane-count=3 --control-plane-size=e2-standard-4 \
173+
--yes
174+
175+
160176
# Generate a cluster spec to apply later.
161177
# Run the following, then: kops create -f filename.yaml
162178
kops create cluster --name=k8s-cluster.example.com \
@@ -279,6 +295,9 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
279295
cmd.Flags().MarkDeprecated("master-count", "use --control-plane-count instead")
280296
cmd.Flags().Int32Var(&options.ControlPlaneCount, "control-plane-count", options.ControlPlaneCount, "Number of control-plane nodes. Defaults to one control-plane node per control-plane-zone")
281297
cmd.Flags().Int32Var(&options.NodeCount, "node-count", options.NodeCount, "Total number of worker nodes. Defaults to one node per zone")
298+
if featureflag.APIServerNodes.Enabled() {
299+
cmd.Flags().Int32Var(&options.APIServerCount, "api-server-count", options.APIServerCount, "Number of API server nodes. Defaults to 0.")
300+
}
282301

283302
cmd.Flags().StringVar(&options.Image, "image", options.Image, "Machine image for all instances")
284303
cmd.RegisterFlagCompletionFunc("image", completeInstanceImage)
@@ -297,6 +316,10 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
297316
cmd.Flags().MarkDeprecated("master-size", "use --control-plane-size instead")
298317
cmd.Flags().StringSliceVar(&options.ControlPlaneSizes, "control-plane-size", options.ControlPlaneSizes, "Machine type(s) for control-plane nodes")
299318
cmd.RegisterFlagCompletionFunc("control-plane-size", completeMachineType)
319+
if featureflag.APIServerNodes.Enabled() {
320+
cmd.Flags().StringSliceVar(&options.APIServerSizes, "api-server-size", options.APIServerSizes, "Machine type(s) for API server nodes")
321+
cmd.RegisterFlagCompletionFunc("api-server-size", completeMachineType)
322+
}
300323

301324
cmd.Flags().Int32Var(&options.ControlPlaneVolumeSize, "master-volume-size", options.ControlPlaneVolumeSize, "Instance volume size (in GB) for control-plane nodes")
302325
cmd.Flags().MarkDeprecated("master-volume-size", "use --control-plane-volume-size instead")
@@ -462,10 +485,6 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
462485
cmd.RegisterFlagCompletionFunc("spotinst-orientation", completeSpotinstOrientation)
463486
}
464487

465-
if featureflag.APIServerNodes.Enabled() {
466-
cmd.Flags().Int32Var(&options.APIServerCount, "api-server-count", options.APIServerCount, "Number of API server nodes. Defaults to 0.")
467-
}
468-
469488
// Openstack flags
470489
cmd.Flags().StringVar(&options.OpenstackExternalNet, "os-ext-net", options.OpenstackExternalNet, "External network to use with the openstack router")
471490
cmd.RegisterFlagCompletionFunc("os-ext-net", completeOpenstackExternalNet)

‎docs/cli/kops_create_cluster.md‎

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pkg/apis/kops/validation/instancegroup.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ func CrossValidateInstanceGroup(g *kops.InstanceGroup, cluster *kops.Cluster, cl
262262
case kops.CloudProviderGCE:
263263
// Fully supported do nothing.
264264
case kops.CloudProviderAWS:
265-
// AWS only supports APIServer if DNS is set to None
265+
// AWS only supports APIServer if DNS is not set to None
266266
if cluster.UsesNoneDNS() {
267267
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "role"), "APIServer cannot be used with topology.dns.type=None"))
268268
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2025 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
set -euo pipefail
19+
20+
REPO_ROOT=$(git rev-parse --show-toplevel)
21+
cd "${REPO_ROOT}/"
22+
23+
# Enable feature flag for APIServer Nodes support
24+
export KOPS_FEATURE_FLAGS=+APIServerNodes
25+
26+
# Override some settings
27+
CLUSTER_NAME="splitkcp.k8s.local"
28+
29+
CLOUD_PROVIDER=gce
30+
ZONES="us-west1-a,us-west1-b,us-west1-c" # Currently the zone name gets encoded in the machinedeployment name (maybe we can use labels instead?)
31+
32+
OVERRIDES="${OVERRIDES-} --node-count=2" # We need at least 2 nodes for CoreDNS to validate
33+
OVERRIDES="${OVERRIDES} --control-plane-count=3" # We need at least 3 control plane nodes to ensure etcd comes up as raft
34+
OVERRIDES="${OVERRIDES} --api-server-count=1" # We need at least 1 api-server node to split the control plane
35+
OVERRIDES="${OVERRIDES} --networking=kubenet" #
36+
OVERRIDES="${OVERRIDES} --node-size=e2-standard-2" #
37+
OVERRIDES="${OVERRIDES} --api-server-size=e2-standard-2" #
38+
OVERRIDES="${OVERRIDES} --control-plane-size=e2-standard-4" #
39+
OVERRIDES="${OVERRIDES} --gce-service-account=default" # Use default service account because boskos permissions are limited
40+
41+
# Create kOps cluster
42+
source "${REPO_ROOT}/tests/e2e/scenarios/lib/common.sh"
43+
44+
kops-acquire-latest
45+
46+
kops-up
47+
48+
# Export KUBECONFIG; otherwise the precedence for controllers is wrong (?)
49+
KUBECONFIG=$(mktemp -t kops.XXXXXXXXX)
50+
export KUBECONFIG
51+
"${KOPS}" export kubecfg --name "${CLUSTER_NAME}" --admin --kubeconfig "${KUBECONFIG}"
52+
53+
54+
# Install kOps CRDs (Cluster & InstanceGroup)
55+
# Ideally we would install these as part of kops-up, but while we're developing CAPI support it's easier to do it here
56+
kubectl apply --server-side -k "${REPO_ROOT}/k8s"
57+
#kubectl apply --server-side -k "${REPO_ROOT}/clusterapi/config"
58+
59+
# Install extra RBAC for kops-controller CAPI support
60+
kubectl apply --server-side -f "${REPO_ROOT}/clusterapi/examples/kopscontroller.yaml"
61+
62+
# Bounce kops-controller in case it went into backoff before the CRDs were installed
63+
kubectl delete pod -n kube-system -l k8s-app=kops-controller
64+
65+
# Install cert-manager
66+
kubectl apply --server-side -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.2/cert-manager.yaml
67+
68+
kubectl wait --for=condition=Available --timeout=5m -n cert-manager deployment/cert-manager
69+
kubectl wait --for=condition=Available --timeout=5m -n cert-manager deployment/cert-manager-cainjector
70+
kubectl wait --for=condition=Available --timeout=5m -n cert-manager deployment/cert-manager-webhook
71+
72+
# Install cluster-api core and cluster-api-provider-gcp
73+
kubectl apply --server-side -k "${REPO_ROOT}/clusterapi/manifests/cluster-api"
74+
kubectl wait --for=condition=Available --timeout=5m -n capi-system deployment/capi-controller-manager
75+
76+
kubectl apply --server-side -k "${REPO_ROOT}/clusterapi/manifests/cluster-api-provider-gcp"
77+
kubectl wait --for=condition=Available --timeout=5m -n capg-system deployment/capg-controller-manager
78+
79+
80+
# Install extra RBAC for capi-manager loopback connection to cluster (used to check node health etc)
81+
kubectl apply --server-side -f "${REPO_ROOT}/clusterapi/examples/capi-loopback.yaml"
82+
83+
# Debug: log kops-controller
84+
kubectl logs -n kube-system -l k8s-app=kops-controller --follow &
85+
86+
# Print the nodes, machines and gcpmachines
87+
kubectl get nodes -owide
88+
kubectl get machine -A -owide
89+
kubectl get gcpmachine -A -owide
90+
91+
# Print the nodes, machines and gcpmachines again
92+
kubectl get nodes -owide
93+
kubectl get machine -A -owide
94+
kubectl get gcpmachine -A -owide
95+
96+
# CAPI currently creates some firewall rules that otherwise are not cleaned up, and block kops cluster cleanup
97+
function cleanup_capi_leaks() {
98+
gcloud compute firewall-rules delete allow-clusterapi-k8s-local-cluster --quiet || true
99+
gcloud compute firewall-rules delete allow-clusterapi-k8s-local-healthchecks --quiet || true
100+
101+
#gcloud compute networks subnets delete us-east4-clusterapi-k8s-local --region us-east4 --quiet
102+
#gcloud compute networks delete clusterapi-k8s-local --quiet
103+
}
104+
cleanup_capi_leaks

0 commit comments

Comments
 (0)