Skip to content

Commit 05a6f78

Browse files
authored
Merge pull request #45 from FourFifthsCode/kubeconfig-based-provider
🌱 Kubeconfig-Based Provider
2 parents 24b5565 + 6d4cb6f commit 05a6f78

File tree

9 files changed

+1819
-0
lines changed

9 files changed

+1819
-0
lines changed

examples/kubeconfig/README.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Kubeconfig Provider Example
2+
3+
This example demonstrates how to use the kubeconfig provider to manage multiple Kubernetes clusters using kubeconfig secrets.
4+
5+
## Overview
6+
7+
The kubeconfig provider allows you to:
8+
1. Discover and connect to multiple Kubernetes clusters using kubeconfig secrets
9+
2. Run controllers that can operate across all discovered clusters
10+
3. Manage cluster access through RBAC rules and service accounts
11+
12+
## Directory Structure
13+
14+
```
15+
examples/kubeconfig/
16+
├── scripts/ # Utility scripts
17+
│ ├── create-kubeconfig-secret.sh
18+
│ └── rules.yaml # Default RBAC rules template
19+
└── main.go # Example operator implementation
20+
```
21+
22+
## Usage
23+
24+
### 1. Setting Up Cluster Access
25+
26+
Before creating a kubeconfig secret, ensure that:
27+
1. The remote cluster has a service account with the necessary RBAC permissions for your operator
28+
2. The service account exists in the namespace where you want to create the kubeconfig secret
29+
30+
Use the `create-kubeconfig-secret.sh` script to create a kubeconfig secret for each cluster you want to manage:
31+
32+
```bash
33+
./scripts/create-kubeconfig-secret.sh \
34+
--name cluster1 \
35+
-n default \
36+
-c prod-cluster \
37+
-a my-service-account
38+
```
39+
40+
The script will:
41+
- Use the specified service account from the remote cluster
42+
- Generate a kubeconfig using the service account's token
43+
- Store the kubeconfig in a secret in your local cluster
44+
- Automatically create RBAC resources (Role/ClusterRole and bindings) with permissions defined in `rules.yaml`
45+
46+
#### Command Line Options
47+
48+
- `-c, --context`: Kubeconfig context to use (required)
49+
- `--name`: Name for the secret (defaults to context name)
50+
- `-n, --namespace`: Namespace to create the secret in (default: "default")
51+
- `-a, --service-account`: Service account name to use from the remote cluster (default: "multicluster-kubeconfig-provider")
52+
- `-t, --role-type`: Create Role or ClusterRole (`role`|`clusterrole`) (default: "clusterrole")
53+
- `-r, --rules-file`: Path to custom rules file (default: `rules.yaml` in script directory)
54+
- `--skip-create-rbac`: Skip creating RBAC resources (Role/ClusterRole and bindings)
55+
- `-h, --help`: Show help message
56+
57+
#### Examples
58+
59+
```bash
60+
# Basic usage with default settings
61+
./scripts/create-kubeconfig-secret.sh -c prod-cluster
62+
63+
# Create namespace-scoped Role instead of ClusterRole
64+
./scripts/create-kubeconfig-secret.sh -c prod-cluster -t role
65+
66+
# Use custom RBAC rules file
67+
./scripts/create-kubeconfig-secret.sh -c prod-cluster -r ./custom-rules.yaml
68+
69+
# Skip RBAC creation (manual RBAC setup)
70+
./scripts/create-kubeconfig-secret.sh -c prod-cluster --skip-create-rbac
71+
72+
# Full example with all options
73+
./scripts/create-kubeconfig-secret.sh \
74+
--name my-cluster \
75+
-n my-namespace \
76+
-c prod-cluster \
77+
-a my-service-account \
78+
-t clusterrole \
79+
-r ./my-rules.yaml
80+
```
81+
82+
### 2. RBAC Configuration
83+
84+
The script automatically creates RBAC resources with the necessary permissions for your operator. By default, it uses the rules defined in `scripts/rules.yaml`:
85+
86+
```yaml
87+
rules:
88+
- apiGroups: [""]
89+
resources: ["configmaps"]
90+
verbs: ["list", "get", "watch"]
91+
```
92+
93+
#### Customizing RBAC Rules
94+
95+
You can customize the RBAC permissions by:
96+
97+
1. **Editing the default rules file** (`scripts/rules.yaml`):
98+
```yaml
99+
rules:
100+
- apiGroups: [""]
101+
resources: ["configmaps", "secrets", "pods"]
102+
verbs: ["list", "get", "watch", "create", "update", "patch", "delete"]
103+
- apiGroups: ["apps"]
104+
resources: ["deployments"]
105+
verbs: ["list", "get", "watch"]
106+
```
107+
108+
2. **Using a custom rules file** with the `-r` option:
109+
```bash
110+
./scripts/create-kubeconfig-secret.sh -c prod-cluster -r ./my-custom-rules.yaml
111+
```
112+
113+
3. **Choosing between Role and ClusterRole**:
114+
- Use `-t role` for namespace-scoped permissions
115+
- Use `-t clusterrole` (default) for cluster-wide permissions
116+
117+
#### RBAC Resource Creation
118+
119+
The script creates the following RBAC resources automatically:
120+
121+
- **Service Account**: If it doesn't exist, creates the specified service account
122+
- **Role/ClusterRole**: With the permissions defined in the rules file
123+
- **RoleBinding/ClusterRoleBinding**: Binds the service account to the role
124+
125+
#### Skipping RBAC Creation
126+
127+
If you prefer to manage RBAC manually, use the `--skip-create-rbac` flag:
128+
129+
```bash
130+
./scripts/create-kubeconfig-secret.sh -c prod-cluster --skip-create-rbac
131+
```
132+
133+
This will only create the kubeconfig secret without setting up any RBAC resources.
134+
135+
### 3. Implementing Your Operator
136+
137+
Add your controllers to `main.go`:
138+
139+
```go
140+
func main() {
141+
err = mcbuilder.ControllerManagedBy(mgr).
142+
Named("multicluster-configmaps").
143+
For(&corev1.ConfigMap{}). // object to watch
144+
Complete(mcreconcile.Func(
145+
func(ctx context.Context, req mcreconcile.Request) (ctrl.Result, error) {
146+
// reconcile logic
147+
148+
return ctrl.Result{}, nil
149+
},
150+
))
151+
}
152+
```
153+
154+
Your controllers can then use the manager to access any cluster and view the resources that the RBAC permissions allow.
155+
156+
## How It Works
157+
158+
1. The kubeconfig provider watches for secrets with a specific label in a namespace
159+
2. When a new secret is found, it:
160+
- Extracts the kubeconfig data
161+
- Creates a new controller-runtime cluster
162+
- Makes the cluster available to your controllers
163+
3. Your controllers can access any cluster through the manager
164+
4. RBAC Rules on the remote clusters ensure the SA operator on the cluster of the controller has the necessary permissions in the remote clusters
165+
166+
## Labels and Configuration
167+
168+
The provider uses the following labels and keys by default:
169+
- Label: `sigs.k8s.io/multicluster-runtime-kubeconfig: "true"`
170+
- Secret data key: `kubeconfig`
171+
172+
You can customize these in the provider options when creating it.
173+
174+
## Prerequisites
175+
176+
- `kubectl` configured with access to both the local and remote clusters
177+
- `yq` command-line tool installed (required for RBAC rule processing)
178+
- Service account with appropriate permissions in the remote cluster (if not using automatic RBAC creation script)

