ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Flynn Controller API 实战指南:认证、核心资源与事件流调用详解

Flynn Controller API 实战指南:认证、核心资源与事件流调用详解 云原生微服务容器编排运维【免费下载链接】flynn[UNMAINTAINED] A next generation open source platform as a service (PaaS)项目地址https://gitcode.com/gh_mirrors/fl/flynn点击查看免费下载本篇技术指南围绕 Flynn 平台控制面Controller的 HTTP API 展开基于仓库中的官方 API 示例文档 docs/api-examples/controller.md 与配套的完整请求/响应样例 docs/api-examples/controller.json并结合 controller/ 模块源码进行底层原理验证。读完本文你将掌握 Controller API 的 Basic Auth 认证机制、核心资源App、Artifact、Release、Formation、Job、Deployment、Route、Provider/Resource的增删改查调用方式、日志与事件流的 SSE 订阅技巧以及各资源字段的取值规则与背后的实现逻辑。API 概览与认证方式Flynn 的 Controller 是集群控制面对外提供一套基于 HTTP 的 REST 风格 API供 CLI如 cli/、Dashboard 以及其他系统组件调用。其 API 根地址就是 Controller 应用自身的域名默认形如https://controller.$CLUSTER_DOMAIN例如在本地开发集群中通常为https://controller.dev.localflynn.com。认证Basic Auth Controller Key所有请求都通过 Basic Auth 进行认证规则如下用户名username为空字符串密码password为你的 Controller KeyAUTH_KEY认证请求头形如Authorization: Basic OnMzY3IzdA其中OnMzY3IzdA就是: key的 Base64 编码冒号前为空的用户名。获取你自己的 Controller Key 的 CLI 命令flynn -a controller env get AUTH_KEY之所以 key 存放在名为controller的系统应用的环境变量中是因为 Controller 进程本身以 Flynn 应用的方式运行从 controller/controller.go 可以看到AUTH_KEY被直接作为认证密钥注入handlerConfig.keys再传给authorizer.New(...)。从 controller/authorizer/authorizer.go 的源码可以看到完整的认证判定顺序若请求头携带Authorization: Bearer ...走 JWT 风格 token 校验否则解析 Basic Auth若用户名为Bearer同样走 token 校验其余情况一律将 Basic Auth 的密码当作 Controller Key与配置的authKeys列表做常数时间比较subtle.ConstantTimeCompare见 authorizer.go防止时序侧信道攻击。此外AUTH_KEY支持逗号分隔的多 key 配置controller.go 中按,切分并可通过AUTH_KEY_IDS为每个 key 绑定一个 ID用于审计日志中标识调用方身份controller.go 会将认证 ID 写入Flynn-Auth-ID与Flynn-Auth-User请求头。事件流的特殊认证方式对于SSE 事件流接口GET /events、日志流等除了 Basic Auth 之外还允许通过 URL 参数key直接携带 Controller Key例如https://controller.$CLUSTER_DOMAIN/events?key$AUTH_KEY这一设计是为了让浏览器中的 JavaScript无法自定义 Authorization 头也能订阅事件流。注意普通 REST 接口不支持key参数只有事件流类接口可以使用。App应用生命周期管理App 是 Process Formation进程编排、资源依赖和元数据的命名空间参见 schema/controller/app.json 中对 App 的描述。示例文档中的 App 相关端点如下端点方法作用/appsPOST创建应用/appsGET列出所有应用/apps/:apps_idGET获取单个应用/apps/:apps_idPOST更新应用如 meta/apps/:apps_idDELETE删除应用/apps/:apps_id/logGET获取应用日志支持 SSE 流/apps/:apps_id/releaseGET/PUT读取/设置当前 Release/apps/:apps_id/releasesGET列出应用的所有 Release/apps/:apps_id/resourcesGET列出应用绑定的资源/apps/:apps_id/formationsGET列出应用的 Formation/apps/:apps_id/jobsGET/POST列出/运行 Job/apps/:apps_id/deployPOST触发一次部署/apps/:apps_id/routesGET/POST列出/创建路由创建应用POST /apps Content-Type: application/json Authorization: Basic OnMzY3IzdA {name: my-app, meta: null}成功响应200{ id: adcccdb4-b1a4-4209-a03a-762f4e021632, name: my-app, meta: {}, strategy: all-at-once, deploy_timeout: 30, created_at: 2015-12-16T02:20:56.657428Z, updated_at: 2015-12-16T02:20:56.657428Z }应用名校验规则示例文档中专门给出了一个创建失败的样例当 name 不合法时API 返回validation_error{ code: validation_error, message: name String must match the pattern: \^[a-z\\d](-[a-z\\d])*$\., detail: {field: name}, retry: false }该正则的语义是应用名只能由小写字母与数字组成且只能用单个连字符-分隔各段如my-app合法this is not valid、MyApp、a--b均不合法。这与 schema/controller/app.json 中name字段的约束完全一致maxLength: 100、minLength: 1、pattern 如上。CRUD 入口的校验逻辑位于 controller/crud.go所有写入请求在落库前都会经过 controller/schema 的 JSON Schema 校验。App 的关键字段id全局唯一 IDUUIDname应用名命名空间标识meta任意键值对元数据可为null创建时传null响应会规范化为{}。系统应用会带有flynn-system-app: true标记strategy部署策略常见取值all-at-once、one-by-one、discoverd-meta、postgres等从示例中 controller 集群的各系统应用可见deploy_timeout单次部署超时秒数普通应用默认 30Postgres/Discoverd/Controller 等数据面应用为 120release当前绑定的 Release IDcreated_at/updated_atRFC3339 时间戳。更新与删除更新应用使用 POST非 PUT例如给 meta 追加内容POST /apps/adcccdb4-b1a4-4209-a03a-762f4e021632 Content-Type: application/json {id: adcccdb4-b1a4-4209-a03a-762f4e021632, meta: {bread: with hemp}}响应中 meta 变为{bread: with hemp}。从 controller/app.go 可以看到更新接口的细节它支持部分更新appUpdate 是map[string]interface{}并对{meta: null}做了特殊处理等价于不更新 meta 字段。删除应用DELETE /apps/adcccdb4-b1a4-4209-a03a-762f4e021632删除并非同步执行而是把app_deletion任务入队controller/app.go由后台 workercontroller/worker/app_deletion/异步完成路由、资源、Job 的清理最终会触发app_deletion类型的事件详见下文事件流部分。应用日志获取最近 10 行日志GET /apps/f7064b9f-c968-4f16-be0e-f2efd1b2c7b7/log?lines10普通模式下响应为text/plain每行是一个 JSON 对象包含host_id、job_id、msg、process_type、source、stream、timestamp字段。若请求头带上Accept: text/event-stream则返回 SSE 流每条日志以data: {event:message,data:{...}}形式推送结束时发送data: {event:eof}。从 controller/app.go 可以看到日志接口支持的查询参数lines返回行数followtrue持续跟随输出配合FlushWriter实现流式输出job_id只取指定 Job 的日志process_type只取指定进程类型如web的日志stream_types逗号分隔可取值stdout、stderr等。日志数据实际来自 logaggregator 组件logaggregator/Controller 通过logaggc.GetLog(appID, opts)拉取后再透传。Artifact容器镜像的描述Artifact 代表一个可运行的容器镜像引用如 Docker 镜像或 slug 镜像是 Release 的基础。端点方法作用/artifactsPOST创建 Artifact/artifactsGET列出所有 Artifact创建 ArtifactPOST /artifacts Content-Type: application/json {type: docker, uri: https://dl.flynn.io/tuf?nameflynn/slugrunnerid...}响应200{ id: c1889f55-c244-43ce-af70-ead357daa6ec, type: docker, uri: https://dl.flynn.io/tuf?nameflynn/slugrunnerid..., created_at: 2015-12-16T02:21:06.727191Z }示例中所有系统组件的 Artifact URI 都指向经 TUF 签名的镜像地址dl.flynn.io/tuf?nameflynn/xxxidsha256...说明 Flynn 使用 TUFThe Update Framework做镜像分发与完整性校验相关工具见 pkg/tufutil/。Artifact 的字段type目前示例中均为docker。Release进程类型的定义Release 将 Artifact、环境变量与进程类型process type绑定描述如何运行一个版本。端点方法作用/releasesPOST创建 Release/releasesGET列出所有 Release创建 Release 的请求体{ artifact: c1889f55-c244-43ce-af70-ead357daa6ec, env: {some: info}, processes: { foo: {cmd: [ls, -l], env: {BAR: baz}} } }响应200——注意系统会自动补全资源限额{ id: 47154f8c-a604-469d-ae6a-e431990ddee8, artifact: c1889f55-c244-43ce-af70-ead357daa6ec, env: {some: info}, processes: { foo: { cmd: [ls, -l], env: {BAR: baz}, resources: { max_fd: {request: 10000, limit: 10000}, memory: {request: 1073741824, limit: 1073741824} } } }, created_at: 2015-12-16T02:21:06.731551Z }从响应可以看出默认资源规格max_fd的 request/limit 均为 10000memory的 request/limit 均为 1073741824 字节1 GiB。这些默认值由 host 侧的资源模块注入相关定义见 host/resource。Release 的processes是map[进程名]ProcessType每个 ProcessType 可包含cmd/args启动命令env该进程类型专属环境变量ports端口声明数组每项含port、proto如tcp以及可选的service含name、create、check其中check可配置type如http、interval、threshold、path等健康检查参数参见 controller/api/api.goresources资源规格request与limit成对出现omni是否在每个宿主机上都运行host_network是否使用宿主机网络data是否为数据型进程示例中 postgres、discoverd 进程带有data: trueresurrect进程退出后是否自动复活系统关键进程均开启service注册到 discoverd 的服务名如gitreceive、controller-scheduler、discoverd、postgresmounts、volumes、linux_capabilities、allowed_devices、writeable_cgroups等高级字段完整字段映射见 controller/api/api.go。将 Release 绑定到 AppPUT /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/release Content-Type: application/json {id: 47154f8c-a604-469d-ae6a-e431990ddee8}查看 App 当前 ReleaseGET /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/release在示例中gitreceive系统应用的 release 展示了完整的进程定义其app进程声明了一个port: 0随机端口、proto: tcp、service.name: gitreceive、service.create: true的端口意味着该服务会自动注册到 discoverd 并创建对应的服务条目。Formation进程编排与扩容Formation 描述某个 App 的某个 Release 各进程类型要运行多少副本是缩放scale的核心对象。端点方法作用/apps/:apps_id/formations/:releases_idPUT创建/更新 Formation/apps/:apps_id/formations/:releases_idGET获取单个 Formation/apps/:apps_id/formations/:releases_idDELETE删除 Formation/apps/:apps_id/formationsGET列出 App 的所有 Formation/formationsGET列出全部 Formation支持activetrue过滤/formations?since...GETFormation 变更流SSE创建 FormationPUT /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/formations/47154f8c-a604-469d-ae6a-e431990ddee8 Content-Type: application/json {app: adcccdb4-b1a4-4209-a03a-762f4e021632, release: 47154f8c-a604-469d-ae6a-e431990ddee8, processes: {foo: 1}}响应200{ app: adcccdb4-b1a4-4209-a03a-762f4e021632, release: 47154f8c-a604-469d-ae6a-e431990ddee8, processes: {foo: 1}, created_at: 2015-12-16T02:21:06.748757Z, updated_at: 2015-12-16T02:21:06.748757Z }展开视图与活跃 Formation 流单个 Formation 支持?expandtrue展开内嵌的 app、release、artifact 完整对象GET /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/formations/47154f8c-a604-469d-ae6a-e431990ddee8?expandtrueGET /formations?activetrue则返回所有活跃有副本数的 Formation 的展开视图——示例响应中可以看到 controller 集群全部 12 个系统应用的完整形态包括controllerscheduler/web/worker 三个进程类型、routeromni: true、host_network: true、TCP 端口段 3000-3500、postgresdata: true、端口 5432、discoverddata: true、端口 1111/53等是理解 Flynn 系统组件编排方式的绝佳样例。Formation 变更流使用 SSE 且支持since参数回溯历史GET /formations?since1970-01-01T00:00:00Z Accept: text/event-stream每帧data:携带一条完整的展开 Formation含 app、release、artifact、processes最后以{updated_at:0001-01-01T00:00:00Z}标记结束。Deployment一次完整的滚动发布Deployment 描述从旧 Release 切换到新 Release的一次发布动作。端点方法作用/apps/:apps_id/deployPOST创建部署/apps/:apps_id/deploymentsGET列出 App 的部署历史/deployments/:deployment_idGET获取单个部署详情创建部署POST /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/deploy Content-Type: application/json {id: 77e9e956-ecf9-427f-a031-222c2f394fb8}响应200——返回 Deployment 对象{ id: aab1ee14-776d-4ba4-979b-1b4bda2d9b35, app: adcccdb4-b1a4-4209-a03a-762f4e021632, old_release: 47154f8c-a604-469d-ae6a-e431990ddee8, new_release: 77e9e956-ecf9-427f-a031-222c2f394fb8, strategy: all-at-once, status: pending, processes: {foo: 1}, deploy_timeout: 30, created_at: 2015-12-16T02:21:16.782263Z }Deployment 状态机取值pending→running→complete异常时为failed相关状态映射见 controller/api/api.go。部署动作由 controller/deployment.go 触发实际执行逻辑在 controller/worker/deployment/ 中会根据 App 的strategy如all-at-once、one-by-one按序拉起新 Job、摘除旧 Job并实时推送deployment、job、scale事件见事件流一节。Job容器中的单个进程Job 是运行在容器中的单个进程实例其状态枚举在 schema/controller/job.jsonpending、starting、up、stopping、down、crashed、failed。端点方法作用/apps/:apps_id/jobsPOST运行一个新 Job一次性任务/apps/:apps_id/jobsGET列出 App 的所有 Job/apps/:apps_id/jobs/:jobs_idGET获取 Job 详情/apps/:apps_id/jobs/:jobs_idPUT更新 Job 状态/apps/:apps_id/jobs/:jobs_idDELETE终止 Job运行一次性 Job示例中cmd里的$BODY会被 env 展开POST /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/jobs Content-Type: application/json {release: 77e9e956-ecf9-427f-a031-222c2f394fb8, cmd: [echo, $BODY], env: {BODY: Hello!}}响应200——返回 Job ID 与命令{id: host-40cc2d07-7a48-4fda-9790-ba9768a3f616, release: 77e9e956-ecf9-427f-a031-222c2f394fb8, cmd: [echo, $BODY]}Job ID 的格式为host-UUID宿主机 ID UUID 拼接从 controller/jobs.go 可见其生成方式cluster.GenerateJobID(hostID, uuid)。Job 会被随机调度到一个宿主机上环境变量会自动注入FLYNN_APP_ID、FLYNN_RELEASE_ID、FLYNN_JOB_ID等系统变量且 metadata 会写入flynn-controller.app、flynn-controller.app_name、flynn-controller.release标签controller/jobs.go。若请求头携带Upgrade: flynn-attach/0API 会升级为双向流式 attach 通道用于flynn run类交互式场景。终止 JobDELETE /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/jobs/host-40cc2d07-7a48-4fda-9790-ba9768a3f616从 controller/jobs.go 可以看到KillJob 会先查出 Job 所在的宿主机再调用client.StopJob(job.ID)真正停止容器未落宿主的 Job 无法被杀掉返回校验错误。RouteHTTP 与 TCP 路由规则Route 定义外部流量如何进入应用目前示例覆盖 HTTP 路由。端点方法作用/apps/:apps_id/routesPOST创建路由/apps/:apps_id/routesGET列出路由/apps/:apps_id/routes/:routes_type/:routes_idGET获取路由/apps/:apps_id/routes/:routes_type/:routes_idPUT更新路由/apps/:apps_id/routes/:routes_type/:routes_idDELETE删除路由创建 HTTP 路由POST /apps/adcccdb4-b1a4-4209-a03a-762f4e021632/routes Content-Type: application/json {type: http, service: my-app-web, domain: http://example.com}响应200{ type: http, id: 5bfb9c8b-ae1f-4a5a-af0c-94fa2996d543, parent_ref: controller/apps/adcccdb4-b1a4-4209-a03a-762f4e021632, service: my-app-web, created_at: 2015-12-16T02:21:06.704111Z, updated_at: 2015-12-16T02:21:06.704111Z, domain: http://example.com, path: / }HTTP 路由关键字段domain对外域名示例中既有http://example.com也有 Flynn 自动生成的app-name.cluster-domain默认路由如my-app-...dev.localflynn.compath路径前缀默认/service后端 discoverd 服务名sticky是否开启会话粘滞示例更新响应中出现sticky: trueparent_ref路由归属引用格式controller/apps/app-id。更新路由使用 PUT可将service改为其他后端并开启 sticky。路由数据最终同步到 router/ 组件生效Router 的 HTTP/TCP 路由类型定义见 router/types/types.go。Provider 与 Resource外部服务资源Provider 描述一类外部资源服务如 PostgreSQL、MySQL、Redis 的托管服务Resource 则是 Provider 上实际开通的一份资源实例如一个数据库。端点方法作用/providersPOST/GET创建/列出 Provider/providers/:providers_idGET获取 Provider/providers/:providers_id/resourcesPOST/GET开通/列出资源/providers/:providers_id/resources/:resources_idGET/PUT/DELETE管理单个资源/apps/:apps_id/resourcesGET列出 App 绑定的资源创建 ProviderPOST /providers Content-Type: application/json {url: http://example-provider-xxx.discoverd:12345/providers/xxx, name: example-provider-xxx}开通资源config可携带 Provider 要求的参数如数据库名POST /providers/0952f692-2667-4be0-a159-9d68382a262c/resources Content-Type: application/json {config: {}}响应200——Provider 返回的连接信息以env键值对形式呈现{ id: 100c3daa-333b-4f46-92bf-414745dc974d, provider: 0952f692-2667-4be0-a159-9d68382a262c, env: {some: data}, created_at: 2015-12-16T02:21:16.833363Z }当资源已绑定到某 App 后资源对象中会出现apps数组被绑定的 App ID 列表与external_idProvider 侧的外部标识。示例中postgresProvider 的地址为http://postgres-api.discoverd/databases其资源数据库的env会包含PGHOST、PGUSER、PGPASSWORD、PGDATABASE、DATABASE_URL等标准连接信息——这在formations_list_active的系统应用展开样例中清晰可见router、blobstore、controller 应用的 env 中都有形如postgres://user:passleader.postgres.discoverd:5432/dbname的DATABASE_URL。事件系统Event 查询与 SSE 订阅Controller 会为集群中的所有重要变化app 创建/删除、job 状态迁移、deployment 推进、release 创建、resource 开通、route 变更、scale 变化等记录事件并可被客户端订阅。端点方法作用/events/:idGET按 ID 获取单条事件/events?count10GETAccept: application/json列出历史事件/events?count10pasttrueGETAccept: text/event-streamSSE 事件流可回溯事件对象结构示例中的事件对象如 resource 开通事件{ id: 111, app: adcccdb4-b1a4-4209-a03a-762f4e021632, object_type: resource, object_id: cc9f3342-bed0-4ed3-840e-c462e05808c6, data: {id: cc9f3342-bed0-4ed3-840e-c462e05808c6, env: {FOO: BAR}, apps: [adcccdb4-b1a4-4209-a03a-762f4e021632], provider: 0952f692-2667-4be0-a159-9d68382a262c, created_at: ..., external_id: /foo/bar}, created_at: 2015-12-16T02:21:16.838613Z }从示例可见的事件object_type包括app、app_deletion、release、artifact、job、deployment、scale、resource、resource_deletion、route、route_deletion等。事件列表查询参数从 controller/events.go 的listEvents实现可以看到支持app_id按应用过滤count返回条数示例count10since_id/before_id按事件 ID 区间过滤object_types逗号分隔的事件类型过滤object_id按对象 ID 过滤。SSE 事件流GET /events?count10pasttrue Accept: text/event-stream Last-Event-Id: 0要点结合 controller/events.go 源码pasttrue先回放历史事件按 ID 升序逐条推送再持续推送新事件Last-Event-Id断点续传服务端会把该 ID 之后的事件补发事件流帧格式每帧为data: {event:message,data:{...}}示例响应清晰展示了一次完整部署周期的事件序列job starting → up → down、deployment pending → running、scale 变更、route_deletion、resource_deletion、app_deletion非常适合用来观测部署全流程事件 ID 为单调递增的整数客户端可用它做去重与断点续传流结束标志日志流发送data: {event:eof}Formation 流发送{updated_at:0001-01-01T00:00:00Z}。事件流之所以允许用keyURL 参数代替 Basic Auth正是为了让浏览器端 SSEEventSource无法自定义请求头可以正常消费controller.md 中明确说明。其他系统级端点除了上述资源类 APIController 还暴露若干集群级端点路由注册见 controller/controller.go端点方法作用/ca-certGET获取集群 CA 证书application/x-x509-ca-cert无需认证/backupGET下载集群备份 tar 包Content-Disposition: attachment/domainPUT发起集群域名迁移/pingGET存活探测返回 200/statusGET健康状态含数据库 ping 检查见 controller.go/sinksPOST/GET/DELETE管理日志汇聚 sink/volumesGET/PUT管理卷/active-jobsGET列出全集群活跃 Job例如GET /backup响应Content-Disposition: attachment; filenameflynn-backup-2015-12-16_022126.tar Content-Type: application/tarPUT /domain发起域名迁移的请求与响应示例展示了old_domain与domain两个核心字段响应对象会携带迁移 ID 与新域名对应的 TLS 证书cert/key迁移流程由 controller/worker/domain_migration/ 后台执行相关接口实现在 controller/domain.go。实战要点小结认证所有请求事件流除外使用空用户名 Controller Key 的 Basic Auth事件流可改用?key参数方便浏览器 SSE 消费Key 通过flynn -a controller env get AUTH_KEY获取支持多 Key 轮换与 Key ID 审计。对象关系App命名空间→ Release版本定义→ Artifact镜像引用FormationAppRelease 的副本数驱动 Job容器进程运行Deployment 负责新旧 Release 的平滑切换Route 把外部流量导向服务的 JobProvider/Resource 提供外部服务连接信息。部署观察发起POST /apps/:id/deploy后通过GET /eventsAccept: text/event-stream、Last-Event-Id断点续传可实时跟踪 job 的 starting/up/down 与 deployment 的 pending/running/complete 全流程。默认资源规格未显式指定时Release 进程的max_fd与memory会被补全为 10000 / 1 GiB磁盘等资源可参考 host/resource 的默认值定义。校验前置所有写接口在落库前都经过 JSON Schema 校验如 App 名的^[a-z\d](-[a-z\d])*$正则非法输入统一返回{code:validation_error,detail:{field:...}}结构。如需进一步探索可阅读完整的请求/响应样例 docs/api-examples/controller.json覆盖 60 余个端点的真实抓包级示例、Controller 路由注册表 controller/controller.go、CRUD 通用实现 controller/crud.go以及各资源的 JSON Schema 定义目录 schema/controller/。赞分享云原生微服务容器编排运维【免费下载链接】flynn[UNMAINTAINED] A next generation open source platform as a service (PaaS)项目地址https://gitcode.com/gh_mirrors/fl/flynn点击查看免费下载相关推荐Sphinx 事件管理器 API 详解EventManager 与核心事件系统实战Sphinx 事件管理器 API 详解EventManager 与核心事件系统实战 导读 Sphinx 文档生成器把整个构建过程拆分成一系列可被挂接的事件文档开发工具超实用BayesianOptimization核心API详解与实战指南超实用BayesianOptimization核心API详解与实战指南 BayesianOptimization是一个强大的Python库专为黑盒函数优化设机器学习Neovim 代码补全与片段使用 nvim-cmp 实现 VSCode 级体验Neovim 代码补全与片段使用 nvim cmp 实现 VSCode 级体验 Neovim 作为一款强大的文本编辑器通过插件可以实现媲美 VSCode 的创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表