这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

文档

一个开放、统一、轻量级、更简单的容器即服务 (CaaS)。

欢迎使用 Drycc

Drycc Workflow 是一个开源容器云平台。

通常我们也称之为容器即服务 (CaaS),它为任何 Kubernetes 集群添加了一个开发者友好的层,使部署和管理应用程序变得容易。

Drycc Workflow 包括通过 git push 从源代码构建和部署的能力、简单的应用程序配置、创建和回滚发布、管理域名和 SSL 证书、提供无缝边缘路由、聚合日志以及与团队共享应用程序。所有这些都通过简单的 REST API 和命令行界面公开。

开始使用

要开始使用 Workflow,请遵循我们的 快速开始 指南。

在我们的 概念架构组件 部分深入了解 Drycc Workflow。

想要贡献一些代码或想成为维护者?选择一个标记为 简单修复需要帮助 的问题并开始贡献!

1 - 快速开始

部署您的第一个应用并掌握 Drycc 基础知识的分步指南。

1.1 - 快速开始

本指南帮助您设置 Drycc Workflow。

通过三个简单步骤开始使用 Drycc Workflow。

  1. 为 Helm 和 Drycc Workflow 安装 CLI 工具
  2. 启动 Kubernetes 并安装 Drycc Workflow
  3. 部署您的第一个应用

本指南将帮助您设置适合评估、开发和测试的集群。当您准备好进行暂存和生产时,请查看我们的生产清单

步骤 1:安装 Workflow

对于快速开始,我们将安装 Drycc Workflow

步骤 2:安装 CLI 工具

对于快速开始,我们将安装 Drycc Workflow CLI

步骤 3:部署您的第一个应用

最后但同样重要的是,登录并部署您的第一个应用

1.2 - 安装 Workflow

在纯主机上安装 Workflow,它可以是云服务器、裸机服务器、虚拟机,甚至您的笔记本电脑。

如果您有一个纯主机,它可以是云服务器、裸机服务器、虚拟机,甚至您的笔记本电脑。那么本章非常适合您。

操作系统

Drycc 预计可以在大多数现代 Linux 系统上运行。一些 OSS 有特定要求:

  • (Red Hat/CentOS) Enterprise Linux,它们通常使用 RPM 包管理。
  • Ubuntu (Desktop/Server/Cloud) Linux,一个非常流行的发行版。
  • Debian GNU Linux,一个非常纯净的开源软件发行版。

如果您想添加更多 Linux 发行版支持,请在 GitHub 上提交 issue 或直接提交 PR。

系统软件

在安装 drycc workflow 之前,需要安装一些基本软件。

OS 配置

K8s 需要大量端口。如果您不确定它们是什么,请关闭本地防火墙或打开这些端口。 同时,因为 k8s 需要系统时间,您需要确保系统时间正确。

安装 NFSv4 客户端

安装 NFSv4 客户端的命令因 Linux 发行版而异。

对于 Debian 和 Ubuntu,使用此命令:

$ apt-get install nfs-common

对于 RHEL、CentOS 和 EKS 与 AmazonLinux2 镜像的 EKS Kubernetes Worker AMI,使用此命令:

$ yum install nfs-utils

安装 curl

对于 Debian 和 Ubuntu,使用此命令:

$ apt-get install curl

对于 RHEL、CentOS 和 EKS 与 AmazonLinux2 镜像的 EKS Kubernetes Worker AMI,使用此命令:

$ yum install curl

硬件

硬件要求基于您的部署规模而扩展。最低推荐在这里概述。

  • RAM:1G 最低(我们推荐至少 2GB)
  • CPU:1 最低

此配置仅包含满足操作的最低要求。

磁盘

Drycc 性能取决于数据库的性能。为了确保最佳速度,我们推荐尽可能使用 SSD。磁盘性能在利用 SD 卡或 eMMC 的 ARM 设备上会有所不同。

域名

Drycc 需要一个完全由您控制的根域名,并将此域名指向要安装的服务器。 假设有一个通配符域名指向当前安装 drycc 的服务器,即名称 *.dryccdoman.com。 我们需要在安装前设置 PLATFORM_DOMAIN 环境变量。

$ export PLATFORM_DOMAIN=dryccdoman.co

当然,如果是测试环境,我们也可以使用 nip.io,一个 IP 到域名的服务。 例如,您的主机 IP 是 59.46.3.190,我们将获得以下域名 59.46.3.190.nip.io

$ export PLATFORM_DOMAIN=59.46.3.190.nip.io

安装

在安装之前,请确保您的安装环境是否是公网。 如果是内网环境且没有公网 IP,您需要禁用自动证书。

$ export CERT_MANAGER_ENABLED=false

然后您可以使用 https://www.drycc.cc/install.sh 上的安装脚本在基于 systemd 和 openrc 的系统上将 drycc 安装为服务。

$ curl -sfL https://www.drycc.cc/install.sh | bash -

安装节点

节点可以是简单的代理或服务器;服务器具有代理的功能。多个服务器具有高可用性,但服务器数量最多不应超过 7 个。代理数量没有限制。

  • 首先,检查主节点的集群令牌。
$ cat /var/lib/rancher/k3s/server/node-token
K1078e7213ca32bdaabb44536f14b9ce7926bb201f41c3f3edd39975c16ff4901ea::server:33bde27f-ac49-4483-b6ac-f4eec2c6dbfa

我们假设集群主节点的 IP 地址是 192.168.6.240,那样的话。

  • 然后,设置环境变量:
$ export K3S_URL=https://192.168.6.240:6443
$ export K3S_TOKEN="K1078e7213ca32bdaabb44536f14b9ce7926bb201f41c3f3edd39975c16ff4901ea::server:33bde27f-ac49-4483-b6ac-f4eec2c6dbfa"
  • 以服务器身份加入集群:
$ curl -sfL https://www.drycc.cc/install.sh | bash -s - install_k3s_server
  • 以代理身份加入集群:
$ curl -sfL https://www.drycc.cc/install.sh | bash -s - install_k3s_agent

安装选项

使用此方法安装 drycc 时,可以使用以下环境变量来配置安装:

环境变量 描述
PLATFORM_DOMAIN 必需项,指定 drycc 的域名
DRYCC_ADMIN_USERNAME 必需项,指定 drycc 的管理员用户名
DRYCC_ADMIN_PASSWORD 必需项,指定 drycc 的管理员密码
CERT_MANAGER_ENABLED 是否使用自动证书。默认是 false
CHANNEL 默认安装 stable 通道。您也可以指定 testing
KUBERNETES_SERVICE_HOST 设置为 kube-apiserver 前面的负载均衡器的 HOST
KUBERNETES_SERVICE_PORT 设置为 kube-apiserver 前面的负载均衡器的 PORT
METALLB_CONFIG_FILE metallb 配置文件路径,默认使用 layer 2 网络
LONGHORN_CONFIG_FILE Longhorn 配置文件路径
INSTALL_DRYCC_MIRROR 指定加速镜像位置。目前仅支持 cn
BUILDER_REPLICAS 要部署的构建器副本数
CONTROLLER_API_REPLICAS 要部署的控制器 API 副本数
CONTROLLER_CELERY_REPLICAS 要部署的控制器 celery 副本数
CONTROLLER_METRIC_REPLICAS 要部署的控制器指标副本数
CONTROLLER_MUTATE_REPLICAS 要部署的控制器变异副本数
CONTROLLER_WEBHOOK_REPLICAS 要部署的控制器 webhook 副本数
CONTROLLER_APP_RUNTIME_CLASS RuntimeClass 用于选择容器运行时配置。
CONTROLLER_APP_GATEWAY_CLASS drycc gateways 分配的 GatewayClass;默认使用默认 GatewayClass
CONTROLLER_APP_STORAGE_CLASS drycc volumes 分配的 StorageClass;默认使用默认 storageClass
VALKEY_PERSISTENCE_SIZE 分配给 valkey 的持久化空间大小,默认是 5Gi
VALKEY_PERSISTENCE_STORAGE_CLASS valkey 的 StorangeClass;默认使用默认 storangeclass
STORAGE_PERSISTENCE_SIZE 分配给 storage 的持久化空间大小,默认是 5Gi
STORAGE_PERSISTENCE_STORAGE_CLASS storage 的 StorangeClass;默认使用默认 storangeclass
MONITOR_GRAFANA_PERSISTENCE_SIZE 分配给 monitor.grafana 的持久化空间大小,默认是 5Gi
MONITOR_GRAFANA_PERSISTENCE_STORAGE_CLASS monitor grafana 的 StorangeClass;默认使用默认 storangeclass
DATABASE_PERSISTENCE_SIZE 分配给 database 的持久化空间大小,默认是 5Gi
DATABASE_PERSISTENCE_STORAGE_CLASS database 的 StorangeClass;默认使用默认 storangeclass
TIMESERIES_REPLICAS 要部署的时间序列副本数
TIMESERIES_PERSISTENCE_SIZE 分配给 timeseries 的持久化空间大小,默认是 5Gi
TIMESERIES_PERSISTENCE_STORAGE_CLASS timeseries 的 StorangeClass;默认使用默认 storangeclass
PASSPORT_REPLICAS 要部署的护照副本数
REGISTRY_REPLICAS 要部署的注册表副本数
HELMBROKER_API_REPLICAS 要部署的 helmbroker api 副本数
HELMBROKER_CELERY_REPLICAS 要部署的 helmbroker celery 副本数
HELMBROKER_PERSISTENCE_SIZE 分配给 helmbroker 的持久化空间大小,默认是 5Gi
HELMBROKER_PERSISTENCE_STORAGE_CLASS helmbroker 的 StorangeClass;默认使用默认 storangeclass
VICTORIAMETRICS_CONFIG_FILE victoriametrics 配置文件的路径,开启此项,下面的两个不会工作。
VICTORIAMETRICS_VMAGENT_PERSISTENCE_SIZE 分配给 victoriametrics vmagent 的持久化空间大小,默认是 10Gi
VICTORIAMETRICS_VMAGENT_PERSISTENCE_STORAGE_CLASS victoriametrics vmagent 的 StorangeClass;默认使用默认 storangeclass
VICTORIAMETRICS_VMSTORAGE_PERSISTENCE_SIZE 分配给 victoriametrics vmstorage 的持久化空间大小,默认是 10Gi
VICTORIAMETRICS_VMSTORAGE_PERSISTENCE_STORAGE_CLASS victoriametrics vmstorage 的 StorangeClass;默认使用默认 storangeclass
K3S_DATA_DIR k3s 数据目录的配置;如果未设置,使用默认路径
ACME_SERVER ACME 服务器 URL,默认使用 letsencrypt
ACME_EAB_KEY_ID 您的外部账户绑定所索引的密钥 ID
ACME_EAB_KEY_SECRET 您的外部账户对称 MAC 密钥的密钥 Secret

由于安装脚本将安装 k3s,其他环境变量可以参考 k3s 安装 环境变量

卸载

如果您使用安装脚本安装了 drycc,您可以使用此脚本卸载整个 drycc。

$ curl -sfL https://www.drycc.cc/uninstall.sh | bash -

1.3 - Drycc Workflow 客户端 CLI

如何下载、安装 Drycc CLI 工具。

Drycc Workflow 客户端 CLI

Drycc 命令行界面 (CLI) 让您与 Drycc Workflow 交互。 使用 CLI 创建、配置和管理应用程序。

使用以下命令为 Linux 或 Mac OS X 安装 drycc 客户端:

$ curl -sfL https://www.drycc.cc/install-cli.sh | bash -

其他人请访问:https://github.com/drycc/workflow-cli/releases

安装程序将 drycc 二进制文件放在当前目录中,但您应该将其移动到 $PATH 中的某个位置:

$ sudo ln -fs $PWD/drycc /usr/local/bin/drycc

$ sudo mv $PWD/drycc /usr/local/bin/drycc

通过运行 drycc version 检查您的工作:

$ drycc version
v1.1.0

将 workflow cli 更新到最新发布。

drycc update

1.4 - 部署您的第一个应用

使用 drycc cli 部署应用程序。

确定您的主机和主机名值

Drycc Workflow 需要一个通配符 DNS 记录来动态映射应用名称到路由器。

用户应该已经设置了 DNS 指向他们的已知主机。$hostname 值可以通过在 global.platformDomain 中设置的值前加上 drycc. 来计算。

登录到 Workflow

Workflow 使用 passport 组件创建和授权用户。 如果您已经有账户,使用 drycc login 对 Drycc Workflow API 进行身份验证。

$ drycc login http://drycc.example.com
Opening browser to http://drycc.example.com/v2/login/drycc/?key=4ccc81ee2dce4349ad5261ceffe72c71
Waiting for login... .o.Logged in as admin
Configuration file written to /root/.drycc/client.json

或者您可以使用用户名和密码登录

$ drycc login http://drycc.example.com --username=demo --password=demo
Configuration file written to /root/.drycc/client.json

部署应用程序

Drycc Workflow 支持三种不同类型的应用程序,Buildpacks、Dockerfiles 和容器镜像。我们的第一个应用程序将是一个简单的基于容器镜像的应用程序,所以您不必与检出代码搏斗。

运行 drycc create 在 Drycc Workflow 上创建一个新应用程序。如果您没有为应用程序指定名称,Workflow 会自动生成一个友好的(有时有趣的)名称。

$ drycc create --no-remote
Creating Application... done, created proper-barbecue
If you want to add a git remote for this app later, use `drycc git remote -a proper-barbecue`

我们的应用程序已创建并命名为 proper-barbecue。与 drycc 主机名一样,任何到 proper-barbecue 的 HTTP 流量将由边缘路由器自动路由到您的应用程序 pod。

让我们使用 CLI 告诉平台部署应用程序,然后使用 curl 向应用发送请求:

$ drycc pull drycc/example-go -a proper-barbecue
Creating build... done
$ curl http://proper-barbecue.$hostname
Powered by Drycc

Workflow 的边缘路由器知道所有关于应用程序名称的信息,并自动将流量发送到正确的应用程序。路由器将 proper-barbecue.104.197.125.75.nip.io 的流量发送到您的应用,就像 drycc.104.197.125.75.nip.io 被发送到 Workflow API 服务一样。

更改应用程序配置

接下来,让我们使用 CLI 更改一些配置。我们的示例应用构建为从环境读取配置。通过使用 drycc config set 我们可以更改应用程序的行为方式:

$ drycc config set POWERED_BY="Container Images + Kubernetes" -a proper-barbecue
Creating config... done

在幕后,Workflow 为您的应用程序创建了一个新发布,并使用 Kubernetes 提供零停机滚动部署到新发布!

验证我们的配置更改是否有效:

$ curl http://proper-barbecue.104.197.125.75.nip.io
Powered by Container Images + Kubernetes

扩展您的应用程序

最后,让我们通过添加更多应用程序进程来扩展我们的应用程序。使用 CLI 您可以轻松添加和删除额外的进程来服务请求:

$ drycc scale web=2 -a proper-barbecue
Scaling processes... but first, coffee!
done in 36s

NAME                                RELEASE    STATE    PTYPE       STARTED
proper-barbecue-v18-web-rk644       v18        up       web         2023-12-08T03:09:25UTC
proper-barbecue-v18-web-0ag04       v18        up       web         2023-12-08T03:09:25UTC

恭喜!您已使用 Drycc Workflow 部署、配置和扩展了您的第一个应用程序。

进一步探索

Drycc Workflow 可以做更多事情,试试 CLI:

2 - 理解 Workflow

理解 Workflow 的架构设计。

2.1 - 概念

Drycc Workflow 是一个轻量级应用程序平台,将十二因子应用作为容器部署并扩展到 Kubernetes 集群。

十二因子应用程序

十二因子应用 是一种构建现代应用程序的方法论,可以在分布式系统中扩展。

十二因子是对多年软件即服务应用经验的宝贵综合,特别是基于 Heroku 平台。

Workflow 旨在运行遵循 十二因子应用 方法论和最佳实践的应用程序。

Kubernetes

Kubernetes 是 Google 开发并捐赠给 云原生计算基金会 的开源集群管理器。Kubernetes 管理集群上的所有活动,包括:期望状态收敛、稳定服务地址、健康监控、服务发现和 DNS 解析。

Workflow 基于 Kubernetes 抽象如 Services、Deployments 和 Pods 来提供开发者友好的体验。从应用程序源代码直接构建容器、聚合日志、管理部署配置和应用发布只是 Workflow 添加的一些功能。

Drycc Workflow 是一组可通过 Helm 安装的 Kubernetes 原生组件。熟悉 Kubernetes 的系统工程师会觉得运行 Workflow 很自在。

有关更多详细信息,请参阅 组件 概述。

容器

[容器][] 是一个开源项目,用于构建、运输和运行任何应用程序作为轻量级、可移植、自给自足的容器。

如果您尚未将应用程序转换为容器,Workflow 提供了简单直接的“源代码到容器镜像”功能。通过社区 buildpacks 支持多种语言运行时,在容器中构建您的应用程序可以像 git push drycc master 一样简单。

使用 Dockerfile 或引用外部容器镜像的应用程序将不经修改地启动。

应用程序

Workflow 围绕 [应用程序][] 或应用的理念设计。

应用程序有三种形式之一:

  1. 存储在 git 仓库中的源文件集合
  2. 存储在 git 仓库中的 Dockerfile 和相关源文件
  3. 对容器仓库中现有镜像的引用

应用程序由唯一的名称标识以便轻松引用。如果您在创建应用程序时未指定名称,Workflow 会为您生成一个。Workflow 还管理相关信息,包括域名、SSL 证书和开发者提供的配置。

构建、发布、运行

Git Push Workflow

构建阶段

builder 组件处理传入的 git push drycc master 请求并管理您的应用程序打包。

如果您的应用程序使用 buildpack,builder 将启动一个临时作业来提取和执行打包指令。生成的应用程序工件由平台存储,用于运行阶段执行。

如果 builder 找到 Dockerfile,它将遵循这些指令创建容器镜像。生成的工件存储在 Drycc 管理的注册表中,将在运行阶段引用。

如果另一个系统已经构建并打包了您的应用程序,可以直接使用该容器工件。当引用 外部容器镜像 时,builder 组件不会尝试重新打包您的应用。

发布阶段

在发布阶段,build应用程序配置 结合创建新的编号 release。每当创建新构建或更改应用程序配置时,就会创建新发布。以“只写账本”的方式跟踪发布,使回滚到任何以前的发布变得容易。

运行阶段

运行阶段通过更改引用新发布的 Deployment 对象,将新发布部署到底层 Kubernetes 集群。通过管理期望副本计数,Workflow 编排应用程序的零停机滚动更新。一旦成功更新,Workflow 将删除对旧发布的最后引用。请注意,在部署期间,您的应用程序将在混合模式下运行。

后备服务

Workflow 将所有持久服务如数据库、缓存、存储、消息系统和其他 [后备服务][] 视为与您的应用程序分开管理的资源。这种理念与十二因子最佳实践一致。

应用程序使用 [环境变量][] 附加到后备服务。因为应用与后备服务解耦,它们可以独立扩展、使用其他应用提供的服务,或切换到外部或第三方供应商服务。

另请参阅

2.2 - 架构

Drycc Workflow 使用面向服务的架构构建。

所有组件都作为一组容器镜像发布,可以部署到任何兼容的 Kubernetes 集群。

概述

系统概述

操作员使用 Helm 配置和安装 Workflow 组件,这些组件直接与底层 Kubernetes 集群接口。服务发现、容器可用性和网络都委托给 Kubernetes,而 Workflow 提供干净简单的开发者体验。

平台服务

Workflow 概述

Drycc Workflow 为您的 Kubernetes 集群提供额外功能,包括:

  • 源到镜像构建器,通过 Buildpacks 或 Dockerfiles 编译您的应用程序代码
  • 简单 REST API,为 CLI 和任何外部集成提供支持
  • 应用程序发布和回滚
  • 对应用程序资源的身份验证和授权

Kubernetes 原生

所有平台组件和通过 Workflow 部署的应用程序都期望在现有的 Kubernetes 集群上运行。这意味着您可以愉快地在通过 Drycc Workflow 管理的应用程序旁边运行您的 Kubernetes 原生工作负载。

Workflow 和 Kubernetes

应用程序布局和边缘路由

默认情况下,Workflow 为每个应用程序创建命名空间和服务,因此您可以通过标准 Kubernetes 机制轻松将您的应用程序连接到集群上的其他服务。

应用程序配置

路由器组件负责将 HTTP/s 流量路由到您的应用程序,以及代理 git push 和平台 API 流量。

默认情况下,路由器组件作为类型为 LoadBalancer 的 Kubernetes 服务部署;根据您的配置,这将自动配置云原生负载均衡器。

路由器通过使用 Kubernetes 注解自动发现可路由的应用程序、SSL/TLS 证书和应用程序特定配置。对路由器配置或证书的任何更改都会在几秒钟内应用。

拓扑

Drycc Workflow 不再为您的部署规定特定的拓扑或服务器计数。平台组件可以在单服务器配置以及多服务器生产集群上愉快运行。

2.3 - 组件

Workflow 由许多小型、独立的服务的组合而成,创建了一个分布式 CaaS。

所有 Workflow 组件都作为服务(以及相关控制器)部署在您的 Kubernetes 集群中。如果您感兴趣,我们有更详细的 Workflow 架构 探索。

Workflow 的所有组件都是以可组合性为理念构建的。如果您需要为您的特定部署定制其中一个组件,或者在您自己的项目中需要该功能,我们邀请您尝试!

Controller

项目位置: drycc/controller

controller 组件是一个 HTTP API 服务器,作为 drycc CLI 的端点。controller 提供所有平台功能以及与您的 Kubernetes 集群的接口。controller 将其所有数据持久化到数据库组件。

Passport

项目位置: drycc/passport

passport 组件公开一个 Web API 并提供 OAuth2 身份验证。

Database

项目位置: drycc/postgres

database 组件是一个托管的 PostgreSQL 实例,保存平台的大部分状态。备份和 WAL 文件通过 WAL-E 推送到对象存储。当数据库重新启动时,备份从对象存储中获取并重放,因此不会丢失数据。

Builder

项目位置: drycc/builder

builder 组件负责通过 Git 接受代码推送并管理您的 Application 的构建过程。构建过程是:

  1. 通过 SSH 接收传入的 git push 请求
  2. 通过 SSH 密钥指纹验证用户
  3. 授权用户访问推送代码到应用程序
  4. 启动应用程序构建阶段(见下文)
  5. 通过 Controller 触发新的 Release

Builder 目前支持基于 buildpack 和 Dockerfile 的构建。

项目位置: drycc/imagebuilder

对于基于 Buildpack 的部署,builder 组件将在 drycc 命名空间中启动一个一次性 Job。此作业运行 imagebuilder 组件,该组件处理默认和自定义 buildpacks(由 .packbuilder 指定)。完成的镜像推送到集群上的托管容器注册表。有关 buildpacks 的更多信息,请参阅 使用 buildpacks

与基于 buildpack 的不同,对于包含根目录中 Dockerfile 的应用程序,它生成一个容器镜像(使用底层容器引擎)。有关更多信息,请参阅 使用 Dockerfiles

Object Storage

项目位置: drycc/storage

所有需要持久化数据的 Workflow 组件都会将它们发送到为集群配置的对象存储。例如,数据库发送其 WAL 文件,注册表存储容器镜像,slugbuilder 存储 slugs。

Workflow 支持集群内或集群外存储。对于生产部署,我们强烈推荐您配置 集群外对象存储

为了便于实验、开发和测试环境,默认的 Workflow 图表包括通过 storage 的集群内存储。

如果您也对使用 Kubernetes 持久卷感到满意,您可以配置存储以使用您的环境中可用的持久存储。

Registry

项目位置: drycc/registry

registry 组件是一个托管的容器注册表,保存从 builder 组件生成的应用程序镜像。Registry 将容器镜像持久化到本地存储(在开发模式下)或为集群配置的对象存储。

Quickwit

项目位置: drycc/quickwit

Quickwit 是第一个直接在云存储上执行复杂搜索和分析查询的引擎,具有亚秒级延迟。由 Rust 和其解耦的计算和存储架构提供支持,它被设计为资源高效、易于操作,并可扩展到 PB 级数据。

Quickwit 非常适合日志管理、分布式跟踪,以及通常不可变的数据,如对话数据(电子邮件、文本、消息平台)和基于事件的分析。

Fluentbit

项目位置: drycc/fluentbit

Fluent Bit 是一个快速且轻量级的遥测代理,用于 Linux、macOS、Windows 和 BSD 系列操作系统的日志、指标和跟踪。Fluent Bit 以强大的性能为重点而构建,允许从不同来源收集和处理遥测数据而无复杂性。

Victoriametrics

项目位置: drycc/victoriametrics

Victoriametrics 是一个系统监控和警报系统。它于 2012 年由 SoundCloud 开源,是继 Kubernetes 之后第二个加入并毕业于云原生计算基金会的项目。Victoriametrics 将所有指标数据存储为时间序列,即指标信息与其记录的时间戳一起存储,可选的键值对称为标签也可以与指标一起存储。

HelmBroker

项目位置: drycc-addons/helmbroker

Helm Broker 是一个服务代理,它在服务目录中将 Helm 图表公开为服务类。为此,Helm Broker 使用插件的概念。插件是 Helm 图表的抽象层,提供将图表转换为服务类所需的所有信息。

Victoriametrics

项目位置: drycc/victoriametrics

Victoriametrics 是一个开源的系统监控和警报工具包,最初由 SoundCloud 构建。

另请参阅

3 - 安装到 Kubernetes

在 Kubernetes 集群上部署 Drycc。

3.1 - 要求

要在 Kubernetes 集群上运行 Drycc Workflow,需要记住一些要求。

Kubernetes 版本

Drycc Workflow 需要 Kubernetes v1.16.15 或更高版本。

组件要求

Drycc 使用网关作为路由实现,因此您必须选择一个网关。我们推荐使用 istiokong

Workflow 支持使用 ACME 来管理自动证书,cert-manager 也是必要组件之一,如果您使用 cert-manager EAB,您需要将 clusterResourceNamespace 设置为 drycc 的命名空间。

Workflow 支持有状态应用。您可以通过 ‘drycc volumes’ 命令创建和使用它们。如果您想使用此功能,您必须有一个支持 ReadWriteManyStorageClass

Workflow 还通过 ‘drycc resources’ 命令支持 OSB API。如果您想使用此功能,需要安装 service-catalog

存储要求

各种 Drycc Workflow 组件依赖对象存储系统来完成工作,包括存储应用程序 slugs、容器镜像和数据库日志。

Drycc Workflow 默认附带 drycc 存储,它提供集群内存储。

Workflow 支持 Amazon Simple Storage Service (S3)、Google Cloud Storage (GCS)、OpenShift Swift 和 Azure Blob Storage。请参阅配置对象存储以获取设置说明。

资源要求

部署 Drycc Workflow 时,为机器提供充足资源很重要。Drycc 是一个高可用分布式系统,这意味着 Drycc 组件和您部署的应用程序会随着主机因各种原因(故障、重启、自动缩放器等)离开集群而移动到集群中的健康主机上。因此,您应该在集群中的任何机器上都有充足的备用资源,以承受运行失败机器服务的额外负载。

Drycc Workflow 组件在集群中使用大约 2.5GB 内存,并需要大约 30GB 硬盘空间。因为如果另一个失败,它可能需要处理额外负载,所以每台机器的最低要求是:

  • 至少 4GB RAM(越多越好)
  • 至少 40GB 硬盘空间

请注意,这些估计仅适用于 Drycc Workflow 和 Kubernetes。确保为您的应用程序占用空间留出足够的备用容量。

运行较小的机器可能会导致系统负载增加,并已知会导致组件故障和不稳定。

3.2 - 安装 Drycc Workflow

本文档面向那些已经配置了 Kubernetes 集群并想要安装 Drycc Workflow 的人。

如果需要有关 Kubernetes 和 Drycc Workflow 入门的帮助,请遵循快速入门指南以获取帮助。

先决条件

  1. 验证 Kubernetes 系统要求
  2. 安装 Helm 和 Drycc Workflow CLI 工具

检查您的设置

检查 helm 命令是否可用且版本为 v2.5.0 或更新版本。

$ helm version
Client: &version.Version{SemVer:"v2.5.0", GitCommit:"012cb0ac1a1b2f888144ef5a67b8dab6c2d45be6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.5.0", GitCommit:"012cb0ac1a1b2f888144ef5a67b8dab6c2d45be6", GitTreeState:"clean"}

选择您的部署策略

Drycc Workflow 包含运行所需的一切。然而,这些默认设置旨在简单而不是生产就绪。Workflow 的生产和暂存部署至少应该使用集群外存储,Workflow 组件使用它来存储和备份关键数据。如果操作员需要完全重新安装 Workflow,所需组件可以从集群外存储恢复。有关更多详细信息,请参阅配置对象存储的文档。

更严格的安装将受益于对以下内容使用外部来源:

网关

现在,workflow 要求必须安装网关和 cert-manager。可以使用任何兼容的 Kubernetes 入口控制器。