examples/kubeconfig/go.mod

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module sigs.k8s.io/multicluster-runtime/examples/kubeconfig
2+
3+
go 1.24.0
4+
5+
replace (
6+
sigs.k8s.io/multicluster-runtime => ../..
7+
sigs.k8s.io/multicluster-runtime/providers/kubeconfig => ../../providers/kubeconfig
8+
)
9+
10+
require (
11+
golang.org/x/sync v0.15.0
12+
k8s.io/api v0.33.1
13+
k8s.io/apimachinery v0.33.1
14+
sigs.k8s.io/controller-runtime v0.21.0
15+
sigs.k8s.io/multicluster-runtime v0.0.0-00010101000000-000000000000
16+
)
17+
18+
require (
19+
github.com/beorn7/perks v1.0.1 // indirect
20+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
21+
github.com/davecgh/go-spew v1.1.1 // indirect
22+
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
23+
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
24+
github.com/fsnotify/fsnotify v1.7.0 // indirect
25+
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
26+
github.com/go-logr/logr v1.4.3 // indirect
27+
github.com/go-logr/zapr v1.3.0 // indirect
28+
github.com/go-openapi/jsonpointer v0.21.0 // indirect
29+
github.com/go-openapi/jsonreference v0.20.2 // indirect
30+
github.com/go-openapi/swag v0.23.0 // indirect
31+
github.com/gogo/protobuf v1.3.2 // indirect
32+
github.com/google/btree v1.1.3 // indirect
33+
github.com/google/gnostic-models v0.6.9 // indirect
34+
github.com/google/go-cmp v0.7.0 // indirect
35+
github.com/google/uuid v1.6.0 // indirect
36+
github.com/josharian/intern v1.0.0 // indirect
37+
github.com/json-iterator/go v1.1.12 // indirect
38+
github.com/mailru/easyjson v0.7.7 // indirect
39+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
40+
github.com/modern-go/reflect2 v1.0.2 // indirect
41+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
42+
github.com/pkg/errors v0.9.1 // indirect
43+
github.com/prometheus/client_golang v1.22.0 // indirect
44+
github.com/prometheus/client_model v0.6.1 // indirect
45+
github.com/prometheus/common v0.62.0 // indirect
46+
github.com/prometheus/procfs v0.15.1 // indirect
47+
github.com/spf13/pflag v1.0.5 // indirect
48+
github.com/x448/float16 v0.8.4 // indirect
49+
go.uber.org/multierr v1.11.0 // indirect
50+
go.uber.org/zap v1.27.0 // indirect
51+
golang.org/x/net v0.38.0 // indirect
52+
golang.org/x/oauth2 v0.27.0 // indirect
53+
golang.org/x/sys v0.32.0 // indirect
54+
golang.org/x/term v0.30.0 // indirect
55+
golang.org/x/text v0.23.0 // indirect
56+
golang.org/x/time v0.9.0 // indirect
57+
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
58+
google.golang.org/protobuf v1.36.5 // indirect
59+
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
60+
gopkg.in/inf.v0 v0.9.1 // indirect
61+
gopkg.in/yaml.v3 v3.0.1 // indirect
62+
k8s.io/apiextensions-apiserver v0.33.0 // indirect
63+
k8s.io/client-go v0.33.1 // indirect
64+
k8s.io/klog/v2 v2.130.1 // indirect
65+
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
66+
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
67+
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
68+
sigs.k8s.io/randfill v1.0.0 // indirect
69+
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
70+
sigs.k8s.io/yaml v1.4.0 // indirect
71+
)

0 commit comments

Comments
 (0)