code-server Helm Chart 深度解析:在 Kubernetes 上部署、配置与运维 VS Code-in-the-Browser
code-server 官方仓库内置了一个社区维护的 Helm Chart(docs/helm.md、ci/helm-chart/),它把 code-server 完整地打包为一组 Kubernetes 资源:Deployment + Service + Secret + PVC(+ 可选 Ingress/ServiceAccount),并通过 extraContainers、extraInitContainers、extraSecretMounts 等扩展点支持 docker-dind、预装扩展等高级玩法。读完本文,你将掌握如何用一条 helm upgrade --install 命令在集群中拉起 code-server、如何解读并修改全部 values 参数、如何取得登录密码与验证服务健康状态,以及各资源模板背后的实现细节。
Chart 概览:部署了一组什么资源
Chart 定义为 type: application,当前版本 version: 3.48.0、appVersion: 4.133.0(见 Chart.yaml)。helm install 后渲染出的核心资源为:
| 资源 | 模板文件 | 说明 |
|---|---|---|
| Secret | secrets.yaml | 随机生成(或指定)登录密码,pre-install hook 先行创建 |
| ServiceAccount | serviceaccount.yaml | 默认创建,可用 serviceAccount.name 覆盖 |
| Deployment | deployment.yaml | 主容器 + 可选 init 容器,/healthz 探针 |
| Service | service.yaml | 默认 ClusterIP,端口跟随 service.port |
| PersistentVolumeClaim | pvc.yaml | 持久化 /home/coder 数据(默认开启) |
| Ingress | ingress.yaml | 默认关闭,按集群版本自动选择 API 组 |
| 测试 Pod | test-connection.yaml | helm.sh/hook: test,供 helm test 使用 |
文档中列出的前置条件为 Kubernetes 1.6+(docs/helm.md 的 Prerequisites 一节)。
安装与卸载
从仓库克隆后直接使用本地 chart 路径安装,release 名为 code-server:
$ git clone https://github.com/coder/code-server
$ cd code-server
$ helm upgrade --install code-server ci/helm-chart
该命令以默认配置把 code-server 部署到集群;安装完成后可以 helm list 查看所有 release,helm delete code-server 删除 release 及其关联的全部 Kubernetes 资源(卸载一节,docs/helm.md)。
部署模板实现细节(deployment.yaml)
deployment.yaml 中几个与运行行为直接相关的点值得逐条对照源码理解:
- 升级策略为
Recreate(第 14-15 行):由于 PVC 是ReadWriteOnce,多副本并发挂载同一卷会有问题,因此滚动升级采用先停后起的方式,replicaCount默认保持 1。 - init 容器
init-chmod-data(第 40-54 行):当volumePermissions.enabled与persistence.enabled同时为真时,chart 会注入一个 busybox init 容器执行chown -R <runAsUser>:<fsGroup> /home/coder,以 root(volumePermissions.securityContext.runAsUser: 0)修正数据卷属主,保证非 root 主容器(securityContext.runAsUser: 1000)可以写入/home/coder。这正是 values 中securityContext/volumePermissions两组参数存在的意义。 - 密码经环境变量注入(第 85-93 行):主容器 env 中注入
PASSWORD,值来自同名 Secret 的password键;若配置了existingSecret,则改从你提供的 Secret 读取。code-server 本身确实支持PASSWORD环境变量——cli.ts 中--password只允许通过$PASSWORD或配置文件传入,且main流程会读取process.env.PASSWORD赋值给args.password,因此 Helm 无需额外传参即可完成认证配置。 - 健康检查(第 128-139 行):liveness 与 readiness 探针默认开启,均为
httpGet /healthz,指向容器端口 8080;可通过livenessProbe.enabled/readinessProbe.enabled单独关闭。 - 主容器端口固定
containerPort: 8080(第 119-122 行),extraPorts可再追加自定义端口(如extraPorts: [{name: minecraft, port: 25565, protocol: tcp}]),Service 模板会同步暴露这些端口。 - 调度控制:
nodeSelector、affinity(注意 affinity 使用tpl渲染,支持引用 values)、tolerations、priorityClassName、hostnameOverride均可直接在 Pod spec 层面使用。
认证:Secret 生成与密码获取
secrets.yaml 的行为:
- 未设置
existingSecret时,chart 生成一个pre-installhook 的 Opaque Secret; - 若你通过 values 指定了
password,则 base64 编码后写入;否则randAlphaNum 24随机生成 24 位字母数字密码; - 设置了
existingSecret时不再创建 Secret,密码须已存在该 Secret 的password键中(values.yaml 第 22-23 行注释即此说明)。
安装后可从 NOTES.txt 输出的提示直接取出密码:
kubectl get secret --namespace <namespace> <fullname> -o jsonpath="{.data.password}" | base64 --decode
全部 Values 参数与当前默认值
说明:docs/helm.md 中的 Values 表格是 4.8.0 时代的快照(如
service.port: 8443、image.tag: "4.8.0"、persistence.size: "1Gi")。以当前仓库 values.yaml 的实际默认值为准,下表同时补充了文档表格未覆盖的新参数。
镜像与命名
| Key | 类型 | 默认值 | 说明 |
|---|---|---|---|
| image.repository | string | "codercom/code-server" |
镜像仓库 |
| image.tag | string | "4.133.0" |
镜像 tag,当前与 appVersion 一致 |
| image.pullPolicy | string | "Always" |
拉取策略 |
| imagePullSecrets | list | [] |
私有镜像仓库凭证 |
| replicaCount | int | 1 |
副本数(RWO 卷建议保持 1) |
| nameOverride / fullnameOverride | string | "" |
名称覆盖,影响 fullname 与 PVC/Secret 名 |
| hostnameOverride | string | "" |
覆盖 Pod hostname |
| annotations / labels / podAnnotations | object | {} |
Deployment 与 Pod 注解、标签 |
调度与安全
| Key | 类型 | 默认值 | 说明 |
|---|---|---|---|
| nodeSelector | object | {} |
节点选择 |
| tolerations | list | [] |
污点容忍 |
| affinity | object | {} |
亲和性,经 tpl 渲染支持模板变量 |
| priorityClassName | string | "" |
优先级类 |
| podSecurityContext | object | {} |
Pod 级安全上下文 |
| securityContext.enabled | bool | true |
启用后主容器以 runAsUser 运行 |
| securityContext.runAsUser | int | 1000 |
与官方镜像内 coder 用户一致 |
| securityContext.fsGroup | int | 1000 |
数据卷属组 |
| volumePermissions.enabled | bool | true |
开启 init-chmod-data |
| volumePermissions.securityContext.runAsUser | int | 0 |
改属主用的 root 身份 |
服务与网络
| Key | 类型 | 默认值 | 说明 |
|---|---|---|---|
| service.type | string | "ClusterIP" |
可改 NodePort / LoadBalancer |
| service.port | int | 8080 |
Service 端口(文档旧表中的 8443 已过时) |
| extraPorts | list | [] |
追加容器/服务端口,如 dind 的 2376 |
| ingress.enabled | bool | false |
是否创建 Ingress |
| ingress.ingressClassName | string | "" |
如 nginx / traefik |
| ingress.annotations | object | {}(注释态) |
Ingress 注解 |
| ingress.hosts / ingress.tls | list | [](注释态) |
域名与 TLS 证书,pathType: Prefix |
数据持久化
| Key | 类型 | 默认值 | 说明 |
|---|---|---|---|
| persistence.enabled | bool | true |
关闭则数据卷退化为 emptyDir |
| persistence.accessMode | string | "ReadWriteOnce" |
访问模式 |
| persistence.size | string | 10Gi |
请求容量(文档旧表中为 1Gi) |
| persistence.storageClass | string | 未设置 | 设为 "-" 表示禁用动态供应(storageClassName: ""),见 pvc.yaml 第 19-25 行 |
| persistence.existingClaim | string | ""(注释态) |
复用已有 PVC,不再创建新 PVC |
| persistence.hostPath | string | ""(注释态) |
直接挂载节点目录,优先级高于 PVC |
| persistence.annotations | object | {} |
PVC 注解 |
扩展点(extra*)
| Key | 类型 | 默认值 | 说明 |
|---|---|---|---|
| extraArgs | list | [] |
追加 code-server 启动参数,每个参数与值须分行书写(如 --bind-addr 与 0.0.0.0:8080 各占一行),原因见 values.yaml 第 66-79 行注释 |
| extraVars | list | [] |
追加环境变量,如 DISABLE_TELEMETRY、DOCKER_HOST |
| extraContainers | string | "" |
以模板字符串追加普通容器(tpl 渲染) |
| extraInitContainers | string | "" |
以模板字符串追加 init 容器(tpl 渲染) |
| extraSecretMounts | list | [] |
挂载 Secret(支持 subPath) |
| extraConfigmapMounts | list | [] |
挂载 ConfigMap(支持 subPath) |
| extraVolumeMounts | list | [] |
挂载已有 PVC / hostPath / emptyDir |
| existingSecret | string | ""(注释态) |
使用已有密码 Secret |
| lifecycle.enabled | bool | false |
开启后可注入 postStart/preStop,例如 dind 场景安装 docker |
| serviceAccount.create / name | bool / string | true / "" |
不创建则回退 default(_helpers.tpl 第 57-63 行) |
| resources | object | {} |
资源请求/限制 |
| livenessProbe.enabled / readinessProbe.enabled | bool | true |
探针开关 |
两种配置方式:--set 与 values 文件
单个参数用 --set key=value 传入,例如关闭持久化:
$ helm upgrade --install code-server \
ci/helm-chart \
--set persistence.enabled=false
多个参数则写一个 YAML 文件,用 -f(或 --values)传入,且可以直接复用仓库自带的 values.yaml 作为起点:
$ helm upgrade --install code-server ci/helm-chart -f values.yaml
进阶:extraContainers 与 extraInitContainers
这是文档(docs/helm.md 的 "Extra Containers" 一节)重点讲解的能力:两个参数都接受字符串,并在渲染时经 tpl 作为 Helm 模板执行,因此可以引用 .Values.image.repository 等变量。典型用途是在主容器启动前,用与主容器相同的镜像跑一个 init 容器,把扩展预装进持久化的 /home/coder。
在文件 init.yaml 中写入:
extraInitContainers: |
- name: customization
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: IfNotPresent
env:
- name: SERVICE_URL
value: https://open-vsx.org/vscode/gallery
- name: ITEM_URL
value: https://open-vsx.org/vscode/item
command:
- sh
- -c
- |
code-server --install-extension ms-python.python
code-server --install-extension golang.Go
volumeMounts:
- name: data
mountPath: /home/coder
然后执行:
$ helm upgrade --install code-server \
ci/helm-chart \
--values init.yaml
即可让 Pod 先由该 init 容器预装 python 与 golang 扩展,再启动主容器。对应渲染逻辑在 deployment.yaml 第 55-57 行(tpl .Values.extraInitContainers .);注意 init 容器段落的开启条件是 volumePermissions.enabled && persistence.enabled 与 extraInitContainers 任一成立(第 38 行)。
extraContainers 同理,官方 values.yaml 第 166-187 行内置了被注释掉的 docker-dind 示例:以 privileged: true 的 dockerd 容器挂载 unix socket 与 tcp://0.0.0.0:2376,配合 extraVars 中的 DOCKER_HOST 与 extraPorts 暴露 2376,即可在浏览器版 VS Code 的终端里使用 Docker。
访问方式与 Ingress
安装后 NOTES.txt 会根据 Service 类型输出不同的访问指引:
- ClusterIP(默认):
kubectl port-forward service/<fullname> 8080:http,然后访问http://127.0.0.1:8080; - NodePort:从 Service 与节点地址取
NODE_PORT/NODE_IP拼接; - LoadBalancer:等待
status.loadBalancer.ingress[0].ip就绪后访问; - Ingress:直接输出
http(s)://<host><path>地址。
Ingress 模板(ingress.yaml)会根据 $.Capabilities.KubeVersion 自动选择 API 版本:Kubernetes 1.19+ 用 networking.k8s.io/v1(带 pathType: Prefix),1.14-1.18 回退 v1beta1,更老版本使用 extensions/v1beta1,这也是文档要求 1.6+ 的原因。启用示例(values.yaml 注释态第 52-64 行):
ingress:
enabled: true
ingressClassName: nginx
hosts:
- host: code-server.example.loc
paths:
- /
tls:
- secretName: code-server
hosts:
- code-server.example.loc
用 helm test 验证部署
Chart 自带连接测试(test-connection.yaml):一个标注 helm.sh/hook: test 的 busybox Pod 对 <fullname>:<service.port>/healthz 发起 wget,与 Deployment 中 readiness 探针探测的是同一路径。安装后可运行:
$ helm test code-server
测试通过说明 Service 可达且 code-server 主进程(其健康检查路由)已就绪。
小结
这份 Helm Chart 以最小的默认配置(单副本、ClusterIP、10Gi RWO 持久卷、随机密码 Secret、8080 端口 /healthz 双探针)覆盖了 code-server 在 Kubernetes 上的标准部署;通过 extraArgs/extraVars/extraContainers/extraInitContainers/extra*Mounts 一组 tpl 可渲染的扩展点,又保留了预装扩展、docker-dind、自定义端口等深度定制空间。所有行为均可直接对照 ci/helm-chart/templates/ 下的模板文件与 values.yaml 验证;升级前建议先核对当前 image.tag(与 Chart.yaml 中 appVersion 保持一致),并保留 persistence.existingClaim 或既有 PVC 以避免数据丢失。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00