1
1
# k8s-multicluster-gitops
2
2
3
- Infrastructure as Code for provisioning multiple Kubernetes clusters, managed
4
- using GitOps with ArgoCD
3
+ Infrastructure as Code (IaC) for provisioning and managing multiple Kubernetes
4
+ clusters across multiple cloud accounts, using GitOps principles with ArgoCD.
5
5
6
- Create all "kind" clusters:
6
+ ## Requirements
7
+
8
+ Guides on setting up Kubernetes clusters in the cloud are common, but few cover
9
+ managing clusters across multiple providers and accounts (a key need for large
10
+ enterprises)
11
+
12
+ This project aims to provide a practical example:
13
+
14
+ - ✅ Provisioning and managing Kubernetes clusters across multiple cloud
15
+ providers (AWS, Azure, GCP).
16
+ - ✅ Deploying and maintaining Kubernetes clusters across multiple accounts and
17
+ regions.
18
+
19
+ ## Architecture
20
+
21
+ You likely need to deploy multiple Kubernetes clusters across various cloud
22
+ providers and accounts.
23
+
24
+ Each cloud provider has a designated "primary account" where subdomains are hosted:
25
+
26
+ - ` aws.mylabs.dev ` - AWS
27
+ - ` az.mylabs.dev ` - Azure
28
+ - ` gcp.mylabs.dev ` - Google Cloud Platform
29
+
30
+ > The second-level domain ` mylabs.dev ` is hosted externally (e.g., Cloudflare),
31
+ > and it's the user's responsibility to configure DNS delegation properly.
32
+
33
+ An IAM role (or the equivalent for each cloud provider) will be created in the
34
+ primary account. This role will allow GitHub Actions / mise to manage resources
35
+ in the primary account and will also be used to access other accounts where
36
+ Kubernetes clusters are deployed.
37
+
38
+ ## Cloud Providers - Multi-Account Setup
39
+
40
+ Let's assume you have 2 AWS accounts, 2 Azure accounts, 2 GCP accounts and you
41
+ want to deploy 2 Kubernetes clusters (EKS, AKS, GKE) in each account:
42
+
43
+ | Cloud Provider | Account 01 | Account 02 |
44
+ | --------------------------------------------------| --------------------------------------------------------------| --------------------------------------------------------------|
45
+ | ** AWS** (` aws.mylabs.dev ` , ` k8s.aws.mylabs.dev ` ) | ` k01.k8s.aws.mylabs.dev ` (US), ` k02.k8s.aws.mylabs.dev ` (EU) | ` k03.k8s.aws.mylabs.dev ` (US), ` k04.k8s.aws.mylabs.dev ` (EU) |
46
+ | ** Azure** (` az.mylabs.dev ` , ` k8s.az.mylabs.dev ` ) | ` k01.k8s.az.mylabs.dev ` (US), ` k02.k8s.az.mylabs.dev ` (EU) | ` k03.k8s.az.mylabs.dev ` (US), ` k04.k8s.az.mylabs.dev ` (EU) |
47
+ | ** GCP** (` gcp.mylabs.dev ` , ` k8s.gcp.mylabs.dev ` ) | ` k01.k8s.gcp.mylabs.dev ` (US), ` k02.k8s.gcp.mylabs.dev ` (EU) | ` k03.k8s.gcp.mylabs.dev ` (US), ` k04.k8s.gcp.mylabs.dev ` (EU) |
48
+
49
+ ### AWS
50
+
51
+ #### Primary account
52
+
53
+ Choose one of your AWS accounts to act as the ** primary account** and create a
54
+ Route 53 hosted zone for ` aws.mylabs.dev `
55
+
56
+ > Ensure that the necessary environment variables are set for the AWS CLI
57
+ > (e.g., ` AWS_ACCESS_KEY_ID ` , ` AWS_SECRET_ACCESS_KEY ` ).
58
+
59
+ ``` bash
60
+ mise run create:aws-primary:cf-route53-gh-action-iam-role-oidc
61
+ ```
62
+
63
+ > For more details please inspect the [ mise.toml] ( ./mise.toml ) file.
64
+
65
+ Next, manually set up the DNS delegation between your second-level domain
66
+ ` mylabs.dev ` and the ` aws.mylabs.dev ` hosted zone in Route 53.
67
+
68
+ Example:
69
+
70
+ ![ Cloudflare DNS records for mylabs.dev] ( images/cloudflare-mylabs-dev-dns-records.avif )
71
+
72
+ #### Tenant Accounts
73
+
74
+ Create an IAM role in each tenant account that allows the primary account to
75
+ assume a role in the tenant account.
76
+
77
+ > Make sure to use AWS credentials (` AWS_ACCESS_KEY_ID ` ,
78
+ > ` AWS_SECRET_ACCESS_KEY ` ) for the tenant account.
79
+
80
+ ``` bash
81
+ mise run create:aws-tenant:cf-iam-role
82
+ ```
83
+
84
+ ### Azure
85
+
86
+ ### GCP
87
+
88
+ ## K8s Clusters
89
+
90
+ All the "kubeconfig files" will be stored in the ` clusters/.kubeconfigs `
91
+ directory.
92
+
93
+ ### Kind
94
+
95
+ The [ kind clusters] ( https://kind.sigs.k8s.io/ ) are created using the ` kind `
96
+ tool, which is a tool for running Kubernetes clusters in Docker containers.
7
97
8
98
``` bash
9
- mise task run " create:kind:*"
10
- mise task run " delete:kind:*"
99
+ mise run create:kind:kind01-internal
100
+ mise run delete:kind:kind01-internal
101
+ mise run create:kind:kind02-internal
102
+ mise run delete:kind:kind02-internal
103
+ mise run create-kind-all
104
+ mise run delete-kind-all
11
105
```
12
106
13
- Create all "k3d" clusters:
107
+ ### K3d
108
+
109
+ The [ k3d clusters] ( https://k3d.io/ ) are created using the ` k3d ` tool, which
110
+ is a lightweight wrapper to run ` k3s ` in Docker containers.
14
111
15
112
``` bash
16
- mise task run " create:k3d:*"
17
- mise task run " delete:k3d:*"
113
+ mise run create:k3d:k3d01-internal
114
+ mise run delete:k3d:k3d01-internal
115
+ mise run create:k3d:k3d02-internal
116
+ mise run delete:k3d:k3d02-internal
117
+ mise run create-k3d-all
118
+ mise run delete-k3d-all
18
119
```
19
120
20
- > Same for eksctl, az, terraform-aws, terraform-az, ... clusters
121
+ > You can also create all the clusters at once using the ` create-all ` and
122
+ > ` delete-all ` commands:
123
+ >
124
+ > ``` bash
125
+ > mise run " create-kind-all" ::: " create-k3d-all"
126
+ > mise run " delete-kind-all" ::: " delete-k3d-all"
127
+ > ` ` `
21
128
22
129
# # Architecture diagrams
23
130
@@ -34,10 +141,6 @@ flowchart TB
34
141
aws.mylabs.dev@{ icon: " logos:aws-route53" , form: " circle" , label: " aws.mylabs.dev" , pos: " b" , h: 60 }
35
142
k8s.aws.mylabs.dev@{ icon: " logos:aws-route53" , form: " square" , label: " k8s.aws.mylabs.dev" , pos: " b" , h: 60 }
36
143
end
37
- subgraph "AWS Account 03"
38
- k05.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k05.k8s.aws.mylabs.dev", pos: "b", h: 60 }
39
- k06.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k06.k8s.aws.mylabs.dev", pos: "b", h: 60 }
40
- end
41
144
subgraph " AWS Account 02"
42
145
k03.k8s.aws.mylabs.dev@{ icon: " logos:aws-route53" , form: " square" , label: " k03.k8s.aws.mylabs.dev" , pos: " b" , h: 60 }
43
146
k04.k8s.aws.mylabs.dev@{ icon: " logos:aws-route53" , form: " square" , label: " k04.k8s.aws.mylabs.dev" , pos: " b" , h: 60 }
@@ -53,10 +156,6 @@ flowchart TB
53
156
az.mylabs.dev@{ icon: " logos:azure-icon" , form: " circle" , label: " az.mylabs.dev" , pos: " b" , h: 60 }
54
157
k8s.az.mylabs.dev@{ icon: " logos:azure-icon" , form: " square" , label: " k8s.az.mylabs.dev" , pos: " b" , h: 60 }
55
158
end
56
- subgraph "Azure Account 03"
57
- k05.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k05.k8s.az.mylabs.dev", pos: "b", h: 60 }
58
- k06.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k06.k8s.az.mylabs.dev", pos: "b", h: 60 }
59
- end
60
159
subgraph " Azure Account 02"
61
160
k03.k8s.az.mylabs.dev@{ icon: " logos:azure-icon" , form: " square" , label: " k03.k8s.az.mylabs.dev" , pos: " b" , h: 60 }
62
161
k04.k8s.az.mylabs.dev@{ icon: " logos:azure-icon" , form: " square" , label: " k04.k8s.az.mylabs.dev" , pos: " b" , h: 60 }
@@ -72,10 +171,6 @@ flowchart TB
72
171
gcp.mylabs.dev@{ icon: " logos:google-cloud" , form: " circle" , label: " gcp.mylabs.dev" , pos: " b" , h: 60 }
73
172
k8s.gcp.mylabs.dev@{ icon: " logos:google-cloud" , form: " square" , label: " k8s.gcp.mylabs.dev" , pos: " b" , h: 60 }
74
173
end
75
- subgraph "GCP Account 03"
76
- k05.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k05.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
77
- k06.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k06.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
78
- end
79
174
subgraph " GCP Account 02"
80
175
k03.k8s.gcp.mylabs.dev@{ icon: " logos:google-cloud" , form: " square" , label: " k03.k8s.gcp.mylabs.dev" , pos: " b" , h: 60 }
81
176
k04.k8s.gcp.mylabs.dev@{ icon: " logos:google-cloud" , form: " square" , label: " k04.k8s.gcp.mylabs.dev" , pos: " b" , h: 60 }
@@ -92,28 +187,20 @@ flowchart TB
92
187
k8s.aws.mylabs.dev --> k02.k8s.aws.mylabs.dev
93
188
k8s.aws.mylabs.dev --> k03.k8s.aws.mylabs.dev
94
189
k8s.aws.mylabs.dev --> k04.k8s.aws.mylabs.dev
95
- k8s.aws.mylabs.dev --> k05.k8s.aws.mylabs.dev
96
- k8s.aws.mylabs.dev --> k06.k8s.aws.mylabs.dev
97
190
mylabs.dev --> az.mylabs.dev
98
191
az.mylabs.dev --> k8s.az.mylabs.dev
99
192
k8s.az.mylabs.dev --> k01.k8s.az.mylabs.dev
100
193
k8s.az.mylabs.dev --> k02.k8s.az.mylabs.dev
101
194
k8s.az.mylabs.dev --> k03.k8s.az.mylabs.dev
102
195
k8s.az.mylabs.dev --> k04.k8s.az.mylabs.dev
103
- k8s.az.mylabs.dev --> k05.k8s.az.mylabs.dev
104
- k8s.az.mylabs.dev --> k06.k8s.az.mylabs.dev
105
196
mylabs.dev --> gcp.mylabs.dev
106
197
gcp.mylabs.dev --> k8s.gcp.mylabs.dev
107
198
k8s.gcp.mylabs.dev --> k01.k8s.gcp.mylabs.dev
108
199
k8s.gcp.mylabs.dev --> k02.k8s.gcp.mylabs.dev
109
200
k8s.gcp.mylabs.dev --> k03.k8s.gcp.mylabs.dev
110
201
k8s.gcp.mylabs.dev --> k04.k8s.gcp.mylabs.dev
111
- k8s.gcp.mylabs.dev --> k05.k8s.gcp.mylabs.dev
112
- k8s.gcp.mylabs.dev --> k06.k8s.gcp.mylabs.dev
113
202
```
114
203
115
- ---
116
-
117
204
## Tests
118
205
119
206
``` bash
0 commit comments