Chạy container HTTP và tác vụ định kỳ. Tự co giãn, scale-to-zero và bảo vệ theo khoá API.
Một Kinetic là một container bạn chạy bên trong một dự án. Bạn mang đến một image, và nền tảng lập lịch cho nó, cấp cho nó một URL ổn định (cho các dịch vụ HTTP), đấu nối TLS, tự động co giãn và ghi log, đồng thời tính CPU/bộ nhớ của nó vào hạn ngạch dự án của bạn. Không có bước build ở đây — một Kinetic chạy một image. Hãy build hoặc đẩy image đó bằng Registry (hoặc bất kỳ registry công khai nào), rồi trỏ một Kinetic vào nó.
Một Kinetic chạy ở một trong hai chế độ:
https://<kid>.<project>.<base-domain>. Nó có thể công khai (bất kỳ ai cũng gọi được) hoặc được bảo vệ (người gọi phải xuất trình một khóa API tài khoản dịch vụ của dự án). Hỗ trợ tự động co giãn và scale-to-zero.Nó nằm ở đâu
Các Kinetic chạy trong namespace của dự ánproject-<project>. Trong console chúng nằm dưới /<project>/kinetic, với các trang con List, Logs, Requests và Testing.kinetic.admin). Cùng một cơ chế phân quyền kiểm soát mọi thao tác create/update/delete ở đây. Xem Dự án & IAM.mksa_…) để gọi nó. Tạo các khóa này trên trang Service Accounts của dự án.Trong console, mở /<project>/kinetic và nhấn New (việc này mở trang con tạo mới tại /<project>/kinetic/new). Rồi:
ghcr.io/acme/hello:1.8080).Pending → Ready khi Deployment của nó trở nên khả dụng.Lệnh gọi API tương đương — tạo bằng REST API:
curl -X POST https://api.<base-domain>/api/v1/projects/<project>/kinetics \
-H "Authorization: Bearer <your-user-token>" \
-H "Content-Type: application/json" \
-d '{
"id": "hello",
"image": "ghcr.io/acme/hello:1",
"mode": "serving",
"port": 8080,
"env": [{"name": "GREETING", "value": "hi"}],
"resources": {"cpu": "500m", "memory": "256Mi"},
"serving": {
"protected": true,
"minReplicas": 1,
"maxReplicas": 4,
"allowedServiceAccounts": ["<sa-id>"]
}
}'| Field | Type | Description |
|---|---|---|
id | string | Bắt buộc. Nhãn DNS-1123, ≤ 30 ký tự, duy nhất trong dự án. Trở thành subdomain của URL. Trùng → 409. |
image | string | Bắt buộc. Tham chiếu container image. |
mode | "serving" | "schedule" | Bắt buộc. Chọn chế độ (và trong serving/schedule bên dưới cái nào được áp dụng). |
port | int | Cổng container của chế độ serving. Mặc định 8080. |
env | [{name, value}] | Biến môi trường tùy chọn được truyền vào container. |
resources | {cpu, memory} | Giới hạn CPU/bộ nhớ tùy chọn (xem Tài nguyên). Mặc định giới hạn 500m / 256Mi. |
registryCredential | {server, username, password} | Tùy chọn. Tạo một pull secret cho một image riêng tư (xem Image riêng tư). |
serving | object | Bắt buộc khi mode=serving. Xem bảng tùy chọn serving. |
schedule | {cron, args, suspend} | Bắt buộc khi mode=schedule. Xem Chế độ theo lịch. |
Đối với một Kinetic serving, backend tính ra host <kid>.<project>.<base-domain> và operator cấp phát một Service, một Ingress và (trên staging/prod) một chứng chỉ TLS. Một khi ở trạng thái Ready, trang chi tiết hiển thị url trực tiếp — hãy luôn đọc nó từ đó thay vì đoán scheme: trên dev không có TLS issuer, nên URL là http://<host>, trong khi staging/prod dùng https://<host>.
Lưu ý DNS trên dev
<kid>.<project>.<base> nằm sâu hai cấp nhãn, nên một chứng chỉ/DNS wildcard duy nhất không bao phủ được nó. Trên dev (minikube) bạn có thể cần một mục /etc/hosts cho host để truy cập nó từ một trình duyệt. Trang Testing bỏ qua điều này bằng cách gọi trực tiếp dịch vụ trong cụm.Một Kinetic serving hoặc là công khai (serving.protected = false — bất kỳ ai trên mạng đều có thể gọi nó) hoặc được bảo vệ (serving.protected = true — mọi yêu cầu phải mang theo một khóa API tài khoản dịch vụ hợp lệ của dự án). Việc bảo vệ được thực thi tại ingress qua một bước kiểm tra xác thực trước khi lưu lượng chạm tới container của bạn.
Các Kinetic được bảo vệ được ràng buộc với những tài khoản dịch vụ cụ thể qua serving.allowedServiceAccounts (một danh sách các id SA). Chỉ những khóa thuộc về một SA đã ràng buộc mới được chấp nhận — là bất kỳ SA nào của dự án thì chưa đủ. Khi protected = true, bạn phải liệt kê ít nhất một SA, nếu không Kinetic sẽ không thể truy cập được. Chuyển sang công khai sẽ xóa các ràng buộc.
| Field | Type | Description |
|---|---|---|
serving.protected | bool | Yêu cầu một khóa API tài khoản dịch vụ của dự án. Mặc định false (công khai). |
serving.allowedServiceAccounts | string[] | Các id SA được phép gọi một Kinetic được bảo vệ. Bắt buộc (≥1) khi được bảo vệ; xóa khi công khai. Mỗi cái phải là một SA của dự án (nếu không thì 400). |
serving.minReplicas | int | Cận dưới của số bản sao. Mặc định 1. 0 = scale-to-zero (KEDA). |
serving.maxReplicas | int | Cận trên tùy chọn cho tự động co giãn. Phải ≥ 1 và ≥ minReplicas (nếu không thì 400). |
Gửi khóa API dưới dạng một header X-API-Key hoặc một Bearer token. Khóa phải thuộc về một trong các tài khoản dịch vụ đã ràng buộc của Kinetic. Trang chi tiết hiển thị các SA đã ràng buộc và một đoạn curl sẵn sàng để sao chép.
# Using X-API-Key
curl https://<kid>.<project>.<base-domain>/ \
-H "X-API-Key: mksa_xxxxxxxxxxxxxxxx"
# Equivalent, using a Bearer token
curl https://<kid>.<project>.<base-domain>/ \
-H "Authorization: Bearer mksa_xxxxxxxxxxxxxxxx"401 từ gateway
Một401 nghĩa là bước kiểm tra xác thực đã từ chối yêu cầu trước khi container của bạn thấy nó: thiếu khóa, một khóa không hợp lệ/đã vô hiệu, hoặc một khóa có SA không được ràng buộc với Kinetic này. Trang Requests ghi lại lý do từ chối cho từng yêu cầu.Truyền cấu hình vào container qua env — một danh sách các cặp {name, value}. Thêm hoặc sửa chúng trong biểu mẫu, hoặc qua API. Sửa env trên một Kinetic serving hiện có sẽ luân chuyển Deployment để áp dụng thay đổi.
"env": [
{"name": "LOG_LEVEL", "value": "info"},
{"name": "DATABASE_URL", "value": "rqlite://my-db.project-acme.svc.cluster.local:4001"}
]Lượng request được giữ thấp một cách có chủ đích (50m CPU / 64Mi bộ nhớ) để một Kinetic rẻ khi lập lịch và thân thiện với hạn ngạch dự án. Thứ bạn đặt là giới hạn — trần mà container có thể dùng. Mặc định là 500m / 256Mi.
Giới hạn quan trọng vì hai lý do: một container vượt quá giới hạn bộ nhớ của nó sẽ bị OOM-kill (thoát 137), và ngưỡng tự động co giãn được tính bằng một phần trăm của giới hạn. Hãy định cỡ nó theo workload của bạn.
"resources": {"cpu": "1", "memory": "512Mi"}JVM và các runtime nặng khác
Các probe readiness và startup là kiểm tra TCP đối với cổng serving, nên nền tảng chờ cho đến khi cổng mở. Các runtime nặng (ví dụ JVM) thường cần 512Mi–1Gi nếu không sẽ OOM trong lúc khởi động — hãy nâng giới hạn bộ nhớ trước khi bạn nghi ngờ một lỗi.Các Kinetic serving co giãn theo chiều ngang giữa serving.minReplicas và serving.maxReplicas. Cách co giãn hoạt động phụ thuộc vào giá trị tối thiểu:
min khi rảnh rỗi.0..maxReplicas dựa trên nhu cầu HTTP. Khi không có lưu lượng, Kinetic chạy không pod nào (không tốn phí); yêu cầu đầu tiên sau khi rảnh rỗi chịu một cold start ~3 giây. HPA dựa trên tài nguyên không áp dụng ở đây.minReplicas.Trang chi tiết hiển thị min..max và số bản sao hiện tại.
Tại sao 90% giới hạn, không phải request
HPA nhắm tới một giá trị trung bình bằng 90% giới hạn của bạn (mức cấp phát thực), không phải một phần trăm của lượng request nhỏ xíu. Điều này giữ lượng request thấp và ResourceQuota của dự án ra khỏi phép tính co giãn.Đặt mode = schedule để chạy image theo một lịch cron thay vì phục vụ HTTP. Không có URL và không có tự động co giãn — nền tảng tạo một CronJob khởi chạy image của bạn theo lịch đã cho, chạy nó đến hoàn thành, và thử lại khi thất bại (tối đa 3 lần).
| Field | Type | Description |
|---|---|---|
schedule.cron | string | Bắt buộc. Biểu thức cron chuẩn 5 trường, ví dụ "*/5 * * * *". |
schedule.args | string[] | Tùy chọn các đối số lệnh truyền vào container. |
schedule.suspend | bool | Tạm dừng lịch mà không xóa nó. Mặc định false. |
curl -X POST https://api.<base-domain>/api/v1/projects/<project>/kinetics \
-H "Authorization: Bearer <your-user-token>" \
-H "Content-Type: application/json" \
-d '{
"id": "nightly-sync",
"image": "ghcr.io/acme/sync:2",
"mode": "schedule",
"schedule": {"cron": "0 2 * * *", "args": ["--full"], "suspend": false}
}'Để chạy nó theo yêu cầu mà không cần chờ nhịp cron tiếp theo, hãy dùng trang Testing — nó tạo một lần chạy thủ công đơn lẻ từ mẫu của CronJob. Lần chạy đó và đầu ra của nó sau đó hiện ra trên các trang Requests và Logs.
Image công khai không cần gì thêm. Đối với một image riêng tư — bao gồm bất cứ thứ gì trong Registry của dự án bạn — hãy cung cấp một registryCredential khi tạo hoặc cập nhật. Backend lưu nó dưới dạng một docker pull secret trong namespace của dự án và đính nó vào Kinetic một cách tự động; xóa Kinetic sẽ xóa secret.
"registryCredential": {
"server": "registry.<project>.<base-domain>",
"username": "<sa-id>",
"password": "<sa-key>"
}Ba trang con thao tác trên một Kinetic đã chọn (trang cung cấp một bộ chọn):
allowed = false hoặc trạng thái ≥ 400) được đánh dấu và mở rộng để hiển thị status và reason của gateway (ví dụ "missing api key", "service account not bound"). Với schedule, nó liệt kê các lần chạy CronJob kèm thời gian bắt đầu/hoàn thành và thành công/thất bại.Lỗi được ghi lại và lỗi từ phía sau
Trang Requests phản ánh kết quả gateway/xác thực, không phải body phản hồi của chính ứng dụng bạn. Một200 ở đây nghĩa là yêu cầu đã được cho qua — container của bạn sau đó trả về gì thì nằm trongLogs của container.Tất cả endpoint nằm dưới /api/v1/projects/{project}/kinetics và yêu cầu một token người dùng owner/editor (hoặc kinetic.admin) làm header Bearer.
BASE=https://api.<base-domain>/api/v1/projects/<project>/kinetics
AUTH="Authorization: Bearer <your-user-token>"
# List all Kinetics
curl "$BASE" -H "$AUTH"
# Get one (phase, url, lastScheduleTime are TOP-LEVEL in the JSON)
curl "$BASE/hello" -H "$AUTH"
# Patch — partial update (here: change image, raise the autoscale ceiling)
curl -X PATCH "$BASE/hello" -H "$AUTH" -H "Content-Type: application/json" \
-d '{"image":"ghcr.io/acme/hello:2","serving":{"maxReplicas":6}}'
# Delete (also removes the pull secret and any SA bindings)
curl -X DELETE "$BASE/hello" -H "$AUTH"PATCH chấp nhận bất kỳ tập con nào của image, env, port, resources, serving (protected, minReplicas, maxReplicas, allowedServiceAccounts), schedule (cron, args, suspend) và registryCredential. Một lần xóa thành công trả về 204.
CPU và bộ nhớ của một Kinetic được tính vào hạn ngạch dự án của bạn trong khi nó chạy. Nếu dự án vượt quá hạn ngạch CPU hoặc bộ nhớ, nền tảng tự động tạm ngưng Kinetic dùng nhiều nhất để đưa mức sử dụng trở lại dưới trần — một Kinetic serving bị tạm ngưng giảm xuống không bản sao (các đối tượng HPA/KEDA của nó bị cắt bỏ), và một schedule bị tạm ngưng ngừng kích hoạt.
Để khôi phục:
Xem Billing để biết hạn ngạch, mức sử dụng và việc thực thi vượt hạn ngạch hoạt động thế nào trên mọi dịch vụ.
502 ngay sau khi triển khai
Một502 từ URL thường nghĩa là container chưa lắng nghe trên cổng của nó, nên probe readiness TCP đang thất bại. Hãy xác nhận ứng dụng bind đúng port đã cấu hình (mặc định 8080) trên 0.0.0.0, kiểm tra Logs của container xem có crash loop không, và cho một ứng dụng khởi động chậm thời gian để đạt Ready.Exit 137 / OOMKilled
Mã thoát 137 nghĩa là container đã vượt quá giới hạn bộ nhớ của nó và bị kill. Hãy nângresources.memory (các ứng dụng JVM nặng thường cần 512Mi–1Gi) hoặc giảm bớt mức chiếm dụng của ứng dụng.Yêu cầu đầu tiên chậm
Độ trễ ~3 giây ở lần gọi đầu tiên sau khi rảnh rỗi là cold start của scale-to-zero (minReplicas = 0). Nếu bạn cần độ trễ thấp ổn định, hãy đặt minReplicas ≥ 1 để giữ một pod luôn sẵn sàng.Chạy gọn nhẹ, co giãn thông minh
:1.4.2, không phải :latest) để một lần triển khai lại có thể tái lập.minReplicas = 0 cho các dịch vụ tải đột biến hoặc lưu lượng thấp để không tốn gì khi rảnh; dùng minReplicas ≥ 1 khi cold start gây ảnh hưởng.