kube/certs: discover TLS domains from TCP TerminateTLS handlers (#19020)

After #18179 switched to L4 TCPForward, EnsureCertLoops found no
domains since it only checked service.Web entries. Certs were never
provisioned, leaving kube-apiserver ProxyGroups stuck at 0/N ready.

Fixes #19019

Signed-off-by: Raj Singh <raj@tailscale.com>
main
Raj Singh 1 month ago committed by GitHub
parent b3c6184f9f
commit a565833998
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 7
      kube/certs/certs.go
  2. 38
      kube/certs/certs_test.go

@ -53,6 +53,7 @@ func (cm *CertManager) EnsureCertLoops(ctx context.Context, sc *ipn.ServeConfig)
currentDomains := make(map[string]bool) currentDomains := make(map[string]bool)
const httpsPort = "443" const httpsPort = "443"
for _, service := range sc.Services { for _, service := range sc.Services {
// L7 Web handlers (HA Ingress).
for hostPort := range service.Web { for hostPort := range service.Web {
domain, port, err := net.SplitHostPort(string(hostPort)) domain, port, err := net.SplitHostPort(string(hostPort))
if err != nil { if err != nil {
@ -63,6 +64,12 @@ func (cm *CertManager) EnsureCertLoops(ctx context.Context, sc *ipn.ServeConfig)
} }
currentDomains[domain] = true currentDomains[domain] = true
} }
// L4 TCP handlers with TLS termination (kube-apiserver proxy).
for _, handler := range service.TCP {
if handler != nil && handler.TerminateTLS != "" {
currentDomains[handler.TerminateTLS] = true
}
}
} }
cm.mu.Lock() cm.mu.Lock()
defer cm.mu.Unlock() defer cm.mu.Unlock()

@ -127,6 +127,43 @@ func TestEnsureCertLoops(t *testing.T) {
initialGoroutines: 2, // initially two loops (one per service) initialGoroutines: 2, // initially two loops (one per service)
updatedGoroutines: 1, // one loop after removing service2 updatedGoroutines: 1, // one loop after removing service2
}, },
{
name: "tcp_terminate_tls",
initialConfig: &ipn.ServeConfig{
Services: map[tailcfg.ServiceName]*ipn.ServiceConfig{
"svc:my-apiserver": {
TCP: map[uint16]*ipn.TCPPortHandler{
443: {
TCPForward: "localhost:80",
TerminateTLS: "my-apiserver.tailnetxyz.ts.net",
},
},
},
},
},
initialGoroutines: 1,
},
{
name: "tcp_terminate_tls_and_web",
initialConfig: &ipn.ServeConfig{
Services: map[tailcfg.ServiceName]*ipn.ServiceConfig{
"svc:my-apiserver": {
TCP: map[uint16]*ipn.TCPPortHandler{
443: {
TCPForward: "localhost:80",
TerminateTLS: "my-apiserver.tailnetxyz.ts.net",
},
},
},
"svc:my-app": {
Web: map[ipn.HostPort]*ipn.WebServerConfig{
"my-app.tailnetxyz.ts.net:443": {},
},
},
},
},
initialGoroutines: 2,
},
{ {
name: "add_domain", name: "add_domain",
initialConfig: &ipn.ServeConfig{ initialConfig: &ipn.ServeConfig{
@ -171,6 +208,7 @@ func TestEnsureCertLoops(t *testing.T) {
CertDomains: []string{ CertDomains: []string{
"my-app.tailnetxyz.ts.net", "my-app.tailnetxyz.ts.net",
"my-other-app.tailnetxyz.ts.net", "my-other-app.tailnetxyz.ts.net",
"my-apiserver.tailnetxyz.ts.net",
}, },
}, },
}, },

Loading…
Cancel
Save