Skip to content

Commit

Permalink
Reconcile KAS endpoints and endpoint slice
Browse files Browse the repository at this point in the history
  • Loading branch information
rtheis committed Apr 24, 2024
1 parent 762dc4d commit b3d7e03
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func generateConfig(p KubeAPIServerConfigParams) *kcpv1.KubeAPIServerConfig {
}
args.Set("enable-aggregator-routing", "true")
args.Set("enable-logs-handler", "false")
args.Set("endpoint-reconciler-type", "lease")
args.Set("endpoint-reconciler-type", "none")
args.Set("etcd-cafile", cpath(kasVolumeEtcdCA().Name, certs.CASignerCertMapKey))
args.Set("etcd-certfile", cpath(kasVolumeEtcdClientCert().Name, pki.EtcdClientCrtKey))
args.Set("etcd-keyfile", cpath(kasVolumeEtcdClientCert().Name, pki.EtcdClientKeyKey))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package kas

import (
"github.com/openshift/hypershift/support/util"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
"k8s.io/utils/ptr"
)

func ReconcileKASEndpoints(endpoints *corev1.Endpoints, address string, port int32) error {
endpoints.Labels = map[string]string{
discoveryv1.LabelSkipMirror: "true",
}
endpoints.Subsets = []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: address,
}},
Ports: []corev1.EndpointPort{{
Name: "https",
Port: port,
Protocol: corev1.ProtocolTCP,
}},
}}
return nil
}

func ReconcileKASEndpointSlice(endpointSlice *discoveryv1.EndpointSlice, address string, port int32) error {
endpointSlice.Labels = map[string]string{
discoveryv1.LabelServiceName: "kubernetes",
}
ipv4, err := util.IsIPv4(address)
if err != nil || ipv4 {
endpointSlice.AddressType = discoveryv1.AddressTypeIPv4
} else {
endpointSlice.AddressType = discoveryv1.AddressTypeIPv6
}
endpointSlice.Endpoints = []discoveryv1.Endpoint{{
Addresses: []string{
address,
},
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
}}
endpointSlice.Ports = []discoveryv1.EndpointPort{{
Name: ptr.To("https"),
Port: ptr.To(port),
Protocol: ptr.To(corev1.ProtocolTCP),
}}
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package manifests

import (
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func KASEndpoints() *corev1.Endpoints {
return &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
Name: "kubernetes",
Namespace: corev1.NamespaceDefault,
},
}
}

func KASEndpointSlice() *discoveryv1.EndpointSlice {
return &discoveryv1.EndpointSlice{
ObjectMeta: metav1.ObjectMeta{
Name: "kubernetes",
Namespace: corev1.NamespaceDefault,
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -49,6 +50,7 @@ import (
ccm "github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/cloudcontrollermanager/azure"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/crd"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/ingress"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/kas"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/konnectivity"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/kubeadminpassword"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/manifests"
Expand Down Expand Up @@ -204,6 +206,7 @@ func Setup(ctx context.Context, opts *operator.HostedClusterConfigOperatorConfig
&prometheusoperatorv1.PrometheusRule{},
&operatorv1.IngressController{},
&imageregistryv1.Config{},
&discoveryv1.EndpointSlice{},
}
for _, r := range resourcesToWatch {
if err := c.Watch(source.Kind(opts.Manager.GetCache(), r), eventHandler()); err != nil {
Expand Down Expand Up @@ -275,6 +278,16 @@ func (r *reconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result
}); err != nil {
errs = append(errs, fmt.Errorf("failed to reconcile kubernetes.default endpoints: %w", err))
}
} else {
// Clusters with "none" as their Kubernetes API server endpoint reconciliation
// type must manually manage the Kubernetes endpoints and endpointslice resources.
// Due to recent Kubernetes changes, we need to reconcile these resources to avoid
// problems such as [1].
// [1] https://github.com/kubernetes/kubernetes/issues/118777
log.Info("reconciling kubernetes.default endpoints and endpointslice")
if err := r.reconcileKASEndpoints(ctx, hcp); err != nil {
errs = append(errs, fmt.Errorf("failed to reconcile kubernetes.default endpoints and endpointslice: %w", err))
}
}

log.Info("reconciling install configmap")
Expand Down Expand Up @@ -1134,6 +1147,25 @@ func (r *reconciler) reconcileOpenshiftOAuthAPIServerAPIServices(ctx context.Con
return errors.NewAggregate(errs)
}

func (r *reconciler) reconcileKASEndpoints(ctx context.Context, hcp *hyperv1.HostedControlPlane) error {
var errs []error
kasAdvertiseAddress := util.GetAdvertiseAddress(hcp, config.DefaultAdvertiseIPv4Address, config.DefaultAdvertiseIPv6Address)
kasPort := util.KASPodPort(hcp)
kasEndpoints := manifests.KASEndpoints()
if _, err := r.CreateOrUpdate(ctx, r.client, kasEndpoints, func() error {
return kas.ReconcileKASEndpoints(kasEndpoints, kasAdvertiseAddress, kasPort)
}); err != nil {
errs = append(errs, fmt.Errorf("failed to reconcile kubernetes.default endpoints: %w", err))
}
kasEndpointSlice := manifests.KASEndpointSlice()
if _, err := r.CreateOrUpdate(ctx, r.client, kasEndpointSlice, func() error {
return kas.ReconcileKASEndpointSlice(kasEndpointSlice, kasAdvertiseAddress, kasPort)
}); err != nil {
errs = append(errs, fmt.Errorf("failed to reconcile kubernetes.default endpoint slice: %w", err))
}
return errors.NewAggregate(errs)
}

func (r *reconciler) reconcileOpenshiftAPIServerEndpoints(ctx context.Context, hcp *hyperv1.HostedControlPlane) error {
cpService := manifests.OpenShiftAPIServerService(hcp.Namespace)
if err := r.cpClient.Get(ctx, client.ObjectKeyFromObject(cpService), cpService); err != nil {
Expand Down

0 comments on commit b3d7e03

Please sign in to comment.