Skip to content

Commit 7e83739

Browse files
committed
Raj Singh
Customer Reliability Engineer [email protected]
1 parent cf9978b commit 7e83739

File tree

2 files changed

+199
-1
lines changed

2 files changed

+199
-1
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
title: "Multi-Cluster Kubernetes Setup with Tailscale and ArgoCD"
3+
date: 2025-05-18T12:00:00-05:00
4+
draft: false
5+
tags: ["Kubernetes", "Tailscale", "ArgoCD", "Networking", "DevOps"]
6+
categories: ["Kubernetes"]
7+
---
8+
9+
This guide focuses on configuring the Tailscale Kubernetes operator to expose Kubernetes API servers across multiple clusters for ArgoCD multi-cluster management.
10+
11+
## Prerequisites
12+
13+
- Multiple Kubernetes clusters
14+
- Tailscale account with admin access
15+
- Tailscale Kubernetes operator [installed in each cluster](https://tailscale.com/kb/1185/kubernetes/)
16+
17+
## Configuring Operator Hostname and API Server Proxy
18+
19+
When installing the Tailscale operator in each cluster, set these critical parameters:
20+
21+
```bash
22+
helm upgrade --install tailscale-operator tailscale/tailscale-operator \\
23+
--namespace=tailscale \\
24+
--create-namespace \\
25+
--set-string oauth.clientId=<oauth_client_id> \\
26+
--set-string oauth.clientSecret=<oauth_client_secret> \\
27+
--set operatorConfig.hostname=cluster1-k8s-operator \\
28+
--set apiServerProxyConfig.mode=true \\
29+
--wait
30+
```
31+
32+
Key parameters:
33+
- `operatorConfig.hostname`: Sets a unique hostname for the operator in your tailnet
34+
- `apiServerProxyConfig.mode=true`: Enables Kubernetes API server proxying
35+
36+
Configure each cluster with a unique hostname (e.g., `cluster1-k8s-operator`, `cluster2-k8s-operator`).
37+
38+
## Configure Tailscale ACL Grants for Cross-Cluster Access
39+
40+
For egress proxies to communicate with Kubernetes API servers exposed by the Tailscale operators, you need to configure appropriate ACL grants in your Tailscale admin console.
41+
42+
### Why ACL Grants Are Required
43+
44+
Without proper ACL grants:
45+
1. Access to remote Kubernetes API servers will be blocked by Tailscale\'s access controls
46+
2. ArgoCD will be unable to manage resources across clusters
47+
3. Cross-cluster communication will fail with authentication errors
48+
49+
### Configuring ACL Grants
50+
51+
Add the following to your Tailscale ACL configuration:
52+
53+
```json
54+
"grants": [
55+
{
56+
"src": ["autogroup:admin", "tag:k8s"],
57+
"dst": ["tag:k8s-operator"],
58+
"app": {
59+
"tailscale.com/cap/kubernetes": [
60+
{
61+
"impersonate": {
62+
"groups": ["system:masters"]
63+
},
64+
"recorder": ["tag:k8s-recorder"],
65+
"enforceRecorder": false
66+
}
67+
]
68+
}
69+
}
70+
]
71+
```
72+
73+
Key components of this configuration:
74+
75+
- `"src": ["autogroup:admin", "tag:k8s"]` - Specifies who can access the Kubernetes API. Here, it allows admin users and any node tagged with `tag:k8s` (your ArgoCD cluster)
76+
- `"dst": ["tag:k8s-operator"]` - Specifies which Kubernetes operators can be accessed (targets)
77+
- `"impersonate": {"groups": ["system:masters"]}` - Grants administrative access to the Kubernetes API
78+
- `"recorder": ["tag:k8s-recorder"]` - Optional audit logging configuration
79+
- `"enforceRecorder": false` - Makes audit recording optional
80+
81+
This grant enables ArgoCD (tagged with `tag:k8s`) to communicate with the Kubernetes API servers exposed by the Tailscale operators in your remote clusters.
82+
83+
## Set Up DNS Configuration in ArgoCD Cluster
84+
85+
### Why DNS Configuration is Necessary
86+
87+
DNS configuration is a critical component that enables your ArgoCD cluster to resolve Tailnet domain names. Without this configuration:
88+
89+
1. Your cluster cannot resolve `*.ts.net` domains that Tailscale uses
90+
2. Communication between clusters would fail as hostname resolution would not work
91+
3. ArgoCD would be unable to connect to remote Kubernetes API servers
92+
93+
The Tailscale DNS nameserver provides resolution for all nodes in your Tailnet, enabling seamless cross-cluster communication through Tailscale\'s private network.
94+
95+
### Implementation
96+
97+
Create a DNSConfig resource in the ArgoCD cluster:
98+
99+
```yaml
100+
apiVersion: tailscale.com/v1alpha1
101+
kind: DNSConfig
102+
metadata:
103+
name: ts-dns
104+
spec:
105+
nameserver:
106+
image:
107+
repo: tailscale/k8s-nameserver
108+
tag: unstable
109+
```
110+
111+
Find the nameserver IP:
112+
113+
```bash
114+
kubectl get dnsconfig ts-dns
115+
# Note the NAMESERVERIP (e.g., 10.100.124.196)
116+
```
117+
118+
Update CoreDNS configuration to forward Tailscale domain lookups to the Tailscale nameserver:
119+
120+
```yaml
121+
apiVersion: v1
122+
kind: ConfigMap
123+
metadata:
124+
name: coredns
125+
namespace: kube-system
126+
data:
127+
Corefile: |
128+
.:53 {
129+
# ... existing config ...
130+
}
131+
ts.net {
132+
errors
133+
cache 30
134+
forward . 10.100.124.196
135+
}
136+
```
137+
138+
This configuration tells CoreDNS to forward all `ts.net` domain resolution requests to the Tailscale nameserver, allowing pods in your cluster to resolve Tailnet hostnames.
139+
140+
## Create Egress Services in ArgoCD Cluster
141+
142+
Apply the following configuration to create egress services in the ArgoCD cluster:
143+
144+
```yaml
145+
apiVersion: v1
146+
kind: Service
147+
metadata:
148+
name: cluster1-k8s-operator
149+
annotations:
150+
tailscale.com/tailnet-fqdn: cluster1-k8s-operator.<TAILNET>.ts.net
151+
spec:
152+
externalName: placeholder
153+
type: ExternalName
154+
ports:
155+
- name: https
156+
port: 443
157+
protocol: TCP
158+
---
159+
apiVersion: v1
160+
kind: Service
161+
metadata:
162+
name: cluster2-k8s-operator
163+
annotations:
164+
tailscale.com/tailnet-fqdn: cluster2-k8s-operator.<TAILNET>.ts.net
165+
spec:
166+
externalName: placeholder
167+
type: ExternalName
168+
ports:
169+
- name: https
170+
port: 443
171+
protocol: TCP
172+
```
173+
174+
Replace `<TAILNET>` with your Tailscale tailnet name.
175+
176+
## Access Remote Clusters
177+
178+
Generate the kubeconfig for each cluster:
179+
180+
```bash
181+
tailscale configure kubeconfig cluster1-k8s-operator.<TAILNET>.ts.net
182+
tailscale configure kubeconfig cluster2-k8s-operator.<TAILNET>.ts.net
183+
```
184+
185+
## Add Clusters to ArgoCD
186+
187+
Add the remote clusters to ArgoCD:
188+
189+
```bash
190+
argocd cluster add cluster1-k8s-operator.<TAILNET>.ts.net --grpc-web
191+
argocd cluster add cluster2-k8s-operator.<TAILNET>.ts.net --grpc-web
192+
```
193+
194+
## References
195+
196+
- [Tailscale Kubernetes Operator Documentation](https://tailscale.com/kb/1185/kubernetes/)
197+
- [Cross-cluster Connectivity Guide](https://tailscale.com/kb/1442/kubernetes-operator-cross-cluster)
198+
- [Cluster Egress Configuration](https://tailscale.com/kb/1438/kubernetes-operator-cluster-egress)

content/post/tailscale-operator/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ tags:
1313
- networking
1414
- security
1515
weight: 1
16-
draft: true
16+
draft: false
1717
---
1818

1919
The **Tailscale Kubernetes Operator** enables seamless integration between Kubernetes clusters and Tailscale's secure networking capabilities. In this deep dive, I'll explore how to use the operator to manage Tailscale connectivity in a Kubernetes environment.

0 commit comments

Comments
 (0)