Skip to content

Commit

Permalink
Add ability to set DockerClusterSpec load balancer
Browse files Browse the repository at this point in the history
We need the ability to set the repository and tag of the load balancer
to use. This adds a field to the DockerClusterSpec in the v1alpha4 API
to enable this.

Signed-off-by: Sean McGinnis <[email protected]>
  • Loading branch information
stmcginnis committed Jul 20, 2021
1 parent 9719e4f commit 7264f91
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 16 deletions.
69 changes: 69 additions & 0 deletions test/infrastructure/docker/api/v1alpha3/conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha3

import (
apiconversion "k8s.io/apimachinery/pkg/conversion"
"sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha4"
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
"sigs.k8s.io/controller-runtime/pkg/conversion"
)

func (src *DockerCluster) ConvertTo(dstRaw conversion.Hub) error {
dst := dstRaw.(*v1alpha4.DockerCluster)

if err := Convert_v1alpha3_DockerCluster_To_v1alpha4_DockerCluster(src, dst, nil); err != nil {
return err
}

// Manually restore data.
restored := &v1alpha4.DockerCluster{}
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
return err
}

if restored.Spec.LoadBalancer.ImageRepository != "" {
dst.Spec.LoadBalancer.ImageRepository = restored.Spec.LoadBalancer.ImageRepository
}

if restored.Spec.LoadBalancer.ImageTag != "" {
dst.Spec.LoadBalancer.ImageTag = restored.Spec.LoadBalancer.ImageTag
}

return nil
}

func (dst *DockerCluster) ConvertFrom(srcRaw conversion.Hub) error {
src := srcRaw.(*v1alpha4.DockerCluster)

if err := Convert_v1alpha4_DockerCluster_To_v1alpha3_DockerCluster(src, dst, nil); err != nil {
return err
}

// Preserve Hub data on down-conversion except for metadata
if err := utilconversion.MarshalData(src, dst); err != nil {
return err
}

return nil
}

// Convert_v1alpha4_DockerClusterSpec_To_v1alpha3_DockerClusterSpec is an autogenerated conversion function.
func Convert_v1alpha4_DockerClusterSpec_To_v1alpha3_DockerClusterSpec(in *v1alpha4.DockerClusterSpec, out *DockerClusterSpec, s apiconversion.Scope) error {
// DockerClusterSpec.LoadBalancer was added in v1alpha4, so automatic conversion is not possible
return autoConvert_v1alpha4_DockerClusterSpec_To_v1alpha3_DockerClusterSpec(in, out, s)
}
16 changes: 6 additions & 10 deletions test/infrastructure/docker/api/v1alpha3/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions test/infrastructure/docker/api/v1alpha4/conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha4

func (*DockerCluster) Hub() {}
func (*DockerClusterList) Hub() {}
24 changes: 24 additions & 0 deletions test/infrastructure/docker/api/v1alpha4/dockercluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ type DockerClusterSpec struct {
// controllers to do what they will with the defined failure domains.
// +optional
FailureDomains clusterv1.FailureDomains `json:"failureDomains,omitempty"`

// LoadBalancer allows defining configurations for the cluster load balancer.
// +optional
LoadBalancer DockerLoadBalancer `json:"loadBalancer,omitempty"`
}

// DockerLoadBalancer allows defining configurations for the cluster load balancer.
type DockerLoadBalancer struct {
// ImageMeta allows customizing the image used for the cluster load balancer.
ImageMeta `json:",inline"`
}

// ImageMeta allows customizing the image used for components that are not
// originated from the Kubernetes/Kubernetes release process.
type ImageMeta struct {
// ImageRepository sets the container registry to pull the haproxy image from.
// if not set, "kindest" will be used instead.
// +optional
ImageRepository string `json:"imageRepository,omitempty"`

// ImageTag allows to specify a tag for the haproxy image.
// if not set, "v20210715-a6da3463" will be used instead.
// +optional
ImageTag string `json:"imageTag,omitempty"`
}

