2gis/k8s-handlek8s-handle 是一个命令行工具,用于简化 Kubernetes 应用的持续交付流程。它支持多环境配置,可使用相同的部署模板部署到不同环境(如 staging 和 production),是 Helm 的替代方案,但不包含包管理器功能。
kubectl(如未安装)[***]bash$ cat > ~/.kube/kubernetes.ca.crt << EOF > <粘贴集群 CA 证书内容> >EOF cat > ~/.kube/config << EOF apiVersion: v1 kind: Config preferences: {} clusters: - cluster: certificate-authority: kubernetes.ca.crt server: <protocol://masterurl:port> name: my-cluster contexts: - context: cluster: my-cluster namespace: my-namespace user: my-user name: my-context current-context: my-context users: - name: my-user user: token: <你的 token> EOF
需 Python 3.4 或更高版本:
bash$ pip install k8s-handle -- 或 -- $ pip install --user k8s-handle
bash$ cd $WORKDIR $ git clone [***] $ cd k8s-handle-example $ docker run --rm -v $(pwd):/tmp/ -v "$HOME/.kube:/root/.kube" 2gis/k8s-handle k8s-handle deploy -s staging --use-kubeconfig INFO:templating:File "/tmp/k8s-handle/configmap.yaml" successfully generated INFO:templating:Trying to generate file from template "secret.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/secret.yaml" successfully generated INFO:templating:Trying to generate file from template "deployment.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/deployment.yaml" successfully generated INFO:k8s.resource:ConfigMap "k8s-starter-kit-nginx-conf" already exists, replace it INFO:k8s.resource:Secret "k8s-starter-kit-secret" already exists, replace it INFO:k8s.resource:Deployment "k8s-starter-kit" does not exist, create it _(_)_ wWWWw _ @@@@ (_)@(_) vVVVv _ @@@@ (___) _(_)_ @@()@@ wWWWw (_)\ (___) _(_)_ @@()@@ Y (_)@(_) @@@@ (___) `|/ Y (_)@(_) @@@@ \|/ (_) / Y \| \|/ /(_) \| |/ | \ | \ |/ | / \ | / \|/ |/ \| \|/ \|// \|/// \|// \|/// \|/// \|// |// \|// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
如果使用 Gitlab CI、TeamCity 等工具,可通过 Docker 运行器/代理集成,脚本略有不同:
bash$ k8s-handle deploy -s staging
需 checkout 代码仓库 [***] 并切换到分支 without-kubeconfig,同时设置以下环境变量:
使用镜像 2gis/k8s-handle:<版本号或 latest>
注意:如果使用 Gitlab CI,可配置 Kubernetes 集成,直接使用 --use-kubeconfig 标志。
bash$ k8s-handle deploy -s staging --use-kubeconfig INFO:templating:Trying to generate file from template "configmap.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/configmap.yaml" successfully generated INFO:templating:Trying to generate file from template "secret.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/secret.yaml" successfully generated INFO:templating:Trying to generate file from template "deployment.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/deployment.yaml" successfully generated INFO:k8s.resource:ConfigMap "k8s-starter-kit-nginx-conf" already exists, replace it INFO:k8s.resource:Secret "k8s-starter-kit-secret" already exists, replace it INFO:k8s.resource:Deployment "k8s-starter-kit" does not exist, create it _(_)_ wWWWw _ @@@@ (_)@(_) vVVVv _ @@@@ (___) _(_)_ @@()@@ wWWWw (_)\ (___) _(_)_ @@()@@ Y (_)@(_) @@@@ (___) `|/ Y (_)@(_) @@@@ \|/ (_) / Y \| \|/ /(_) \| |/ | \ | \ |/ | / \ | / \|/ |/ \| \|/ \|// \|/// \|// \|/// \|/// \|// |// \|// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ $ kubectl get configmap NAME DATA AGE k8s-starter-kit-nginx-conf 1 1m $ kubectl get secret | grep starter-kit k8s-starter-kit-secret Opaque 1 1m $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE k8s-starter-kit 1 1 1 1 3m
修改 config.yaml 中 replicas_count 为 3,使用同步模式重新运行:
bash$ k8s-handle deploy -s staging --use-kubeconfig --sync-mode ... INFO:k8s.resource:Deployment "k8s-starter-kit" already exists, replace it INFO:k8s.resource:desiredReplicas = 3, updatedReplicas = 3, availableReplicas = 1 INFO:k8s.resource:Deployment not completed on 1 attempt, next attempt in 5 sec. INFO:k8s.resource:desiredReplicas = 3, updatedReplicas = 3, availableReplicas = 2 INFO:k8s.resource:Deployment not completed on 2 attempt, next attempt in 5 sec. INFO:k8s.resource:desiredReplicas = 3, updatedReplicas = 3, availableReplicas = 3 INFO:k8s.resource:Deployment completed on 3 attempt ... $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE k8s-starter-kit 3 3 3 3 7m
可通过示例仓库快速开始:[***] Nginx 应用及所需的 Kubernetes 资源配置。
bash$ cd $WORKDIR $ git clone [***] $ cd k8s-handle-example $ k8s-handle deploy -s staging --use-kubeconfig --sync-mode INFO:__main__:Using default namespace k8s-handle-test INFO:templating:Trying to generate file from template "configmap.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/configmap.yaml" successfully generated INFO:templating:Trying to generate file from template "deployment.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/deployment.yaml" successfully generated INFO:templating:Trying to generate file from template "service.yaml.j2" in "/tmp/k8s-handle" INFO:templating:File "/tmp/k8s-handle/service.yaml" successfully generated INFO:k8s.resource:ConfigMap "example-nginx-conf" does not exist, create it INFO:k8s.resource:Deployment "example" does not exist, create it INFO:k8s.resource:desiredReplicas = 1, updatedReplicas = 1, availableReplicas = None INFO:k8s.resource:Deployment not completed on 1 attempt, next attempt in 5 sec. INFO:k8s.resource:desiredReplicas = 1, updatedReplicas = 1, availableReplicas = None INFO:k8s.resource:Deployment not completed on 2 attempt, next attempt in 5 sec. INFO:k8s.resource:desiredReplicas = 1, updatedReplicas = 1, availableReplicas = 1 INFO:k8s.resource:Deployment completed on 3 attempt INFO:k8s.resource:Service "example" does not exist, create it $ kubectl -n k8s-handle-test get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example NodePort 10.100.132.168 <none> 80:31153/TCP 52s $ curl http://<任意节点IP>:31153 <h1>Hello world!</h1> Deployed with k8s-handle.
k8s-handle 工作依赖两个组件:
-c 参数指定的其他 YAML 文件):存储所有部署配置如果有测试、预发、生产等多环境,可通过一套模板覆盖所有环境,无需重复配置。
Common 部分定义所有环境共享的变量:
yamlcommon: app_name: my-shiny-app app_port: 8080
这些变量会与指定环境的变量合并。Common 部分为可选。
定义具体环境的变量:
yamltesting: replicas: 1 request_cpu: 100m request_memory: 128M some_option: disabled
测试环境通常资源需求较低,副本数为 1。
yamlstaging: replicas: 2 request_cpu: 200m request_memory: 512M
预发环境用于集成测试和演示,可适当提高副本数和资源。
yamlproduction-zone-1: replicas: 50 request_cpu: 1000m request_memory: 1G production: "true" never_give_up: "true"
生产环境需处理高并发,设置高副本数和资源,并配置生产特定变量。
在 CI/CD 脚本中部署指定环境:
bash$ k8s-handle deploy -s staging # 或 testing、production-zone-1
例如在 Gitlab CI 中,可为每个环境创建手动触发任务。
模板使用 Jinja2 语法,支持标准过滤器及以下特殊过滤器:
{{ my_var | b64encode }} - 将 my_var 的值编码为 base64{{ my_var | b64decode }} - 将 my_var 的值从 base64 解码{{ my_var | hash_sha256 }} - 将 my_var 的值编码为 sha256 哈希{{ my_var | to_yaml(flow_style=True, width=99999) }} - 将变量渲染为 YAML 格式(flow_style=True 为单行,False 为多行;width 为最大行宽)注意:过滤器仅用于模板,不可用于 config.yaml
{{ include_file('my_file.txt') }} - 导入 my_file.txt 内容(不解析),适用于将配置文件导入 ConfigMap。文件路径相对于模板目录的父目录(通常为项目根目录):bash$ ls -1 config.yaml templates my_file.txt ...
{{ list_files('dir/or/glob*') }} - 返回指定目录下的文件列表,适用于导入文件夹中所有文件到 ConfigMap。路径相对于模板目录的父目录。注:两个函数均支持 Unix glob 模式,例如导入
conf.d/*.conf所有文件。
在 config.yaml 中指定模板:
yamltesting: replicas: 1 request_cpu: 100m request_memory: 128M some_option: disabled templates: - template: my-deployment.yaml.j2
同一模板可在多个环境中复用:
yamlstaging: ... templates: - template: my-deployment.yaml.j2 production-zone-1: ... templates: - template: my-deployment.yaml.j2
k8s-handle 使用 Jinja2 模板引擎,基于环境变量 TEMPLATES_DIR 指定的目录初始化。模板路径需相对于 TEMPLATES_DIR,例如:
模板目录结构:
templates / subdirectory / template_A.yaml template_B.yaml
在 template_A 中导入 template_B 需使用:
{% include "subdirectory/template_B.yaml" %}
对于包含多个独立组件(如主应用和迁移任务)的大型
探索更多轩辕镜像的使用方法,找到最适合您系统的配置方式
通过 Docker 登录认证访问私有仓库
在 Linux 系统配置镜像服务
在 Docker Desktop 配置镜像
Docker Compose 项目配置
Kubernetes 集群配置 Containerd
K3s 轻量级 Kubernetes 镜像加速
VS Code Dev Containers 配置
MacOS OrbStack 容器配置
在宝塔面板一键配置镜像
Synology 群晖 NAS 配置
飞牛 fnOS 系统配置镜像
极空间 NAS 系统配置服务
爱快 iKuai 路由系统配置
绿联 NAS 系统配置镜像
QNAP 威联通 NAS 配置
Podman 容器引擎配置
HPC 科学计算容器配置
ghcr、Quay、nvcr 等镜像仓库
无需登录使用专属域名
需要其他帮助?请查看我们的 常见问题Docker 镜像访问常见问题解答 或 提交工单
免费版仅支持 Docker Hub 访问,不承诺可用性和速度;专业版支持更多镜像源,保证可用性和稳定速度,提供优先客服响应。
专业版支持 docker.io、gcr.io、ghcr.io、registry.k8s.io、nvcr.io、quay.io、mcr.microsoft.com、docker.elastic.co 等;免费版仅支持 docker.io。
当返回 402 Payment Required 错误时,表示流量已耗尽,需要充值流量包以恢复服务。
通常由 Docker 版本过低导致,需要升级到 20.x 或更高版本以支持 V2 协议。
先检查 Docker 版本,版本过低则升级;版本正常则验证镜像信息是否正确。
使用 docker tag 命令为镜像打上新标签,去掉域名前缀,使镜像名称更简洁。
来自真实用户的反馈,见证轩辕镜像的优质服务