Deploy a Coder Control Plane¶
Install the coder-k8s operator, then create one Coder instance from a CoderControlPlane resource.
Time: 10–15 minutes.
Prerequisites¶
- A Kubernetes cluster and
kubectlpointed at it. - Permission to create what
dist/install.yamlcontains: a Namespace, CustomResourceDefinitions, a ServiceAccount, a ClusterRole, a ClusterRoleBinding, and a Deployment. Step 1 also creates thecodernamespace.
1. Install the operator¶
Set the source once. For reproducible installs, use a release tag that contains dist/install.yaml instead of main.
BASE="https://raw.githubusercontent.com/coder/coder-k8s/main"
Apply the install bundle, then create the namespace for the control plane:
kubectl apply -f "$BASE/dist/install.yaml"
kubectl rollout status deployment/coder-k8s -n coder-system
kubectl create namespace coder
dist/install.yaml installs the operator in controller mode: the coder-system namespace, the coder.com CRDs, RBAC, and the operator Deployment. It does not deploy Coder; step 2 does that. It also does not include the aggregated API server; to add it, see Deploy the aggregated API server. The bundle runs the ghcr.io/coder/coder-k8s:latest image, so pin the image too if you need a fixed operator version.
2. Create a control plane¶
kubectl apply -f "$BASE/config/samples/coder_v1alpha1_codercontrolplane.yaml"
3. Verify¶
kubectl get codercontrolplane codercontrolplane-sample -n coder \
-o jsonpath='{.status.phase}{"\n"}{.status.url}{"\n"}'
kubectl rollout status deployment/codercontrolplane-sample -n coder
kubectl get deployment,service codercontrolplane-sample -n coder
You should see:
status.phaseisReady.status.urlis set, for examplehttp://codercontrolplane-sample.coder.svc.cluster.local:80.- A Deployment and Service named
codercontrolplane-sampleexist incoder.
4. Open Coder (optional)¶
kubectl port-forward svc/codercontrolplane-sample -n coder 3000:80
Then browse to http://127.0.0.1:3000.
5. Clean up (optional)¶
Delete the control plane first, while the operator is still running, so it can clean up and remove its finalizer. Then remove the bundle. The block sets BASE again in case you are in a new shell:
BASE="https://raw.githubusercontent.com/coder/coder-k8s/main"
kubectl delete -f "$BASE/config/samples/coder_v1alpha1_codercontrolplane.yaml" --ignore-not-found
kubectl wait --for=delete codercontrolplane/codercontrolplane-sample -n coder --timeout=120s
kubectl delete -f "$BASE/dist/install.yaml" --ignore-not-found
kubectl delete namespace coder --ignore-not-found
Deleting the bundle also deletes the coder.com CRDs, which removes every remaining CoderControlPlane, CoderProvisioner, and CoderWorkspaceProxy in the cluster; delete those first. Deleting the coder namespace removes everything else in it, such as Secrets and PersistentVolumeClaims.