安装 Drycc Workflow

如果 helm 版本为 3.0+;您需要提前创建命名空间:

kubectl create ns drycc

如果您想更改它,请在使用 helm 时设置变量。

$ helm install drycc oci://registry.drycc.cc/charts/workflow \
    --namespace drycc \
    --set builder.imageRegistry=quay.io \
    --set imagebuilder.imageRegistry=quay.io \
    --set controller.imageRegistry=quay.io \
    --set database.imageRegistry=quay.io \
    --set fluentbit.imageRegistry=quay.io \
    --set valkey.imageRegistry=quay.io \
    --set storage.imageRegistry=quay.io \
    --set grafana.imageRegistry=quay.io \
    --set registry.imageRegistry=quay.io \
    --set global.platformDomain=drycc.cc

Helm 将在 drycc 命名空间中安装各种 Kubernetes 资源。 等待 Helm 启动的 pod 准备就绪。通过运行以下命令监控其状态:

$ kubectl --namespace=drycc get pods

如果希望 kubectl 在 pod 状态更改时自动更新,请运行(键入 Ctrl-C 停止监视):

$ kubectl --namespace=drycc get pods -w

根据 Workflow 组件初始化的顺序,一些 pod 可能会重新启动。这在安装期间很常见:如果组件的依赖项尚不可用,该组件将退出,Kubernetes 将自动重新启动它。

在这里,可以看到控制器、构建器和注册表都花了几次循环才能启动:

$ kubectl --namespace=drycc get pods
NAME                                     READY     STATUS    RESTARTS   AGE
drycc-builder-574483744-l15zj             1/1       Running   0          4m
drycc-controller-3953262871-pncgq         1/1       Running   2          4m
drycc-controller-celery-cmxxn             3/3       Running   0          4m
drycc-database-83844344-47ld6             1/1       Running   0          4m
drycc-fluentbit-zxnqb                     1/1       Running   0          4m
drycc-valkey-304849759-1f35p              1/1       Running   0          4m
drycc-storage-676004970-nxqgt             1/1       Running   0          4m
drycc-monitor-grafana-432627134-lnl2h     1/1       Running   0          4m
drycc-monitor-telegraf-wmcmn              1/1       Running   1          4m
drycc-registry-756475849-lwc6b            1/1       Running   1          4m
drycc-registry-proxy-96c4p                1/1       Running   0          4m

一旦所有 pod 都处于 READY 状态,Drycc Workflow 就启动并运行了!

有关更多安装参数,请检查 workflow 的 values.yaml 文件。

安装 Workflow 后,注册用户并部署应用程序

配置 DNS

用户必须设置主机名,并采用 drycc-builder.$host 约定。

我们需要将 drycc-builder.$host 记录指向您的构建器的公共 IP 地址。您可以使用以下命令获取公共 IP。这里需要通配符条目,因为应用程序在部署后将使用相同的规则。

$ kubectl get svc drycc-builder --namespace drycc
NAME              CLUSTER-IP   EXTERNAL-IP      PORT(S)                      AGE
drycc-builder     10.0.25.3    138.91.243.152   2222:31625/TCP               33m

如果我们使用 drycc.cc 作为主机名,我们需要创建以下 A DNS 记录。

名称 类型
drycc-builder.drycc.cc A 138.91.243.152

一旦所有 pod 都处于 READY 状态,并且 drycc-builder.$host 解析为上面找到的外部 IP,Workflow 就启动并运行了!

安装 Workflow 后,注册用户并部署应用程序

如果您的 k8s 不提供公共网络负载均衡器,您需要在可以访问内部和外部网络的机器上安装 haproxy 等 TCP 代理服务,然后公开 80443

3.3 - 指定网关

选择最适合您需求和平台的网关提供商。

安装 Drycc Workflow(指定网关)

现在 Helm 已安装并添加了仓库,通过运行以下命令使用原生网关安装 Workflow:

$ helm install drycc oci://registry.drycc.cc/charts/workflow \
    --namespace drycc \
    --set gateway.gatewayClass=istio \
    --set controller.appGatewayClass=istio \
    --set global.platformDomain=drycc.cc \
    --set builder.service.type=LoadBalancer

当然,如果您在裸机上部署,您可能没有负载均衡器。您需要使用 NodePort:

$ helm install drycc oci://registry.drycc.cc/charts/workflow \
    --namespace drycc \
    --set gateway.gatewayClass=istio \
    --set controller.appGatewayClass=istio \
    --set global.platformDomain=drycc.cc \
    --set builder.service.type=NodePort \
    --set builder.service.nodePort=32222

如果您想在裸机上使用负载均衡器,您可以查看 metallb

其中 global.platformDomain 是一个必需参数,对于 Workflow 传统上不是必需的,这在下一节中解释。在此示例中,我们使用 drycc.cc 作为 $hostname

Helm 将在 drycc 命名空间中安装各种 Kubernetes 资源。 等待 Helm 启动的 pod 准备就绪。通过运行以下命令监控其状态:

$ kubectl --namespace=drycc get pods

您还应该注意到您的集群上已安装了几个 Kubernetes gatewayclass。您可以通过运行以下命令查看它:

$ kubectl get gatewayclass

根据 Workflow 组件初始化的顺序,一些 pod 可能会重新启动。这在安装期间很常见:如果组件的依赖项尚不可用,该组件将退出,Kubernetes 将自动重新启动它。

在这里,可以看到控制器、构建器和注册表都花了几次循环等待存储才能启动:

$ kubectl --namespace=drycc get pods
NAME                          READY     STATUS    RESTARTS   AGE
drycc-builder-hy3xv            1/1       Running   5          5m
drycc-controller-g3cu8         1/1       Running   5          5m
drycc-controller-celery-cmxxn  3/3       Running   0          5m
drycc-database-rad1o           1/1       Running   0          5m
drycc-fluentbit-1v8uk          1/1       Running   0          5m
drycc-fluentbit-esm60          1/1       Running   0          5m
drycc-storage-4ww3t            1/1       Running   0          5m
drycc-registry-asozo           1/1       Running   1          5m

安装 Kubernetes 网关

现在 Workflow 已使用 gatewayClass 部署,我们需要安装 Kubernetes 网关来开始路由流量。

以下是如何使用 istio 作为 Workflow 网关的示例。当然,您可以随意使用任何您希望的控制器。

$ helm repo add istio https://istio-release.storage.googleapis.com/charts
$ helm repo update
$ kubectl create namespace istio-system
$ helm install istio-base istio/base -n istio-system
$ helm install istiod istio/istiod -n istio-system --wait
$ kubectl create namespace istio-ingress
$ helm install istio-ingress istio/gateway -n istio-ingress --wait

配置 DNS

用户必须安装 drycc 然后设置主机名,并采用 *.$host 约定。

我们需要将 *.$host 记录指向您的网关的公共 IP 地址。您可以使用以下命令获取公共 IP。这里需要通配符条目,因为应用程序在部署后将使用相同的规则。

$ kubectl get gateway --namespace drycc
NAME      CLASS   ADDRESS         PROGRAMMED   AGE
gateway   istio   138.91.243.152  True         36d

如果我们使用 drycc.cc 作为主机名,我们需要创建以下 A DNS 记录。

名称 类型
*.drycc.cc A 138.91.243.152

一旦所有 pod 都处于 READY 状态,并且 *.$host 解析为上面找到的外部 IP,网关的准备就完成了!

安装 Workflow 后,注册用户并部署应用程序

如果您的 k8s 不提供公共网络负载均衡器,您需要在可以访问内部和外部网络的机器上安装 haproxy 等 TCP 代理服务,然后公开 80443

3.4 - 配置 Postgres

Drycc Workflow 的控制器和护照组件依赖 PostgreSQL 数据库来存储平台状态。

配置 Postgres

默认情况下,Drycc Workflow 附带 database 组件,它提供集群内 PostgreSQL 数据库,并备份到集群内或集群外 object storage。目前,对于对象存储(由_多个_ Workflow 组件使用),在生产环境中仅推荐集群外解决方案,如 S3 或 GCS。经验表明,许多操作员已经选择集群外对象存储,同样更喜欢在集群外托管 Postgres,使用 Amazon RDS 或类似服务。当同时行使这两个选项时,Workflow 安装变得完全无状态,因此在需要时可以更容易地恢复或重建。

提供集群外 Postgres

首先,使用您选择的云提供商或其他基础设施提供 PostgreSQL RDBMS。请注意确保安全组或其他防火墙规则将允许从您的 Kubernetes 工作节点连接,任何节点都可能托管 Workflow 控制器组件。

记下以下内容:

  1. 您的 PostgreSQL RDBMS 的主机名或公共 IP
  2. 您的 PostgreSQL RDBMS 运行的端口 - 通常为 5432

在集群外 RDBMS 中,手动提供以下内容:

  1. 数据库用户(记下用户名和密码)
  2. 该用户拥有的数据库(记下其名称)

如果您能够以超级用户或具有适当权限的用户身份登录 RDBMS,此过程通常如下所示:

$ psql -h <host> -p <port> -d postgres -U <"postgres" 或您自己的用户名>
> create user <drycc 用户名;通常为 "drycc"> with password '<password>';
> create database <数据库名称;通常为 "drycc"> with owner <drycc 用户名>;
> \q

配置 Workflow

Drycc Workflow 的 Helm chart 可以轻松配置以将 Workflow 控制器组件连接到集群外 PostgreSQL 数据库。

  • 步骤 1: 如果您尚未获取 values,请使用 helm inspect values drycc/workflow > values.yaml 获取
  • 步骤 2: 通过修改 values.yaml 更新数据库连接详细信息:
    • database.enabled 参数更新为 false
    • 更新 [database] 配置部分中的值以正确反映所有连接详细信息。
    • 更新 [controller] 配置部分中的值以正确反映 platformDomain 详细信息。
    • 保存您的更改。
    • 注意:您不需要(也不必须)对任何值进行 base64 编码,因为 Helm chart 将根据需要自动处理编码。

现在您可以使用 helm install drycc oci://registry.drycc.cc/charts/workflow --namespace drycc -f values.yaml 照常安装。

3.5 - 配置注册表

Drycc Workflow 的构建器组件依赖注册表来存储应用程序容器镜像。

Drycc Workflow 默认附带 registry 组件,它提供集群内容器注册表,由平台配置的 object storage 支持。操作员可能出于性能或安全原因想要使用集群外注册表。

配置集群外私有注册表

每个依赖注册表的组件使用两个输入进行配置:

  1. 名为 DRYCC_REGISTRY_LOCATION 的注册表位置环境变量
  2. 访问凭据存储为名为 registry-secret 的 Kubernetes secret

Drycc Workflow 的 Helm chart 可以轻松配置以将 Workflow 组件连接到集群外注册表。Drycc Workflow 支持外部注册表,这些注册表提供仅在指定时间内有效的短期令牌或永久有效的长期令牌(基本用户名/密码)来进行身份验证。对于那些提供短期令牌进行身份验证的注册表,Drycc Workflow 将生成并刷新它们,以便部署的应用程序只能访问短期令牌,而不是注册表的实际凭据。

使用私有注册表时,容器镜像不再由 Drycc Workflow Controller 拉取,而是由 Kubernetes 管理。这将提高安全性和整体速度,但是 port 信息不再能够被发现。相反,可以通过在部署应用程序之前使用 drycc config set PORT=<port> 设置 port 信息。

Drycc Workflow 目前支持:

  1. 集群外:任何支持长期用户名/密码身份验证的提供商,如 Azure Container RegistryDocker Hubquay.io 或自托管容器注册表。

配置

  1. 如果您尚未获取 values 文件,请使用 helm inspect values drycc/workflow > values.yaml 获取
  2. 通过修改 values 文件更新注册表位置详细信息: * 将 registry.enabled 参数更新为引用您使用的注册表位置:truefalse * 更新与您的注册表位置类型对应的部分中的值。

现在您可以使用所需的注册表运行 helm install drycc oci://registry.drycc.cc/charts/workflow --namespace drycc -f values.yaml

示例

在这里,我们展示了获取的 values.yaml 文件的相关部分在为特定集群外注册表配置后可能的样子:

Azure Container Registry (ACR)

按照 docs 创建注册表后,例如 myregistry,其对应的登录服务器为 myregistry.azurecr.io,应提供以下值:

builder:
  registryHost: "myregistry.azurecr.io"
  registryUsername: "xxxx"
  registryPassword: "xxxx"
  registryOrganization: "xxxx"
registry:
  enabled: false

注意: 强制性组织字段(此处为 myorg)将在 ACR 仓库中创建,如果它尚不存在。

Quay.io

builder:
  registryHost: "quay.io"
  registryUsername: "xxxx"
  registryPassword: "xxxx"
  registryOrganization: "xxxx"
registry:
  enabled: false

3.6 - 配置对象存储

各种 Drycc Workflow 组件依赖对象存储系统来完成工作,包括存储应用程序、容器镜像

Drycc Workflow 默认附带 Storage,它提供集群内存储。

配置集群外对象存储

每个依赖对象存储的组件使用两个输入进行配置:

  1. 您必须使用与 S3 API 兼容的对象存储服务。
  2. 访问凭据存储在Kubernetes secret之中以保证安全。

Drycc Workflow 的 helm chart 可以轻松配置以将 Workflow 组件连接到集群外对象存储。Drycc Workflow 目前支持 Google Compute Storage、Amazon S3、Azure Blob Storage 和 OpenStack Swift Storage。

步骤 1:创建存储桶

为每个 Workflow 子系统创建存储桶:builderregistry

根据您选择的对象存储,您可能需要提供全局唯一的桶名称。如果您使用 S3,请在桶名称中使用连字符而不是句点。在桶名称中使用句点会导致 S3 的 ssl 证书验证问题

如果您提供对底层存储有足够访问权限的凭据,Workflow 组件将在桶不存在时创建它们。

步骤 2:生成存储凭据

如果适用,生成对步骤 1 中创建的存储桶具有创建和写入访问权限的凭据。

如果您使用 AWS S3 并且您的 Kubernetes 节点通过 InstanceRoles 配置了适当的 IAM API 密钥,您不需要创建 API 凭据。但是,请验证 InstanceRole 对配置的桶具有适当的权限!

步骤 3:配置 Workflow Chart

操作员应该在运行 helm install 之前通过编辑 Helm values 文件来配置对象存储。为此:

  • 通过运行 helm inspect values oci://registry.drycc.cc/charts/workflow > values.yaml 获取 Helm values
  • 更新 builder/storageregistry/storage 参数以引用您使用的平台。
  • 找到您的存储类型的相应部分,并提供适当的值,包括区域、桶名称和访问凭据。
  • 保存您的更改。

现在您可以使用所需的集群外对象存储运行 helm install drycc oci://registry.drycc.cc/charts/workflow --namespace drycc -f values.yaml

4 - 用户

在本教程中,您将学习如何管理用户。

4.1 - Drycc Workflow CLI

如何下载、安装和开始使用 Drycc CLI。Drycc CLI 曾经是 Drycc Toolbelt 的一部分。

Drycc Workflow 命令行界面 (CLI) 或客户端允许您与 Drycc Workflow 进行交互。

安装

使用以下命令为 Linux 或 Mac OS X 安装最新的 drycc 客户端: $ curl -sfL https://www.drycc.cc/install-cli.sh | bash -

安装程序将 drycc 放在当前目录中,但您应该将其移动到 $PATH 中的某个位置:

$ ln -fs $PWD/drycc /usr/local/bin/drycc

获取帮助

Drycc 客户端为每个命令提供了全面的文档。使用 drycc help 来探索可用的命令:

$ drycc help
The Drycc command-line client issues API calls to a Drycc controller.

Usage: drycc <command> [<args>...]

Auth commands::

  login         login to a controller
  logout        logout from the current controller

Subcommands, use `drycc help [subcommand]` to learn more::
...

要获取子命令的帮助,请使用 drycc help [subcommand]

$ drycc help apps
Valid commands for apps:

apps:create        create a new application
apps:list          list accessible applications
apps:info          view info about an application
apps:open          open the application in a browser
apps:logs          view aggregated application logs
apps:run           run a command in an ephemeral app container
apps:destroy       destroy an application
apps:transfer      transfer app ownership to another user

Use `drycc help [command]` to learn more

支持多个配置文件

CLI 从默认的 client 配置文件读取,该文件位于您工作站上的 $HOME/.drycc/client.json

通过设置 $DRYCC_PROFILE 环境变量或使用 -c 标志,可以轻松在多个 Drycc Workflow 安装或用户之间切换。

设置 $DRYCC_PROFILE 选项有两种方法。

  1. json 配置文件的路径。
  2. 配置文件名称。如果您将配置文件设置为仅名称,它将与默认配置文件一起保存,在 $HOME/.drycc/<name>.json 中。

示例:

$ DRYCC_PROFILE=production drycc login drycc.production.com
...
Opening browser to http://drycc.example.com/v2/login/drycc/?key=4ccc81ee2dce4349ad5261ceffe72c71
Waiting for login... .o.Logged in as drycc
Configuration saved to /home/testuser/.drycc/production.json
$ DRYCC_PROFILE=~/config.json drycc login drycc.example.com
...
Opening browser to http://drycc.example.com/v2/login/drycc/?key=4ccc81ee2dce4349ad5261ceffe72c71
Waiting for login... .o.Logged in as drycc
Configuration saved to /home/testuser/config.json

配置标志的工作方式与 $DRYCC_PROFILE 相同并覆盖它:

$ drycc whoami -c ~/config.json
You are drycc at drycc.example.com

代理支持

如果您的工作站使用代理来访问集群所在的网络,请设置 http_proxyhttps_proxy 环境变量以启用代理支持:

$ export http_proxy="http://proxyip:port"
$ export https_proxy="http://proxyip:port"

CLI 插件

插件允许开发人员扩展 Drycc 客户端的功能,添加新命令或功能。

如果指定了未知命令,客户端将尝试将命令作为破折号分隔的命令执行。在这种情况下,drycc resource:command 将执行 drycc-resource 并使用参数列表 command。完整形式:

$ # 以下两个命令相同
$ drycc accounts list
$ drycc-accounts list

命令后的任何标志也将作为参数发送到插件:

$ # 以下两个命令相同
$ drycc accounts list --debug
$ drycc-accounts list --debug

但命令前的标志不会:

$ # 以下两个命令相同
$ drycc --debug accounts list
$ drycc-accounts list

4.2 - 用户和注册

立即开始使用 Drycc

Workflow 使用 passport 组件来创建和授权用户,它可以配置 LDAP 认证选项或浏览 passport 网站来注册用户。

登录到 Workflow

如果您已经有账户,请使用 drycc login 来针对 Drycc Workflow API 进行认证。

$ drycc login http://drycc.example.com
Opening browser to http://drycc.example.com/v2/login/drycc/?key=4ccc81ee2dce4349ad5261ceffe72c71
Waiting for login... .o.Logged in as drycc
Configuration file written to /root/.drycc/client.json

或者您可以使用用户名和密码登录 $ drycc login http://drycc.example.com –username=demo –password=demo Configuration file written to /root/.drycc/client.json

从 Workflow 注销

使用 drycc logout 从现有控制器会话注销。

$ drycc logout
Logged out as drycc

验证您的会话

您可以通过运行 drycc whoami 来验证您的客户端配置。

$ drycc whoami
You are drycc at http://drycc.example.com

4.3 - 用户和 SSH 密钥

为 Drycc 创建、管理和上传 SSH 密钥,用于部署和连接应用程序。

对于通过 git push 进行的 DockerfileBuildpack 基础应用部署,Drycc Workflow 通过 SSH 密钥识别用户。SSH 密钥被推送到平台,并且必须对每个用户唯一。用户可以根据需要拥有多个 SSH 密钥。

生成 SSH 密钥

如果您还没有 SSH 密钥或者想为 Drycc Workflow 创建新密钥,请使用 ssh-keygen 生成新密钥:

$ ssh-keygen -f ~/.ssh/id_drycc -t rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/admin/.ssh/id_drycc.
Your public key has been saved in /Users/admin/.ssh/id_drycc.pub.
The key fingerprint is:
3d:ac:1f:f4:83:f7:64:51:c1:7e:7f:80:b6:70:36:c9 admin@plinth-23437.local
The key's randomart image is:
+--[ RSA 2048]----+
|              .. |
|               ..|
|           . o. .|
|         o. E .o.|
|        S == o..o|
|         o +.  .o|
|        . o + o .|
|         . o =   |
|          .   .  |
+-----------------+
$ ssh-add ~/.ssh/id_drycc
Identity added: /Users/admin/.ssh/id_drycc (/Users/admin/.ssh/id_drycc)

添加和移除 SSH 密钥

通过将 SSH 密钥的公钥部分发布到 Drycc Workflow,负责接收 git push 的组件将能够认证用户并确保他们有权访问目标应用。

$ drycc keys add ~/.ssh/id_drycc.pub
Uploading id_drycc.pub to drycc... done

您还可以随时查看与您的用户关联的密钥:

$ drycc keys list
ID                              OWNER    KEY                           
admin@plinth-23437.local        admin    ssh-rsa abc AAAAB3Nz...3437.local
admin@subgenius.local           admin    ssh-rsa 123 AAAAB3Nz...nius.local

按名称移除密钥:

$ drycc keys remove admin@plinth-23437.local
Removing admin@plinth-23437.local SSH Key... don

5 - 管理 Workflow

使用 kubectl 管理 Workflow。

5.1 - 调整组件设置

Helm Charts 是一组 Kubernetes 清单,反映了在 Kubernetes 上部署应用程序或服务的最佳实践。

在添加 Drycc Chart Repository 后,您可以在使用 helm install 完成安装之前,使用 helm inspect values drycc/workflow > values.yaml 来自定义图表。

有几种方法可以自定义相应组件:

  • 如果值在上面派生的 values.yaml 文件中暴露,可以修改组件的部分来调整这些设置。修改的值将在图表安装或发布升级时通过以下两个相应命令之一生效:

     $ helm install drycc oci://registry.drycc.cc/charts/workflow \
         -n drycc \
         --namespace drycc \
         -f values.yaml
     $ helm upgrade drycc oci://registry.drycc.cc/charts/workflow \
         -n drycc \
         --namespace drycc \
         -f values.yaml
    
  • 如果值尚未在 values.yaml 文件中暴露,可以编辑组件部署以调整设置。这里我们编辑 drycc-controller 部署:

     $ kubectl --namespace drycc edit deployment drycc-controller
    

    env 部分下通过适当的环境变量和值添加/编辑设置并保存。更新后的部署将使用新的/修改的设置重新创建组件 pod。

  • 最后,可以获取并编辑版本控制/图表仓库本身提供的图表:

     $ helm fetch oci://registry.drycc.cc/charts/workflow --untar
     $ $EDITOR workflow/charts/controller/templates/controller-deployment.yaml
    

    然后运行 helm install ./workflow --namespace drycc --name drycc 来应用更改,或者如果集群已经在运行,则运行 helm upgrade drycc ./workflow

设置资源限制

您可以通过修改之前获取的 values.yaml 文件来为 Workflow 组件设置资源限制。此文件为每个 Workflow 组件都有一个部分。要为任何 Workflow 组件设置限制,只需在部分中添加 resources 并将其设置为适当的值。

以下是设置了 CPU 和内存限制的 values.yaml 中 builder 部分的样子示例:

builder:
  imageOrg: "drycc"
  imagePullPolicy: "Always"
  imageTag: "canary"
  resources:
    limits:
      cpu: 1000m
      memory: 2048Mi
    requests:
      cpu: 500m
      memory: 1024Mi

自定义 Builder

Builder 组件可以调整以下环境变量:

设置 描述
DEBUG 启用调试日志输出(默认:false)
BUILDER_POD_NODE_SELECTOR builder 作业的节点选择器设置。由于它有时会消耗大量节点资源,您可能希望给定的 builder 作业仅在特定节点上运行,这样就不会影响关键节点。例如 pool:testing,disk:magnetic

自定义 Controller

Controller 组件可以调整以下环境变量:

设置 描述
REGISTRATION_MODE 将注册设置为 “enabled”、“disabled” 或 “admin_only”(默认:“admin_only”)
GUNICORN_WORKERS 生成的 gunicorn 工作进程数量,用于处理请求(默认:CPU 核心数 * 4 + 1)
RESERVED_NAMES 应用程序无法为路由保留的名称的逗号分隔列表(默认:“drycc, drycc-builder”)
DRYCC_DEPLOY_HOOK_URLS 发送 deploy hooks 的 URL 逗号分隔列表。
DRYCC_DEPLOY_HOOK_SECRET_KEY 用于计算部署钩子 HMAC 签名的私钥。
DRYCC_DEPLOY_REJECT_IF_PROCFILE_MISSING 如果之前的构建有 Procfile 但当前部署缺少它,则拒绝部署。API 中抛出 409。防止意外删除进程类型。(默认:“false”,允许值:“true”、“false”)
DRYCC_DEPLOY_PROCFILE_MISSING_REMOVE 开启时(默认),与之前部署相比,Procfile 中缺少的任何进程类型都会被移除。设置为 false 时,将允许空的 Procfile 通过而不移除缺少的进程类型,请注意,新镜像、配置等将在所有进程类型上更新。(默认:“true”,允许值:“true”、“false”)
DRYCC_DEFAULT_CONFIG_TAGS 默认情况下为所有应用程序设置标签,例如:’{“role”: “worker”}’。(默认:’’)
KUBERNETES_NAMESPACE_DEFAULT_QUOTA_SPEC 通过设置 ResourceQuota 规范为应用程序命名空间设置资源配额,例如:{"spec":{"hard":{"pods":"10"}}}, 限制应用所有者生成超过 10 个 pod(默认:"", 不会对命名空间应用配额)

LDAP 认证设置

LDAP 认证的配置选项详细说明此处

Passport 组件中启用用户账户 LDAP 认证的可用环境变量如下:

