{"id":37179321,"url":"https://github.com/triton-io/triton","last_synced_at":"2026-01-14T20:52:30.889Z","repository":{"id":41181290,"uuid":"391012624","full_name":"triton-io/triton","owner":"triton-io","description":"cloud native application deploy flow ","archived":false,"fork":false,"pushed_at":"2023-05-05T02:27:31.000Z","size":16814,"stargazers_count":43,"open_issues_count":3,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-18T23:17:45.029Z","etag":null,"topics":["cd","crd-controller","openkruise"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/triton-io.png","metadata":{"files":{"readme":"README-zh_CN.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-30T09:45:12.000Z","updated_at":"2023-09-18T11:12:20.000Z","dependencies_parsed_at":"2024-06-18T23:01:20.474Z","dependency_job_id":"cf0206c1-464e-48b9-92ff-e7664bac4dca","html_url":"https://github.com/triton-io/triton","commit_stats":{"total_commits":37,"total_committers":3,"mean_commits":"12.333333333333334","dds":0.05405405405405406,"last_synced_commit":"06411a6308fc24334bcaed4f836477c5e72de2a4"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/triton-io/triton","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/triton-io%2Ftriton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/triton-io%2Ftriton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/triton-io%2Ftriton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/triton-io%2Ftriton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/triton-io","download_url":"https://codeload.github.com/triton-io/triton/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/triton-io%2Ftriton/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28434500,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T18:57:19.464Z","status":"ssl_error","status_checked_at":"2026-01-14T18:52:48.501Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cd","crd-controller","openkruise"],"created_at":"2026-01-14T20:52:30.077Z","updated_at":"2026-01-14T20:52:30.880Z","avatar_url":"https://github.com/triton-io.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Triton\n\n## Triton 概述\n\n伴随着云原生技术在越来越多的企业落地，如今的 Kubernetes 和容器已经完全进入主流市场，成为云计算的新界面，帮助企业充分享受云原生的优势，加速应用迭代创新效率，降低开发运维成本。但在向着云原生架构转型的过程中，也有许多问题需要被解决。比如原生 Kubernetes 的复杂性、容器化应用的生命周期管理，以及向以容器为基础设施迁移的过程中可能出现的服务稳定性挑战等等。\n\n开源云原生应用发布组件 Triton 的出现，就是为了解决企业应用在容器化过程中安全落地生产的问题。Triton 以 [OpenKruise](https://openkruise.io/zh-cn/docs/what_is_openkruise.html \"OpenKruise\") 作为容器应用自动化引擎，实现应用负载的扩展增强能力，为原有持续交付系统带来全面升级，不仅解决了应用生命周期管理的问题，包括开发、部署、运维等，同时打通微服务治理，可以帮助研发提升持续交付的效率。\n\n有关 Trion 设计方案、实现原理的详细介绍可以参考[这篇文章](https://mp.weixin.qq.com/s/CAFNxnKkS5PjeE8ywfoQqQ)。本文将从源码级安装、debug、demo 应用发布演示三个方面介绍 Triton 的核心特性以及 Triton 的快速上手使用、开发，最后介绍 Triton 的 Roadmap。由于时间关系，一键安装、Helm 安装的方式正在开发中，会在正式版本 release 中提供。\n\n## 核心能力\n\n本次带来的 v0.1.0 开源版本在代码上进行了重构，暂时去掉了对网络方案、微服务架构的依赖，抽象出应用模型的概念，更具备普适性，核心特性如下：\n\n- 全托管于 k8s 集群，便于组件安装、维护和升级；\n\n- 支持使用 API 和 kubectl 插件（规划中）完成应用创建、部署、升级，并支持单批发布、分批发布和金丝雀发布；\n\n- 提供从创建到运行的应用全生命周期管理服务，包括应用的发布、启动、停止、扩容、缩容和删除等服务，可以轻松管理上千个应用实例的交付问题；\n\n- Triton 提供了大量 API 来简化部署等操作，如Next、Cancel、Pause、Resume、Scale、Gets、Restart 等，轻松对接公司内部的 PaaS 系统；\n\n  \n\n  ## 操作指南\n\n  在开始之前，检查一下当前环境是否满足一下前提条件:\n\n  1. 确保环境能够与 kube-apiserver 连通；\n\n  2. 确保 `OpenKruise` 已经在当前操作 k8s 集群安装，若未安装可以参考[文档](https://openkruise.io/en-us/docs/installation.html \"OpenKruise 安装文档\")；\n\n  3. 确保有 Golang 开发环境，Fork \u0026 git clone 代码后，执行 `make install` 安装 CRD `DeployFlow` ；\n\n  4. 操作 API 的过程中需要 `grpcurl` 这个工具，参考 [grpcurl 文档](https://github.com/fullstorydev/grpcurl \"grpcurl 安装文档\")进行安装；\n\n  \n\n  ### 创建 DeployFlow 来发布 Nginx Demo Application\n\n  #### 运行 DeployFlow controller\n\n  进入到代码根目录下执行  `make run`\n\n  #### 创建 DeployFlow 准备发布应用\n\n  ```bash\n  kubectl apply -f https://github.com/triton-io/triton/raw/main/docs/tutorial/v1/nginx-deployflow.yaml\n  ```\n\n  ![](https://tva1.sinaimg.cn/large/008i3skNly1guf6qrw2zpj61tq04cmya02.jpg)\n\n  \n\n  会创建出一个 DeployFlow 资源和本应用对应的 Service，可以查看该 yaml 文件了解详细的 DeployFlow 定义。\n\n  ```yaml\n  apiVersion: apps.triton.io/v1alpha1\n  kind: DeployFlow\n  metadata:\n    labels:\n      app: \"12122\"\n      app.kubernetes.io/instance: 12122-sample-10010\n      app.kubernetes.io/name: deploy-demo-hello\n      group: \"10010\"\n      managed-by: triton-io\n    name: 12122-sample-10010-df\n    namespace: default\n  spec:\n    action: create\n    application:\n      appID: 12122\n      appName: deploy-demo-hello\n      groupID: 10010\n      instanceName: 12122-sample-10010\n      replicas: 3\n      selector:\n        matchLabels:\n          app: \"12122\"\n          app.kubernetes.io/instance: 12122-sample-10010\n          app.kubernetes.io/name: deploy-demo-hello\n          group: \"10010\"\n          managed-by: triton-io\n      template:\n        metadata: {}\n        spec:\n          containers:\n            - image: nginx:latest\n              name: 12122-sample-10010-container\n              ports:\n                - containerPort: 80\n                  protocol: TCP\n              resources: {}\n    updateStrategy:\n      batchSize: 1\n      batchIntervalSeconds: 10\n      canary: 1 # the number of canary batch\n      mode: auto # the mode is auto after canary batch\n  ```\n\n  可以看到我们本次发布的应用名字是 `12122-sample-10010`，副本数量是 3，批次大小是 1，有一个金丝雀批次，批次大小是 1，发布的模式是 auto，意味着本次发布只会在金丝雀批次和普通批次之间暂停，后续两个批次会以 `batchIntervalSeconds` 为时间间隔自动触发。\n\n  #### 检查 DeployFlow 状态\n\n  ![](https://tva1.sinaimg.cn/large/008i3skNly1guf6slwhwvj62bm04aq3x02.jpg)\n\n  可以看到我们创建出一个名为 `12122-sample-10010-df` 的 DeployFlow 资源，通过展示的字段了解到本次发布分为 3 个批次，当前批次的大小是 1，已升级和已完成的副本数量都是 0。\n\n  启动几十秒后，检查 DeployFlow 的 status 字段：\n\n  ```bash\n  kubectl get df  12122-sample-10010-df -o yaml\n  ```\n\n  ```yaml\n  status:\n    availableReplicas: 0\n    batches: 3\n    conditions:\n    - batch: 1\n      batchSize: 1\n      canary: true\n      failedReplicas: 0\n      finishedAt: null\n      phase: Smoked\n      pods:\n      - ip: 172.31.230.23\n        name: 12122-sample-10010-2mwkt\n        phase: ContainersReady\n        port: 80\n        pullInStatus: \"\"\n      pulledInAt: null\n      startedAt: \"2021-09-13T12:49:04Z\"\n    failedReplicas: 0\n    finished: false\n    finishedAt: null\n    finishedBatches: 0\n    finishedReplicas: 0\n    paused: false\n    phase: BatchStarted\n    pods:\n    - 12122-sample-10010-2mwkt\n    replicas: 1\n    replicasToProcess: 3\n    startedAt: \"2021-09-13T12:49:04Z\"\n    updateRevision: 12122-sample-10010-6ddf9b7cf4\n    updatedAt: \"2021-09-13T12:49:21Z\"\n    updatedReadyReplicas: 0\n    updatedReplicas: 1\n  ```\n\n  可以看到目前在启动的是 `canary` 批次，该批次已经处于 `smoked` 阶段，该批次中的 pod 是 `12122-sample-10010-2mwkt` ，同时也能看到当前批次中 pod 的拉入状态、拉入时间等信息。\n\n  #### 将应用拉入流量\n\n在此之前我们可以先检查一下 Service 的状态：\n\n```bash\nkubectl describe svc sample-12122-svc -o yaml\n```\n\n从显示的结果来看，pod `12122-sample-10010-2mwkt` 并没有出现在 Service 的 `Endpoints` 中，意味着当前应用没有正式接入流量：\n\n```yaml\nName:              sample-12122-svc\nNamespace:         default\nLabels:            app=12122\n                   app.kubernetes.io/instance=12122-sample-10010\n                   app.kubernetes.io/name=deploy-demo-hello\n                   group=10010\n                   managed-by=triton-io\nAnnotations:       \u003cnone\u003e\nSelector:          app.kubernetes.io/instance=12122-sample-10010,app.kubernetes.io/name=deploy-demo-hello,app=12122,group=10010,managed-by=triton-io\nType:              ClusterIP\nIP Families:       \u003cnone\u003e\nIP:                10.22.6.154\nIPs:               \u003cnone\u003e\nPort:              web  80/TCP\nTargetPort:        80/TCP\nEndpoints:\nSession Affinity:  None\nEvents:            \u003cnone\u003e\n```\n\n接下来我们执行拉入操作(Bake)，对应 pod 的状态会从 `ContainerReady` 变为 `Ready`，从而被挂载到对应 Service 的 Endpoints 上开始正式接入流量：\n\n```bash\ngrpcurl --plaintext -d '{\"deploy\":{\"name\":\"12122-sample-10010-df\",\"namespace\":\"default\"}}' localhost:8099 deployflow.DeployFlow/Next\n```\n\n再次检查 DeployFlow，Service，CloneSet 的状态后，发现 Pod 已被挂载到 Endpoints，DeployFlow 的 `UPDATED_READY_REPLICAS` 字段变为 1，金丝雀批次进入 `baking` 阶段，如果此时应用正常工作，我们再次执行上面的 `Next` 操作，将 DeployFlow 置为 `baked` 阶段，表示本批次点火成功，应用流量正常。\n\n#### Rollout 操作\n\n金丝雀批次到达 `baked` 阶段后，执行 `Next` 操作就会进入后面的普通批次发布，由于我们应用的副本数量设置为 3，去掉金丝雀批次中的一个副本后，还剩 2 个，而 batchSize 的大小为 1，所有剩余的普通批次会分两个批次发布，两个批次之间会间隔 10s 触发。\n\n```bash\ngrpcurl --plaintext -d '{\"deploy\":{\"name\":\"12122-sample-10010-df\",\"namespace\":\"default\"}}' localhost:8099 deployflow.DeployFlow/Next\n```\n\n![](https://tva1.sinaimg.cn/large/008i3skNgy1gufd0ojjm2j62eg04a3z902.jpg)\n\n![](https://tva1.sinaimg.cn/large/008i3skNly1gufb22h1dej62dg04iwfk02.jpg)\n\n最后应用发布完成，检查 DeployFlow 的状态为 `Success`:\n\n![](https://tva1.sinaimg.cn/large/008i3skNgy1gufb2saqe6j629604gq3x02.jpg)\n\n再次查看 Service 的 Endpoints 可以看到本次发布的 3 个副本都已经挂载上去。\n\n再次回顾整个发布流程，可以总结为下面的状态流转图：\n\n![deployflow-status](https://tva1.sinaimg.cn/large/008i3skNly1gufb5ht6w9j61du0ingnw02.jpg)\n\n#### 暂停/继续 DeployFlow\n\n在部署过程中，如果要暂停 DeployFlow，可以执行 `Pause` 操作：\n\n```bash\ngrpcurl --plaintext -d '{\"deploy\":{\"name\":\"12122-sample-10010-df\",\"namespace\":\"default\"}}' localhost:8099 deployflow.DeployFlow/Pause\n\n```\n\n可以继续发布了，就执行 `Resume` 操作：\n\n```bash\ngrpcurl --plaintext -d '{\"deploy\":{\"name\":\"12122-sample-10010-df\",\"namespace\":\"default\"}}' localhost:8099 deployflow.DeployFlow/Resume\n\n```\n\n#### 取消本次发布\n\n如果在发布过程中，遇到启动失败，或者拉入失败的情况，要取消本次发布，可执行 `Cancel` 操作：\n\n```bash\ngrpcurl --plaintext -d '{\"deploy\":{\"name\":\"12122-sample-10010-df\",\"namespace\":\"default\"}}' localhost:8099 deployflow.DeployFlow/Cancel\n\n```\n\n#### 启动一个扩缩容 DeployFlow\n\n同样可以使用 `auto` 或 `mannual` 模式划分多个批次来执行扩缩容操作。 当一个 CloneSet 缩容时，有时用户倾向于删除特定的 Pod，可以使用 podsToDelete 字段实现指定 Pod 缩容：\n\n```bash\nkubectl get pod | grep 12122-sample\n12122-sample-10010-2mwkt                      1/1     Running             0          29m\n12122-sample-10010-hgdp6                      1/1     Running             0          9m55s\n12122-sample-10010-zh98f                      1/1     Running             0          10m\n```\n\n我们在缩容的时候指定被缩掉的 Pod 为 `12122-sample-10010-zh98f  `:\n\n```bash\ngrpcurl --plaintext -d '{\"instance\":{\"name\":\"12122-sample-10010\",\"namespace\":\"default\"},\"replicas\":2,\"strategy\":{\"podsToDelete\":[\"12122-sample-10010-zh98f\"],\"batchSize\":\"1\",\"batches\":\"1\",\"batchIntervalSeconds\":10}}' \\\nlocalhost:8099 application.Application/Scale\n{\n  \"deployName\": \"12122-sample-10010-kvn6b\"\n}\n\n❯ kubectl get pod | grep 12122-sample\n12122-sample-10010-2mwkt                      1/1     Running             0          29m\n12122-sample-10010-zh98f                      1/1     Running             0          11m\n\n\n```\n\nCloneSet 被缩容为 2 个副本，被缩容的 Pod 正是指定的那个。该功能的实现得益于 OpenKruise 中增强型无状态 workload CloneSet 提供的能力，具体的功能描述可以参考 OpenKruise 文档。\n\n在操作过程中，Triton 也提供了 `Get` 方法实时获取当前 DeployFlow 的 Pod 信息：\n\n```bash\ngrpcurl --plaintext -d '{\"deploy\":{\"name\":\"12122-sample-10010-df\",\"namespace\":\"default\"}}' localhost:8099 deployflow.DeployFlow/Get\n```\n\n```json\n{\n  \"deploy\": {\n    \"namespace\": \"default\",\n    \"name\": \"12122-sample-10010-df\",\n    \"appID\": 12122,\n    \"groupID\": 10010,\n    \"appName\": \"deploy-demo-hello\",\n    \"instanceName\": \"12122-sample-10010\",\n    \"replicas\": 3,\n    \"action\": \"create\",\n    \"availableReplicas\": 3,\n    \"updatedReplicas\": 3,\n    \"updatedReadyReplicas\": 3,\n    \"updateRevision\": \"6ddf9b7cf4\",\n    \"conditions\": [\n      {\n        \"batch\": 1,\n        \"batchSize\": 1,\n        \"canary\": true,\n        \"phase\": \"Baked\",\n        \"pods\": [\n          {\n            \"name\": \"12122-sample-10010-2mwkt\",\n            \"ip\": \"172.31.230.23\",\n            \"port\": 80,\n            \"phase\": \"Ready\",\n            \"pullInStatus\": \"PullInSucceeded\"\n          }\n        ],\n        \"startedAt\": \"2021-09-13T12:49:04Z\",\n        \"finishedAt\": \"2021-09-13T13:07:43Z\"\n      },\n      {\n        \"batch\": 2,\n        \"batchSize\": 1,\n        \"phase\": \"Baked\",\n        \"pods\": [\n          {\n            \"name\": \"12122-sample-10010-zh98f\",\n            \"ip\": \"172.31.226.94\",\n            \"port\": 80,\n            \"phase\": \"Ready\",\n            \"pullInStatus\": \"PullInSucceeded\"\n          }\n        ],\n        \"startedAt\": \"2021-09-13T13:07:46Z\",\n        \"finishedAt\": \"2021-09-13T13:08:03Z\"\n      },\n      {\n        \"batch\": 3,\n        \"batchSize\": 1,\n        \"phase\": \"Baked\",\n        \"pods\": [\n          {\n            \"name\": \"12122-sample-10010-hgdp6\",\n            \"ip\": \"172.31.227.215\",\n            \"port\": 80,\n            \"phase\": \"Ready\",\n            \"pullInStatus\": \"PullInSucceeded\"\n          }\n        ],\n        \"startedAt\": \"2021-09-13T13:08:15Z\",\n        \"finishedAt\": \"2021-09-13T13:08:45Z\"\n      }\n    ],\n    \"phase\": \"Success\",\n    \"finished\": true,\n    \"batches\": 3,\n    \"batchSize\": 1,\n    \"finishedBatches\": 3,\n    \"finishedReplicas\": 3,\n    \"startedAt\": \"2021-09-13T12:49:04Z\",\n    \"finishedAt\": \"2021-09-13T13:08:45Z\",\n    \"mode\": \"auto\",\n    \"batchIntervalSeconds\": 10,\n    \"canary\": 1,\n    \"updatedAt\": \"2021-09-13T13:08:45Z\"\n  }\n}\n```\n\n## TODOS\n\n上面演示的就是 Triton 提供的核心能力。对于基础团队来说，Triton 不仅仅是一个开源项目，它也是一个真实的比较接地气的云原生持续交付项目。通过开源，我们希望 Triton 能丰富云原生社区的持续交付工具体系，为更多开发者和企业搭建云原生化的 PaaS 平台助力，提供一种现代的、高效的的技术方案。\n\n开源只是迈出的一小步，未来我们会进一步推动 Triton 不断走向完善，包括但不限于以下几点：\n\n- 支持自定义注册中心，可以看到目前 Triton 采用的是 k8s 原生的 Service 作为应用的注册中心，但据我们所了解，很多企业都使用自定义的注册中心，比如 spring cloud 的 Nacos 等；\n- 提供 helm 安装方式；\n- 完善 REST \u0026 GRPC API 以及相应文档；\n- 结合内外部用户需求，持续迭代。项目开源后，我们也会根据开发者需求开展迭代。\n\n欢迎大家向 Triton 提交 issue 和 PR 共建 Triton 社区。我们诚心期待更多的开发者加入，也期待 Triton 能够助力越来越多的企业快速构建云原生持续交付平台。如果有企业或者用户感兴趣，我们可以提供专项技术支持和交流，欢迎入群咨询。\n\n### 相关链接\n\n项目地址：https://github.com/triton-io/triton\n\n### 交流群\n\n\u003cimg src=\"https://tva1.sinaimg.cn/large/008i3skNgy1gufd1pbwh9j60e60iuabg02.jpg\" alt=\"triton-wechat\" style=\"zoom:67%;\" /\u003e\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftriton-io%2Ftriton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftriton-io%2Ftriton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftriton-io%2Ftriton/lists"}