跳转到内容

部署一个 Web 应用

Goal

您运行在主机名后面、启用 TLS 的应用程序,并且在您更改时无需停机即可替换。

Before you start

  • 您的租户中至少有一个就绪节点 — 参见注册节点。
  • 一个已推送到平台可拉取的注册表的镜像,并固定到一个不是 latest 的标签。
  • 一个指向路由边缘的 DNS 名称。

Steps

  1. 打开 部署 并选择 新建部署。
  2. 为其提供名称、镜像引用和副本计数。
  3. 添加其所需的网络,以及入口下的路由主机名和端口。
  4. 添加一个类型为 exec 的健康检查,命令是镜像实际可以运行的。
  5. 选择 部署,并观察其达到运行状态。
Odysseus 仪表盘中的部署列表,显示每个部署的堆栈、镜像引用、副本计数和运行状态,以及步骤 1 中使用的“新建部署”按钮。
apiVersion: odysseus/v1
kind: Deployment
metadata:
name: api
labels:
app: api
spec:
image: registry.delta-telematics.ca/acme/api:1.4.2
replicas: 3
environment:
LOG_LEVEL: info
networks: [acme-network, traefik-public]
resources:
limits: {cpu: "1", memory: 512Mi}
requests: {cpu: 250m, memory: 256Mi}
healthCheck: # required for rolling
type: exec
command: "wget -qO- http://localhost:8080/healthz"
interval: 10s
timeout: 15s
retries: 3
startPeriod: 20s
secrets:
- name: DB
vaultPath: deployments/api/db
dependsOn:
- job: api-migrate
condition: complete
placement:
affinity: {label: role, value: app}
onNodeFailure: reschedule
ingress:
host: api.example.com
port: 8080
tls: {enabled: true, certResolver: letsencrypt}
healthCheck: {path: /healthz, interval: 10s, timeout: 3s} # LB probe — the zero-downtime part
compress: true
headers:
response:
set: {X-Frame-Options: DENY}
retry: {attempts: 3, initialInterval: 100ms}
update:
strategy: rolling
allow_concurrent_versions: true # required attestation
max_surge: 1
max_unavailable: 0
health_timeout: 90s
min_healthy_time: 15s
progress_deadline: 10m
failure_action: rollback
Validated against Manifest · testdata/docs-examples/routed-deployment.yaml

Verify

部署报告其所有副本都在运行,主机名通过 HTTPS 提供您的应用程序。

Evidence this worked

GET /api/v1/deployments/{name} 显示运行的副本计数和您发送的镜像。仪表盘的日志视图显示应用程序自身的启动输出——一个启动后立即退出的容器只显示启动行,没有其他内容。

When it fails

  • 镜像被拒绝。 拒绝要求提供固定的引用,例如 “nginx:1.27” — 绝不使用 :latest,因为没有它就没有什么可运行的。请固定标签。
  • 健康检查被拒绝。 只有 exec 会生成容器健康检查,没有其他类型会生成容器健康检查 — 请参阅健康检查和进程回收。
  • 滚动更新被拒绝。 渐进式滚动更新有前提条件,每次拒绝都会指出您遗漏的那一个:请参阅滚动更新。
  • 每个代码,以及它所命名的字段和接受的形式:拒绝和更改。