设置 描述
LDAP_ENDPOINT LDAP 服务器的 URI。如果未指定,则不启用 LDAP 认证(默认:"", 示例:ldap://hostname)。
LDAP_BIND_DN 绑定到 LDAP 服务器时使用的可分辨名称(默认:"")
LDAP_BIND_PASSWORD 与 LDAP_BIND_DN 一起使用的密码(默认:"")
LDAP_USER_BASEDN 用户名的搜索基础的可分辨名称(默认:"")
LDAP_USER_FILTER 用户搜索基础中的登录字段名称(默认:“username”)
LDAP_GROUP_BASEDN 用户组名的搜索基础的可分辨名称(默认:"")
LDAP_GROUP_FILTER 用户组的过滤器(默认:"", 示例:objectClass=person

全局和每个应用程序设置

设置 描述
DRYCC_DEPLOY_BATCHES 缩放期间顺序启动和停止的 pod 数量(默认:可用节点数量)
DRYCC_DEPLOY_TIMEOUT 每个部署批次的部署超时时间(秒)(默认:120)
IMAGE_PULL_POLICY 应用程序镜像的 kubernetes 镜像拉取策略(默认:“IfNotPresent”)(允许值:“Always”、“IfNotPresent”)
KUBERNETES_DEPLOYMENTS_REVISION_HISTORY_LIMIT Kubernetes 为给定 Deployment 保留的修订数量(默认:所有修订)
KUBERNETES_POD_TERMINATION_GRACE_PERIOD_SECONDS 发送 SIGKILL 之前,kubernetes 在 SIGTERM 后等待 pod 完成工作的秒数(默认:30)

有关这些的更多详细信息,请参阅[部署应用][]指南。

自定义数据库

Database 组件可以调整以下环境变量:

设置 描述
BACKUP_FREQUENCY 数据库执行基础备份的频率(默认:“12h”)
BACKUPS_TO_RETAIN 后备存储应保留的基础备份数量(默认:5)

自定义 Fluentbit

以下值可以在 values.yaml 文件中更改,或使用 Helm CLI 的 --values 标志。

描述
config.service 服务部分定义服务的全局属性。
config.inputs 输入部分定义源(与输入插件相关)。
config.filters 过滤器部分定义过滤器(与过滤器插件相关)
config.outputs 输出部分指定某些记录在标签匹配后应遵循的目的地。

有关可以设置的各种变量的更多信息,请参阅 fluentbit

自定义监控

Grafana

我们直接在图表中暴露了一些更有用的配置值。这允许使用 values.yaml 文件或 Helm CLI 的 --set 标志来设置它们。您可以在下面看到这些选项:

设置 默认值 描述
user “admin” 数据库中创建的第一个用户(此用户具有管理员权限)
password “admin” 第一个用户的密码。
allow_sign_up “true” 允许用户注册账户。

有关可以使用环境变量设置的其他选项列表,请参阅 Github 中的配置文件

Victoriametrics

您可以在此处找到可以使用环境变量设置的值列表。

自定义注册表

Registry 组件可以通过遵循 drycc/distribution config doc 来调整。

自定义路由器

大多数路由器设置可以通过注解进行调整,这允许在安装后零停机重新配置路由器。您可以在此处找到要调整的注解列表。

[Router][] 组件可以调整以下环境变量:

设置 描述
POD_NAMESPACE 路由器所在的 pod 命名空间。这是通过 Kubernetes downward API 设置的。

自定义 Workflow Manager

[Workflow Manager][] 可以调整以下环境变量:

设置 描述
CHECK_VERSIONS https://versions.drycc.info/ 启用外部版本检查(默认:“true”)
POLL_INTERVAL_SEC Workflow Manager 执行版本检查的时间间隔(秒)(默认:43200,即 12 小时)
VERSIONS_API_URL 版本 API URL(默认:"https://versions-staging.drycc.info")
DOCTOR_API_URL doctor API URL(默认:"https://doctor-staging.drycc.info")
API_VERSION Workflow Manager 发送到版本 API 的版本号(默认:“v2”)

5.2 - 配置 DNS

Drycc Workflow 控制器和通过 Workflow 部署的所有应用程序默认情况下旨在作为 Workflow 集群域的子域访问。

例如,假设 example.com 是集群的域:

  • 控制器应该可以在 drycc.example.com 访问
  • 应用程序应该默认可以在 <application name>.example.com 访问

鉴于这种情况,配置 DNS 的主要目标是将集群域的所有子域的流量定向到托管平台的路由器组件的集群节点,该组件能够将流量引导到集群内的正确端点。

使用负载均衡器

通常,建议使用 [load balancer][] 将入站流量定向到一个或多个路由器。在这种情况下,配置 DNS 就像在 DNS 中定义一个指向负载均衡器的通配符记录一样简单。

例如,假设域为 example.com

  • 枚举每个负载均衡器 IP 的 A 记录(即 DNS 轮询)
  • 引用负载均衡器现有完全限定域名的 CNAME 记录
    • 根据 AWS 自己的文档,当使用 AWS Elastic Load Balancers 时,这是推荐策略,因为 ELB IP 可能会随时间变化。

对于使用"自定义域"(不是集群自己域的子域的完全限定域名)的任何应用程序的 DNS,可以通过创建引用上述通配符记录的 CNAME 记录来配置。

虽然这取决于您的 Kubernetes 发行版和底层基础设施,但在许多情况下,可以使用 kubectl 工具直接确定负载均衡器的 IP 或现有完全限定域名:

$ kubectl --namespace=istio-nginx describe service | grep "LoadBalancer"
LoadBalancer Ingress:	a493e4e58ea0511e5bb390686bc85da3-1558404688.us-west-2.elb.amazonaws.com

LoadBalancer Ingress 字段通常描述现有域名或公共 IP。请注意,如果 Kubernetes 能够为您自动提供负载均衡器,它会异步执行此操作。如果在 Workflow 安装后不久发出上述命令,负载均衡器可能尚不存在。

没有负载均衡器

在某些平台(例如 Minikube)上,提供负载均衡器不是一件容易或实际的事情。在这些情况下,可以直接识别托管路由器 pod 的 Kubernetes 节点的公共 IP,并使用该信息来配置本地 /etc/hosts 文件。

因为通配符条目在本地 /etc/hosts 文件中不起作用,使用此策略可能导致频繁编辑该文件,为添加到该集群的每个应用程序添加集群的完全限定子域。因此,更可行的选项可能是利用 xip.io 服务。

一般来说,对于任何 IP a.b.c.d,完全限定域名 any-subdomain.a.b.c.d.xip.io 将解析为 IP a.b.c.d。这可能非常有用。

首先,使用 kubectl 查找托管路由器实例的节点:

$ kubectl --namespace=istio-ingress describe pod | grep Node:
Node:       ip-10-0-0-199.us-west-2.compute.internal/10.0.0.199
Node:       ip-10-0-0-198.us-west-2.compute.internal/10.0.0.198

该命令将显示每个路由器 pod 的信息。对于每个,Node 字段中显示节点名称和 IP。如果这些字段中出现的 IP 是公共的,则可以使用其中任何一个来配置您的本地 /etc/hosts 文件,或与 xip.io 一起使用。如果显示的 IP 不是公共的,则可能需要进一步调查。

您可以使用 kubectl 列出节点的 IP 地址:

$ kubectl describe node ip-10-0-0-199.us-west-2.compute.internal
# ...
Addresses:	10.0.0.199,10.0.0.199,54.218.85.175
# ...

在这里,Addresses 字段列出了节点的所有 IP。如果其中任何一个是公共的,则可以再次使用它们来配置您的本地 /etc/hosts 文件,或与 xip.io 一起使用。

教程:使用 Google Cloud DNS 配置 DNS

在本节中,我们将描述如何配置 Google Cloud DNS 以将您的域名路由到您的 Drycc 集群。

在本节中,我们假设以下内容:

  • 您的入口服务前面有一个负载均衡器。
    • 负载均衡器不必基于云,它只需要提供稳定的 IP 地址或稳定的域名
  • 您在注册商处注册了 mystuff.com 域名
    • 在以下说明中用您的域名替换 mystuff.com
  • 您的注册商允许您更改域名的名称服务器(大多数注册商都这样做)

以下是配置云 DNS 以路由到您的 drycc 集群的步骤:

  1. 获取负载均衡器 IP 或域名
  • 如果您在 Google Container Engine 上,可以运行 kubectl get svc -n istio-ingress 并查找 LoadBalancer Ingress 列以获取 IP 地址
  1. 创建新的 Cloud DNS Zone(在控制台上:Networking => Cloud DNS,然后点击 Create Zone
  2. 命名您的区域,并将 DNS 名称设置为 mystuff.com.(注意末尾的 .
  3. 点击 Create 按钮
  4. 在结果页面上点击 Add Record Set 按钮
  5. 如果您的负载均衡器提供稳定的 IP 地址,请在结果表单中输入以下字段:
  6. DNS Name: *
  7. Resource Record Type: A
  8. TTL: 您选择的 DNS TTL。如果您正在测试或预计您会随着时间推移拆除和重建许多 drycc 集群,我们推荐较低的 TTL
  9. IPv4 Address: 您在第一步中获得的 IP
  10. 点击 Create 按钮
  11. 如果您的负载均衡器提供稳定的域名 lbdomain.com,请在结果表单中输入以下字段:
  12. DNS Name: *
  13. Resource Record Type: CNAME
  14. TTL: 您选择的 DNS TTL。如果您正在测试或预计您会随着时间推移拆除和重建许多 drycc 集群,我们推荐较低的 TTL
  15. Canonical name: lbdomain.com.(注意末尾的 .
  16. 点击 Create 按钮
  17. 在您的域注册商中,将您的 mystuff.com 域的名称服务器设置为同一页面上 NS 记录的 data 列下的名称服务器。它们通常如下所示(注意尾随 . 字符)。
ns-cloud-b1.googledomains.com.
ns-cloud-b2.googledomains.com.
ns-cloud-b3.googledomains.com.
ns-cloud-b4.googledomains.com.

注意:如果您必须重新创建您的 drycc 集群,只需返回步骤 6.4 或 7.4(取决于您的负载均衡器)并将 IP 地址或域名更改为新值。您可能必须等待您设置的 TTL 到期。

测试

要测试流量是否到达其预期目的地,可以像这样向 Drycc 控制器发送请求(不要忘记尾随斜杠!):

curl http://drycc.example.com/v2/

或:

curl http://drycc.54.218.85.175.xip.io/v2/

由于此类请求需要身份验证,以下响应应被视为成功的指标:

{"detail":"Authentication credentials were not provided."}

5.3 - 部署钩子

部署钩子允许外部服务在您的应用程序的新版本推送到 Workflow 时接收通知。

它有助于让开发团队了解部署情况,同时也可以用于将不同系统集成在一起。

设置一个或多个钩子后,钩子输出和错误会出现在您的Drycc Grafana应用程序日志中:

2011-03-15T15:07:29-07:00 drycc[api]: Deploy hook sent to http://drycc.rocks

部署钩子是一个通用的 HTTP 钩子。管理员可以通过 调整控制器设置 来创建和配置多个部署钩子。

HTTP POST 钩子

HTTP 部署钩子对 URL 执行 HTTP POST。请求中包含的参数与钩子消息中可用的变量相同:appreleaserelease_summaryshauser。请参见下面的描述:

app=secure-woodland&release=v4&release_summary=gabrtv%20deployed%35b3726&sha=35b3726&user=gabrtv

可选地,如果通过 调整控制器设置 将部署钩子密钥添加到控制器,则 POST 请求中将存在新的 Authorization 标头。此标头的值是使用密钥作为密钥计算的请求 URL 的 HMAC 十六进制摘要。

为了验证此请求是否来自 Workflow,请使用密钥、完整 URL 和 HMAC-SHA1 哈希算法来计算签名。在 Python 中,这看起来像这样:

import hashlib
import hmac

hmac.new("my_secret_key", "http://drycc.rocks?app=secure-woodland&release=v4&release_summary=gabrtv%20deployed%35b3726&sha=35b3726&user=gabrtv", digestmod=hashlib.sha1).hexdigest()

如果计算的 HMAC 十六进制摘要的值和 Authorization 标头中的值相同,则请求来自 Workflow。

5.4 - 平台日志

日志是从您的应用程序所有运行进程的输出流中聚合的时间戳事件流。检索、过滤或使用 syslog drains。

我们正在与 Quickwit 合作,为您提供应用程序日志集群和搜索界面。

架构图

┌───────────┐                   ┌───────────┐
│ Container │                   │  Grafana  │
└───────────┘                   └───────────┘
      │                               ^
     log                              |
      │                               |
      ˅                               │
┌───────────┐                   ┌───────────┐
│ Fluentbit │─────otel/grpc────>│  Quickwit │
└───────────┘                   └───────────┘

默认配置

Fluent Bit 基于可插拔架构,其中不同的插件在数据管道中发挥主要作用,有 70 多个内置插件可用。 请参考 charts values.yaml 以获取特定配置。

5.5 - 平台监控

为您的应用提供平台监控,提前发现问题并快速响应事件。

描述

我们现在为运行中的 Kubernetes 集群提供了一个监控堆栈,用于内省。该堆栈包括 4 个组件:

架构图

┌────────────────┐                                                        
│ HOST           │                                                        
│  node-exporter │◀──┐                          ┌──────────────────┐         
└────────────────┘   │                          │kube-state-metrics│         
                     │                          └──────────────────┘         
┌────────────────┐   │                                    ▲                    
│ HOST           │   │    ┌─────────────────┐             │                    
│  node-exporter │◀──┼────│ victoriametrics │─────────────┘                    
└────────────────┘   │    └─────────────────┘                                  
                     │             ▲                                         
┌───────────────┐    │             │                                         
│ HOST          │    │             ▼                                         
│  node-exporter│◀───┘       ┌──────────┐                                    
└───────────────┘            │ Grafana  │                                    
                             └──────────┘                                    

Grafana

Grafana 允许用户创建自定义仪表板,可视化捕获到运行中的 VictoriaMetrics 组件的数据。默认情况下,Grafana 通过路由器使用服务注解暴露在以下 URL:http://grafana.mydomain.com。默认登录是 admin/admin。如果您有兴趣更改这些值,请参阅[调整组件设置][]。

Grafana 将预加载几个仪表板,帮助操作员开始监控 Kubernetes 和 Drycc Workflow。这些仪表板旨在作为起点,并不包括生产安装中可能需要监控的每个项目。

Drycc Workflow 监控默认情况下不会将数据写入主机文件系统或长期存储。如果 Grafana 实例失败,修改的仪表板将丢失。

生产配置

生产安装的 Grafana 应尽可能更改以下配置值:

  • 将默认用户名和密码从 admin/admin 更改。密码值以明文传递,因此最好在命令行上设置此值,而不是将其检入版本控制。
  • 启用持久性
  • 使用受支持的外部数据库,如 mysql 或 postgres。您可以在此处找到更多信息

集群内持久性

启用持久性将允许您的自定义配置在 pod 重启后保持。这意味着如果您升级 Workflow 安装,默认的 sqllite 数据库(存储会话和用户数据等)不会消失。

如果您希望为 Grafana 启用持久性,可以在运行 helm install 之前在 values.yaml 文件中将 enabled 设置为 true

 grafana:
   # Configure the following ONLY if you want persistence for on-cluster grafana
   # GCP PDs and EBS volumes are supported only
   persistence:
     enabled: true # Set to true to enable persistence
     size: 5Gi # PVC size

集群外 Grafana

如果您希望提供自己的 Grafana 实例,可以在运行 helm install 之前在 values.yaml 文件中设置 grafana.enabled

VictoriaMetrics

VictoriaMetrics 是一个快速且可扩展的开源时序数据库和监控解决方案,让用户无需扩展性问题和最小的运营负担即可构建监控平台,它与 prometheus 格式完全兼容。

集群内持久性

您可以在 values.yaml 中将 node-exporterkube-state-metrics 设置为 truefalse。 如果您希望为 VictoriaMetrics 启用持久性,可以在运行 helm install 之前在 values.yaml 文件中将 enabled 设置为 true

victoriametrics:
  vmstorage:
    replicas: 3
    extraArgs:
    - --retentionPeriod=30d
    temporary:
      enabled: true
      size: 5Gi
      storageClass: "toplvm-ssd"
    persistence:
      enabled: true
      size: 10Gi
      storageClass: "toplvm-hdd"
  node-exporter:
    enabled: true
  kube-state-metrics:
    enabled: true

集群外 VictoriaMetrics

要使用外部 VictoriaMetrics,请在运行 helm install 之前在 values.yaml 文件中提供以下值。

  • victoriametrics.enabled=false
  • grafana.prometheusUrl="http://my.prometheus.url:9090"
  • controller.prometheusUrl="http://my.prometheus.url:9090"

5.6 - 升级 Workflow

Drycc Workflow 版本可以就地升级,最小化停机时间。

此升级过程需要:

升级过程

步骤 1:应用 Workflow 升级

Helm 将从之前的版本中移除所有组件。通过 Workflow 部署的应用程序流量将在升级期间继续流动。不应发生服务中断。

如果 Workflow 未配置为使用集群外 Postgres,Workflow API 将在数据库从备份恢复时经历短暂的停机时间。

首先,使用 helm ls 查找 helm 给您的部署的版本名称,然后运行

$ helm upgrade <release-name> oci://registry.drycc.cc/charts/workflow

注意: 如果使用 gcs 上的集群外对象存储和/或使用 gcr 的集群外注册表,并打算从 pre-v2.10.0 图表升级到 v2.10.0 或更高版本,现在需要预先 base64 编码 key_json 值。因此,假设其余的自定义/集群外值在用于之前安装的现有 values.yaml 中定义,可以运行以下命令:

$ B64_KEY_JSON="$(cat ~/path/to/key.json | base64 -w 0)"
$ helm upgrade <release_name> drycc/workflow -f values.yaml --set gcs.key_json="${B64_KEY_JSON}",registry-token-refresher.gcr.key_json="${B64_KEY_JSON}"

或者,只需在 values.yaml 中替换适当的值,而不使用 --set 参数。确保用单引号包装,因为双引号会在升级时给出解析器错误。

步骤 2:验证升级

验证所有组件已启动并通过了就绪检查:

$ kubectl --namespace=drycc get pods
NAME                                     READY     STATUS    RESTARTS   AGE
drycc-builder-2448122224-3cibz            1/1       Running   0          5m
drycc-controller-1410285775-ipc34         1/1       Running   3          5m
drycc-controller-celery-694f75749b-cmxxn  3/3       Running   0          5m
drycc-database-e7c5z                      1/1       Running   0          5m
drycc-fluentbit-45h7j                     1/1       Running   0          5m
drycc-fluentbit-4z7lw                     1/1       Running   0          5m
drycc-fluentbit-k2wsw                     1/1       Running   0          5m
drycc-fluentbit-skdw4                     1/1       Running   0          5m
drycc-valkey-8nazu                        1/1       Running   0          5m
drycc-grafana-tm266                       1/1       Running   0          5m
drycc-registry-1814324048-yomz5           1/1       Running   0          5m
drycc-registry-proxy-4m3o4                1/1       Running   0          5m
drycc-registry-proxy-no3r1                1/1       Running   0          5m
drycc-registry-proxy-ou8is                1/1       Running   0          5m
drycc-registry-proxy-zyajl                1/1       Running   0          5m

步骤 3:升级 Drycc 客户端

Drycc Workflow 的用户现在应该升级他们的 drycc 客户端,以避免收到 WARNING: Client and server API versions do not match. Please consider upgrading. 警告。

curl -sfL https://www.drycc.cc/install-cli.sh | bash - && sudo mv drycc $(which drycc)

5.7 - 生产部署

为生产工作负载准备 Workflow 部署时,有一些额外的建议。

在生产环境中运行 Workflow 而无需 drycc 存储

在生产环境中,可以通过运行外部对象存储来实现持久存储。对于 AWS、GCE/GKE 或 Azure 上的用户,Amazon S3、Google GCS 或 Microsoft Azure Storage 的便利性使得运行无存储的 Workflow 集群的前景相当合理。对于对使用外部对象存储有限制的用户,使用 swift 对象存储可能是一个选项。

运行无存储的 Workflow 集群提供了几个优势:

  • 从工作节点移除状态
  • 减少资源使用
  • 减少管理 Workflow 的复杂性和运营负担

有关移除此运营复杂性的详细信息,请参阅Configuring Object Storage

审查安全注意事项

在生产环境中运行 Workflow 时,有一些额外的安全相关注意事项。有关详细信息,请参阅[Security Considerations][]。

注册仅限管理员

默认情况下,与 Workflow 控制器的注册处于"admin_only"模式。第一个运行 drycc register 命令的用户成为初始"admin"用户,此后的注册将被禁止,除非由管理员请求。

请参阅以下文档了解如何更改注册模式:

禁用 Grafana 注册

还建议禁用 Grafana 仪表板的注册。

请参阅以下文档了解如何禁用 Grafana 注册:

6 - 应用

一个简单且可扩展的云平台,满足所有开发者的需求。

6.1 - 部署应用程序

了解如何将应用程序部署到 Drycc。

[应用程序][] 使用 git pushdrycc 客户端部署到 Drycc。

支持的应用程序

Drycc Workflow 可以部署任何可以在容器中运行的应用程序或服务。为了能够水平扩展,应用程序必须遵循 Twelve-Factor App 方法,并在外部后端服务中存储任何应用程序状态。

例如,如果您的应用程序将状态持久化到本地文件系统(内容管理系统如 WordPress 和 Drupal 中常见),则无法使用 drycc scale 进行水平扩展。

幸运的是,大多数现代应用程序具有无状态应用程序层,可以在 Drycc 中水平扩展。

登录到控制器

在部署应用程序之前,用户必须首先使用 Drycc 管理员提供的 URL 对 Drycc [控制器][] 进行身份验证。

$ drycc login http://drycc.example.com
Opening browser to http://drycc.example.com/v2/login/drycc/?key=4ccc81ee2dce4349ad5261ceffe72c71
Waiting for login... .o.Logged in as admin
Configuration file written to /root/.drycc/client.json

或者您可以使用用户名和密码登录

$ drycc login http://drycc.example.com --username=demo --password=demo
Configuration file written to /root/.drycc/client.json

选择构建过程

Drycc Workflow 支持三种不同的应用程序构建方式:

Buildpacks

Cloud Native Buildpacks 如果您想遵循 cnb’s docs 来构建应用程序会很有用。

了解如何使用 Buildpacks 部署应用程序。

Dockerfiles

Dockerfiles 是一种强大的方式,可以定义基于您选择的基 OS 的可移植执行环境。

了解如何使用 Dockerfiles 部署应用程序。

容器镜像

将容器镜像部署到 Drycc 允许您从公共或私有注册表获取容器镜像,并逐位复制,确保您在开发环境或 CI 流水线中运行的镜像与生产环境中的相同。

了解如何使用容器镜像部署应用程序。

调整应用程序设置

可以使用 config:set 在每个应用程序基础上配置一些全局可调设置

设置 描述
DRYCC_DISABLE_CACHE 如果设置,将禁用 [imagebuilder 缓存][](默认:未设置)
DRYCC_DEPLOY_BATCHES 在扩展期间顺序启动和停止的 pod 数量(默认:可用节点数量)
DRYCC_DEPLOY_TIMEOUT 每个部署批次的部署超时时间(秒)(默认:120)
IMAGE_PULL_POLICY 应用程序镜像的 Kubernetes [镜像拉取策略][pull-policy](默认:“IfNotPresent”)(允许值:“Always”、“IfNotPresent”)
KUBERNETES_DEPLOYMENTS_REVISION_HISTORY_LIMIT Kubernetes 为给定 Deployment 保留的修订数量(默认:所有修订)
KUBERNETES_POD_TERMINATION_GRACE_PERIOD_SECONDS Kubernetes 在发送 SIGKILL 之前等待 pod 完成工作的秒数(默认:30)

部署超时

部署超时(秒)- 有两种部署方法,Deployments(见下文)和 RC(2.4 版本之前),此设置对它们的影响略有不同。

Deployments

Deployments 的行为与基于 RC 的部署策略略有不同。

Kubernetes 负责整个部署,在后台进行滚动更新。因此,只有一个整体部署超时,而不是可配置的每批次超时。

基础超时乘以 DRYCC_DEPLOY_BATCHES 来创建整体超时。这将是 240(超时)* 4(批次)= 960 秒整体超时。

RC 部署

此部署超时定义在 DRYCC_DEPLOY_BATCHES 中等待每个批次完成的时长。

基础超时的附加项

基础超时也会通过健康检查使用 livenessreadiness 上的 initialDelaySeconds 进行扩展,其中应用较大的那个。 此外,超时系统通过在看到镜像拉取超过 1 分钟时添加额外 10 分钟来考虑慢速镜像拉取。这允许超时值合理,而不必在基础部署超时中考虑镜像拉取的缓慢。

Deployments

Workflow 使用 Deployments 进行部署。在之前的版本中,使用 ReplicationControllers,可以通过 DRYCC_KUBERNETES_DEPLOYMENTS=1 启用 Deployments。

Deployments 的优势是滚动更新将在 Kubernetes 服务器端发生,而不是在 Drycc Workflow Controller 中进行,以及其他一些 Pod 管理相关功能。这允许即使 CLI 连接中断,部署也能继续。

在后台,您的应用程序部署将由每个进程类型的 Deployment 对象组成,每个对象有多个 ReplicaSets(每个发布一个),这些 ReplicaSets 反过来管理运行您的应用程序的 Pods。

Drycc Workflow 的行为在启用或禁用 DRYCC_KUBERNETES_DEPLOYMENTS 时相同(仅适用于 2.4 版本之前)。 变化发生在后台。您在使用 CLI 时会看到差异的地方是 drycc ps:list 将以不同的方式输出 Pod 名称。

6.2 - 使用 Buildpacks

Buildpacks 概述,负责将部署的代码转换为 slug,然后可以在容器上执行。

Drycc 支持通过 Cloud Native Buildpacks 部署应用程序。如果您想遵循 cnb 的文档 来构建应用程序,Cloud Native Buildpacks 很有用。

添加 SSH 密钥

对于通过 git push 的基于 Buildpack 的应用程序部署,Drycc Workflow 通过 SSH 密钥识别用户。SSH 密钥被推送到平台,并且必须对每个用户唯一。

  • 请参阅 此文档 以获取生成 SSH 密钥的说明。

  • 运行 drycc keys add 将您的 SSH 密钥上传到 Drycc Workflow。

$ drycc keys add ~/.ssh/id_drycc.pub
Uploading id_drycc.pub to drycc... done

阅读有关添加/删除 SSH 密钥的更多信息 此处

准备应用程序

如果您没有现有应用程序,您可以克隆演示 Heroku Buildpack 工作流的示例应用程序。

$ git clone https://github.com/drycc/example-go.git
$ cd example-go

创建应用程序

使用 drycc createController 上创建应用程序。

$ drycc create
Creating application... done, created skiing-keypunch
Git remote drycc added

推送以部署

使用 git push drycc master 部署您的应用程序。

$ git push drycc master
Counting objects: 75, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (75/75), 18.28 KiB | 0 bytes/s, done.
Total 75 (delta 30), reused 58 (delta 22)
remote: --->
Starting build... but first, coffee!
---> Waiting podman running.
---> Process podman started.
---> Waiting caddy running.
---> Process caddy started.
---> Building pack
---> Using builder registry.drycc.cc/drycc/buildpacks:bookworm
Builder 'registry.drycc.cc/drycc/buildpacks:bookworm' is trusted
Pulling image 'registry.drycc.cc/drycc/buildpacks:bookworm'
Resolving "drycc/buildpacks" using unqualified-search registries (/etc/containers/registries.conf)
Trying to pull registry.drycc.cc/drycc/buildpacks:bookworm...
Getting image source signatures
...
---> Skip generate base layer
---> Python Buildpack
---> Downloading and extracting Python 3.10.0
---> Installing requirements with pip
Collecting Django==3.2.8
Downloading Django-3.2.8-py3-none-any.whl (7.9 MB)
Collecting gunicorn==20.1.0
Downloading gunicorn-20.1.0-py3-none-any.whl (79 kB)
Collecting sqlparse>=0.2.2
Downloading sqlparse-0.4.2-py3-none-any.whl (42 kB)
Collecting pytz
Downloading pytz-2021.3-py2.py3-none-any.whl (503 kB)
Collecting asgiref<4,>=3.3.2
Downloading asgiref-3.4.1-py3-none-any.whl (25 kB)
Requirement already satisfied: setuptools>=3.0 in /layers/drycc_python/python/lib/python3.10/site-packages (from gunicorn==20.1.0->-r requirements.txt (line 2)) (57.5.0)
Installing collected packages: sqlparse, pytz, asgiref, gunicorn, Django
Successfully installed Django-3.2.8 asgiref-3.4.1 gunicorn-20.1.0 pytz-2021.3 sqlparse-0.4.2
---> Generate Launcher
...
Build complete.
Launching App...
...
Done, skiing-keypunch:v2 deployed to Workflow

Use 'drycc open' to view this application in your browser

To learn more, use 'drycc help' or visit https://www.drycc.cc

To ssh://git@drycc.staging-2.drycc.cc:2222/skiing-keypunch.git
 * [new branch]      master -> master

$ curl -s http://skiing-keypunch.example.com
Powered by Drycc
Release v2 on skiing-keypunch-v2-web-02zb9

因为检测到 Buildpacks 风格的应用程序,web 进程类型在首次部署时自动扩展到 1。

使用 drycc scale web=3web 进程增加到 3,例如。直接扩展进程类型会更改运行该进程的 pods 数量。

包含的 Buildpacks

为方便起见,Drycc 捆绑了许多 buildpacks:

Drycc 将循环遍历每个 buildpack 的 bin/detect 脚本以匹配您推送的代码。

使用自定义 Buildpack

要使用自定义 buildpack,您需要在您的根路径应用中创建 .pack_builder 文件。

$  tee > .pack-builder << EOF
   > registry.drycc.cc/drycc/buildpacks:bookworm
   > EOF

在您的下一次 git push 中,将使用自定义 buildpack。

使用私有仓库

要从私有仓库拉取代码,将 SSH_KEY 环境变量设置为具有访问权限的私钥。使用私钥文件的路径或原始密钥材料:

$ drycc config set SSH_KEY=/home/user/.ssh/id_rsa
$ drycc config set SSH_KEY="""-----BEGIN RSA PRIVATE KEY-----
(...)
-----END RSA PRIVATE KEY-----"""

例如,要使用托管在私有 GitHub URL 的自定义 buildpack,请确保 SSH 公钥存在于您的 [GitHub 设置][] 中。然后将 SSH_KEY 设置为相应的 SSH 私钥,并将 .pack_builder 设置为构建器镜像:

$  tee > .pack-builder << EOF
   > registry.drycc.cc/drycc/buildpacks:bookworm
   > EOF
$ git add .buildpack
$ git commit -m "chore(buildpack): modify the pack_builder"
$ git push drycc master

构建器选择器

构建项目的哪种方式符合以下原则:

  • 如果项目中存在 Dockerfile,堆栈使用 container
  • 如果项目中存在 Procfile,堆栈使用 buildpack
  • 如果两者都存在,默认使用 container
  • 您也可以设置 DRYCC_STACKcontainerbuildpack 来确定使用哪种堆栈。

6.3 - 使用 Dockerfiles

Drycc 容器注册表允许您将基于 Docker 的应用部署到 Drycc。支持通用运行时和私有空间。

Drycc 支持通过 Dockerfiles 部署应用程序。Dockerfile 自动化了制作 [容器镜像][] 的步骤。 Dockerfiles 非常强大,但需要额外工作来定义您的确切应用程序运行时环境。

添加 SSH 密钥

对于通过 git push 的基于 Dockerfile 的应用程序部署,Drycc Workflow 通过 SSH 密钥识别用户。SSH 密钥被推送到平台,并且必须对每个用户唯一。

  • 请参阅 此文档 以获取生成 SSH 密钥的说明。

  • 运行 drycc keys add 将您的 SSH 密钥上传到 Drycc Workflow。

$ drycc keys add ~/.ssh/id_drycc.pub
Uploading id_drycc.pub to drycc... done

阅读有关添加/删除 SSH 密钥的更多信息 此处

准备应用程序

如果您没有现有应用程序,您可以克隆演示 Dockerfile 工作流的示例应用程序。

$ git clone https://github.com/drycc/helloworld.git
$ cd helloworld

Dockerfile 要求

为了部署 Dockerfile 应用程序,它们必须符合以下要求:

  • Dockerfile 必须使用 EXPOSE 指令来公开恰好一个端口。
  • 该端口必须监听 HTTP 连接。
  • Dockerfile 必须使用 CMD 指令来定义将在容器内运行的默认进程。
  • 容器镜像必须包含 bash 来运行进程。

创建应用程序

使用 drycc createController 上创建应用程序。

$ drycc create
Creating application... done, created folksy-offshoot
Git remote drycc added

推送部署

使用 git push drycc master 部署您的应用程序。

$ git push drycc master
Counting objects: 13, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (13/13), 1.99 KiB | 0 bytes/s, done.
Total 13 (delta 2), reused 0 (delta 0)
-----> Building Docker image
Uploading context 4.096 kB
Uploading context
Step 0 : FROM drycc/base:latest
 ---> 60024338bc63
Step 1 : RUN wget -O /tmp/go1.2.1.linux-amd64.tar.gz -q https://go.googlecode.com/files/go1.2.1.linux-amd64.tar.gz
 ---> Using cache
 ---> cf9ef8c5caa7
Step 2 : RUN tar -C /usr/local -xzf /tmp/go1.2.1.linux-amd64.tar.gz
 ---> Using cache
 ---> 515b1faf3bd8
Step 3 : RUN mkdir -p /go
 ---> Using cache
 ---> ebf4927a00e9
Step 4 : ENV GOPATH /go
 ---> Using cache
 ---> c6a276eded37
Step 5 : ENV PATH /usr/local/go/bin:/go/bin:$PATH
 ---> Using cache
 ---> 2ba6f6c9f108
Step 6 : ADD . /go/src/github.com/drycc/helloworld
 ---> 94ab7f4b977b
Removing intermediate container 171b7d9fdb34
Step 7 : RUN cd /go/src/github.com/drycc/helloworld && go install -v .
 ---> Running in 0c8fbb2d2812
github.com/drycc/helloworld
 ---> 13b5af931393
Removing intermediate container 0c8fbb2d2812
Step 8 : ENV PORT 80
 ---> Running in 9b07da36a272
 ---> 2dce83167874
Removing intermediate container 9b07da36a272
Step 9 : CMD ["/go/bin/helloworld"]
 ---> Running in f7b215199940
 ---> b1e55ce5195a
Removing intermediate container f7b215199940
Step 10 : EXPOSE 80
 ---> Running in 7eb8ec45dcb0
 ---> ea1a8cc93ca3
Removing intermediate container 7eb8ec45dcb0
Successfully built ea1a8cc93ca3
-----> Pushing image to private registry

       Launching... done, v2

-----> folksy-offshoot deployed to Drycc
       http://folksy-offshoot.local3.dryccapp.com

       To learn more, use `drycc help` or visit https://www.drycc.cc

To ssh://git@local3.dryccapp.com:2222/folksy-offshoot.git
 * [new branch]      master -> master

$ curl -s http://folksy-offshoot.local3.dryccapp.com
Welcome to Drycc!
See the documentation at http://docs.drycc.cc/ for more information.

因为检测到 Dockerfile 应用程序,web 进程类型在首次部署时自动扩展到 1。

使用 drycc scale web=3web 进程增加到 3,例如。直接扩展进程类型会更改运行该进程的 容器 数量。

容器构建参数

从 Workflow v2.13.0 开始,用户可以使用 容器构建参数 将其应用程序配置注入到容器镜像中。要选择加入,用户必须向其应用程序添加新的环境变量:

$ drycc config set DRYCC_DOCKER_BUILD_ARGS_ENABLED=1

使用 drycc config set 设置的每个环境变量都将在用户的 Dockerfile 中可用。例如,如果用户运行 drycc config set POWERED_BY=Workflow,用户可以在其 Dockerfile 中使用该构建参数:

ARG POWERED_BY
RUN echo "Powered by $POWERED_BY" > /etc/motd

6.4 - 使用容器镜像

使用存储在 Drycc 容器注册表中的容器镜像部署应用程序。

Drycc 支持通过现有的 [Docker 镜像][] 部署应用程序。 这对于将 Drycc 集成到基于 Docker 的 CI/CD 流水线中很有用。

准备应用程序

首先克隆示例应用程序:

$ git clone https://github.com/drycc/example-dockerfile-http.git
$ cd example-dockerfile-http

接下来使用您的本地 docker 客户端构建镜像并推送 到 DockerHub

$ docker build -t <username>/example-dockerfile-http .
$ docker push <username>/example-dockerfile-http

Docker 镜像要求

为了部署 Docker 镜像,它们必须符合以下要求:

  • Dockerfile 必须使用 EXPOSE 指令来公开恰好一个端口。
  • 该端口必须监听 HTTP 连接。
  • Dockerfile 必须使用 CMD 指令来定义将在容器内运行的默认进程。
  • Docker 镜像必须包含 bash 来运行进程。

创建应用程序

使用 drycc createcontroller 上创建应用程序。

$ mkdir -p /tmp/example-dockerfile-http && cd /tmp/example-dockerfile-http
$ drycc create example-dockerfile-http --no-remote
Creating application... done, created example-dockerfile-http

部署应用程序

使用 drycc pullDockerHub 或 公共注册表部署您的应用程序。

$ drycc pull <username>/example-dockerfile-http:latest
Creating build...  done, v2

$ curl -s http://example-dockerfile-http.local3.dryccapp.com
Powered by Drycc

因为您正在部署 Docker 镜像,web 进程类型在首次部署时自动扩展到 1。

使用 drycc scale web=3web 进程增加到 3,例如。直接扩展进程类型会更改运行该进程的 容器 数量。

私有注册表

要从私有注册表或私有仓库部署 Docker 镜像,请使用 drycc registry 将凭据附加到您的应用程序。这些凭据与您在私有注册表运行 docker login 时使用的凭据相同。

要部署私有 Docker 镜像,请执行以下步骤:

  • 收集注册表的用户名和密码,例如 Quay.io Robot AccountGCR.io Long Lived Token
  • 运行 drycc registry set <the-user> <secret> -a <application-name>
  • 现在像往常一样对私有注册表中的镜像执行 drycc pull

当使用 GCR.io Long Lived Token 时,JSON blob 必须首先使用 jq 等工具压缩,然后在 drycc registry set 的密码字段中使用。对于用户名,使用 _json_key。例如:

drycc registry set _json_key "$(cat google_cloud_cred.json | jq -c .)"

当使用私有注册表时,Docker 镜像不再通过 Drycc Workflow Controller 拉取到 Drycc 内部注册表,而是由 Kubernetes 管理。这将提高安全性和整体速度, 但是应用程序 port 信息无法再被发现。相反,应用程序 port 信息可以通过 drycc config set PORT=80 在设置注册表信息之前设置。

6.5 - 管理应用进程

Procfile 是应用中进程类型的列表。每个进程类型声明一个命令,该命令在启动该进程类型的容器时执行。

Drycc Workflow 将您的应用作为一组可以根据其角色命名、扩展和配置的进程进行管理。这为您提供了灵活性,可以轻松管理应用的各个方面。例如,您可能有面向 Web 的进程处理 HTTP 流量、后台工作进程执行异步工作,以及从 Twitter API 流式传输的辅助进程。

通过使用 Procfile(已检入您的应用或通过 CLI 提供),您可以指定类型的名称和应运行的应用命令。要生成其他进程类型,请使用 drycc scale <ptype>=<n> 来相应地扩展这些类型。

默认进程类型

在没有 Procfile 的情况下,为每个应用假设单个默认进程类型。

使用 Buildpacks 通过 git push 构建的应用隐式接收 web 进程类型,该类型启动应用服务器。例如,Rails 4 具有以下进程类型:

web: bundle exec rails server -p $PORT

所有使用 Dockerfiles 的应用都有一个隐含的 web 进程类型,该类型运行 Dockerfile 的 CMD 指令而不修改:

$ cat Dockerfile
FROM centos:latest
COPY . /app
WORKDIR /app
CMD python -m SimpleHTTPServer 5000
EXPOSE 5000

对于上述基于 Dockerfile 的应用,web 进程类型将运行容器的 CMD python -m SimpleHTTPServer 5000

使用 远程容器镜像 的应用也会隐含 web 进程类型,并运行容器镜像中指定的 CMD

声明进程类型

如果您使用 BuildpackDockerfile 构建并想要覆盖或指定其他进程类型,只需在应用源树的根目录中包含一个名为 Procfile 的文件。

Procfile 的格式是每行一个进程类型,每行包含要调用的命令:

<process type>: <command>

语法定义为:

  • <process type> – 小写字母数字字符串,是您的命令的名称,如 web、worker、urgentworker、clock 等。
  • <command> – 启动进程的命令行,如 rake jobs:work

此示例 Procfile 指定了两种类型,websleeperweb 进程在端口 5000 上启动 Web 服务器,一个简单的进程休眠 900 秒然后退出。

$ cat Procfile
web: bundle exec ruby web.rb -p ${PORT:-5000}
sleeper: sleep 900

如果您使用 远程容器镜像,您可以通过在工作目录中使用 Procfile 运行 drycc pull,或通过将字符串化的 Procfile 传递给 --procfile CLI 选项来定义进程类型。

例如,内联传递进程类型:

$ drycc pull drycc/example-go:latest --procfile="web: /app/bin/boot"

读取另一个目录中的 Procfile

$ drycc pull drycc/example-go:latest --procfile="$(cat deploy/Procfile)"

或通过位于当前工作目录中的 Procfile:

$ cat Procfile
web: /bin/boot
sleeper: echo "sleeping"; sleep 900


$ drycc pull -a steely-mainsail drycc/example-go
Creating build... done

$ drycc scale sleeper=1 -a steely-mainsail
Scaling processes... but first, coffee!
done in 0s

NAME                                        RELEASE    STATE    PTYPE      READY    RESTARTS     STARTED
steely-mainsail-sleeper-76c45b967c-4qm6w    v3         up       sleeper    1/1      0            2023-12-08T02:25:00UTC
steely-mainsail-web-c4f44c4b4-7p7dh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC

要删除进程类型,只需将其扩展到 0:

$ drycc scale sleeper=0 -a steely-mainsail
Scaling processes... but first, coffee!
done in 3s

NAME                                        RELEASE    STATE    PTYPE      READY    RESTARTS     STARTED
steely-mainsail-web-c4f44c4b4-7p7dh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC

扩展进程

部署在 Drycc Workflow 上的应用通过 [进程模型][] 向外扩展。使用 drycc scale 来控制为您的应用提供动力的 容器 数量。

$ drycc scale web=5 -a iciest-waggoner
Scaling processes... but first, coffee!
done in 3s

NAME                                        RELEASE    STATE    PTYPE      READY    RESTARTS     STARTED
iciest-waggoner-web-c4f44c4b4-7p7dh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC
iciest-waggoner-web-c4f44c4b4-8p7dh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC
iciest-waggoner-web-c4f44c4b4-9p7dh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC
iciest-waggoner-web-c4f44c4b4-1p7dh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC
iciest-waggoner-web-c4f44c4b4-2p7dh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC

如果您的应用有多个进程类型,您可以分别为每个类型扩展进程计数。例如,这允许您独立管理 Web 进程和后台工作进程。有关进程类型的更多信息,请参阅我们的 管理应用进程 文档。

在此示例中,我们将进程类型 web 扩展到 5,但将进程类型 background 保留为一个工作进程。

$ drycc scale web=5
Scaling processes... but first, coffee!
done in 4s

NAME                                                RELEASE    STATE    PTYPE      READY    RESTARTS     STARTED
scenic-icehouse-web-3291896318-7lord                v3         up       web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-jn957                v3         up       web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-rsekj                v3         up       web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-vwhnh                v3         up       web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-vokg7                v3         up       web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-vokg7                v3         up       web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-background-3291896318-yf8kh         v3         up       web        1/1      0            2023-12-08T02:25:00UTC

通过减少进程计数来扩展进程会向进程发送 TERM 信号,如果它们在 30 秒内未退出,则跟随 SIGKILL。根据您的应用,扩展可能会中断长时间运行的 HTTP 客户端连接。

例如,从 5 个进程扩展到 3:

$ drycc scale web=3
Scaling processes... but first, coffee!
done in 1s

NAME                                                RELEASE    STATE    PTYPE     READY    RESTARTS     STARTED
scenic-icehouse-web-3291896318-vwhnh                v2         up       web       1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-vokg7                v2         up       web       1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-vokg9                v2         up       web       1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-background-3291896318-yf8kh         v2         up       web       1/1      0            2023-12-08T02:25:00UTC

自动扩展

自动扩展允许在每个进程类型的基础上添加最小和最大数量的 Pod。这是通过指定所有可用 Pod 的目标 CPU 使用率来实现的。

此功能建立在 Kubernetes 中的 Horizontal Pod Autoscaling 或简称 HPA 之上。

$ drycc autoscale set web --min=3 --max=8 --cpu-percent=75
Applying autoscale settings for process type web on scenic-icehouse... done

然后查看为 web 创建的扩展规则

$ drycc autoscale list
PTYPE    PERCENT    MIN    MAX
web      75         3      8

删除扩展规则

$ drycc autoscale unset web
Removing autoscale for process type web on scenic-icehouse... done

为了使自动扩展工作,必须在每个应用 Pod 上指定 CPU 请求(可以通过 drycc limits --cpu 完成)。这允许自动扩展策略进行 适当计算 并决定何时向上和向下扩展。

向上扩展只能在过去 3 分钟内没有重新扩展的情况下发生。向下扩展将等待上次重新扩展后的 5 分钟。该信息和更多信息可以在 HPA 算法页面 找到。

获取应用容器的日志

列出容器:

$ drycc ps
NAME                                                RELEASE    STATE    PTYPEE     READY    RESTARTS     STARTED
python-getting-started-web-69b7d4bfdc-kl4xf         v2         up       web        1/1      0             2023-12-08T02:25:00UTC

=== python-getting-started Processes
--- web:
python-getting-started-web-69b7d4bfdc-kl4xf up (v2)

获取容器日志:

$ drycc ps logs -f python-getting-started-web-69b7d4bfdc-kl4xf
[2024-05-24 07:14:39 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2024-05-24 07:14:39 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
[2024-05-24 07:14:39 +0000] [1] [INFO] Using worker: gevent
[2024-05-24 07:14:39 +0000] [8] [INFO] Booting worker with pid: 8
[2024-05-24 07:14:39 +0000] [9] [INFO] Booting worker with pid: 9
[2024-05-24 07:14:39 +0000] [10] [INFO] Booting worker with pid: 10
[2024-05-24 07:14:39 +0000] [11] [INFO] Booting worker with pid: 11

获取应用容器的信息

列出容器:

$ drycc ps describe python-getting-started-web-69b7d4bfdc-kl4xf
Container:        python-getting-started-web                   
Image:            drycc/python-getting-started:latest          
Command:          
Args:             
                  - gunicorn                                   
                  - -c                                         
                  - gunicorn_config.py                         
                  - helloworld.wsgi:application                
State:            running                                      
  startedAt:      "2024-05-24T07:14:39Z"                       
Ready:            true                                         
Restart Count:    0                 

删除应用容器

删除容器。 由于设置了副本数量,将启动新容器以满足数量要求。

$ drycc ps delete python-getting-started-web-69b7d4bfdc-kl4xf
Deleting python-getting-started-web-69b7d4bfdc-kl4xf from python-getting-started... done

获取运行容器的 Shell

验证容器正在运行:

$ drycc ps
NAME                                                RELEASE    STATE    PTYPEE     READY    RESTARTS     STARTED
python-getting-started-web-69b7d4bfdc-kl4xf         v2         up       web        1/1      0             2023-12-08T02:25:00UTC

=== python-getting-started Processes
--- web:
python-getting-started-web-69b7d4bfdc-kl4xf up (v2)

获取运行容器的 shell:

$ drycc ps exec python-getting-started-web-69b7d4bfdc-kl4xf -it -- bash

在您的 shell 中,列出根目录:

# 在容器内运行此命令
ls /

在容器中运行单个命令

$ drycc ps exec python-getting-started-web-69b7d4bfdc-kl4xf -- date

使用 “drycc ps –help” 获取全局命令行列表(适用于所有命令)。

重启应用进程

如果您需要重启应用进程,您可以使用 drycc pts restart。在幕后,Drycc Workflow 指示 Kubernetes 终止旧进程并启动新进程来替换它。

$ drycc ps
NAME                                               RELEASE    STATE       PTYPE      READY    RESTARTS     STARTED
scenic-icehouse-web-3291896318-vokg7               v2         up          web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-rsekj               v2         up          web        1/1      0            2023-12-08T02:50:21UTC
scenic-icehouse-web-3291896318-vokg7               v2         up          web        1/1      0            2023-12-08T02:25:00UTC
scenic-icehouse-background-3291896318-yf8kh        v2         up          web        1/1      0            2023-12-08T02:25:00UTC

$ drycc pts restart scenic-icehouse-background
NAME                                               RELEASE    STATE       PTYPE      READY    RESTARTS    STARTED
scenic-icehouse-web-3291896318-vokg7               v2         up          web        1/1      0           2023-12-08T02:25:00UTC
scenic-icehouse-web-3291896318-rsekj               v2         up          web        1/1      0           2023-12-08T02:50:21UTC
scenic-icehouse-web-3291896318-vokg7               v2         up          web        1/1      0           2023-12-08T02:25:00UTC
scenic-icehouse-background-3291896318-yf8kh        v2         starting    web        1/1      0           2023-12-08T02:25:00UTC

注意进程名称已从 scenic-icehouse-background-3291896318-yf8kh 更改为 scenic-icehouse-background-3291896318-yd87g。在多节点 Kubernetes 集群中,这也可能具有将 Pod 调度到新节点的效果。

使用 “drycc pts –help” 获取 pts 命令行列表(进程类型信息)。

列出应用进程类型

$ drycc pts
NAME          RELEASE    READY    UP-TO-DATE    AVAILABLE    GARBAGE    STARTED                   
web           v2         3/3      1             1            true       2023-12-08T02:25:00UTC    
background    v2         1/1      1             1            false      2023-12-08T02:25:00UTC    

清理进程类型

清理不存在的 ptype,通常在 autodeploy 设置为 true 时自动执行。

$ drycc pts clean background

获取应用进程类型的部署信息

$ drycc pts describe web
Container:    python-getting-started-web                   
Image:        drycc/python-getting-started:latest          
Command:      
Args:         
              - gunicorn                                   
              - -c                                         
              - gunicorn_config.py                         
              - helloworld.wsgi:application                
Limits:       
              cpu 1                                                                                               
              ephemeral-storage 2Gi                                                                               
              memory 1Gi                                                                                          
Liveness:     http-get headers=[] path=/geo/ port=8000 delay=120s timeout=10s period=20s #success=1 #failure=3    
Readiness:    http-get headers=[] path=/geo/ port=8000 delay=120s timeout=10s period=20s #success=1 #failure=3  

6.6 - 配置应用程序

如何在环境中存储 Drycc 应用的配置,将配置与代码分离,使其易于维护应用或部署特定的配置。

配置应用程序

Drycc 应用程序[将配置存储在环境变量中][]。

设置环境变量

使用 drycc config 修改已部署应用程序的环境变量。

$ drycc help config
管理定义应用配置的环境变量

用法:
drycc config [flags]
drycc config [command]

可用命令:
info        应用配置信息
set         为应用设置环境变量
unset       取消设置应用的环境变量
pull        将环境变量拉取到路径
push        从路径推送环境变量
attach      选择要附加到应用 ptype 的环境组
detach      选择要从应用 ptype 分离的环境组

标志:
-a, --app string     应用程序的唯一可识别名称
-g, --group string   需要列出配置的组
-p, --ptype string   需要列出配置的 ptype
-v, --version int    需要列出配置的版本

全局标志:
-c, --config string   配置文件路径。(默认 "~/.drycc/client.json")
-h, --help            显示帮助信息

使用 "drycc config [command] --help" 获取有关命令的更多信息。

当配置更改时,会自动创建并部署新版本。

您可以使用一个 drycc config set 命令设置多个环境变量, 或者使用 drycc config push 和本地 .env 文件。

$ drycc config set FOO=1 BAR=baz && drycc config pull
$ cat .env
FOO=1
BAR=baz
$ echo "TIDE=high" >> .env
$ drycc config push
Creating config... done, v4

=== yuppie-earthman
DRYCC_APP: yuppie-earthman
FOO: 1
BAR: baz
TIDE: high

它可以修改应用程序进程类型的环境变量。

$ drycc config set FOO=1 BAR=baz --ptype=web

它还可以修改环境组的环境变量。

$ drycc config set FOO1=1 BAR1=baz --group=web.env

然后将此环境变量组绑定到 web。

$ drycc config attach web web.env

当然,您也可以分离它。

$ drycc config detach web web.env

附加到后端服务

Drycc 将数据库、缓存和队列等后端服务视为[附加资源][]。 附加使用环境变量执行。

例如,使用 drycc config 设置 DATABASE_URL,将 应用程序附加到外部 PostgreSQL 数据库。

$ drycc config set DATABASE_URL=postgres://user:pass@example.com:5432/db
=== peachy-waxworks
DATABASE_URL: postgres://user:pass@example.com:5432/db

可以使用 drycc config unset 执行分离。

Buildpacks 缓存

默认情况下,使用 [Imagebuilder][] 的应用将重用最新的镜像数据。 在部署依赖于必须获取的第三方库的应用程序时, 这可以大大加快部署速度。为了利用这一点,buildpack 必须通过写入缓存目录来实现 缓存。大多数 buildpack 已经实现了这一点,但在使用 自定义 buildpack 时,可能需要更改以充分利用缓存。

禁用和重新启用缓存

在某些情况下,缓存可能不会加快您的应用程序速度。要禁用缓存,您可以使用 drycc config set DRYCC_DISABLE_CACHE=1 设置 DRYCC_DISABLE_CACHE 变量。当您禁用缓存时,Drycc 将清除它创建的用于存储缓存的文件。关闭后,运行 drycc config unset DRYCC_DISABLE_CACHE 来重新启用缓存。

清除缓存

使用以下过程清除缓存:

$ drycc config set DRYCC_DISABLE_CACHE=1
$ git commit --allow-empty -m "Clearing Drycc cache"
$ git push drycc # (如果您使用不同的远程仓库,您应该使用您的远程仓库名称)
$ drycc config unset DRYCC_DISABLE_CACHE

自定义健康检查

默认情况下,Workflow 仅检查应用程序是否在其容器中启动。可以为应用程序配置健康检查探针来添加健康检查。健康检查作为 Kubernetes 容器探针实现。可以配置 ‘startupProbe’ ’livenessProbe’ 和 ‘readinessProbe’,每个探针可以是 ‘httpGet’、’exec’ 或 ’tcpSocket’ 类型,具体取决于容器所需的探针类型。

‘startupProbe’ 指示容器内的应用程序是否已启动。 如果提供了启动探针,则所有其他探针都被禁用,直到它成功。 如果启动探针失败,容器将受到其重启策略的影响。

’livenessProbe’ 对于长时间运行的应用程序很有用,最终 会过渡到损坏状态,除非通过重启它们,否则无法恢复。

其他时候,‘readinessProbe’ 很有用,当容器只是暂时无法 服务,并且会自行恢复。在这种情况下,如果容器未能通过 ‘readinessProbe’, 容器不会被关闭,而是容器将停止接收 传入请求。

‘httpGet’ 探针正如其名称:它在容器上执行 HTTP GET 操作。 200-399 范围内的响应代码被视为通过。‘httpGet’ 探针接受一个 端口号,以便在容器上执行 HTTP GET 操作。

’exec’ 探针在容器内运行命令来确定其健康状况。退出代码为 零被视为通过,而非零状态代码被视为失败。’exec’ 探针接受要在容器内运行的参数字符串。

’tcpSocket’ 探针尝试在容器中打开套接字。只有当检查可以建立连接时,容器才被视为健康。’tcpSocket’ 探针接受一个 端口号,以便在容器上执行套接字连接。

可以使用 drycc healthchecks set 为每个应用程序的每个 proctype 配置健康检查。如果未提及类型,则健康检查将应用于默认进程类型 web(无论存在哪个)。要 配置 httpGet liveness 探针:

$ drycc healthchecks set livenessProbe httpGet 80 --ptype web
Applying livenessProbe healthcheck... done

App:             peachy-waxworks
UUID:            afd84067-29e9-4a5f-9f3a-60d91e938812
Owner:           dev
Created:         2023-12-08T10:25:00Z
Updated:         2023-12-08T10:25:00Z
Healthchecks:
                 livenessProbe web http-get headers=[] path=/ port=80 delay=50s timeout=50s period=10s #success=1 #failure=3

If the application relies on certain headers being set (such as the Host header) or a specific URL path relative to the root, you can also send specific HTTP headers:

$ drycc healthchecks set livenessProbe httpGet 80 \
    --path /welcome/index.html \
    --headers "X-Client-Version:v1.0,X-Foo:bar"
Applying livenessProbe healthcheck... done

App:             peachy-waxworks
UUID:            afd84067-29e9-4a5f-9f3a-60d91e938812
Owner:           dev
Created:         2023-12-08T10:25:00Z
Updated:         2023-12-08T10:25:00Z
Healthchecks:
                 livenessProbe web http-get headers=[X-Client-Version=v1.0] path=/welcome/index.html port=80 delay=50s timeout=50s period=10s #success=1 #failure=3

To configure an exec readiness probe:

$ drycc healthchecks set readinessProbe exec -- /bin/echo -n hello --ptype web
Applying readinessProbe healthcheck... done

App:             peachy-waxworks
UUID:            afd84067-29e9-4a5f-9f3a-60d91e938812
Owner:           dev
Created:         2023-12-08T10:25:00Z
Updated:         2023-12-08T10:25:00Z
Healthchecks:
                 readinessProbe web exec /bin/echo -n hello delay=50s timeout=50s period=10s #success=1 #failure=3

You can overwrite a probe by running drycc healthchecks set again:

$ drycc healthchecks set readinessProbe httpGet 80 --ptype web
Applying livenessProbe healthcheck... done

App:             peachy-waxworks
UUID:            afd84067-29e9-4a5f-9f3a-60d91e938812
Owner:           dev
Created:         2023-12-08T10:25:00Z
Updated:         2023-12-08T10:25:00Z
Healthchecks:
                 livenessProbe web http-get headers=[] path=/ port=80 delay=50s timeout=50s period=10s #success=1 #failure=3

Configured health checks also modify the default application deploy behavior. When starting a new Pod, Workflow will wait for the health check to pass before moving onto the next Pod.

自动部署

默认情况下,更改配置、限制或健康检查等将触发部署。 如果您不想部署,可以禁用。

$ drycc autodeploy disable

要重新启用自动部署。

drycc autodeploy enable

您可以通过执行以下命令进行部署。 部署所有 ptype

drycc releases deploy

部署 web 进程类型,并支持 --force 选项强制部署。

drycc releases deploy web --force

自动回滚

默认情况下,部署失败将回滚到之前的成功版本。 如果您不想发生这种情况,可以禁用。

$ drycc autorollback disable

要重新启用自动回滚。

drycc autorollback enable

隔离应用程序

Workflow 支持使用 drycc tags 将应用程序隔离到一组节点上。

一旦您的节点配置了适当的标签选择器,使用 drycc tags set 将应用程序 ptype 限制到这些节点:

$ drycc tags set web environ=prod
Applying tags...  done, v4

environ  prod

6.7 - 管理应用指标

指标支持 Pod 的基本监控功能,提供 CPU、内存、磁盘、网络等各种监控指标,以满足 Pod 资源的基本监控需求。

创建认证令牌

使用 drycc 客户端创建认证令牌。

# drycc tokens add prometheus --password admin --username admin
 !    WARNING: Make sure to copy your token now.
 !    You won't be able to see it again, please confirm whether to continue.
 !    To proceed, type "yes" !

> yes
UUID                                  USERNAME    TOKEN
58176cf1-37a8-4c52-9b27-4c7a47269dfb  admin       1F2c7A802aF640fd9F31dD846AdDf56BcMsay

为 prometheus 添加抓取配置

有效的示例文件可以在这里找到。

全局配置指定在所有其他配置上下文中有效的参数。它们还作为其他配置部分的默认值。

global:
  scrape_interval:   60s
  evaluation_interval: 60s
scrape_configs:
- job_name: 'drycc'
  scheme: https
  metrics_path: /v2/apps/<appname>/metrics
  authorization:
    type: Token
    credentials: 1F2c7A802aF640fd9F31dD846AdDf56BcMsay
  static_configs:
  - targets: ['drycc.domain.com']

6.8 - 管理应用

这是 Drycc 工作方式的高级技术描述。它将您在 Drycc 平台上编写、配置、部署和运行应用时遇到的许多概念联系在一起。

跟踪应用更改

Drycc Workflow 跟踪对您的应用的所有更改。应用更改是新应用代码推送到平台(通过 git push drycc master)或应用配置更新(通过 drycc config:set KEY=VAL)的结果。

每次对您的应用进行构建或配置更改时,都会创建一个新的 release。这些发布编号单调递增。

您可以使用 drycc releases 查看对您的应用的更改记录:

$ drycc releases
OWNER    STATE      VERSION    CREATED                 SUMMARY
dev      succeed    v3         2023-12-04T10:17:46Z    dev deleted PIP_INDEX_URL, DISABLE_COLLECTSTATIC
dev      succeed    v2         2023-12-01T10:20:22Z    dev added IMAGE_PULL_POLICY, PIP_INDEX_URL, PORT, DISABLE_COLLEC[...]
dev      succeed    v1         2023-11-30T17:54:57Z    dev created initial release

回滚发布

Drycc Workflow 还支持回滚到以前的发布。如果有问题的代码或错误的配置更改被推送到您的应用,您可以回滚到以前已知良好的发布。

在此示例中,应用当前运行发布 v4。使用 drycc rollback v2 告诉 Workflow 部署用于发布 v2 的构建和配置。这创建一个名为 v5 的新发布,其内容是发布 v2 的源代码和配置:

$ drycc releases
OWNER    STATE      VERSION    CREATED                 SUMMARY
dev      succeed    v3         2023-12-04T10:17:46Z    dev deleted PIP_INDEX_URL, DISABLE_COLLECTSTATIC
dev      succeed    v2         2023-12-01T10:20:22Z    dev added IMAGE_PULL_POLICY, PIP_INDEX_URL, PORT, DISABLE_COLLEC[...]
dev      succeed    v1         2023-11-30T17:54:57Z    dev created initial release

$ drycc rollback v2
Rolled back to v2

$ drycc releases
OWNER    STATE      VERSION    CREATED                 SUMMARY
dev      succeed    v4         2023-12-04T10:20:46Z    dev rolled back to v2
dev      succeed    v3         2023-12-04T10:17:46Z    dev deleted PIP_INDEX_URL, DISABLE_COLLECTSTATIC
dev      succeed    v2         2023-12-01T10:20:22Z    dev added IMAGE_PULL_POLICY, PIP_INDEX_URL, PORT, DISABLE_COLLEC[...]
dev      succeed    v1         2023-11-30T17:54:57Z    dev created initial release

仅回滚 web 进程类型:

$ drycc rollback v3 web
Rolled back to v3

$ drycc releases
OWNER    STATE      VERSION    CREATED                 SUMMARY
dev      succeed    v5         2023-12-04T10:23:49Z    dev rolled back to v3
dev      succeed    v4         2023-12-04T10:20:46Z    dev rolled back to v2
dev      succeed    v3         2023-12-04T10:17:46Z    dev deleted PIP_INDEX_URL, DISABLE_COLLECTSTATIC
dev      succeed    v2         2023-12-01T10:20:22Z    dev added IMAGE_PULL_POLICY, PIP_INDEX_URL, PORT, DISABLE_COLLEC[...]
dev      succeed    v1         2023-11-30T17:54:57Z    dev created initial release

运行一次性管理任务

Drycc 应用 [使用一次性进程进行管理任务][] 如数据库迁移和其他必须针对实时应用运行的命令。

使用 drycc run 在部署的应用上执行命令。

$ drycc run -- 'ls -l'
Running `ls -l`...

total 28
-rw-r--r-- 1 root root  553 Dec  2 23:59 LICENSE
-rw-r--r-- 1 root root   60 Dec  2 23:59 Procfile
-rw-r--r-- 1 root root   33 Dec  2 23:59 README.md
-rw-r--r-- 1 root root 1622 Dec  2 23:59 pom.xml
drwxr-xr-x 3 root root 4096 Dec  2 23:59 src
-rw-r--r-- 1 root root   25 Dec  2 23:59 system.properties
drwxr-xr-x 6 root root 4096 Dec  3 00:00 target

共享应用

使用 drycc perms add 允许其他 Drycc 用户与您协作应用。

$ drycc perms add otheruser view,change,delete
Adding user otheruser as a collaborator for view,change,delete peachy-waxwork... done

使用 drycc perms 查看应用当前与谁共享,使用 drycc perms remove 删除协作者。

在使用与您共享的应用时,克隆原始存储库并在尝试 git push 任何更改到 Drycc 之前添加 Drycc 的 git 远程条目。

$ git clone https://github.com/drycc/example-java-jetty.git
Cloning into 'example-java-jetty'... done
$ cd example-java-jetty
$ git remote add -f drycc ssh://git@local3.dryccapp.com:2222/peachy-waxworks.git
Updating drycc
From drycc-controller.local:peachy-waxworks
 * [new branch]      master     -> drycc/master

应用故障排除

部署在 Drycc Workflow 上的应用 [将日志视为事件流][]。Drycc Workflow 聚合每个 Containerstdoutstderr,使排除应用问题变得容易。

使用Drycc Grafana查看部署应用的日志输出。

Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.5]: INFO:oejsh.ContextHandler:started o.e.j.s.ServletContextHandler{/,null}
Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.8]: INFO:oejs.Server:jetty-7.6.0.v20120127
Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.5]: INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:10005
Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.6]: INFO:oejsh.ContextHandler:started o.e.j.s.ServletContextHandler{/,null}
Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.7]: INFO:oejsh.ContextHandler:started o.e.j.s.ServletContextHandler{/,null}
Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.6]: INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:10006
Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.7]: INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:10007
Dec  3 00:30:31 ip-10-250-15-201 peachy-waxworks[web.8]: INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:10008

