-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/{k8s-operator,k8s-nameserver},k8s-operator: update nameserver config with records for ingress/egress proxies #11019
Conversation
15ec9ad
to
741167e
Compare
return svc != nil && svc.Annotations[AnnotationExpose] == "true" | ||
} | ||
|
||
// hasTailnetTargetAnnotation returns the value of tailscale.com/tailnet-ip | ||
// annotation or of the deprecated tailscale.com/ts-tailnet-target-ip | ||
// annotation. If neither is set, it returns an empty string. If both are set, | ||
// it returns the value of the new annotation. | ||
func (a *ServiceReconciler) tailnetTargetAnnotation(svc *corev1.Service) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes make these functions re-usable for dns-records reconciler.
e2b89bb
to
caf7cdb
Compare
a6ff826
to
703e7af
Compare
256cc93
to
58766a6
Compare
nameserver: | ||
image: | ||
repo: gcr.io/csi-test-290908/nameserver | ||
tag: v0.0.1ns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add functionality to actually push the nameserver image in a follow-up PR
cmd/k8s-operator/dnsrecords.go
Outdated
// The records that it creates are: | ||
// - For tailscale Ingress, a mapping of the Ingress's MagicDNSName to the IP address of | ||
// the ingress proxy Pod. | ||
// - For egress proxies configured via tailscale.com/tailnet-fqdn annotation, a | ||
// mapping of the the tailnet FQDN to the IP address of the egress proxy Pod. | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially I was creating records for all proxy types. However, the L3 ingress proxies don't route cluster traffic to the backend. Also no-one has asked for this functionality for cluster ingress proxies and with regards to the egress proxies, it seems good enough to only implement it for the ones configured via tailscale.com/tailnet-fqdn
annotation and not tailscale.com/tailnet-ip
. We can always add more functionality later.
58766a6
to
e2fd26a
Compare
// egress configured via tailscale.com/tailnet-fqdn annotation. | ||
// | ||
// For Ingress, the record is a mapping between the MagicDNSName of the Ingress, retrieved from | ||
// ingress.status.loadBalancer.ingress.hostname field and the proxy Pod IP addresses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently always a single IP address
1567e91
to
7c266d6
Compare
ips := make([]string, 0) | ||
for _, ep := range eps.Endpoints { | ||
for _, ip := range ips { | ||
if !net.IsIPv4String(ip) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add IPv6 support in a follow-up. At the moment the nameserver only responds to queries for A records.
be183ff
to
dd28a4a
Compare
What's the status of this? did this PR get abandoned in favor of a different approach? |
Hi @Scalahansolo , it's not abandoned, just that we're a bit low bandwidth right now. The current plan is still to get it in. |
dd28a4a
to
615f714
Compare
…ords for proxies. This commit adds functionality to automatically populate DNS records for the in-cluster ts.net nameserver to allow cluster workloads to resolve MagicDNS names associated with operator's proxies. The records are created as follows: * For tailscale Ingress proxies there will be a record mapping the MagicDNS name of the Ingress device and each proxy Pod's IP address. * For cluster egress proxies, configured via tailscale.com/tailnet-fqdn annotation, there will be a record for each proxy Pod, mapping the MagicDNS name of the exposed tailnet workload to the proxy Pod's IP. No records will be created for any other proxy types. Records will only be created if users have configured the operator to deploy an in-cluster ts.net nameserver by applying tailscale.com/v1alpha1.DNSConfig. It is user's responsibility to add the ts.net nameserver as a stub nameserver for ts.net DNS names. https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configuration-of-stub-domain-and-upstream-nameserver-using-coredns https://cloud.google.com/kubernetes-engine/docs/how-to/kube-dns#upstream_nameservers See also #11017 Updates #10499 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
615f714
to
3f8e137
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM, though I'm not familiar with the K8s APIs being used.
I left a few comments/questions.
61e1240
to
4b77860
Compare
@@ -60,7 +60,7 @@ type DNSConfigStatus struct { | |||
// +optional | |||
Conditions []ConnectorCondition `json:"conditions"` | |||
// +optional | |||
NameserverStatus *NameserverStatus `json:"nameserverStatus"` | |||
Nameserver *NameserverStatus `json:"nameserver"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated this to not have dnsconfig.status.nameserverStatus
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
4b77860
to
0bfaaa5
Compare
Updates #11019 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Updates #11019 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
…NSConfig description Also removes hardcoded image repo/tag from example DNSConfig resource as the operator now knows how to default those. Updates #11019 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
…NSConfig description Also removes hardcoded image repo/tag from example DNSConfig resource as the operator now knows how to default those. Updates #11019 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
…NSConfig description Also removes hardcoded image repo/tag from example DNSConfig resource as the operator now knows how to default those. Updates #11019 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
…NSConfig description Also removes hardcoded image repo/tag from example DNSConfig resource as the operator now knows how to default those. Updates #11019 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
…NSConfig description Also removes hardcoded image repo/tag from example DNSConfig resource as the operator now knows how to default those. Updates #11019 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This PR adds functionality to the operator to optionally populate DNS records config for the in-cluster ts.net nameserver (added in #11017) with records for cluster proxies' MagicDNS names:
For Tailscale Ingress the record is a mapping between
Ingress
s MagicDNS name and the proxy's Pod IPFor cluster egress proxies configured via
tailscale.com/tailnet-fqdn
annotation the record is a mapping between the annotation's value and the proxy's Pod IPNo records are currently created for any other proxy types.
The records are created only if there is a ready
tailscale.com/v1alpha1.DNSConfig
instance in the cluster (see #11017 ) i.e if users have explicitly configured the operator to deploy the in-cluster ts.net nameserver.Below see the user flow for a setup where:
cluster A uses kube-dns.
Ingress
. They can do it by exposing theIngress
to their cluster (see cross-cluster connectivity). Because A's Service is exposed over HTTPS, they need to use the MagicDNS name of theIngress
(so it needs to resolve within the cluster). See a use case.cluster B uses CoreDNS.
DNSConfig
to tell the operator to deploy an in-cluster ts.net nameserver, i.e$ kubectl apply -f ./cmd/k8s-operator/examples/dnsconfig.yaml
kube-dns
ConfigMap to tell kube-dns to use the ts.net nameserver to resolvets.net
DNS names$ k get dnsconfig NAME NAMESERVERIP ts-dns 10.27.1.90 $ kubectl get cm kube-dns -n kube-system -oyaml apiVersion: v1 data: stubDomains: | { "ts.net": ["10.27.1.90"] } kind: ConfigMap metadata: name: kube-dns namespace: kube-system ...
Ingress
.Note the use of
tailscale.com/experimental-forward-cluster-traffic-via-ingress
annotation- this makes the ingress proxy to listen on the Pod's IP address which it does not do by default.apiVersion: apps/v1 kind: Deployment metadata: name: kuardfoobar spec: selector: matchLabels: app: kuardfoobar template: metadata: labels: app: kuardfoobar spec: containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuardfoobar ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: kuardfoobar spec: ports: - port: 80 targetPort: 8080 type: ClusterIP selector: app: kuardfoobar --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: kuardfoobar annotations: tailscale.com/experimental-forward-cluster-traffic-via-ingress: "true" spec: tls: - hosts: - "dnstest" rules: - http: paths: - backend: service: name: kuardfoobar port: number: 80 pathType: Prefix path: / ingressClassName: tailscale
Ingress
and that the workload can be accessed over that from a non-tailscalePod
in cluster:$ kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE kuardfoobar tailscale * dnstest-3.tailbd97a.ts.net 80, 443 64m $ kubectl exec -it somepod -- sh / # curl -vvv https://dnstest-3.tailbd97a.ts.net * Host dnstest-3.tailbd97a.ts.net:443 was resolved. * IPv6: (none) * IPv4: 10.0.0.6 * Trying 10.0.0.6:443... * Connected to dnstest-3.tailbd97a.ts.net (10.0.0.6) port 443 ....
In cluster B:
DNSConfig
to tell the operator to deploy an in-cluster ts.net nameserver, i.e$ kubectl apply -f ./cmd/k8s-operator/examples/dnsconfig.yaml
$ kubectl get dnsconfig NAME NAMESERVERIP ts-dns 10.100.198.212 $ kubectl get cm coredns -n kube-system -oyaml apiVersion: v1 data: Corefile: | ts.net { cache 5 errors forward . 10.100.198.212 } .:53 { } kind: ConfigMap metadata: name: coredns namespace: kube-system
tailscale.com/tailnet-fqdn
annotation pointing at theIngress
in cluster A:kind: Service metadata: annotations: tailscale.com/tailnet-fqdn: dnstest-3.tailbd97a.ts.net name: kuard-egress spec: type: ExternalName
Ingress
in cluster A from a non-tailscalePod
in cluster B:$ kubectl exec -it sompod -- sh # curl -vvv https://dnstest-3.tailbd97a.ts.net * Host dnstest-3.tailbd97a.ts.net:443 was resolved. * IPv6: (none) * IPv4: 172.31.24.228 * Trying 172.31.24.228:443... * Connected to dnstest-3.tailbd97a.ts.net (172.31.24.228) port 443 ...
Notes:
Ingress
resource withtailscale.com/experimental-forward-cluster-traffic-via-ingress
annotation, seecmd/{containerboot,k8s-operator/deploy/manifests}: optionally allow proxying cluster traffic to a cluster target via ingress proxy #11036
Pod
in a cluster configured with our nameserver, still use 100.100.100.100 to resolve tailnet DNS names. Operator configured proxies do not accept Tailscale DNS, so they would use the ts.net nameserver. I cannot think of cases where this would be an issue (because they don't need to talk to anything on tailnet via MagicDNS)cc @jaxxstorm
Next steps: