Skip to content

Commit 3024e25

Browse files
kylecarbsbpmct
andauthored
example: Add Kubernetes multi-service (#1092)
* example: Add Kubernetes multi-service * fix: change to CODER_AGENT_TOKEN * example: use ServiceAccount for cluster authentication (#1096) Co-authored-by: Ben <ben@coder.com>
1 parent f581724 commit 3024e25

File tree

2 files changed

+209
-0
lines changed

2 files changed

+209
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
name: Develop multiple services in Kubernetes
3+
description: Get started with Kubernetes development.
4+
tags: [cloud, kubernetes]
5+
---
6+
7+
# Authentication
8+
9+
This template has several ways to authenticate to a Kubernetes cluster.
10+
11+
## kubeconfig (Coder host)
12+
13+
If the Coder host has a local `~/.kube/config`, this can be used to authenticate with Coder. Make sure this is on the same user running the `coder` service.
14+
15+
## ServiceAccount
16+
17+
Create a ServiceAccount and role on your cluster to authenticate your template with Coder.
18+
19+
1. Run the following command on a device with Kubernetes context:
20+
21+
```sh
22+
CODER_NAMESPACE=default
23+
kubectl apply -n $CODER_NAMESPACE -f - <<EOF
24+
apiVersion: v1
25+
kind: ServiceAccount
26+
metadata:
27+
name: coder
28+
---
29+
apiVersion: rbac.authorization.k8s.io/v1
30+
kind: Role
31+
metadata:
32+
name: coder
33+
rules:
34+
- apiGroups: ["", "apps", "networking.k8s.io"] # "" indicates the core API group
35+
resources: ["persistentvolumeclaims", "pods", "deployments", "services", "secrets", "pods/exec","pods/log", "events", "networkpolicies", "serviceaccounts"]
36+
verbs: ["create", "get", "list", "watch", "update", "patch", "delete", "deletecollection"]
37+
- apiGroups: ["metrics.k8s.io", "storage.k8s.io"]
38+
resources: ["pods", "storageclasses"]
39+
verbs: ["get", "list", "watch"]
40+
---
41+
apiVersion: rbac.authorization.k8s.io/v1
42+
kind: RoleBinding
43+
metadata:
44+
name: coder
45+
subjects:
46+
- kind: ServiceAccount
47+
name: coder
48+
roleRef:
49+
kind: Role
50+
name: coder
51+
apiGroup: rbac.authorization.k8s.io
52+
EOF
53+
```
54+
55+
1. Use the following commands to fetch the values:
56+
57+
**Cluster IP:**
58+
59+
```sh
60+
kubectl cluster-info | grep "control plane"
61+
```
62+
63+
**CA certificate**
64+
65+
```sh
66+
kubectl get secrets -n $CODER_NAMESPACE -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='coder')].data['ca\.crt']}{'\n'}"
67+
```
68+
69+
**Token**
70+
71+
```sh
72+
kubectl get secrets -n $CODER_NAMESPACE -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='coder')].data['token']}{'\n'}"
73+
```
74+
75+
**Namespace**
76+
77+
This should be the same as `$CODER_NAMESPACE`, set in step 1.
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
version = "~> 0.3.1"
6+
}
7+
kubernetes = {
8+
source = "hashicorp/kubernetes"
9+
version = "~> 2.10"
10+
}
11+
}
12+
}
13+
14+
variable "step1_use_kubeconfig" {
15+
type = bool
16+
sensitive = true
17+
description = "Use local ~/.kube/config? (true/false)"
18+
}
19+
20+
variable "step2_cluster_host" {
21+
type = string
22+
sensitive = true
23+
description = <<-EOF
24+
Hint: You can use:
25+
$ kubectl cluster-info | grep "control plane"
26+
27+
28+
Leave blank if using ~/.kube/config (from step 1)
29+
EOF
30+
}
31+
32+
variable "step3_certificate" {
33+
type = string
34+
sensitive = true
35+
description = <<-EOF
36+
Use docs at https://github.com/coder/coder/tree/main/examples/kubernetes-multi-service#serviceaccount to create a ServiceAccount for Coder and grab values.
37+
38+
Enter CA certificate
39+
40+
Leave blank if using ~/.kube/config (from step 1)
41+
EOF
42+
}
43+
44+
variable "step4_token" {
45+
type = string
46+
sensitive = true
47+
description = <<-EOF
48+
Enter token (refer to docs at https://github.com/coder/coder/tree/main/examples/kubernetes-multi-service#serviceaccount)
49+
50+
Leave blank if using ~/.kube/config (from step 1)
51+
EOF
52+
}
53+
54+
variable "step5_coder_namespace" {
55+
type = string
56+
sensitive = true
57+
description = <<-EOF
58+
Enter namespace (refer to docs at https://github.com/coder/coder/tree/main/examples/kubernetes-multi-service#serviceaccount)
59+
60+
Leave blank if using ~/.kube/config (from step 1)
61+
EOF
62+
}
63+
64+
provider "kubernetes" {
65+
# Authenticate via ~/.kube/config or a Coder-specific ServiceAccount, depending on admin preferences
66+
config_path = var.step1_use_kubeconfig == true ? "~/.kube/config" : null
67+
host = var.step1_use_kubeconfig == false ? var.step2_cluster_host : null
68+
cluster_ca_certificate = var.step1_use_kubeconfig == false ? base64decode(var.step3_certificate) : null
69+
token = var.step1_use_kubeconfig == false ? base64decode(var.step4_token) : null
70+
}
71+
72+
data "coder_workspace" "me" {}
73+
74+
resource "coder_agent" "go" {
75+
os = "linux"
76+
arch = "amd64"
77+
}
78+
79+
resource "coder_agent" "java" {
80+
os = "linux"
81+
arch = "amd64"
82+
}
83+
84+
resource "coder_agent" "ubuntu" {
85+
os = "linux"
86+
arch = "amd64"
87+
}
88+
89+
resource "kubernetes_pod" "main" {
90+
count = data.coder_workspace.me.start_count
91+
metadata {
92+
name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
93+
}
94+
spec {
95+
container {
96+
name = "go"
97+
image = "mcr.microsoft.com/vscode/devcontainers/go:1"
98+
command = ["sh", "-c", coder_agent.go.init_script]
99+
security_context {
100+
run_as_user = "1000"
101+
}
102+
env {
103+
name = "CODER_AGENT_TOKEN"
104+
value = coder_agent.go.token
105+
}
106+
}
107+
container {
108+
name = "java"
109+
image = "mcr.microsoft.com/vscode/devcontainers/java"
110+
command = ["sh", "-c", coder_agent.java.init_script]
111+
security_context {
112+
run_as_user = "1000"
113+
}
114+
env {
115+
name = "CODER_AGENT_TOKEN"
116+
value = coder_agent.java.token
117+
}
118+
}
119+
container {
120+
name = "ubuntu"
121+
image = "mcr.microsoft.com/vscode/devcontainers/base:ubuntu"
122+
command = ["sh", "-c", coder_agent.ubuntu.init_script]
123+
security_context {
124+
run_as_user = "1000"
125+
}
126+
env {
127+
name = "CODER_AGENT_TOKEN"
128+
value = coder_agent.ubuntu.token
129+
}
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)