6.9 - 为应用挂载卷

Drycc 支持多种类型的卷。一个容器可以同时使用任意数量的卷类型。

我们可以使用以下命令创建卷并挂载已创建的卷。 Drycc 创建卷支持 ReadWriteMany,因此在部署 drycc 之前,您需要有一个支持 ReadWriteMany 的 StorageClass。 部署 drycc 时,将 controller.appStorageClass 设置为此 StorageClass。

使用 drycc volumes 为已部署应用的进程挂载卷。

$ drycc help volumes
Valid commands for volumes:

add              create a volume for the application
expand           expand a volume for the application
list             list volumes in the application
info             print information about a volume
remove           delete a volume from the application
client           the client used to manage volume files
mount            mount a volume to process of the application
unmount          unmount a volume from process of the application

Use 'drycc help [command]' to learn more.

为应用创建卷

您可以使用 drycc volumes add 命令创建 csi 卷。

$ drycc volumes add myvolume 200M
Creating myvolume to scenic-icehouse... done

或使用现有的 nfs 服务器

$ drycc volumes add mynfsvolume 200M -t nfs --nfs-server=nfs.drycc.com --nfs-path=/
Creating mynfsvolume to scenic-icehouse... done

或使用现有的 oss3

$ drycc volumes add myossvolume 200M -t oss --oss-server=oss.drycc.com --oss-bucket=vbucket --oss-access-key=ak --oss-secret-key=sk
Creating myossvolume to scenic-icehouse... done

