diff --git a/pkg/controller/installation/core_controller.go b/pkg/controller/installation/core_controller.go index ebce8b40f4..a018c16364 100644 --- a/pkg/controller/installation/core_controller.go +++ b/pkg/controller/installation/core_controller.go @@ -1410,13 +1410,14 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile // Build a configuration for rendering calico/typha. typhaCfg := render.TyphaConfiguration{ - K8sServiceEp: k8sapi.Endpoint, - Installation: &instance.Spec, - TLS: typhaNodeTLS, - MigrateNamespaces: needsNamespaceMigration, - ClusterDomain: r.clusterDomain, - NonClusterHost: nonclusterhost, - FelixHealthPort: *felixConfiguration.Spec.HealthPort, + K8sServiceEp: k8sapi.Endpoint, + K8sServiceEpPodNetwork: k8sapi.PodNetworkEndpoint, + Installation: &instance.Spec, + TLS: typhaNodeTLS, + MigrateNamespaces: needsNamespaceMigration, + ClusterDomain: r.clusterDomain, + NonClusterHost: nonclusterhost, + FelixHealthPort: *felixConfiguration.Spec.HealthPort, } components = append(components, render.Typha(&typhaCfg)) diff --git a/pkg/render/typha.go b/pkg/render/typha.go index b2be1eab52..0e33dff85c 100644 --- a/pkg/render/typha.go +++ b/pkg/render/typha.go @@ -69,7 +69,12 @@ var ( // TyphaConfiguration is the public API used to provide information to the render code to // generate Kubernetes objects for installing calico/typha on a cluster. type TyphaConfiguration struct { - K8sServiceEp k8sapi.ServiceEndpoint + K8sServiceEp k8sapi.ServiceEndpoint + + // K8sServiceEpPodNetwork is used for pod-networked Typha (i.e. the non-cluster-host + // deployment), where K8sServiceEp may be unreachable from pods. + K8sServiceEpPodNetwork k8sapi.ServiceEndpoint + Installation *operatorv1.InstallationSpec TLS *TyphaNodeTLS MigrateNamespaces bool @@ -675,6 +680,13 @@ func (c *typhaComponent) typhaEnvVarsNonClusterHost() []corev1.EnvVar { envVars = replaceOrAppendEnvVar(envVars, "TYPHA_CLIENTCN", c.cfg.TLS.NodeNonClusterHostCommonName) envVars = replaceOrAppendEnvVar(envVars, "TYPHA_CLIENTURISAN", c.cfg.TLS.NodeNonClusterHostURISAN) + // NCH Typha runs pod-networked, so the host-network apiserver endpoint + // (e.g. MKE's proxy.local) may not be reachable. + if podEp := c.cfg.K8sServiceEpPodNetwork; podEp.Host != "" && podEp.Port != "" { + envVars = replaceOrAppendEnvVar(envVars, "KUBERNETES_SERVICE_HOST", podEp.Host) + envVars = replaceOrAppendEnvVar(envVars, "KUBERNETES_SERVICE_PORT", podEp.Port) + } + // Tell the health aggregator to listen on all interfaces. envVars = append(envVars, corev1.EnvVar{Name: "TYPHA_HEALTHHOST", Value: "0.0.0.0"}) return envVars diff --git a/pkg/render/typha_test.go b/pkg/render/typha_test.go index cff8537dfd..e498da8336 100644 --- a/pkg/render/typha_test.go +++ b/pkg/render/typha_test.go @@ -217,6 +217,27 @@ var _ = Describe("Typha rendering tests", func() { Expect(d.Spec.Template.Spec.Containers[0].ReadinessProbe.ProbeHandler.HTTPGet.Host).To(BeEmpty()) }) + It("should override KUBERNETES_SERVICE_HOST/PORT on the non-cluster-host Typha when a pod-network endpoint is configured", func() { + cfg.K8sServiceEp = k8sapi.ServiceEndpoint{Host: "proxy.local", Port: "6444"} + cfg.K8sServiceEpPodNetwork = k8sapi.ServiceEndpoint{Host: "10.96.0.1", Port: "443"} + + component := render.Typha(&cfg) + resources, _ := component.Objects() + + d := rtest.GetResource(resources, "calico-typha-noncluster-host", "calico-system", "apps", "v1", "Deployment").(*appsv1.Deployment) + Expect(d.Spec.Template.Spec.Containers[0].Env).To(ContainElements( + corev1.EnvVar{Name: "KUBERNETES_SERVICE_HOST", Value: "10.96.0.1"}, + corev1.EnvVar{Name: "KUBERNETES_SERVICE_PORT", Value: "443"}, + )) + + // The host-networked Typha should still use the host-network endpoint. + dMain := rtest.GetResource(resources, "calico-typha", "calico-system", "apps", "v1", "Deployment").(*appsv1.Deployment) + Expect(dMain.Spec.Template.Spec.Containers[0].Env).To(ContainElements( + corev1.EnvVar{Name: "KUBERNETES_SERVICE_HOST", Value: "proxy.local"}, + corev1.EnvVar{Name: "KUBERNETES_SERVICE_PORT", Value: "6444"}, + )) + }) + It("should use custom client common name when specified for non-cluster host Typha deployment", func() { cfg.TLS.NodeNonClusterHostCommonName = "custom-nch-cn" component := render.Typha(&cfg)