// DockerClusterStatus defines the observed state of DockerCluster.
Expand Down
32 changes: 32 additions & 0 deletions test/infrastructure/docker/api/v1alpha4/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,19 @@ spec:
will simply copy these into the Status and allow the Cluster API
controllers to do what they will with the defined failure domains.
type: object
loadBalancer:
description: LoadBalancer allows defining configurations for the cluster
load balancer.
properties:
imageRepository:
description: ImageRepository sets the container registry to pull
the haproxy image from. if not set, "kindest" will be used instead.
type: string
imageTag:
description: ImageTag allows to specify a tag for the haproxy
image. if not set, "v20210715-a6da3463" will be used instead.
type: string
type: object
type: object
status:
description: DockerClusterStatus defines the observed state of DockerCluster.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (r *DockerClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reques
log = log.WithValues("cluster", cluster.Name)

// Create a helper for managing a docker container hosting the loadbalancer.
externalLoadBalancer, err := docker.NewLoadBalancer(cluster)
externalLoadBalancer, err := docker.NewLoadBalancer(cluster, dockerCluster)
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to create helper for managing the externalLoadBalancer")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func (r *DockerMachineReconciler) Reconcile(ctx context.Context, req ctrl.Reques
// NB. the machine controller has to manage the cluster load balancer because the current implementation of the
// docker load balancer does not support auto-discovery of control plane nodes, so CAPD should take care of
// updating the cluster load balancer configuration when control plane machines are added/removed
externalLoadBalancer, err := docker.NewLoadBalancer(cluster)
externalLoadBalancer, err := docker.NewLoadBalancer(cluster, dockerCluster)
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to create helper for managing the externalLoadBalancer")
}
Expand Down
29 changes: 27 additions & 2 deletions test/infrastructure/docker/docker/loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/pkg/errors"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
"sigs.k8s.io/cluster-api/test/infrastructure/container"
"sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha4"
"sigs.k8s.io/cluster-api/test/infrastructure/docker/docker/types"
"sigs.k8s.io/cluster-api/test/infrastructure/docker/third_party/forked/loadbalancer"
ctrl "sigs.k8s.io/controller-runtime"
Expand All @@ -37,13 +38,14 @@ type lbCreator interface {
// LoadBalancer manages the load balancer for a specific docker cluster.
type LoadBalancer struct {
name string
image string
container *types.Node
ipFamily clusterv1.ClusterIPFamily
lbCreator lbCreator
}

// NewLoadBalancer returns a new helper for managing a docker loadbalancer with a given name.
func NewLoadBalancer(cluster *clusterv1.Cluster) (*LoadBalancer, error) {
func NewLoadBalancer(cluster *clusterv1.Cluster, dockerCluster *v1alpha4.DockerCluster) (*LoadBalancer, error) {
if cluster.Name == "" {
return nil, errors.New("create load balancer: cluster name is empty")
}
Expand All @@ -65,14 +67,37 @@ func NewLoadBalancer(cluster *clusterv1.Cluster) (*LoadBalancer, error) {
return nil, fmt.Errorf("create load balancer: %s", err)
}

image := getLoadBalancerImage(dockerCluster)

return &LoadBalancer{
name: cluster.Name,
image: image,
container: container,
ipFamily: ipFamily,
lbCreator: &Manager{},
}, nil
}

// getLoadBalancerImage will return the image (e.g. "kindest/haproxy:2.1.1-alpine") to use for
// the load balancer.
func getLoadBalancerImage(dockerCluster *v1alpha4.DockerCluster) string {
// Check if a non-default image was provided
image := loadbalancer.Image
imageRepo := loadbalancer.DefaultImageRepository
imageTag := loadbalancer.DefaultImageTag

if dockerCluster != nil {
if dockerCluster.Spec.LoadBalancer.ImageRepository != "" {
imageRepo = dockerCluster.Spec.LoadBalancer.ImageRepository
}
if dockerCluster.Spec.LoadBalancer.ImageTag != "" {
imageTag = dockerCluster.Spec.LoadBalancer.ImageTag
}
}

return fmt.Sprintf("%s/%s:%s", imageRepo, image, imageTag)
}

// ContainerName is the name of the docker container with the load balancer.
func (s *LoadBalancer) containerName() string {
return fmt.Sprintf("%s-lb", s.name)
Expand All @@ -94,7 +119,7 @@ func (s *LoadBalancer) Create(ctx context.Context) error {
s.container, err = s.lbCreator.CreateExternalLoadBalancerNode(
ctx,
s.containerName(),
loadbalancer.Image,
s.image,
s.name,
listenAddr,
0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ limitations under the License.

package loadbalancer

// Image defines the loadbalancer image:tag
const Image = "kindest/haproxy:v20210715-a6da3463"
// Image defines the loadbalancer image name
const Image = "haproxy"

// DefaultImageRepository defines the loadbalancer image repository
const DefaultImageRepository = "kindest"

// DefaultImageTag defines the loadbalancer image tag
const DefaultImageTag = "v20210715-a6da3463"

// ConfigPath defines the path to the config file in the image
const ConfigPath = "/usr/local/etc/haproxy/haproxy.cfg"

0 comments on commit 7264f91

Please sign in to comment.