列出应用中的卷

卷创建后,您可以列出此应用中的卷。

$ drycc volumes list
NAME          OWNER    TYPE    PTYPE    PATH     SIZE
myvolume      admin    csi                       200M
mynfsvolume   admin    nfs                       200M
myossvolume   admin    oss                       200M

挂载卷

名为 myvolume 的卷已创建,您可以使用应用的进程挂载该卷,使用 drycc volumes mount 命令。卷挂载时,将自动创建并部署新版本。

$ drycc volumes mount myvolume web=/data/web
Mounting volume... done

使用 drycc volumes list 显示挂载详情。

$ drycc volumes list
NAME       OWNER    TYPE    PTYPE    PATH         SIZE
myvolume   admin    nfs     web      /data/web    200M

如果您不再需要卷,请使用 drycc volumes unmount 卸载卷,然后使用 drycc volumes remove 从应用中删除卷。 删除卷之前,必须先卸载卷。

$ drycc volumes unmount myvolume web
Unmounting volume... done

$ drycc volumes remove myvolume
Deleting myvolume from scenic-icehouse... done

使用卷客户端管理卷文件。

假设名为 myvolume 的卷已创建并挂载。

准备一个名为 testfile 的文件。

$ echo "testtext" > testfile

上传。 $ drycc volumes client cp testfile vol://myvolume/ [↑] testfile 100% [==================================================] (5/ 5 B, 355 B/s)

列出 myvolume 中的文件。

$ drycc volumes client ls vol://myvolume/
[2024-07-22T15:32:28+08:00]    5    testfile

删除 myvolume 中的 testfile。

$ drycc volumes client rm vol://myvolume/testfile

6.10 - 关于应用的网关

Gateway 描述了如何将流量转换为集群内的服务。

Gateway 描述了如何将流量转换为集群内的服务。也就是说,它定义了一种将流量从不知道 Kubernetes 的地方转换为知道的地方的方式。例如,由云负载均衡器、集群内代理或外部硬件负载均衡器发送到 Kubernetes 服务的流量。虽然许多用例的客户端流量源于"集群外部",但这不是必需的。

为应用创建网关

网关是一种对外暴露服务的方式,它生成一个外部 IP 地址来连接路由和服务。 部署后,网关已创建。

列出容器:

# drycc gateways
NAME                      LISENTER       PORT     PROTOCOL    ADDRESSES
python-getting-started    tcp-80-0       80       HTTP        101.65.132.51

您也可以在此网关中添加端口或创建一个端口。

# drycc gateways add python-getting-started --port=443 --protocol=HTTPS
Adding gateway python-getting-started to python-getting-started... done

为应用创建服务

服务是一种对内暴露服务的方式,创建服务会生成一个内部 DNS,可以访问 ptype。 web 进程类型已创建,对于其他类型,您应该根据需要添加。

列出服务:

$ drycc services
PTYPE      PORT    PROTOCOL    TARGET-PORT    DOMAIN
web        80      TCP         8000           python-getting-started.python-getting-started.svc

为进程类型添加新服务

# drycc services add --help
# drycc services add sleep 8001:8001

为应用创建路由

网关可以附加到一个或多个路由引用,这些路由引用用于将部分流量引导到特定服务。 与上述相同,web 进程类型已经绑定了网关和服务。

# drycc routes
NAME                           OWNER        KIND           GATEWAYS                              SERVICES
python-getting-started         demo         HTTPRoute      ["python-getting-started:80"]         ["python-getting-started:80"]

创建新路由并附加网关。

drycc routes add sleep HTTPRoute --ptype=sleep  sleep:8001,100
drycc routes attach sleep --gateway=python-getting-started --port=80

6.11 - 管理应用的资源

用于开发、扩展和操作您的应用的工具和服务。

我们可以使用以下命令创建资源并绑定已创建的资源。 此命令依赖于 service-catalog

使用 drycc resources 为已部署的应用创建和绑定资源。

$ drycc help resources
Manage resources for your applications

Usage:
drycc resources [flags]
drycc resources [command]

Available Commands:
services    List all available resource services
plans       List all available plans for a resource service
create      Create a resource for the application
list        List resources in the application
describe    Get a resource's detail in the application
update      Update a resource from the application
bind        Bind a resource for an application
unbind      unbind a resources for an application
destroy     Delete a resource from the application

Flags:
-a, --app string   The uniquely identifiable name for the application
-l, --limit int    The maximum number of results to display

Global Flags:
-c, --config string   Path to configuration file. (default "~/.drycc/client.json")
-h, --help            Display help information
-v, --version         Display client version

Use "drycc resources [command] --help" for more information about a command.

列出所有可用的资源服务

您可以使用 drycc resources services 命令列出可用的资源服务

$ drycc resources services
ID                                      NAME                  UPDATEABLE
15032a52-33c2-4b40-97aa-ceb972f51509    airflow               true
b7cb26a4-b258-445c-860b-a664239a67f8    cloudbeaver           true
9ce3c3ba-33b5-4e4e-a5e9-a338a83d5070    flink                 true
b80c51a1-957c-4d93-b3d5-efde84cd8031    fluentbit             true
fff5b6c7-ed85-429b-8265-493e40cc53c7    grafana               true
412e368f-bf78-4798-92cc-43343119a57d    kafka                 true
ea2a9b87-fbc4-4e2a-adee-161c1f91d98d    minio                 true
383f7316-84f3-4955-8491-1d4b02b749c8    mongodb               true
fbee746b-f3a7-4bef-8b55-cbecfd4c8ac3    mysql-cluster         true
5975094d-45cc-4e85-8573-f93937d026c7    opensearch            true
1db95161-7193-4544-8c76-e5ad5f6c03f6    pmm                   true
5cfb0abf-276c-445b-9060-9aa964ede87d    postgresql-cluster    true
b8f70264-eafc-4b2f-848e-2ec0d059032b    prometheus            true
e1fd0d37-9046-4152-a29b-d155c5657c8b    redis                 true
7d2b64c6-0b59-4f08-a2f5-7b17cea6e5ee    redis-cluster         true
2e6877df-86e7-4bcc-a869-2a9b6847a465    seaweedfs             true
4aea5c0f-9495-420d-896a-ffc61a3eced5    spark                 true
b50db3b5-8d5f-4be9-b8bd-467ecd6cc11d    zookeeper             true

列出资源服务的所有可用计划

您可以使用 drycc resources plans 命令列出资源服务的所有可用计划

$ drycc resources plans redis
ID                                      NAME              DESCRIPTION
8d659058-a3b4-4058-b039-cc03a31b9442    standard-128      Redis standard-128 plan which limit resources memory size 128Mi.
36e3dbec-fc51-4f6b-9baa-e31e316858be    standard-256      Redis standard-256 plan which limit resources memory size 256Mi.
560817c2-5aa1-41c4-9ee6-a77e3ee552d5    standard-512      Redis standard-512 plan which limit resources memory size 512Mi.
d544d989-9fb8-43e9-a74e-0840ce1b8f0f    standard-1024     Redis standard-1024 plan which limit resources memory size 1Gi.
ad51b7bb-9b12-4ffd-8e49-010c0141b263    standard-2048     Redis standard-2048 plan which limit resources memory size 2Gi.
5097d76e-557c-453f-bdb1-54009e0df78d    standard-4096     Redis standard-4096 plan which limit resources memory size 4Gi.
be3fa2d0-36d2-47c5-9561-9deffe5ba373    standard-8192     Redis standard-8192 plan which limit resources memory size 8Gi.
4ca812a8-d7c3-439f-96cd-26523e88400e    standard-16384    Redis standard-16384 plan which limit resources memory size 16Gi.
b7f2a71f-0d97-48fd-8eed-aab24a7822f3    standard-32768    Redis standard-32768 plan which limit resources memory size 32Gi.
25c6b5d5-7505-47c8-95b1-dc9bdc698063    standard-65536    Redis standard-65536 plan which limit resources memory size 64Gi.

在应用中创建资源

您可以使用 drycc resources create 命令创建资源

$ drycc resources create redis redis standard-128
Creating redis to scenic-icehouse... done

资源创建后,您可以列出此应用中的资源。

$ drycc resources list
UUID                                    NAME     OWNER    PLAN                  UPDATED
07220e9e-d54d-4d74-a88c-f464aa374386    redis    admin    redis:standard-128    2024-05-08T01:01:00Z

绑定资源

名为 redis 的资源已创建,您可以将 redis 绑定到应用,使用 drycc resources bind redis 命令。

$ drycc resources bind redis
Binding resource... done

描述资源

使用 drycc resources describe 显示绑定详情。如果绑定成功,此命令将显示连接到资源的信息。

$ drycc resources describe redis
=== scenic-icehouse resource redis
plan:               redis:1000
status:             Ready
binding:            Ready

REDISPORT:          6379
REDIS_PASSWORD:     RzG87SJWG1
SENTINELHOST:       172.16.0.2
SENTINELPORT:       26379

更新资源

您可以使用 drycc resources update 命令升级到新计划。 将计划容量升级到 128MB 的示例:

$ drycc resources update redis redis standard-128
Updating redis to scenic-icehouse... done

删除资源

如果您不再需要资源,请使用 drycc resources unbind 取消绑定资源,然后使用 drycc resources destroy 从应用中删除资源。 删除资源之前,必须先取消绑定资源。

$ drycc resources unbind redis
Unbinding resource... done

$ drycc resources destroy redis
Deleting redis from scenic-icehouse... done

6.12 - 应用间通信

Drycc 应用程序之间的通信解决方案。

多进程应用程序的常见架构模式是让一个进程服务公共请求,同时让多个其他进程支持公共进程,例如按计划执行操作或处理队列中的工作项。要在 Drycc Workflow 中实现这种应用程序系统,请设置应用程序使用 DNS 解析进行通信,如上所示,并通过从 Drycc Workflow 路由器中删除它们来隐藏支持进程的公共视图。

DNS 服务发现

Drycc Workflow 支持部署由进程系统组成的单个应用程序。每个 Drycc Workflow 应用程序都在单个端口上通信,因此与其他 Workflow 应用程序通信意味着找到该应用程序的地址和端口。所有 Workflow 应用程序在外部都映射到端口 80,因此找到其 IP 地址是唯一的挑战。Workflow 为每个应用程序创建一个 Kubernetes Service,这有效地为应用程序分配了一个名称和一个集群内部 IP 地址。集群中运行的 DNS 服务添加和删除 DNS 记录,这些记录在添加和删除服务时从应用程序名称指向其 IP 地址。然后,Drycc Workflow 应用程序可以简单地向服务的域名发送请求,该域名是"app-name.app-namespace"。

6.13 - 资源限制

Drycc Workflow 支持限制每个进程的内存和 CPU 份额。

管理应用资源限制

Drycc Workflow 支持限制每个进程的内存和 CPU 份额。为每个进程类型设置的请求/限制将作为请求和限制提供给 Kubernetes。这意味着您为进程保证 <requests> 数量的资源,同时限制进程使用不超过 <limits> 的资源。 默认情况下,如果我们没有明确设置 <requests> 值,Kubernetes 会将 <requests> 设置为等于 <limit>。请记住 0 <= requests <= limits

限制

如果您设置的请求/限制超出集群的范围,Kubernetes 将无法将您的应用进程调度到集群中!

$ drycc limits plans

ID                    SPEC    CPU              VCPUS    MEMORY     FEATURES
std1.large.c1m1       std1    Universal CPU    1        1 GiB      Integrated GPU shared
std1.large.c1m2       std1    Universal CPU    1        2 GiB      Integrated GPU shared
std1.large.c1m4       std1    Universal CPU    1        4 GiB      Integrated GPU shared
std1.large.c1m8       std1    Universal CPU    1        8 GiB      Integrated GPU shared
std1.large.c2m2       std1    Universal CPU    2        2 GiB      Integrated GPU shared
std1.large.c2m4       std1    Universal CPU    2        4 GiB      Integrated GPU shared
std1.large.c2m8       std1    Universal CPU    2        8 GiB      Integrated GPU shared
std1.large.c2m16      std1    Universal CPU    2        16 GiB     Integrated GPU shared

$ drycc limits set web=std1.large.c1m1
Applying limits... done

6.14 - 域名和路由

通过自定义域名使您的应用可访问。

您可以使用 drycc domains 向应用程序添加或删除自定义域名:

$ drycc domains add hello.bacongobbler.com --ptype=web
Adding hello.bacongobbler.com to finest-woodshed... done

完成后,您可以进入 DNS 注册商并设置从新应用名称到旧应用名称的 CNAME:

$ dig hello.dryccapp.com
[...]
;; ANSWER SECTION:
hello.bacongobbler.com.         1759    IN    CNAME    finest-woodshed.dryccapp.com.
finest-woodshed.dryccapp.com.    270     IN    A        172.17.8.100

要从路由网格中添加或删除应用程序,请使用 drycc routing

$ drycc routing disable
Disabling routing for finest-woodshed... done

这将使应用程序无法通过 [路由器][] 访问,但应用程序仍然可以通过其 Kubernetes 服务 在内部访问。要重新启用路由:

$ drycc routing enable
Enabling routing for finest-woodshed... done

6.15 - 应用 SSL 证书

SSL 是一种加密协议,为所有 Web 请求提供端到端加密和完整性。

应用 SSL 证书

SSL 是一种加密协议,为所有 Web 请求提供端到端加密和完整性。传输敏感数据的应用应启用 SSL,以确保所有信息安全传输。

要在自定义域名(如 www.example.com)上启用 SSL,请使用 SSL 端点。

概述

由于 SSL 验证的独特性质,为您的域名配置 SSL 是一个涉及多个第三方的多步骤过程。您需要:

  1. 从 SSL 提供商处购买 SSL 证书
  2. 将证书上传到 Drycc

获取 SSL 证书

购买 SSL 证书的成本和过程因供应商而异。RapidSSL 提供了一种简单的方式来购买证书,是推荐的解决方案。如果您可以使用此提供商,请参阅[使用 RapidSSL 购买 SSL 证书][]以获取说明。

DNS 和域名配置

SSL 证书配置完成后,您的证书确认后,您必须通过 Drycc 路由对域名的请求。除非您已经这样做,否则使用以下命令将生成 CSR 时指定的域名添加到您的应用中:

$ drycc domains add www.example.com --ptype==web -a foo
Adding www.example.com to foo... done

添加证书

使用 certs:add 命令将您的证书、任何中间证书和私钥添加到端点。

$ drycc certs add example-com server.crt server.key -a foo
Adding SSL endpoint... done
www.example.com

Drycc 平台将检查证书并从中提取相关信息,如通用名称、主题备用名称 (SAN)、指纹等。

这允许通配符证书和 SAN 中的多个域名,而无需上传重复项。

添加证书链

有时,您的证书(如自签名或廉价证书)需要额外的证书来建立信任链。您需要将所有证书捆绑到一个文件中并提供给 Drycc。重要的是,您的站点证书必须是第一个:

$ cat server.crt server.ca > server.bundle

之后,您可以使用 certs add 命令将其添加到 Drycc:

$ drycc certs add example-com server.bundle server.key -a foo
Adding SSL endpoint... done
www.example.com

将 SSL 证书附加到域名

证书不会自动连接到域名,而是您必须将证书附加到域名

$ drycc certs attach example-com example.com -a foo

每个证书可以连接到多个域名。不需要上传重复项。

要删除关联

$ drycc certs detach example-com example.com -a foo

端点概述

您可以使用 drycc certs 验证域名的 SSL 配置详情。

$ drycc certs
NAME           COMMON-NAME    EXPIRES        SAN                 DOMAINS           
example-com    example.com    14 Jan 2017    blog.example.com    example.com

或通过查看每个证书的详细信息

$ drycc certs info example-com -a foo

=== bar-com Certificate
Common Name(s):     example.com
Expires At:         2017-01-14 23:57:57 +0000 UTC
Starts At:          2016-01-15 23:57:57 +0000 UTC
Fingerprint:        7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0
Subject Alt Name:   blog.example.com
Issuer:             /C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=example.com/emailAddress=engineering@drycc.cc
Subject:            /C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=example.com/emailAddress=engineering@drycc.cc

Connected Domains:  example.com
Owner:              admin-user
Created:            2016-01-28 19:07:41 +0000 UTC
Updated:            2016-01-30 00:10:02 +0000 UTC

测试 SSL

使用命令行工具如 curl 来测试您的安全域名的配置是否正确。

注意输出。它应该打印 SSL certificate verify ok。如果它打印类似 common name: www.example.com (does not match 'www.somedomain.com') 的内容,则说明配置不正确。

在路由器上强制 SSL

要强制所有 HTTP 请求重定向到 HTTPS,可以通过运行以下命令在路由器级别强制 TLS

$ drycc tls force enable -a foo
Enabling https-only requests for foo... done

访问应用 HTTP 端点的用户现在将收到 301 重定向到 HTTPS 端点。

要禁用强制 TLS,请运行

$ drycc tls force disable -a foo
Disabling https-only requests for foo... done

自动证书管理

通过自动证书管理 (ACM),Drycc 自动管理通用运行时上具有 Hobby 和 Professional dyno 的应用的 TLS 证书,以及启用该功能的私有空间中的应用。由 ACM 处理的证书会在到期前一个月自动续订,每当您添加或删除自定义域名时,会自动创建新证书。所有具有付费 dyno 的应用都免费包含 ACM。自动证书管理使用 Let’s Encrypt,这是免费、自动化和开放的证书颁发机构,用于管理您的应用的 TLS 证书。Let’s Encrypt 由互联网安全研究小组 (ISRG) 为公共利益运营。

使用以下命令启用 ACM: $ drycc tls auto enable -a foo

使用以下命令禁用 ACM: $ drycc tls auto disable -a foo

删除证书

您可以使用 certs:remove 命令删除证书:

$ drycc certs remove my-cert -a foo
Removing www.example.com... Done.

更换证书

在应用的生命周期中,操作员将不得不获取具有新到期日期的证书并将其应用到所有相关应用,下面是更换证书的推荐方法。

有意选择证书名称,尽可能将其命名为 example-com-2017,其中年份表示到期年份。这允许在购买新证书时使用 example-com-2018

假设所有应用已经在使用 example-com-2017,可以运行以下命令,链接在一起或其他方式:

$ drycc certs detach example-com-2017 example.com -a foo
$ drycc certs attach example-com-2018 example.com -a foo

这将处理单个域名,允许操作员验证一切按计划进行,并慢慢将其推广到使用相同方法的任何其他应用。

故障排除

如果您的 SSL 端点未按预期工作,以下是一些可以遵循的步骤。

不受信任的证书

在某些情况下访问 SSL 端点时,它可能会将您的证书列为不受信任。

如果发生这种情况,可能是因为它不受 Mozilla 的[root CA][]列表信任。如果是这种情况,您的证书可能被许多浏览器视为不受信任。

如果您上传了由根机构签名的证书,但收到消息说它不受信任,则证书有问题。例如,它可能缺少[中间证书][]。如果是这样,从您的 SSL 提供商下载中间证书,从 Drycc 中删除证书,然后重新运行 certs add 命令。

6.16 - 使用 drycc 路径

Drycc 容器注册表允许您将基于 Docker 的应用部署到 Drycc。支持通用运行时和私有空间。

Drycc 堆栈仅适用于高级用例。除非您有自定义 Docker 镜像的具体需求,否则我们建议使用 Drycc 的默认 buildpack 驱动的构建系统。它提供自动基础镜像安全更新和特定于语言的优化。它还避免了维护容器 Dockerfile 的需要。

Drycc 配置路径概述

Drycc 仓库有两种不同的形式:

  • 工作树根目录下的 .drycc 目录;

  • 根目录是一个"裸"仓库(即没有自己的工作树)。 通常用于 drycc pull

Drycc 仓库中可能存在这些东西。

config/[a-z0-9]+(\.[a-z0-9]+)*::
        配置文件名,文件名是组名。
        格式是环境变量格式。

[a-z0-9]+(\-[a-z0-9]+)*.(yaml|yml)::
        流水线配置文件。

配置格式

Environment variables follow = formatting. By convention, but not rule, environment variable names are always capitalized.

配置格式

环境变量遵循 = 格式。按照惯例,但不是规则,环境变量名称总是大写的。

DEBUG=true
JVM_OPTIONS=-XX:+UseG1GC

流水线格式

清单有三个顶级部分。

  • build – 指定要构建的 Dockerfile。
  • env – 指定容器中的环境变量。
  • run – 指定要执行的发布阶段任务。
  • config – 指定配置组,全局组自动引用。
  • deploy – 指定部署的命令和参数。

这是一个说明使用清单构建 Docker 镜像的示例。

kind: pipeline
ptype: web
build:
  docker: Dockerfile
  arg:
    CODENAME: bookworm
env:
  VERSION: 1.2.1
run:
  command:
  - ./deployment-tasks.sh
  image: task
  timeout: 100
config:
- jvm-config
deploy:
  command:
  - bash
  - -ec
  args:
  - bundle exec puma -C config/puma.rb

有关更多部署信息,请参考 drycc 示例

Pipeline format

A manifest has three top-level sections.

  • build – Specifies the to build Dockerfile.
  • env – Specifies environment variables in container.
  • run – Specifies the release phase tasks to execute.
  • config – Specifies config group, global group automatic reference.
  • deploy – Specifies the commands and args to deploy.

Here’s an example that illustrates using a manifest to build Docker images.

kind: pipeline
ptype: web
build:
  docker: Dockerfile
  arg:
    CODENAME: bookworm
env:
  VERSION: 1.2.1
run:
  command:
  - ./deployment-tasks.sh
  image: task
  timeout: 100
config:
- jvm-config
deploy:
  command:
  - bash
  - -ec
  args:
  - bundle exec puma -C config/puma.rb

For more deployment information, please refer to the drycc examples.

7 - 故障排除

故障排除是系统性问题解决方法。

7.1 - Workflow 故障排除

用户在配置 Workflow 时遇到的常见问题详述如下。

组件启动失败

有关故障排除失败组件的信息,请参见使用 Kubectl 进行故障排除

应用启动失败

有关应用部署问题故障排除的信息,请参见应用故障排除

权限被拒绝 (publickey)

此问题最常见的原因是用户忘记运行 drycc keys:add 或将他们的私钥添加到 SSH 代理。要这样做,请运行 ssh-add ~/.ssh/id_rsa,然后再次尝试运行 git push drycc master

如果在尝试运行上述 ssh-add 命令后收到 Could not open a connection to your authentication agent 错误,您可能需要在运行 ssh-add 之前通过发出 eval "$(ssh-agent)" 命令来加载 SSH 代理环境变量。

其他问题

遇到这里没有详细说明的问题?请打开一个 issue 或加入 Slack 上的 #community 获取帮助!

7.2 - 使用 Kubectl 进行故障排除

Kubernetes 提供了一个命令行工具,用于与 Kubernetes 集群的控制平面通信,使用 Kubernetes API。

本文档描述了如何使用 kubectl 来调试集群的任何问题。

深入了解组件

使用 kubectl,可以检查集群的当前状态。当使用 helm 安装 Workflow 时,Workflow 被安装到 drycc 命名空间中。要检查 Workflow 是否正在运行,请运行:

$ kubectl --namespace=drycc get pods
NAME                          READY     STATUS              RESTARTS   AGE
drycc-builder-gqum7            0/1       ContainerCreating   0          4s
drycc-controller-h6lk6         0/1       ContainerCreating   0          4s
drycc-controller-celery-cmxxn  0/3       ContainerCreating   0          4s
drycc-database-56v39           0/1       ContainerCreating   0          4s
drycc-fluentbit-xihr1          0/1       Pending             0          2s
drycc-storage-c2exb            0/1       Pending             0          3s
drycc-grafana-9ccur            0/1       Pending             0          3s
drycc-registry-5bor6           0/1       Pending             0          3s

要获取特定组件的日志,请使用 kubectl logs

$ kubectl --namespace=drycc logs drycc-controller-h6lk6
system information:
Django Version: 1.9.6
Python 3.5.1
addgroup: gid '0' in use
Django checks:
System check identified no issues (2 silenced).
[...]

要深入运行中的容器来检查其环境,请使用 kubectl exec

$ kubectl --namespace=drycc exec -it drycc-database-56v39 gosu postgres psql
psql (13.4 (Debian 13.4-1.pgdg100+1))
Type "help" for help.

postgres=# \l
                                                List of databases
     Name          |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-------------------+----------+----------+------------+------------+-----------------------
 drycc_controller  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 drycc_passport    | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres          | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0         | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
                   |          |          |            |            | postgres=CTc/postgres
 template1         | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
                   |          |          |            |            | postgres=CTc/postgres
(4 rows)
postgres=# \connect drycc_controller
You are now connected to database "drycc_controller" as user "postgres".
drycc_controller=# \dt
                                 List of relations
 Schema |              Name              | Type  |      Owner
--------+--------------------------------+-------+-------------------
 public | api_app                        | table | drycc_controller
 public | api_build                      | table | drycc_controller
 public | api_certificate                | table | drycc_controller
 public | api_config                     | table | drycc_controller
 public | api_domain                     | table | drycc_controller
 public | api_key                        | table | drycc_controller
 public | api_push                       | table | drycc_controller
 public | api_release                    | table | drycc_controller
 public | auth_group                     | table | drycc_controller
 --More--
 drycc_controller=# SELECT COUNT(*) from api_app;
 count
-------
     0
(1 row)

7.3 - 应用故障排除

本文档描述了如何在部署或调试无法启动或部署的应用时排除常见问题。

应用有 Dockerfile,但发生了 Buildpack 部署

当您使用 git push drycc master 将应用部署到 Workflow 时,如果 Builder 尝试使用 Buildpack 工作流进行部署,请检查以下步骤:

  1. 您是否在部署正确的项目?
  2. 您是否在推送正确的 git 分支(git push drycc <branch>)?
  3. Dockerfile 是否在项目的根目录中?
  4. 您是否已将 Dockerfile 提交到项目中?

应用已部署,但无法启动

如果您部署了应用但它无法启动,您可以使用Drycc Grafana来检查应用无法启动的原因。有时,应用容器可能在没有记录任何错误信息的情况下启动失败。这通常发生在为应用配置的健康检查失败时。在这种情况下,您可以首先使用 kubectl 进行故障排除。您可以通过检查部署在应用命名空间中的 pod 来检查应用当前状态。为此,请运行

$ kubectl --namespace=myapp get pods
NAME                          READY     STATUS                RESTARTS   AGE
myapp-web-1585713350-3brbo    0/1       CrashLoopBackOff      2          43s

然后我们可以描述 pod 并确定它为什么无法启动:

Events:
  FirstSeen     LastSeen        Count   From                            SubobjectPath                           Type            Reason          Message
  ---------     --------        -----   ----                            -------------                           --------        ------          -------
  43s           43s             1       {default-scheduler }                                                    Normal          Scheduled       Successfully assigned myapp-web-1585713350-3brbo to kubernetes-node-1
  41s           41s             1       {kubelet kubernetes-node-1}     spec.containers{myapp-web}              Normal          Created         Created container with container id b86bd851a61f
  41s           41s             1       {kubelet kubernetes-node-1}     spec.containers{myapp-web}              Normal          Started         Started container with container id b86bd851a61f
  37s           35s             1       {kubelet kubernetes-node-1}     spec.containers{myapp-web}              Warning         Unhealthy       Liveness probe failed: Get http://10.246.39.13:8000/healthz: dial tcp 10.246.39.13:8000: getsockopt: connection refused

在这种情况下,我们将应用的健康检查初始延迟超时设置为 1 秒,这太激进了。应用在容器启动后需要一些时间来设置 API 服务器。通过将健康检查初始延迟超时增加到 10 秒,应用能够启动并正确响应。

有关如何自定义应用健康检查以更好地满足应用需求的更多信息,请参见自定义健康检查

8 - 路线图

浏览不断增长的、社区驱动的最新路线图列表。

8.1 - 规划过程

Drycc 采用轻量级过程,强调开放性,确保每个社区成员都能成为未来规划不可或缺的一部分。

维护者的角色

[维护者][] 领导 Drycc 项目。他们的职责包括提出路线图、审查和整合贡献以及维护项目的愿景。

开放路线图

Drycc 路线图 是一个社区文档。虽然维护者提出路线图,但它会在发布规划会议中进行讨论和完善。

为路线图做贡献

任何人都可以提出建议和问题。[社区][] 的每个成员都欢迎通过提供反馈和/或提出反建议来参与讨论。

发布里程碑

路线图通过 [发布计划][] 逐步交付。发布在发布规划会议期间定义,并使用 GitHub 里程碑来跟踪特定的交付成果和工作进展。

发布规划会议

影响路线图的主要决定在每个月的第一个星期四的发布规划会议上讨论,与 [发布计划][] 保持一致。

发布规划会议对公众开放,通过 Drycc #community Slack 频道 协调访问。 过去会议的笔记如下,以及整个会议在 YouTube 上的录像链接。

致谢

感谢 Amy Lindburg 和我们在 Podman 的朋友们的启发。

8.2 - Drycc Workflow 路线图

Drycc 路线图由社区驱动并通过 GitHub 管理。

Drycc Workflow 路线图

Drycc Workflow 路线图是一个社区文档,作为开放 规划过程 的一部分创建。每个路线图项目描述了一个高级功能或功能分组,这些被认为对 Drycc 的未来很重要。

鉴于项目的快速 发布计划,路线图项目旨在提供跨越多个发布的方向感。

交互式 drycc run /bin/bash

为开发者提供在他们的应用程序环境中启动交互式终端会话的能力。

相关问题:

日志流式传输

通过 Drycc Grafana 查看流式传输应用日志。

团队和权限

团队和权限代表了一个更灵活的权限模型,允许对平台上的应用程序、能力和资源进行更细致的控制。在这个领域有许多提议,需要在开始实施 Drycc Workflow 之前进行协调。

相关问题:

监控

Workflow 插件/服务

开发者应该能够使用服务或插件抽象快速轻松地配置应用程序依赖项。 https://github.com/drycc/drycc/issues/231

入站/出站 Webhooks

Drycc Workflow 应该能够从外部系统发送和接收 webhooks。促进与第三方服务如 GitHub、Gitlab、Slack、Hipchat 的集成。

8.3 - 发布

Drycc 的发布模型允许应用记录和回滚到以前的版本。

Drycc 使用 [持续交付][] 方法来创建发布。每个通过测试的合并提交都会产生一个可交付成果,可以为其指定 [语义版本][] 标签并发布。

项目的 master git 分支应该始终工作。只有被认为准备好公开发布的更改才会合并。

组件按需发布

Drycc 组件根据需要发布新版本。修复高优先级错误需要项目维护者创建新的补丁发布。合并向后兼容的功能意味着次要发布。

通过频繁发布,每个组件发布都成为安全且常规的事件。这使得用户更快更容易地获得特定修复。持续交付还减少了发布像 Drycc Workflow 这样的产品所需的工作,该产品集成了多个组件。

“组件"不仅适用于 Drycc Workflow 项目,还适用于开发和发布工具、容器基础镜像,以及进行 [语义版本][] 发布 的其他 Drycc 项目。

有关更多详细信息,请参见”如何发布组件"。

Workflow 每月发布

Drycc Workflow 有规律的公开发布节奏。从 v2.8.0 开始,新 Workflow 功能发布在每个月的第一个星期四到达。补丁发布根据需要随时创建。GitHub 里程碑用于传达主要和次要发布的内容和时间,更长期的规划在 路线图 上可见。

Workflow 发布时间不与特定功能相关联。如果某个功能在发布日期之前合并,它将包含在下一个发布中。

有关更多详细信息,请参见"如何发布 Workflow"。

语义版本控制

Drycc 发布符合 语义版本控制,其中"公共 API"广泛定义为:

  • REST、gRPC 或其他网络可访问的 API
  • 供公众使用的库或框架 API
  • 用户可以重定向的"可插拔"套接字级协议
  • CLI 命令和输出格式

一般来说,对用户可能合理链接、自定义或集成的任何内容的更改都应该是向后兼容的,否则需要主要发布。Drycc 用户可以确信升级到补丁或次要发布不会破坏任何东西。

如何发布组件

大多数 Drycc 项目都是"组件",它们产生容器镜像或二进制可执行文件作为交付成果。本节指导维护者创建组件发布。

步骤 1:更新代码并运行发布工具

主要或次要发布应该在 master 分支上进行。补丁发布应该检出之前的发布标签并从 master 樱桃挑选特定提交。

注意: 如果是补丁发布,发布工件将需要通过触发 component-promote 作业手动提升,并使用以下值:

COMPONENT_NAME=<component name>
COMPONENT_SHA=<patch commit sha>

确保您的搜索 $PATH 中有 dryccrel 发布工具。

使用假的 semver 标签运行一次 dryccrel release 来校对变更日志内容。(如果 master 的 HEAD 不是发布意图,请添加 --sha 标志,如 dryccrel release --help 中所述。)

$ dryccrel release controller v0.0.0
Doing a dry run of the component release...
skipping commit 943a49267eeb28546819a266654806cfcbae0e38

Creating changelog for controller with tag v2.8.1 through commit 943a49267eeb28546819a266654806cfcbae0e38

### v2.8.1 -> v0.0.0

#### 修复

- [`615b834`](https://github.com/drycc/controller/commit/615b834f39cb68a854cc1f1e2f0f82d862ea2731) boot: Ensure DRYCC_DEBUG==true for debug output

根据变更日志内容,确定组件是否值得次要或补丁发布。使用该 semver 标签再次运行命令,并使用 --dry-run=false。您仍会在创建发布之前被要求确认:

$ dryccrel release controller v2.8.2 --dry-run=false
skipping commit 943a49267eeb28546819a266654806cfcbae0e38

Creating changelog for controller with tag v2.8.1 through commit 943a49267eeb28546819a266654806cfcbae0e38

### v2.8.1 -> v2.8.2


#### 修复

- [`615b834`](https://github.com/drycc/controller/commit/615b834f39cb68a854cc1f1e2f0f82d862ea2731) boot: Ensure DRYCC_DEBUG==true for debug output


请检查上述变更日志内容并确保:
  1. 所有预期的提交都已提及
  2. 更改与 semver 发布标签(主要、次要或补丁)一致

为 Drycc Controller v2.8.2 创建发布? [y/n]: y
新发布可在此处获取 https://github.com/drycc/controller/releases/tag/v2.8.2

步骤 2:验证组件可用

标记组件(参见 步骤 1)启动 CI 作业,最终导致工件可供公众下载。请参见 CI 流程图 了解详细信息。

通过 podman pull 命令或运行适当的安装脚本来仔细检查工件是否可用。

如果无法下载工件,请确保其 CI 发布作业仍在进行中,或修复管道中出现的任何问题。例如,master 合并管道 可能未能提升 :git-abc1d23 候选镜像,需要使用该组件和提交重新启动。

如果组件有相关的 Kubernetes Helm 图表,此图表也将被打包、签名并上传到其生产图表仓库。请验证它可以被获取(并验证):

$ helm fetch oci://registry.drycc.cc/charts/controller --version 1.0.0
Verification: &{0xc4207ec870 sha256:026e766e918ff28d2a7041bc3d560d149ee7eb0cb84165c9d9d00a3045ff45c3 controller-v1.0.1.tgz}

如何发布 Workflow

Drycc Workflow 将多个组件发布与 Kubernetes Helm 图表交付成果集成在一起。本节指导维护者创建 Workflow 发布。

步骤 1:设置环境变量

导出将在后续步骤中使用的两个环境变量:

export WORKFLOW_RELEASE=v2.17.0 WORKFLOW_PREV_RELEASE=v2.16.0  # 例如

步骤 2:标记支持仓库

一些不在 Helm 图表中的 Workflow 组件也必须与发布同步标记。按照上面的 组件发布过程 进行操作,并确保这些组件被标记:

drycc/workflow-cli 的版本号应始终与整体 Workflow 版本号匹配。

步骤 3:创建 Helm 图表

要为 Workflow 创建和暂存发布候选图表,我们将使用以下参数构建 workflow-chart-stage 作业:

RELEASE_TAG=$WORKFLOW_RELEASE

此作业将收集所有最新的组件发布标签,并使用这些来指定所有组件图表的版本。然后它将打包 Workflow 图表,将其上传到暂存图表仓库,并针对该图表启动 e2e 运行。

步骤 4:手动测试

现在是时候超越当前 CI 测试了。创建一个测试矩阵电子表格(从之前的文档复制是一个好的开始),并注册测试人员来覆盖所有排列。

测试人员应特别注意整体用户体验,确保从早期版本升级顺利,并覆盖各种存储配置、Kubernetes 版本和基础设施提供商。

当发现关键级别的错误时,过程如下:

  1. 创建一个修复错误的组件 PR。
  2. 一旦 PR 通过并审查,合并它并进行新的 组件发布
  3. 触发与步骤 3 中提到的相同的 workflow-chart-stage 作业,将新生成的 Workflow 发布候选图表上传到暂存。

步骤 5:发布图表

当测试完成且没有发现任何新的关键级别错误时,使用以下参数启动 workflow-chart-release 作业:

RELEASE_TAG=$WORKFLOW_RELEASE

此作业将已批准的发布候选图表(现在由 CI 和手动测试批准)从暂存仓库复制到生产仓库,如果尚未签名则签名。

步骤 6:组装主变更日志

每个组件已经在 GitHub 上使用 CHANGELOG 内容更新了其发布说明。我们现在将生成 Workflow 图表的主变更日志,由所有组件和辅助仓库更改组成。

我们将使用 WORKFLOW_PREV_RELEASE 图表的 requirements.lock 文件,以及 repo-to-chart-name 映射文件,这次调用 dryccrel changelog global 来获取图表版本在 WORKFLOW_PREV_RELEASE 图表中存在和 GitHub 中存在的 最新 发布之间的所有组件更改。(因此,如果组件仓库中有任何未发布的提交,它们不会出现在这里):

helm fetch --untar oci://registry.drycc.cc/charts/workflow --version $WORKFLOW_PREV_RELEASE
dryccrel changelog global workflow/requirements.lock map.json > changelog-$WORKFLOW_RELEASE.md

此主变更日志应放置在一个 gist 中。该文件也将添加到下一步创建的文档更新 PR 中。

步骤 7:更新文档

drycc/workflow 创建一个新的拉取请求,更新对新发布的版本引用。使用 git grep $WORKFLOW_PREV_RELEASE 查找任何引用,但要小心不要更改 CHANGELOG.md

将步骤 7 中生成的 $WORKFLOW_RELEASE 主变更日志放置在 changelogs 目录中。确保为页面添加标题以明确这是 Workflow 发布,例如:

## Workflow v2.16.0 -> v2.17.0

一旦 PR 被审查并合并,对 drycc/workflow 本身进行 组件发布drycc/workflow 的版本号应始终与整体 Workflow 版本号匹配。

步骤 8:关闭 GitHub 里程碑

seed-repo 创建一个拉取请求以关闭发布里程碑并创建下一个。当更改合并到 seed-repo 时,所有相关项目的里程碑将被更新。如果里程碑上有未解决的问题,在合并拉取请求之前将它们移动到下一个即将到来的里程碑。

里程碑映射到 drycc/workflow 中的 Drycc Workflow 发布。这些里程碑不对应于单个组件发布标签。

步骤 9:发布 Workflow CLI 稳定版

现在 $WORKFLOW_RELEASE 版本的 Workflow CLI 已经过验证,我们可以基于此版本推送 stable 工件。

使用 $WORKFLOW_RELEASETAG 构建参数启动 https://ci.drycc.info/job/workflow-cli-build-stable/,然后在作业完成后验证 stable 工件可用且适当更新:

$ curl -sfL https://www.drycc.cc/install-cli.sh | bash -
$ ./drycc version
# (应该显示 $WORKFLOW_RELEASE)

步骤 10:让每个人知道

让团队的其他成员知道他们可以开始为新的 Workflow 发布写博客和发推文。在 Slack 的 #company 频道发布消息。包括指向已发布图表和主 CHANGELOG 的链接:

@here Drycc Workflow v2.17.0 is现在上线了!
主 CHANGELOG: https://drycc.info/docs/workflow/changelogs/v2.17.0/

发布完成了。干得好!

9 - 贡献指南

此 HowTo 适用于需要为项目提供贡献指南的项目维护者。

9.1 - 贡献者概述

对为 Drycc 项目做贡献感兴趣?有很多方法可以帮助。

提交 Bug 和增强功能

发现 bug?想要看到新功能?对维护者有请求?在适用的仓库中打开一个 Github 问题,我们将开始对话。

我们的官方支持渠道是 Drycc #community Slack 频道

不知道问题的适用仓库是什么?在 workflow 中打开一个问题,或在 Drycc #community Slack 频道 中与维护者聊天,我们会确保它到达正确的地方。

此外,请查看 troubleshooting 文档以了解常见问题。

在打开新问题之前,搜索并查看是否其他人已经报告了这个问题是有帮助的。您可以在这里搜索所有 Drycc 项目的 issue 列表。

编写文档

我们一直在寻求改进和扩展我们的文档。大多数文档位于 drycc/workflow 仓库中。只需 fork 项目,更新文档并给我们发送拉取请求。

贡献代码

我们一直在寻求帮助改进核心平台、其他工作负载、工具和测试覆盖率。对贡献代码感兴趣?让我们在 Drycc #community Slack 频道 中聊天。确保查看标记为 easy fixhelp wanted 的问题。

当您准备开始编写代码时,请查看 Design Documents 并设置您的 Development Environment

通过为任何 Drycc 项目做贡献,您同意其 Developer Certificate of Origin (DCO)。此文档由 Linux Kernel 社区创建,是一个简单的声明,即您作为贡献者拥有做出贡献的合法权利。

分流问题

如果您没有时间编码,请考虑帮助分流。社区会感谢您通过花费一些时间来节省他们的时间。请参阅 Triaging Issues 以获取更多信息。

分享您的经验

在我们的用户邮件列表上与社区互动,或在我们的 Drycc #community Slack 频道 中实时聊天,您可以在一天中的任何时间与其他 Drycc Workflow 用户聊天。

提交错误和增强功能

发现错误?想要新功能?对维护者有请求?在适用的仓库中打开 GitHub issue,我们将开始对话。

我们的官方支持渠道是 Drycc #community Slack 频道

不知道某个问题的适用仓库?在 workflow 中打开 issue,或在 Drycc #community Slack 频道 中与维护者聊天,我们会确保将其放到正确的位置。

此外,请查看[故障排除][]文档以了解常见问题。

在打开新 issue 之前,搜索看看是否其他人已经报告了这个问题会很有帮助。您可以在这里搜索所有 Drycc 项目的 issue 列表。

编写文档

我们一直在寻求改进和扩展我们的文档。大多数文档位于 drycc/workflow 仓库中。只需 fork 项目,更新文档并向我们发送拉取请求。

贡献代码

我们一直在寻求帮助改进核心平台、其他工作负载、工具和测试覆盖率。有兴趣贡献代码?让我们在 Drycc #community Slack 频道 中聊天。请务必查看标记为 easy fixhelp wanted 的 issue。

当您准备开始编写代码时,请查看设计文档并设置您的开发环境

通过为任何 Drycc 项目做贡献,您同意其开发者证书起源 (DCO)。此文档由 Linux 内核社区创建,是一个简单的声明,即作为贡献者,您拥有合法权利做出贡献。

分流 Issue

如果您没有时间编码,可以考虑帮助分流。社区会感谢您通过花费一些时间来节省他们的时间。有关更多信息,请参见分流 Issue

分享您的经验

在我们的用户邮件列表或实时在 Drycc #community Slack 频道中与社区互动,您可以随时与其他 Drycc Workflow 用户聊天。

9.2 - 设计文档

在提交将显著改变任何 Drycc 组件行为的拉取请求之前。

在提交将显著改变任何 Drycc 组件行为的拉取请求之前,例如新功能或主要重构,贡献者应该首先打开一个代表设计文档的问题。

目标

设计文档帮助确保项目贡献者:

  • 在功能开发中尽早涉及利益相关者
  • 确保代码更改实现原始动机和设计目标
  • 为功能或更改建立明确的验收标准
  • 强制执行测试驱动的设计方法和自动化测试覆盖

内容

设计文档问题应该命名为 Design Doc: <change description> 并包含以下部分:

目标

本节应简要描述提议的更改及其背后的动机。将编写测试以确保此设计目标由更改实现。

本节还应引用一个单独的 GitHub 问题,该问题跟踪功能或更改,通常分配给发布里程碑。

代码更改

本节应详细说明实现更改所需的代码更改,以及提议的实现。这应该尽可能详细,以帮助审阅者理解更改。

测试

所有更改都应由自动化测试覆盖,无论是单元测试还是集成测试(理想情况下两者都有)。本节应详细说明如何编写测试来验证更改是否实现设计目标并且不会引入任何回归。

如果更改无法通过自动化测试充分覆盖,则应重新考虑设计。如果受影响的代码部分根本没有测试覆盖,则应提交单独的问题以将自动化测试与该代码库部分集成。

此处描述的测试还形成了更改的验收标准,以便在完成后,维护者可以在确认测试通过 CI 后合并拉取请求。

批准

设计文档遵循与最终拉取请求相同的合并批准审查过程,维护者将特别注意确保任何更改的利益相关者都包含在设计文档的讨论和审查中。

一旦设计被接受,作者可以完成更改并提交拉取请求进行审查。拉取请求应关闭更改的设计文档以及跟踪问题或因更改而关闭的任何问题。

有关拉取请求和提交消息格式的更多信息,请参见提交拉取请求

9.3 - 开发环境

本文档面向对直接在 Drycc 代码库上工作的开发者。

在本指南中,我们将引导您完成设置适合对大多数 Drycc 组件进行黑客攻击的开发环境的过程。

我们努力使对 Drycc 组件进行黑客攻击变得简单。然而,必然有几个移动部件和一些设置要求。我们欢迎任何自动化或简化此过程的建议。

如果您刚刚接触 Drycc 代码库,请寻找带有 easy-fix 标签的 GitHub 问题。这些是更直接或低风险的问题,是熟悉 Drycc 的好方法。

先决条件

为了成功编译和测试 Drycc 二进制文件以及构建 Drycc 组件的容器镜像,需要以下内容:

  • git
  • Go 1.5 或更高版本,支持编译到 linux/amd64
  • glide
  • golint
  • shellcheck
  • Podman(在非 Linux 环境中,您还需要 [Podman Machine][machine])

对于 drycc/controller,特别是,您还需要:

  • Python 2.7 或更高版本(带有 pip
  • virtualenv(sudo pip install virtualenv

在大多数情况下,您应该按照说明简单安装。不过有一些特殊情况。我们在下面介绍这些。

配置 Go

如果您的本地工作站不支持 linux/amd64 目标环境,您将不得不从源代码安装 Go,并支持交叉编译该环境。这是因为某些组件是在您的本地机器上构建的,然后注入到容器中。

Homebrew 用户可以安装带有交叉编译支持:

$ brew install go --with-cc-common

从源代码构建 Go 也很简单:

$ sudo su
$ curl -sSL https://golang.org/dl/go1.5.src.tar.gz | tar -v -C /usr/local -xz
$ cd /usr/local/go/src
$ # 首先为我们的默认平台编译 Go,然后添加交叉编译支持
$ ./make.bash --no-clean
$ GOOS=linux GOARCH=amd64 ./make.bash --no-clean

一旦您可以编译到 linux/amd64,您应该能够正常编译 Drycc 组件。

Fork 仓库

一旦满足先决条件,我们就可以开始处理 Drycc 组件。

从 Github 开始,fork 您想要贡献的 Drycc 项目,然后在本地克隆该 fork。由于 Drycc 主要用 Go 编写,最好的位置是在 $GOPATH/src/github.com/drycc/ 下。

$ mkdir -p  $GOPATH/src/github.com/drycc
$ cd $GOPATH/src/github.com/drycc
$ git clone git@github.com:<username>/<component>.git
$ cd <component>

如果您要向您 fork 的上游仓库发出拉取请求,我们建议配置 Git,以便您可以轻松地将代码变基到上游仓库的主分支。有各种策略可以做到这一点,但最常见的是添加一个 upstream 远程:

$ git remote add upstream https://github.com/drycc/<component>.git

为了简单起见,您可能希望将环境变量指向您的 Drycc 代码 - 包含一个或多个 Drycc 组件的目录:

$ export DRYCC=$GOPATH/src/github.com/drycc

在本文档的其余部分,$DRYCC 指的是该位置。

替代方案:使用 Pushurl Fork

许多 Drycc 贡献者更喜欢直接从 drycc/<component> 拉取,但推送到 <username>/<component>。如果该工作流程更适合您,您可以这样设置:

$ git clone git@github.com:drycc/<component>.git
$ cd drycc
$ git config remote.origin.pushurl git@github.com:<username>/<component>.git

在此设置中,获取和拉取代码将直接与上游仓库一起工作,而推送代码将向您的 fork 发送更改。这使得保持最新状态变得容易,同时进行更改然后发出拉取请求。

进行更改

设置好开发环境并 fork 和克隆了您想要处理的代码后,您可以开始进行更改。

测试更改

Drycc 组件每个都包含一套全面的自动化测试,主要用 Go 编写。请参阅 testing 以获取运行测试的说明。

部署更改

虽然编写和执行测试对于确保代码质量至关重要,但大多数贡献者还希望将更改部署到实时环境中,无论是使用这些更改还是进一步测试它们。本节的其余部分记录了在开发集群中运行官方发布的 Drycc 组件并用您的自定义替换其中任何一个的过程。

运行用于开发的 Kubernetes 集群

要在本地或其他地方运行 Kubernetes 集群以支持您的开发活动,请参考 Drycc 安装说明 here

使用开发注册表

为了便于将包含您的更改的容器镜像部署到您的 Kubernetes 集群,您需要使用容器注册表。这是一个位置,您可以将自定义构建的镜像推送到那里,从那里您的 Kubernetes 集群可以检索相同的镜像。

如果您的开发集群在本地运行(例如在 Minikube 中),实现这一目标的最有效和经济的方法是在本地作为容器运行容器注册表。

为了促进这一点,大多数 Drycc 组件提供了一个 make 目标来创建这样的注册表:

$ make dev-registry

在 Linux 环境中,开始使用注册表:

export DRYCC_REGISTRY=<主机机器的 IP>:5000

在非 Linux 环境中:

export DRYCC_REGISTRY=<drycc 容器机器 VM 的 IP>:5000

如果您的开发集群在 Google Container Engine 等云提供商上运行,上述本地注册表将无法被您的 Kubernetes 节点访问。在这种情况下,[DockerHub][dh] 或 quay.io 等公共注册表就足够了。

例如,要使用 DockerHub:

$ export DRYCC_REGISTRY="registry.drycc.cc"
$ export IMAGE_PREFIX=<您的 DockerHub 用户名>

要使用 quay.io:

$ export DRYCC_REGISTRY=quay.io
$ export IMAGE_PREFIX=<您的 quay.io 用户名>

注意尾随斜杠的重要性。

开发/部署工作流程

有了功能正常的 Kubernetes 集群和安装在其上的官方发布的 Drycc 组件,通过用包含您的更改的自定义构建镜像替换官方发布的组件,可以促进任何您已更改的 Drycc 组件的部署和进一步测试。大多数 Drycc 组件包括 Makefiles,其中包含专门旨在以最小摩擦促进此工作流程的目标。

一般情况下,此工作流程如下所示:

  1. 使用 git 更新源代码并提交您的更改
  2. 使用 make build 构建新的容器镜像
  3. 使用 make dev-release 生成 Kubernetes 清单
  4. 使用 make deploy 使用更新的清单重新启动组件

这可以使用 deploy 目标缩短为一行:

$ make deploy

有用的命令

一旦您的自定义 Drycc 组件已部署,以下是一些有用的命令,允许您检查集群并在必要时进行故障排除:

查看所有 Drycc Pods

$ kubectl --namespace=drycc get pods

描述 Pod

这通常对故障排除处于待处理或崩溃状态的 pod 很有用:

$ kubectl --namespace=drycc describe -f <pod 名称>

尾随日志

$ kubectl --namespace=drycc logs -f <pod 名称>

Django Shell

特定于 drycc/controller

$ kubectl --namespace=drycc exec -it <pod 名称> -- python manage.py shell

有其他 Drycc 贡献者可能觉得有用的命令?给我们发 PR!

拉取请求

对您的更改满意?分享它们!

请阅读 Submitting a Pull Request。它包含了在提议对任何 Drycc 组件进行更改时应该做的事情的清单。

9.4 - 测试 Drycc

每个 Drycc 组件都是这样一个生态系统中的一员 - 其中许多组件相互集成 - 这使得彻底测试每个组件成为至关重要的事情。

每个 Drycc 组件都包含自己的风格检查套件、[单元测试][] 和黑盒类型的 [功能测试][]。

[集成测试][] 验证 Drycc 组件作为一个系统的行为,并由 drycc/workflow-e2e 项目单独提供。

所有 Drycc 组件的 GitHub 拉取请求都由 Travis CI [持续集成][] 系统自动测试。贡献者在提议对 Drycc 代码库进行任何更改之前,应该在本地运行相同的测试。

设置环境

成功执行任何 Drycc 组件的单元测试和功能测试需要首先设置 开发环境

运行测试

每个组件的风格检查、单元测试和功能测试都可以通过 make 目标执行:

要执行风格检查:

$ make test-style

要执行单元测试:

$ make test-unit

要执行功能测试:

$ make test-functional

要一次性执行风格检查、单元测试和功能测试:

$ make test

要执行集成测试,请参考 drycc/workflow-e2e 文档。

9.5 - 提交拉取请求

对 Drycc 项目的提议更改通过 GitHub 拉取请求进行。

设计文档

在打开拉取请求之前,如果贡献是实质性的,请确保您的更改也引用了设计文档。有关更多信息,请参阅 Design Documents

单一问题

当拉取请求不聚焦时,很难就其优点达成一致。在修复问题或实现新功能时,抵制重构附近代码或修复您注意到的潜在 bug 的诱惑。相反,打开单独的问题或拉取请求。将关注点分开允许拉取请求更快地被测试、审查和合并。

使用 git 将拉取请求中的提交或提交压缩并变基为逻辑工作单元。在同一提交中包含测试和文档更改,以便恢复会删除该功能或修复的所有痕迹。

大多数拉取请求将引用 GitHub 问题。在 PR 描述中 - 而不是在提交本身中 - 包含一行如 “closes #1234”。当您的 PR 被合并时,引用的 issue 将自动关闭。

包含测试

如果您显著更改或添加影响更广泛的 Drycc Workflow PaaS 的组件功能,您应该提交补充 PR 来修改或修改端到端集成测试。这些集成测试可以在 drycc/workflow-e2e 仓库中找到。

有关更多信息,请参阅 testing

包含文档

对任何可能影响用户体验的 Drycc Workflow 组件的更改也需要更改或添加到相关文档。对于大多数 Drycc 组件,这涉及更新组件自己的文档。在某些情况下,当组件紧密集成到 drycc/workflow 中时,其文档也必须更新。

跨仓库提交

如果拉取请求是涉及其他 Workflow 仓库中的一个或多个额外提交的更大工作的部分,则这些提交可以在最后提交的 PR 中引用。下游 e2e 测试作业 将为测试运行器提供每个引用的提交(从提供的 PR issue 编号派生),以便它可以为要测试的生成的 Workflow chart 包含必要的容器镜像。

例如,考虑在 drycc/controllerdrycc/workflow-e2e 中的配对提交。drycc/workflow-e2e 中第一个 PR 的提交主体将如下所示:

feat(foo_test): add e2e test for feature foo

[skip e2e] test for controller#42

为这个提交添加 [skip e2e] 会放弃 e2e 测试。除了最终 PR 之外的任何其他必需 PR 应该首先提交,以便它们的相应构建和镜像推送作业运行。

最后,应该使用所需的 PR 编号创建 drycc/controller 中的最终 PR,以 [Rr]equires <repoName>#<pullRequestNumber> 的形式列出,以供下游 e2e 运行使用。

feat(foo): add feature foo

Requires workflow-e2e#42

代码标准

Drycc 组件使用 GoPython 实现。对于两种语言,我们同意 The Zen of Python,它强调简单胜过聪明。可读性很重要。

Go 代码应该始终使用默认设置通过 gofmt 运行。代码行最多可以长达 99 个字符。所有导出的函数都需要文档字符串和测试。第三方 go 包的使用应该最小化,但这样做时,此类依赖应该通过 glide 工具管理。

Python 代码应该始终遵守 PEP8,Python 代码风格指南,但例外是代码行最多可以长达 99 个字符。所有公共方法都需要文档字符串和测试,尽管 Drycc 使用的 flake8 工具不强制执行此项。

提交风格

我们遵循从 CoreOS 借来的提交消息约定,他们从 AngularJS 借来的。这是提交的示例:

feat(scripts/test-cluster): add a cluster test command

this uses tmux to setup a test cluster that you can easily kill and
start for debugging.

要使其更正式,它看起来像这样:

{type}({scope}): {subject}
<BLANK LINE>
{body}
<BLANK LINE>
{footer}

允许的 {types} 如下:

  • feat -> 功能
  • fix -> bug 修复
  • docs -> 文档
  • style -> 格式化
  • ref -> 重构代码
  • test -> 添加缺失的测试
  • chore -> 维护

{scope} 可以是指定提交更改位置的任何内容。

{subject} 需要是祈使式、现在时动词:“change”,而不是 “changed” 也不是 “changes”。第一个字母不应大写,并且末尾没有点 (.)。

就像 {subject} 一样,消息 {body} 需要是现在时,包括更改的动机,以及与之前行为的对比。段落中的第一个字母必须大写。

所有破坏性更改需要在 {footer} 中提及,更改的描述、更改背后的理由以及所需的任何迁移说明。

提交消息的任何行都不能超过 72 个字符,主题行限制为 50 个字符。这允许消息在 GitHub 以及各种 git 工具中更容易阅读。

合并批准

任何代码更改 - 除了简单的拼写错误修复或单行文档更改 - 需要至少两个 Drycc 维护者 接受它。维护者使用 “LGTM1” 和 “LGTM2"(Looks Good To Me)标签标记拉取请求以表示接受。

在至少一个核心维护者以 LGTM 签字之前,不能合并任何拉取请求。另一个 LGTM 可以来自核心维护者或贡献维护者。

如果 PR 来自 Drycc 维护者,那么他或她应该是关闭它的人。这保持了提交流的清洁,并让维护者在决定是否合并更改之前重新审视 PR。

一个例外是当需要紧急恢复错误提交时。如果必要,仅恢复先前提交的 PR 可以不等待 LGTM 批准而合并。

Design Document

Before opening a pull request, ensure your change also references a design document if the contribution is substantial. For more information, see Design Documents.

Single Issue

It’s hard to reach agreement on the merit of a PR when it isn’t focused. When fixing an issue or implementing a new feature, resist the temptation to refactor nearby code or to fix that potential bug you noticed. Instead, open a separate issue or pull request. Keeping concerns separated allows pull requests to be tested, reviewed, and merged more quickly.

Squash and rebase the commit or commits in your pull request into logical units of work with git. Include tests and documentation changes in the same commit, so that a revert would remove all traces of the feature or fix.

Most pull requests will reference a GitHub issue. In the PR description - not in the commit itself - include a line such as “closes #1234”. The issue referenced will automatically be closed when your PR is merged.

Include Tests

If you significantly alter or add functionality to a component that impacts the broader Drycc Workflow PaaS, you should submit a complementary PR to modify or amend end-to-end integration tests. These integration tests can be found in the drycc/workflow-e2e repository.

See testing for more information.

Include Docs

Changes to any Drycc Workflow component that could affect a user’s experience also require a change or addition to the relevant documentation. For most Drycc components, this involves updating the component’s own documentation. In some cases where a component is tightly integrated into drycc/workflow, its documentation must also be updated.

Cross-repo commits

If a pull request is part of a larger piece of work involving one or more additional commits in other Workflow repositories, these commits can be referenced in the last PR to be submitted. The downstream e2e test job will then supply every referenced commit (derived from PR issue number supplied) to the test runner so it can source the necessary Container images for inclusion in the generated Workflow chart to be tested.

For example, consider paired commits in drycc/controller and drycc/workflow-e2e. The commit body for the first PR in drycc/workflow-e2e would look like:

feat(foo_test): add e2e test for feature foo

[skip e2e] test for controller#42

Adding [skip e2e] forgoes the e2e tests on this commit. This and any other required PRs aside from the final PR should be submitted first, so that their respective build and image push jobs run.

Lastly, the final PR in drycc/controller should be created with the required PR number(s) listed, in the form of [Rr]equires <repoName>#<pullRequestNumber>, for use by the downstream e2e run.

feat(foo): add feature foo

Requires workflow-e2e#42

Code Standards

Drycc components are implemented in Go and Python. For both languages, we agree with The Zen of Python, which emphasizes simple over clever. Readability counts.

Go code should always be run through gofmt on the default settings. Lines of code may be up to 99 characters long. Documentation strings and tests are required for all exported functions. Use of third-party go packages should be minimal, but when doing so, such dependencies should be managed via the glide tool.

Python code should always adhere to PEP8, the python code style guide, with the exception that lines of code may be up to 99 characters long. Docstrings and tests are required for all public methods, although the flake8 tool used by Drycc does not enforce this.

Commit Style

We follow a convention for commit messages borrowed from CoreOS, who borrowed theirs from AngularJS. This is an example of a commit:

feat(scripts/test-cluster): add a cluster test command

this uses tmux to setup a test cluster that you can easily kill and
start for debugging.

To make it more formal, it looks something like this:

{type}({scope}): {subject}
<BLANK LINE>
{body}
<BLANK LINE>
{footer}

The allowed {types} are as follows:

  • feat -> feature
  • fix -> bug fix
  • docs -> documentation
  • style -> formatting
  • ref -> refactoring code
  • test -> adding missing tests
  • chore -> maintenance

The {scope} can be anything specifying the location(s) of the commit change(s).

The {subject} needs to be an imperative, present tense verb: “change”, not “changed” nor “changes”. The first letter should not be capitalized, and there is no dot (.) at the end.

Just like the {subject}, the message {body} needs to be in the present tense, and includes the motivation for the change, as well as a contrast with the previous behavior. The first letter in a paragraph must be capitalized.

All breaking changes need to be mentioned in the {footer} with the description of the change, the justification behind the change and any migration notes required.

Any line of the commit message cannot be longer than 72 characters, with the subject line limited to 50 characters. This allows the message to be easier to read on GitHub as well as in various git tools.

Merge Approval

Any code change - other than a simple typo fix or one-line documentation change - requires at least two Drycc maintainers to accept it. Maintainers tag pull requests with “LGTM1” and “LGTM2” (Looks Good To Me) labels to indicate acceptance.

No pull requests can be merged until at least one core maintainer signs off with an LGTM. The other LGTM can come from either a core maintainer or contributing maintainer.

If the PR is from a Drycc maintainer, then he or she should be the one to close it. This keeps the commit stream clean and gives the maintainer the benefit of revisiting the PR before deciding whether or not to merge the changes.

An exception to this is when an errant commit needs to be reverted urgently. If necessary, a PR that only reverts a previous commit can be merged without waiting for LGTM approval.

9.6 - 社区

Drycc 是一个开源项目,社区中的任何人都可以使用、改进和享受。我们很乐意您加入我们!以下是一些了解最新动态并参与其中的方式。

Drycc 软件是完全开源的。因此,“Drycc 社区"由任何使用 Drycc 软件并参与其发展的人组成,无论是回答问题、发现错误、建议增强功能,还是编写文档或代码。

Drycc 开发通过众多项目仓库在 GitHub 上协调。任何人都可以查看任何 Drycc 组件的源代码,分叉它,进行改进,并创建拉取请求,将这些更改提供给 Drycc 社区。

Engine Yard 维护众多 Drycc 项目,因此决定最终出现在官方 GitHub 仓库中的内容。Drycc 依赖于社区的贡献;维护者不会忽略拉取请求或问题。

Drycc 使用永恒、高效且完全不公平的系统,称为"终身仁慈独裁者”(BDFL)。Gabriel Monroy,Drycc 的创建者,是我们的 BDFL,对与 Drycc 相关的所有决定拥有最终决定权。

开源赏金

Drycc 项目支持赏金。我们相信开源赏金网站可以成为开发开源软件的有建设性工具。鼓励社区成员 a) 提供赏金和 b) 为有益于每个人的开源贡献获得赏金。然而,Drycc 维护者不会接受此项目的赏金,但很乐意帮助尝试赏金的社区成员。

9.7 - 分流问题

问题分流为为开源项目做贡献提供了一种重要方式。

分流通过以下方式帮助确保问题快速解决:

  • 精确传达问题的意图和目的。这是必要的,因为问题可能难以解释最终用户如何体验问题以及他们采取了什么行动。
  • 在贡献者承诺解决问题的之前,为他们提供所需的信息。
  • 通过防止重复问题来降低问题数量。
  • 通过防止重复讨论来简化开发过程。

如果您没有时间编码,请考虑帮助分流。社区会感谢您通过花费一些时间来节省他们的时间。

确保问题包含基本信息

在对问题进行深入分流之前,请确保问题的作者提供了标准问题信息。这将帮助您对如何分类问题做出明智的建议。大多数问题中应包含的标准信息包括:

  • 此问题影响的 Drycc 版本
  • 如果这是 bug,可重现的案例
  • 如果这是文档问题,则为页面 URL 或手册页面的名称

根据问题,您可能觉得并非所有这些信息都是必需的。请使用您的最佳判断。如果您无法使用问题的作者提供的内容来分流问题,请友好地向作者解释,他们必须提供上述信息来澄清问题。

如果作者提供了推荐的信息,但您仍然无法分流问题,请请求额外信息。请友好而礼貌地这样做,因为您在请求更多作者的时间。

如果作者在请求信息后一周内没有响应,请关闭问题,并附上友好的说明,说明作者可以在提供必要信息时请求重新打开问题。

分类问题

一个问题可以有以下多个标签:

问题类型

类型 描述
bug Bug 就是 bug。原因在分流时可能已知也可能未知,因此调试应计入时间估计。
docs 编写文档、手册页、文章、博客或其他重要的文字驱动任务。
enhancement 增强功能可以大幅改善组件的可用性或性能。
question 包含需要响应的用户或贡献者问题。
security 与安全相关的问题,如 TLS 加密、网络隔离、身份验证/授权功能等。

功能区域

  • builder
  • cache
  • contrib and provisioning
  • client
  • controller
  • database
  • docs
  • kubernetes
  • registry
  • router
  • store (Ceph)
  • tests

简单修复

“简单修复” 问题是新贡献者找到适合其经验水平问题的一种方式。这些问题通常适合对 Drycc(可能还有 Go)不熟悉的用户,他们希望在学习基础知识的同时提供帮助。

优先级问题

当附加到特定里程碑时,问题可以归属于以下标签之一,以指示其优先级程度。

优先级 描述
priority 0 紧急:安全、严重 bug、阻塞性问题。放下一切,今天就修复这个,然后考虑创建补丁版本。
priority 1 严重:阻碍用户操作或回归。在下一个计划发布之前修复这个。

就是这样。这应该是新贡献者或现有贡献者进来解决问题的所有必需信息。

9.8 - 行为准则

Drycc 社区欢迎并鼓励每个人的参与。

行为准则

Drycc 社区欢迎并鼓励每个人的参与。

无论您如何认同自己或他人如何看待您:我们欢迎您。只要与我们的社区建设性地互动,我们欢迎来自每个人的贡献。

Drycc 开发者社区继续增长,意见分歧和冲突不可避免。我们要求参与者按照这些原则行事:

  1. 保持欢迎、友好和耐心。

  2. 保持体贴。

您的工作将被其他人使用,反过来您也将依赖他人的工作。您做出的任何决定都会影响用户和同事,在做决定时应该考虑到这些后果。请记住,我们是一个全球性的社区,所以您可能不是用别人的母语进行沟通。

  1. 保持尊重。

我们并非总是意见一致,但分歧不是不良行为和粗鲁举止的借口。我们可能偶尔会感到沮丧,但我们不能让这种沮丧变成人身攻击。重要的是要记住,一个让人们感到不舒服或受到威胁的社区不是一个富有成效的社区。

  1. 谨慎选择您的措辞。

对他人友善。不要侮辱或贬低其他参与者。专业行事。请记住,骚扰以及性别歧视、种族歧视或排他性玩笑在社区中永远不合适。

(感谢 DebianDjango 社区的文本和灵感。)

9.9 - Drycc 维护者

本文档用于描述 Drycc 项目的领导结构,并列出当前的项目维护者。

什么是维护者?

(毫不掩饰地从 Podman 项目窃取而来)

有不同类型的维护者,具有不同的职责,但所有维护者有 3 个共同点:

  1. 他们对项目的成功承担共同责任。
  2. 他们对改进项目进行了长期、反复的时间投资。
  3. 他们将时间花在需要做的事情上,不一定是他们最感兴趣或最有趣的事情。

维护者往往被低估,因为他们的工作更难被欣赏。欣赏一个真正酷炫和技术先进的特性很容易。欣赏 bug 的缺失、稳定性的缓慢但稳步改进,或发布过程的可靠性则更难。但这些东西将一个好的项目与一个伟大的项目区分开来。

Drycc 维护者

Drycc 除了我们亲爱的终身仁慈独裁者外,还有两个维护者群体。

BDFL

Drycc 遵循永恒、高效且完全不公平的系统,称为终身仁慈独裁者

Gabriel Monroy (@gabrtv),作为 Drycc 项目的创建者,担任我们项目的 BDFL。虽然日常项目管理由维护者执行,但 Gabriel 作为任何争议的最终仲裁者,并对项目方向有最终决定权。

核心维护者

核心维护者对 Drycc 的所有领域都具有异常丰富的知识。有些维护者全职在 Drycc 上工作,尽管这不是要求。

核心维护者的职责包括:

  • 对 GitHub 问题进行分类和响应,并审查拉取请求
  • 帮助塑造 Drycc 路线图并领导实现路线图里程碑的努力
  • 积极参与功能开发和 bug 修复
  • Drycc #community Slack 频道 中回答问题并帮助用户

当前核心维护者的列表可以在这里看到。

在至少一个核心维护者以 LGTM 签字之前,不能合并任何拉取请求。另一个 LGTM 可以来自核心维护者或贡献维护者。

贡献维护者

贡献维护者对 Drycc 的某些但不一定是所有领域具有异常丰富的知识,并且通常由于特定领域知识而被选中,这些知识补充了项目(但持续贡献项目的意愿是最重要的!)。通常,核心维护者会要求贡献维护者在他们知识渊博的问题、拉取请求或对话中发表意见。

贡献维护者的职责与核心维护者非常相似,但它们限于贡献维护者知识渊博的 Drycc 项目领域。

贡献维护者在实践中被定义为那些对 Drycc 仓库具有写访问权限的人。所有维护者都可以审查拉取请求并根据需要添加 LGTM 标签。

成为维护者

Drycc 项目如果没有其社区就不会是今天的样子。项目的许多社区成员体现了维护者的精神,并为项目做出了重大贡献。

贡献维护者群体部分是为了让对项目持续成功感兴趣的杰出社区成员有机会与核心维护者一起指导 Drycc 的未来而创建的。

通常,潜在的贡献维护者由 Drycc 核心维护者基于以下标准部分选择:

  • 在一段时间内(通常是几个月)对项目的持续贡献
  • 愿意在 GitHub 和 Drycc #community Slack 频道 上帮助 Drycc 用户
  • 友好的态度 :)

Drycc 核心维护者必须一致同意,才能邀请社区成员加入作为贡献维护者,尽管在许多情况下,候选人已经在贡献维护者的能力范围内行事一段时间,并已在问题、拉取请求等方面被咨询。

10 - 参考指南

参考指南定义和含义。

10.1 - 创建自签名 SSL 证书

自签名 TLS/SSL 证书不是由公开信任的证书颁发机构 (CA) 签发的,而是由负责网站的开发人员或公司签发的。

使用应用 SSL 功能用于非生产应用程序或为平台安装 SSL 时,您可以通过使用自签名 SSL 证书来避免与 SSL 证书相关的成本。虽然证书实现了完全加密,但访问您网站的访客会看到浏览器警告,指示该证书不应被信任。

先决条件

需要 openssl 库来生成您自己的证书。在您的本地环境中运行以下命令来查看是否已经安装了 openssl。

$ which openssl
/usr/bin/openssl

如果 which 命令没有返回路径,那么您需要自己安装 openssl:

如果您有… 使用以下方式安装…
Mac OS X Homebrew: brew install openssl
Windows 完整包 .exe 安装
Ubuntu Linux apt-get install openssl

生成私钥和证书签名请求

需要私钥和证书签名请求来创建 SSL 证书。这些可以通过几个简单的命令生成。当 openssl req 命令询问"challenge password"时,只需按回车键,将密码留空。

$ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
...
$ openssl rsa -passin pass:x -in server.pass.key -out server.key
writing RSA key
$ rm server.pass.key
$ openssl req -new -key server.key -out server.csr
...
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
...
A challenge password []:
...

生成 SSL 证书

自签名 SSL 证书是从 server.key 私钥和 server.csr 文件生成的。

$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

server.crt 文件是您的站点证书,适合与 Drycc 的 SSL 端点 一起使用,以及 server.key 私钥。

10.2 - Controller API v2.0

这是 Controller 的 v2.0 REST API。

新增功能

新增! POST /v2/apps/<app id>/run 的格式已更改。

认证

注册新用户

示例请求:

POST /v2/auth/register/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{
    "username": "test",
    "password": "opensesame",
    "email": "test@example.com"
}

可选参数:

{
    "first_name": "test",
    "last_name": "testerson"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "id": 1,
    "last_login": "2014-10-19T22:01:00.601Z",
    "is_superuser": true,
    "username": "test",
    "first_name": "test",
    "last_name": "testerson",
    "email": "test@example.com",
    "is_staff": true,
    "is_active": true,
    "date_joined": "2014-10-19T22:01:00.601Z",
    "groups": [],
    "user_permissions": []
}

登录

示例请求:

POST /v2/auth/login/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{"username": "test", "password": "opensesame"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"token": "abc123"}

取消账户

示例请求:

DELETE /v2/auth/cancel/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

重新生成令牌

注意

此命令可能需要管理权限

示例请求:

POST /v2/auth/tokens/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
    "username" : "test"
    "all" : "true"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"token": "abc123"}

更改密码

示例请求:

POST /v2/auth/passwd/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "password": "foo",
    "new_password": "bar"
}

可选参数:

{"username": "testuser"}

注意

使用 username 参数需要管理权限,并使 password 参数可选。

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

应用程序

列出所有应用程序

示例请求:

GET /v2/apps HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "example-go",
            "owner": "test",
            "structure": {},
            "updated": "2014-01-01T00:00:00UTC",
            "url": "example-go.example.com",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

创建应用程序

示例请求:

POST /v2/apps/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

可选参数:

{"id": "example-go"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

销毁应用程序

示例请求:

DELETE /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

列出应用程序详情

示例请求:

GET /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

更新应用程序详情

示例请求:

POST /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
  "owner": "test"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 1.8.0
Content-Type: application/json

检索应用程序日志

示例请求:

GET /v2/apps/example-go/logs/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选 URL 查询参数:

?log_lines=

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: text/plain

"16:51:14 drycc[api]: test created initial release\n"

运行一次性命令

POST /v2/apps/example-go/run/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"command": "echo hi"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"exit_code": 0, "output": "hi\n"}

证书

列出所有证书

示例请求:

GET /v2/certs HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 22,
      "owner": "test",
      "san": [],
      "domains": [],
      "created": "2016-06-22T22:24:20Z",
      "updated": "2016-06-22T22:24:20Z",
      "name": "foo",
      "common_name": "bar.com",
      "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
      "expires": "2017-01-14T23:57:57Z",
      "starts": "2016-01-15T23:57:57Z",
      "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
      "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
    }
  ]
}

获取证书详情

示例请求:

GET /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22T22:24:20Z",
  "updated": "2016-06-22T22:24:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

创建证书

示例请求:

POST /v2/certs/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{
    "name": "foo"
    "certificate": "-----BEGIN CERTIFICATE-----",
    "key": "-----BEGIN RSA PRIVATE KEY-----"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22T22:24:20Z",
  "updated": "2016-06-22T22:24:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

销毁证书

示例请求:

DELETE /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

将域名附加到证书

示例请求:

POST /v2/certs/foo/domain/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "domain": "test.com"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

从证书中移除域名

示例请求:

DELETE /v2/certs/foo/domain/test.com/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

Pod

列出所有 Pod

示例请求:

GET /v2/apps/example-go/pods/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

按类型列出所有 Pod

示例请求:

GET /v2/apps/example-go/pods/web/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

重启所有 Pod

示例请求:

POST /v2/apps/example-go/pods/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型重启 Pod

示例请求:

POST /v2/apps/example-go/pods/web/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型和名称重启 Pod

示例请求:

POST /v2/apps/example-go/pods/go-v2-web-atots/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

缩放 Pod

示例请求:

POST /v2/apps/example-go/scale/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"web": 3}

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

配置

列出应用程序配置

示例请求:

GET /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
      "PLATFORM": "drycc"
    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建新配置

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": "world", "PLATFORM": "drycc"}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json
X-Drycc-Release: 3

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v3",
        "HELLO": "world",
        "PLATFORM": "drycc"

    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

取消设置配置变量

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": null}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json
X-Drycc-Release: 4

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v4",
        "PLATFORM": "drycc"
   },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

域名

列出应用程序域名

示例请求:

GET /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "created": "2014-01-01T00:00:00UTC",
            "domain": "example.example.com",
            "owner": "test",
            "updated": "2014-01-01T00:00:00UTC"
        }
    ]
}

添加域名

示例请求:

POST /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{'domain': 'example.example.com'}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "domain": "example.example.com",
    "owner": "test",
    "updated": "2014-01-01T00:00:00UTC"
}

移除域名

示例请求:

DELETE /v2/apps/example-go/domains/example.example.com HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

构建

列出应用程序构建

示例请求:

GET /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "FROM drycc/slugrunner RUN mkdir -p /app WORKDIR /app ENTRYPOINT [\"/runner/init\"] ADD slug.tgz /app ENV GIT_SHA 060da68f654e75fac06dbedd1995d5f8ad9084db",
    "image": "example-go",
    "owner": "test",
    "procfile": {
        "web": "example-go"
    },
    "sha": "060da68f",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建应用程序构建

示例请求:

POST /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"image": "drycc/example-go:latest"}

可选参数:

{
    "procfile": {
      "web": "./cmd"
    }
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json
X-Drycc-Release: 4

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "",
    "image": "drycc/example-go:latest",
    "owner": "test",
    "procfile": {},
    "sha": "",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

发布

列出应用程序发布

示例请求:

GET /v2/apps/example-go/releases/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 3,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "build": "202d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "ed637ceb-5d32-44bd-9406-d326a777a513",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test changed nothing",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 3
        },
        {
            "app": "example-go",
            "build": "202d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test deployed 060da68",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 2
        },
        {
            "app": "example-go",
            "build": null,
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test created initial release",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 1
        }
    ]
}

列出发布详情

示例请求:

GET /v2/apps/example-go/releases/v2/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "app": "example-go",
    "build": null,
    "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
    "created": "2014-01-01T00:00:00UTC",
    "owner": "test",
    "summary": "test created initial release",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
    "version": 1
}

回滚发布

示例请求:

POST /v2/apps/example-go/releases/rollback/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"version": 1}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"version": 5}

