cmd/k8s-operator: add replica support to nameserver (#17246)

This commit modifies the `DNSConfig` custom resource to allow specifying
a replica count when deploying a nameserver. This allows deploying
nameservers in a HA configuration.

Updates https://github.com/tailscale/corp/issues/32589

Signed-off-by: David Bond <davidsbond93@gmail.com>
pull/17260/head
David Bond 2 months ago committed by GitHub
parent a32102f741
commit e466488a2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -100,6 +100,11 @@ spec:
tag:
description: Tag defaults to unstable.
type: string
replicas:
description: Replicas specifies how many Pods to create. Defaults to 1.
type: integer
format: int32
minimum: 0
service:
description: Service configuration.
type: object

@ -431,6 +431,11 @@ spec:
description: Tag defaults to unstable.
type: string
type: object
replicas:
description: Replicas specifies how many Pods to create. Defaults to 1.
format: int32
minimum: 0
type: integer
service:
description: Service configuration.
properties:

@ -30,6 +30,7 @@ import (
tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
"tailscale.com/kube/kubetypes"
"tailscale.com/tstime"
"tailscale.com/types/ptr"
"tailscale.com/util/clientmetric"
"tailscale.com/util/set"
)
@ -130,7 +131,7 @@ func (a *NameserverReconciler) Reconcile(ctx context.Context, req reconcile.Requ
return setStatus(&dnsCfg, metav1.ConditionFalse, reasonNameserverCreationFailed, msg)
}
}
if err := a.maybeProvision(ctx, &dnsCfg, logger); err != nil {
if err = a.maybeProvision(ctx, &dnsCfg); err != nil {
if strings.Contains(err.Error(), optimisticLockErrorMsg) {
logger.Infof("optimistic lock error, retrying: %s", err)
return reconcile.Result{}, nil
@ -167,7 +168,7 @@ func nameserverResourceLabels(name, namespace string) map[string]string {
return labels
}
func (a *NameserverReconciler) maybeProvision(ctx context.Context, tsDNSCfg *tsapi.DNSConfig, logger *zap.SugaredLogger) error {
func (a *NameserverReconciler) maybeProvision(ctx context.Context, tsDNSCfg *tsapi.DNSConfig) error {
labels := nameserverResourceLabels(tsDNSCfg.Name, a.tsNamespace)
dCfg := &deployConfig{
ownerRefs: []metav1.OwnerReference{*metav1.NewControllerRef(tsDNSCfg, tsapi.SchemeGroupVersion.WithKind("DNSConfig"))},
@ -175,6 +176,11 @@ func (a *NameserverReconciler) maybeProvision(ctx context.Context, tsDNSCfg *tsa
labels: labels,
imageRepo: defaultNameserverImageRepo,
imageTag: defaultNameserverImageTag,
replicas: 1,
}
if tsDNSCfg.Spec.Nameserver.Replicas != nil {
dCfg.replicas = *tsDNSCfg.Spec.Nameserver.Replicas
}
if tsDNSCfg.Spec.Nameserver.Image != nil && tsDNSCfg.Spec.Nameserver.Image.Repo != "" {
dCfg.imageRepo = tsDNSCfg.Spec.Nameserver.Image.Repo
@ -211,6 +217,7 @@ type deployable struct {
}
type deployConfig struct {
replicas int32
imageRepo string
imageTag string
labels map[string]string
@ -236,6 +243,7 @@ var (
if err := yaml.Unmarshal(deployYaml, &d); err != nil {
return fmt.Errorf("error unmarshalling Deployment yaml: %w", err)
}
d.Spec.Replicas = ptr.To(cfg.replicas)
d.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", cfg.imageRepo, cfg.imageTag)
d.ObjectMeta.Namespace = cfg.namespace
d.ObjectMeta.Labels = cfg.labels

@ -22,6 +22,7 @@ import (
operatorutils "tailscale.com/k8s-operator"
tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
"tailscale.com/tstest"
"tailscale.com/types/ptr"
"tailscale.com/util/mak"
)
@ -33,6 +34,7 @@ func TestNameserverReconciler(t *testing.T) {
},
Spec: tsapi.DNSConfigSpec{
Nameserver: &tsapi.Nameserver{
Replicas: ptr.To[int32](3),
Image: &tsapi.NameserverImage{
Repo: "test",
Tag: "v0.0.1",
@ -74,6 +76,7 @@ func TestNameserverReconciler(t *testing.T) {
}
wantsDeploy.OwnerReferences = []metav1.OwnerReference{*ownerReference}
wantsDeploy.Spec.Template.Spec.Containers[0].Image = "test:v0.0.1"
wantsDeploy.Spec.Replicas = ptr.To[int32](3)
wantsDeploy.Namespace = tsNamespace
wantsDeploy.ObjectMeta.Labels = nameserverLabels
expectEqual(t, fc, wantsDeploy)

@ -443,6 +443,7 @@ _Appears in:_
| --- | --- | --- | --- |
| `image` _[NameserverImage](#nameserverimage)_ | Nameserver image. Defaults to tailscale/k8s-nameserver:unstable. | | |
| `service` _[NameserverService](#nameserverservice)_ | Service configuration. | | |
| `replicas` _integer_ | Replicas specifies how many Pods to create. Defaults to 1. | | Minimum: 0 <br /> |
#### NameserverImage

@ -84,6 +84,10 @@ type Nameserver struct {
// Service configuration.
// +optional
Service *NameserverService `json:"service,omitempty"`
// Replicas specifies how many Pods to create. Defaults to 1.
// +optional
// +kubebuilder:validation:Minimum=0
Replicas *int32 `json:"replicas,omitempty"`
}
type NameserverImage struct {

@ -422,6 +422,11 @@ func (in *Nameserver) DeepCopyInto(out *Nameserver) {
*out = new(NameserverService)
**out = **in
}
if in.Replicas != nil {
in, out := &in.Replicas, &out.Replicas
*out = new(int32)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Nameserver.

Loading…
Cancel
Save