密钥

列出密钥

示例请求:

GET /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "test@example.com",
            "owner": "test",
            "public": "ssh-rsa <...>",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

为用户添加密钥

示例请求:

POST /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "id": "example",
    "public": "ssh-rsa <...>"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example",
    "owner": "example",
    "public": "ssh-rsa <...>",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

从用户移除密钥

示例请求:

DELETE /v2/keys/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

权限

列出应用程序权限

注意

这不包括应用程序所有者。

示例请求:

GET /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "users": [
        "test",
        "foo"
    ]
}

创建应用程序权限

示例请求:

POST /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

移除应用程序权限

示例请求:

DELETE /v2/apps/example-go/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

列出管理员

示例请求:

GET /v2/admin/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 2,
    "next": null
    "previous": null,
    "results": [
        {
            "username": "test",
            "is_superuser": true
        },
        {
            "username": "foo",
            "is_superuser": true
        }
    ]
}

授予用户管理权限

注意

此命令需要管理权限

示例请求:

POST /v2/admin/perms HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

移除用户的管理权限

注意

此命令需要管理权限

示例请求:

DELETE /v2/admin/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0

用户

列出所有用户

注意

此命令需要管理权限

示例请求:

GET /v2/users HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.0
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "last_login": "2014-10-19T22:01:00.601Z",
            "is_superuser": true,
            "username": "test",
            "first_name": "test",
            "last_name": "testerson",
            "email": "test@example.com",
            "is_staff": true,
            "is_active": true,
            "date_joined": "2014-10-19T22:01:00.601Z",
            "groups": [],
            "user_permissions": []
        }
    ]
}

10.3 - Controller API v2.1

这是 Controller 的 v2.1 REST API。

新功能

新增! 配置中的 healthcheck 字段,弃用 HEALTHCHECK_* 环境变量。

新增! 取消设置不存在的配置变量将返回 422。

新增! 创建相同的连续发布将返回 409 而不是创建无操作发布。

认证

注册新用户

示例请求:

POST /v2/auth/register/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{
    "username": "test",
    "password": "opensesame",
    "email": "test@example.com"
}

可选参数:

{
    "first_name": "test",
    "last_name": "testerson"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "id": 1,
    "last_login": "2014-10-19T22:01:00.601Z",
    "is_superuser": true,
    "username": "test",
    "first_name": "test",
    "last_name": "testerson",
    "email": "test@example.com",
    "is_staff": true,
    "is_active": true,
    "date_joined": "2014-10-19T22:01:00.601Z",
    "groups": [],
    "user_permissions": []
}

登录

示例请求:

POST /v2/auth/login/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{"username": "test", "password": "opensesame"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"token": "abc123"}

注销账户

示例请求:

DELETE /v2/auth/cancel/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

重新生成令牌

注意

此命令可能需要管理员权限

示例请求:

POST /v2/auth/tokens/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
    "username" : "test"
    "all" : "true"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"token": "abc123"}

修改密码

示例请求:

POST /v2/auth/passwd/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "password": "foo",
    "new_password": "bar"
}

可选参数:

{"username": "testuser"}

注意

使用 username 参数需要管理员权限,并使 password 参数可选。

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

应用

列出所有应用

示例请求:

GET /v2/apps HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "example-go",
            "owner": "test",
            "structure": {},
            "updated": "2014-01-01T00:00:00UTC",
            "url": "example-go.example.com",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

创建应用

示例请求:

POST /v2/apps/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

可选参数:

{"id": "example-go"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

销毁应用

示例请求:

DELETE /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

列出应用详情

示例请求:

GET /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

更新应用详情

示例请求:

POST /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
  "owner": "test"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 1.8.0
Content-Type: application/json

获取应用日志

示例请求:

GET /v2/apps/example-go/logs/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选 URL 查询参数:

?log_lines=

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: text/plain

"16:51:14 drycc[api]: test created initial release\n"

运行一次性命令

POST /v2/apps/example-go/run/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"command": "echo hi"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"exit_code": 0, "output": "hi\n"}

证书

列出所有证书

示例请求:

GET /v2/certs HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 22,
      "owner": "test",
      "san": [],
      "domains": [],
      "created": "2016-06-22T22:24:20Z",
      "updated": "2016-06-22T22:24:20Z",
      "name": "foo",
      "common_name": "bar.com",
      "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
      "expires": "2017-01-14T23:57:57Z",
      "starts": "2016-01-15T23:57:57Z",
      "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
      "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
    }
  ]
}

获取证书详情

示例请求:

GET /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22T22:24:20Z",
  "updated": "2016-06-22T22:24:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

创建证书

示例请求:

POST /v2/certs/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{
    "name": "foo"
    "certificate": "-----BEGIN CERTIFICATE-----",
    "key": "-----BEGIN RSA PRIVATE KEY-----"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22T22:24:20Z",
  "updated": "2016-06-22T22:24:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

销毁证书

示例请求:

DELETE /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

将域名附加到证书

示例请求:

POST /v2/certs/foo/domain/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "domain": "test.com"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

从证书中移除域名

示例请求:

DELETE /v2/certs/foo/domain/test.com/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

Pods

列出所有 Pods

示例请求:

GET /v2/apps/example-go/pods/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

按类型列出所有 Pods

示例请求:

GET /v2/apps/example-go/pods/web/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

重启所有 Pods

示例请求:

POST /v2/apps/example-go/pods/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型重启 Pods

示例请求:

POST /v2/apps/example-go/pods/web/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型和名称重启 Pods

示例请求:

POST /v2/apps/example-go/pods/go-v2-web-atots/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

缩放 Pods

示例请求:

POST /v2/apps/example-go/scale/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"web": 3}

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

配置

列出应用配置

示例请求:

GET /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
      "PLATFORM": "drycc"
    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建新配置

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": "world", "PLATFORM": "drycc"}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v3",
        "HELLO": "world",
        "PLATFORM": "drycc"

    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

取消设置配置变量

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": null}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v4",
        "PLATFORM": "drycc"
   },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

域名

列出应用域名

示例请求:

GET /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "created": "2014-01-01T00:00:00UTC",
            "domain": "example.example.com",
            "owner": "test",
            "updated": "2014-01-01T00:00:00UTC"
        }
    ]
}

添加域名

示例请求:

POST /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{'domain': 'example.example.com'}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "domain": "example.example.com",
    "owner": "test",
    "updated": "2014-01-01T00:00:00UTC"
}

移除域名

示例请求:

DELETE /v2/apps/example-go/domains/example.example.com HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

构建

列出应用构建

示例请求:

GET /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "FROM drycc/slugrunner RUN mkdir -p /app WORKDIR /app ENTRYPOINT [\"/runner/init\"] ADD slug.tgz /app ENV GIT_SHA 060da68f654e75fac06dbedd1995d5f8ad9084db",
    "image": "example-go",
    "owner": "test",
    "procfile": {
        "web": "example-go"
    },
    "sha": "060da68f",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建应用构建

示例请求:

POST /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"image": "drycc/example-go:latest"}

可选参数:

{
    "procfile": {
      "web": "./cmd"
    }
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "",
    "image": "drycc/example-go:latest",
    "owner": "test",
    "procfile": {},
    "sha": "",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

发布

列出应用发布

示例请求:

GET /v2/apps/example-go/releases/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 3,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "build": "202d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "ed637ceb-5d32-44bd-9406-d326a777a513",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test changed nothing",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 3
        },
        {
            "app": "example-go",
            "build": "202d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test deployed 060da68",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 2
        },
        {
            "app": "example-go",
            "build": null,
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test created initial release",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 1
        }
    ]
}

列出发布详情

示例请求:

GET /v2/apps/example-go/releases/v2/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "app": "example-go",
    "build": null,
    "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
    "created": "2014-01-01T00:00:00UTC",
    "owner": "test",
    "summary": "test created initial release",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
    "version": 1
}

回滚发布

示例请求:

POST /v2/apps/example-go/releases/rollback/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"version": 1}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{"version": 5}

密钥

列出密钥

示例请求:

GET /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "test@example.com",
            "owner": "test",
            "public": "ssh-rsa <...>",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

向用户添加密钥

示例请求:

POST /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "id": "example",
    "public": "ssh-rsa <...>"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example",
    "owner": "example",
    "public": "ssh-rsa <...>",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

从用户移除密钥

示例请求:

DELETE /v2/keys/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

权限

列出应用权限

注意

这不包括应用所有者。

示例请求:

GET /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "users": [
        "test",
        "foo"
    ]
}

创建应用权限

示例请求:

POST /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

移除应用权限

示例请求:

DELETE /v2/apps/example-go/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

列出管理员

示例请求:

GET /v2/admin/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 2,
    "next": null
    "previous": null,
    "results": [
        {
            "username": "test",
            "is_superuser": true
        },
        {
            "username": "foo",
            "is_superuser": true
        }
    ]
}

授予用户管理员权限

注意

此命令需要管理员权限

示例请求:

POST /v2/admin/perms HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

移除用户的管理员权限

注意

此命令需要管理员权限

示例请求:

DELETE /v2/admin/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0

用户

列出所有用户

注意

此命令需要管理员权限

示例请求:

GET /v2/users HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.1
DRYCC_PLATFORM_VERSION: 2.1.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "last_login": "2014-10-19T22:01:00.601Z",
            "is_superuser": true,
            "username": "test",
            "first_name": "test",
            "last_name": "testerson",
            "email": "test@example.com",
            "is_staff": true,
            "is_active": true,
            "date_joined": "2014-10-19T22:01:00.601Z",
            "groups": [],
            "user_permissions": []
        }
    ]
}

10.4 - Controller API v2.2

这是 Controller 的 v2.2 REST API。

新功能

新增! /v2/auth/whoami 端点

认证

注册新用户

示例请求:

POST /v2/auth/register/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{
    "username": "test",
    "password": "opensesame",
    "email": "test@example.com"
}

可选参数:

{
    "first_name": "test",
    "last_name": "testerson"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "id": 1,
    "last_login": "2014-10-19T22:01:00.601Z",
    "is_superuser": true,
    "username": "test",
    "first_name": "test",
    "last_name": "testerson",
    "email": "test@example.com",
    "is_staff": true,
    "is_active": true,
    "date_joined": "2014-10-19T22:01:00.601Z",
    "groups": [],
    "user_permissions": []
}

登录

示例请求:

POST /v2/auth/login/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{"username": "test", "password": "opensesame"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{"token": "abc123"}

注销账户

示例请求:

DELETE /v2/auth/cancel/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

我是谁

示例请求:

GET /v2/auth/whoami/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "id": 1,
    "last_login": "2014-10-19T22:01:00.601Z",
    "is_superuser": true,
    "username": "test",
    "first_name": "test",
    "last_name": "testerson",
    "email": "test@example.com",
    "is_staff": true,
    "is_active": true,
    "date_joined": "2014-10-19T22:01:00.601Z",
    "groups": [],
    "user_permissions": []
}

重新生成令牌

注意

此命令可能需要管理员权限

示例请求:

POST /v2/auth/tokens/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
    "username" : "test"
    "all" : "true"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{"token": "abc123"}

修改密码

示例请求:

POST /v2/auth/passwd/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "password": "foo",
    "new_password": "bar"
}

可选参数:

{"username": "testuser"}

注意

使用 username 参数需要管理员权限,并使 password 参数可选。

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

应用

列出所有应用

示例请求:

GET /v2/apps HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "example-go",
            "owner": "test",
            "structure": {},
            "updated": "2014-01-01T00:00:00UTC",
            "url": "example-go.example.com",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

创建应用

示例请求:

POST /v2/apps/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

可选参数:

{"id": "example-go"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

销毁应用

示例请求:

DELETE /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

列出应用详情

示例请求:

GET /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

更新应用详情

示例请求:

POST /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
  "owner": "test"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 1.8.0
Content-Type: application/json

获取应用日志

示例请求:

GET /v2/apps/example-go/logs/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选 URL 查询参数:

?log_lines=

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: text/plain

"16:51:14 drycc[api]: test created initial release\n"

运行一次性命令

POST /v2/apps/example-go/run/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"command": "echo hi"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{"exit_code": 0, "output": "hi\n"}

证书

列出所有证书

示例请求:

GET /v2/certs HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 22,
      "owner": "test",
      "san": [],
      "domains": [],
      "created": "2016-06-22T22:24:20Z",
      "updated": "2016-06-22T22:24:20Z",
      "name": "foo",
      "common_name": "bar.com",
      "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
      "expires": "2017-01-14T23:57:57Z",
      "starts": "2016-01-15T23:57:57Z",
      "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
      "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
    }
  ]
}

获取证书详情

示例请求:

GET /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22T22:24:20Z",
  "updated": "2016-06-22T22:24:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

创建证书

示例请求:

POST /v2/certs/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{
    "name": "foo"
    "certificate": "-----BEGIN CERTIFICATE-----",
    "key": "-----BEGIN RSA PRIVATE KEY-----"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22T22:24:20Z",
  "updated": "2016-06-22T22:24:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

销毁证书

示例请求:

DELETE /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

将域名附加到证书

示例请求:

POST /v2/certs/foo/domain/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "domain": "test.com"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

从证书中移除域名

示例请求:

DELETE /v2/certs/foo/domain/test.com/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

Pods

列出所有 Pods

示例请求:

GET /v2/apps/example-go/pods/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

按类型列出所有 Pods

示例请求:

GET /v2/apps/example-go/pods/web/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

重启所有 Pods

示例请求:

POST /v2/apps/example-go/pods/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型重启 Pods

示例请求:

POST /v2/apps/example-go/pods/web/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型和名称重启 Pods

示例请求:

POST /v2/apps/example-go/pods/go-v2-web-atots/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

缩放 Pods

示例请求:

POST /v2/apps/example-go/scale/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"web": 3}

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

配置

列出应用配置

示例请求:

GET /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
      "PLATFORM": "drycc"
    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建新配置

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": "world", "PLATFORM": "drycc"}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v3",
        "HELLO": "world",
        "PLATFORM": "drycc"

    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

取消设置配置变量

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": null}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v4",
        "PLATFORM": "drycc"
   },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

域名

列出应用域名

示例请求:

GET /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "created": "2014-01-01T00:00:00UTC",
            "domain": "example.example.com",
            "owner": "test",
            "updated": "2014-01-01T00:00:00UTC"
        }
    ]
}

添加域名

示例请求:

POST /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{'domain': 'example.example.com'}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "domain": "example.example.com",
    "owner": "test",
    "updated": "2014-01-01T00:00:00UTC"
}

移除域名

示例请求:

DELETE /v2/apps/example-go/domains/example.example.com HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

构建

列出应用构建

示例请求:

GET /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "FROM drycc/slugrunner RUN mkdir -p /app WORKDIR /app ENTRYPOINT [\"/runner/init\"] ADD slug.tgz /app ENV GIT_SHA 060da68f654e75fac06dbedd1995d5f8ad9084db",
    "image": "example-go",
    "owner": "test",
    "procfile": {
        "web": "example-go"
    },
    "sha": "060da68f",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建应用构建

示例请求:

POST /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"image": "drycc/example-go:latest"}

可选参数:

{
    "procfile": {
      "web": "./cmd"
    }
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "",
    "image": "drycc/example-go:latest",
    "owner": "test",
    "procfile": {},
    "sha": "",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

发布

列出应用发布

示例请求:

GET /v2/apps/example-go/releases/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 3,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "build": "202d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "ed637ceb-5d32-44bd-9406-d326a777a513",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test changed nothing",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 3
        },
        {
            "app": "example-go",
            "build": "202d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test deployed 060da68",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 2
        },
        {
            "app": "example-go",
            "build": null,
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test created initial release",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 1
        }
    ]
}

列出发布详情

示例请求:

GET /v2/apps/example-go/releases/v2/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "app": "example-go",
    "build": null,
    "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
    "created": "2014-01-01T00:00:00UTC",
    "owner": "test",
    "summary": "test created initial release",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
    "version": 1
}

回滚发布

示例请求:

POST /v2/apps/example-go/releases/rollback/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"version": 1}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{"version": 5}

密钥

列出密钥

示例请求:

GET /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "test@example.com",
            "owner": "test",
            "public": "ssh-rsa <...>",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

向用户添加密钥

示例请求:

POST /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "id": "example",
    "public": "ssh-rsa <...>"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example",
    "owner": "example",
    "public": "ssh-rsa <...>",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

从用户移除密钥

示例请求:

DELETE /v2/keys/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

权限

列出应用权限

注意

这不包括应用所有者。

示例请求:

GET /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "users": [
        "test",
        "foo"
    ]
}

创建应用权限

示例请求:

POST /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

移除应用权限

示例请求:

DELETE /v2/apps/example-go/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

列出管理员

示例请求:

GET /v2/admin/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 2,
    "next": null
    "previous": null,
    "results": [
        {
            "username": "test",
            "is_superuser": true
        },
        {
            "username": "foo",
            "is_superuser": true
        }
    ]
}

授予用户管理员权限

注意

此命令需要管理员权限

示例请求:

POST /v2/admin/perms HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

移除用户的管理员权限

注意

此命令需要管理员权限

示例请求:

DELETE /v2/admin/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0

用户

列出所有用户

注意

此命令需要管理员权限

示例请求:

GET /v2/users HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.2
DRYCC_PLATFORM_VERSION: 2.2.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "last_login": "2014-10-19T22:01:00.601Z",
            "is_superuser": true,
            "username": "test",
            "first_name": "test",
            "last_name": "testerson",
            "email": "test@example.com",
            "is_staff": true,
            "is_active": true,
            "date_joined": "2014-10-19T22:01:00.601Z",
            "groups": [],
            "user_permissions": []
        }
    ]
}

10.5 - Controller API v2.3

这是 Controller 的 v2.3 REST API。

新功能

新增! /v2/apps/{name}/logs 端点已修复,不再返回 b'log data',而是返回正常的字符串 log data

认证

注册新用户

示例请求:

POST /v2/auth/register/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{
    "username": "test",
    "password": "opensesame",
    "email": "test@example.com"
}

可选参数:

{
    "first_name": "test",
    "last_name": "testerson"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "id": 1,
    "last_login": "2014-10-19T22:01:00.601Z",
    "is_superuser": true,
    "username": "test",
    "first_name": "test",
    "last_name": "testerson",
    "email": "test@example.com",
    "is_staff": true,
    "is_active": true,
    "date_joined": "2014-10-19T22:01:00.601Z",
    "groups": [],
    "user_permissions": []
}

登录

示例请求:

POST /v2/auth/login/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json

{"username": "test", "password": "opensesame"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{"token": "abc123"}

注销账户

示例请求:

DELETE /v2/auth/cancel/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

我是谁

示例请求:

GET /v2/auth/whoami/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "id": 1,
    "last_login": "2014-10-19T22:01:00.601Z",
    "is_superuser": true,
    "username": "test",
    "first_name": "test",
    "last_name": "testerson",
    "email": "test@example.com",
    "is_staff": true,
    "is_active": true,
    "date_joined": "2014-10-19T22:01:00.601Z",
    "groups": [],
    "user_permissions": []
}

重新生成令牌

注意

此命令可能需要管理员权限

示例请求:

POST /v2/auth/tokens/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
    "username" : "test"
    "all" : "true"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{"token": "abc123"}

修改密码

示例请求:

POST /v2/auth/passwd/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "password": "foo",
    "new_password": "bar"
}

可选参数:

{"username": "testuser"}

注意

使用 username 参数需要管理员权限,并使 password 参数可选。

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

应用

列出所有应用

示例请求:

GET /v2/apps HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "example-go",
            "owner": "test",
            "structure": {},
            "updated": "2014-01-01T00:00:00UTC",
            "url": "example-go.example.com",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

创建应用

示例请求:

POST /v2/apps/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

可选参数:

{"id": "example-go"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

销毁应用

示例请求:

DELETE /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

列出应用详情

示例请求:

GET /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example-go",
    "owner": "test",
    "structure": {},
    "updated": "2014-01-01T00:00:00UTC",
    "url": "example-go.example.com",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

更新应用详情

示例请求:

POST /v2/apps/example-go/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选参数:

{
  "owner": "test"
}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 1.8.0
Content-Type: application/json

获取应用日志

示例请求:

GET /v2/apps/example-go/logs/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

可选 URL 查询参数:

?log_lines=

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: text/plain

"16:51:14 drycc[api]: test created initial release\n"

运行一次性命令

POST /v2/apps/example-go/run/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"command": "echo hi"}

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{"exit_code": 0, "output": "hi\n"}

证书

列出所有证书

示例请求:

GET /v2/certs HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 22,
      "owner": "test",
      "san": [],
      "domains": [],
      "created": "2016-06-22.32.34:20Z",
      "updated": "2016-06-22.32.34:20Z",
      "name": "foo",
      "common_name": "bar.com",
      "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
      "expires": "2017-01-14T23:57:57Z",
      "starts": "2016-01-15T23:57:57Z",
      "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
      "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
    }
  ]
}

获取证书详情

示例请求:

GET /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22.32.34:20Z",
  "updated": "2016-06-22.32.34:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

创建证书

示例请求:

POST /v2/certs/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{
    "name": "foo"
    "certificate": "-----BEGIN CERTIFICATE-----",
    "key": "-----BEGIN RSA PRIVATE KEY-----"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
  "id": 22,
  "owner": "test",
  "san": [],
  "domains": [],
  "created": "2016-06-22.32.34:20Z",
  "updated": "2016-06-22.32.34:20Z",
  "name": "foo",
  "common_name": "bar.com",
  "fingerprint": "7A:CA:B8:50:FF:8D:EB:03:3D:AC:AD:13:4F:EE:03:D5:5D:EB:5E:37:51:8C:E0:98:F8:1B:36:2B:20:83:0D:C0",
  "expires": "2017-01-14T23:57:57Z",
  "starts": "2016-01-15T23:57:57Z",
  "issuer": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc",
  "subject": "/C=US/ST=CA/L=San Francisco/O=Drycc/OU=Engineering/CN=bar.com/emailAddress=engineering@drycc.cc"
}

销毁证书

示例请求:

DELETE /v2/certs/foo HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

将域名附加到证书

示例请求:

POST /v2/certs/foo/domain/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "domain": "test.com"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

从证书中移除域名

示例请求:

DELETE /v2/certs/foo/domain/test.com/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

启用或禁用 TLS

示例请求:

POST /v2/apps/example-go/tls/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{
  "https_enforced": true
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "app": "example-go",
    "owner": "test",
    "https_enforced": true,
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

获取 TLS 状态

示例请求:

GET /v2/apps/example-go/tls/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "app": "example-go",
    "owner": "test",
    "https_enforced": false,
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

Pods

列出所有 Pods

示例请求:

GET /v2/apps/example-go/pods/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

按类型列出所有 Pods

示例请求:

GET /v2/apps/example-go/pods/web/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 1,
    "results": [
        {
            "name": "go-v2-web-e7dej",
            "release": "v2",
            "started": "2014-01-01T00:00:00Z",
            "state": "up",
            "type": "web"
        }
    ]
}

重启所有 Pods

示例请求:

POST /v2/apps/example-go/pods/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型重启 Pods

示例请求:

POST /v2/apps/example-go/pods/web/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

按类型和名称重启 Pods

示例请求:

POST /v2/apps/example-go/pods/go-v2-web-atots/restart/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

[
    {
        "name": "go-v2-web-atots",
        "release": "v2",
        "started": "2016-04-11T21:07:54Z",
        "state": "up",
        "type": "web"
    }
]

缩放 Pods

示例请求:

POST /v2/apps/example-go/scale/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"web": 3}

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

配置

列出应用配置

示例请求:

GET /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
      "PLATFORM": "drycc"
    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建新配置

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": "world", "PLATFORM": "drycc"}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v3",
        "HELLO": "world",
        "PLATFORM": "drycc"

    },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

取消设置配置变量

示例请求:

POST /v2/apps/example-go/config/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"values": {"HELLO": null}}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "owner": "test",
    "app": "example-go",
    "values": {
        "DRYCC_APP": "example-go",
        "DRYCC_RELEASE": "v4",
        "PLATFORM": "drycc"
   },
    "memory": {},
    "cpu": {},
    "tags": {},
    "healthcheck": {},
    "created": "2014-01-01T00:00:00UTC",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

域名

列出应用域名

示例请求:

GET /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "created": "2014-01-01T00:00:00UTC",
            "domain": "example.example.com",
            "owner": "test",
            "updated": "2014-01-01T00:00:00UTC"
        }
    ]
}

添加域名

示例请求:

POST /v2/apps/example-go/domains/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{'domain': 'example.example.com'}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "domain": "example.example.com",
    "owner": "test",
    "updated": "2014-01-01T00:00:00UTC"
}

移除域名

示例请求:

DELETE /v2/apps/example-go/domains/example.example.com HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

构建

列出应用构建

示例请求:

GET /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "FROM drycc/slugrunner RUN mkdir -p /app WORKDIR /app ENTRYPOINT [\"/runner/init\"] ADD slug.tgz /app ENV GIT_SHA 060da68f654e75fac06dbedd1995d5f8ad9084db",
    "image": "example-go",
    "owner": "test",
    "procfile": {
        "web": "example-go"
    },
    "sha": "060da68f",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

创建应用构建

示例请求:

POST /v2/apps/example-go/build/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"image": "drycc/example-go:latest"}

可选参数:

{
    "procfile": {
      "web": "./cmd"
    }
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "app": "example-go",
    "created": "2014-01-01T00:00:00UTC",
    "dockerfile": "",
    "image": "drycc/example-go:latest",
    "owner": "test",
    "procfile": {},
    "sha": "",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

发布

列出应用发布

示例请求:

GET /v2/apps/example-go/releases/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 3,
    "next": null,
    "previous": null,
    "results": [
        {
            "app": "example-go",
            "build": "2.3d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "ed637ceb-5d32-44bd-9406-d326a777a513",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test changed nothing",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 3
        },
        {
            "app": "example-go",
            "build": "2.3d8e4b-600e-4425-a85c-ffc7ea607f61",
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test deployed 060da68",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 2
        },
        {
            "app": "example-go",
            "build": null,
            "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
            "created": "2014-01-01T00:00:00UTC",
            "owner": "test",
            "summary": "test created initial release",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
            "version": 1
        }
    ]
}

列出发布详情

示例请求:

GET /v2/apps/example-go/releases/v2/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "app": "example-go",
    "build": null,
    "config": "95bd6dea-1685-4f78-a03d-fd7270b058d1",
    "created": "2014-01-01T00:00:00UTC",
    "owner": "test",
    "summary": "test created initial release",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75",
    "version": 1
}

回滚发布

示例请求:

POST /v2/apps/example-go/releases/rollback/ HTTP/1.1
Host: drycc.example.com
Content-Type: application/json
Authorization: token abc123

{"version": 1}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{"version": 5}

密钥

列出密钥

示例请求:

GET /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created": "2014-01-01T00:00:00UTC",
            "id": "test@example.com",
            "owner": "test",
            "public": "ssh-rsa <...>",
            "updated": "2014-01-01T00:00:00UTC",
            "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
        }
    ]
}

向用户添加密钥

示例请求:

POST /v2/keys/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{
    "id": "example",
    "public": "ssh-rsa <...>"
}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "created": "2014-01-01T00:00:00UTC",
    "id": "example",
    "owner": "example",
    "public": "ssh-rsa <...>",
    "updated": "2014-01-01T00:00:00UTC",
    "uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
}

从用户移除密钥

示例请求:

DELETE /v2/keys/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

权限

列出应用权限

注意

这不包括应用所有者。

示例请求:

GET /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "users": [
        "test",
        "foo"
    ]
}

创建应用权限

示例请求:

POST /v2/apps/example-go/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

移除应用权限

示例请求:

DELETE /v2/apps/example-go/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

列出管理员

示例请求:

GET /v2/admin/perms/ HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 2,
    "next": null
    "previous": null,
    "results": [
        {
            "username": "test",
            "is_superuser": true
        },
        {
            "username": "foo",
            "is_superuser": true
        }
    ]
}

授予用户管理员权限

注意

此命令需要管理员权限

示例请求:

POST /v2/admin/perms HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

{"username": "example"}

示例响应:

HTTP/1.1 201 CREATED
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

移除用户的管理员权限

注意

此命令需要管理员权限

示例请求:

DELETE /v2/admin/perms/example HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 204 NO CONTENT
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0

用户

列出所有用户

注意

此命令需要管理员权限

示例请求:

GET /v2/users HTTP/1.1
Host: drycc.example.com
Authorization: token abc123

示例响应:

HTTP/1.1 200 OK
DRYCC_API_VERSION: 2.3
DRYCC_PLATFORM_VERSION: 2.3.0
Content-Type: application/json

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "last_login": "2014-10-19T22:01:00.601Z",
            "is_superuser": true,
            "username": "test",
            "first_name": "test",
            "last_name": "testerson",
            "email": "test@example.com",
            "is_staff": true,
            "is_active": true,
            "date_joined": "2014-10-19T22:01:00.601Z",
            "groups": [],
            "user_permissions": []
        }
    ]
}