Registry
Registry ảnh container riêng tư: build trong cụm, quản lý tag và pull secret theo tài khoản dịch vụ.
Registry là gì?
Registry là một kho image container riêng tư cho project của bạn, cộng thêm một dịch vụ build image trong cụm. Đẩy image bằng bộ công cụ Docker tiêu chuẩn, kéo chúng ẩn danh (với repo công khai) hoặc bằng một thông tin đăng nhập theo từng service-account, và build image thẳng từ mã nguồn trong một Dev Box — không cần Docker daemon. Image bạn lưu ở đây có thể được triển khai bởi Kinetic hoặc chạy bên trong một Dev Box.
Bên dưới, nó là một máy chủ registry:2 tiêu chuẩn được hậu thuẫn bởi lưu trữ tương thích S3 của nền tảng (RustFS), với luồng token-auth Docker được xử lý bởi backend Mikademy Cloud. Các build chạy dưới dạng Job Kaniko bên trong namespace project của bạn.
Một repository (repo) là một nhóm image có tên bên trong một project.
Đường dẫn kéo image
Mỗi image được định địa chỉ bằng endpoint của registry, id project của bạn, repo, tên image và một tag:
registry.<base-domain>/<project>/<repo>/<image>:<tag>
Endpoint của registry là registry.<base-domain> cho các client Docker. Với một project demo-01 có repo backend và một image api, tham chiếu đầy đủ là registry.example.com/demo-01/backend/api:v1. Bạn luôn có thể tra cứu endpoint chính xác của mình và một ví dụ sẵn-sao-chép từ console hoặc endpoint API.
Điều kiện tiên quyết
- Một project mà bạn thuộc về. Đọc repo và image cần bất kỳ tư cách thành viên nào; tạo hoặc xóa repo, xóa tag và khởi chạy build cần owner, editor, hoặc vai trò
registry.admin. - Để đẩy/kéo từ máy của riêng bạn: Docker (hoặc bất kỳ client OCI nào) và một registry key được cấp cho một service account giữ vai trò ghi.
- Để build trong cụm: mã nguồn trong một Dev Box đang chạy với một
Dockerfile.
Tạo một repository
Trong console, mở /<project>/registry và nhấp New repository. Một id repo là một tên kiểu DNS, duy nhất trong project. Repo mới mặc định là private.
| Field | Type | Description |
|---|---|---|
id | string | Tên repository, duy nhất trong project. Kiểu DNS (chữ thường, số, dấu gạch ngang). |
public | boolean | Tùy chọn. Khi true, ai cũng có thể kéo từ repo ẩn danh. Mặc định false (private). |
Hoặc tạo nó bằng API:
curl -s -X POST "$BASE/projects/demo-01/registry/repos" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":"backend","public":false}'Endpoint registry & docker login
Để đẩy hoặc kéo từ máy của bạn, bạn xác thực bằng một registry key. Một registry key được dựng từ API key của một service account: id của service account là Docker username và key là password. Vì khóa mksa_ của một service account chỉ được hiển thị một lần, việc cấp một registry key sẽ đúc một key mới cho service account và trao cho bạn thông tin đăng nhập đúng một lần.
Đẩy cần vai trò ghi
Service account mà bạn đăng nhập phải giữ một vai trò ghi trên project — owner, editor, hoặcregistry.admin. Thông tin đăng nhập ẩn danh và chỉ-đọc chỉ có thể kéo, và chỉ từ repo công khai.Cấp một registry key từ thẻ Registry key của service account trong console (phản chiếu luồng Bucket S3-key), hoặc qua API:
curl -s -X POST \
"$BASE/projects/demo-01/service-accounts/<sa-id>/registry-key" \
-H "Authorization: Bearer $TOKEN"Phản hồi bao gồm endpoint của registry, key mới, và một dockerconfigjson dựng sẵn (cộng thêm một gợi ý kubectl create secret). Sau đó hãy đăng nhập và đẩy:
# Log in (username = service-account id, password = the issued key)
docker login registry.example.com -u <sa-id> -p <registry-key>
# Tag a local image for your repo and push it
docker tag myapp:latest registry.example.com/demo-01/backend/api:v1
docker push registry.example.com/demo-01/backend/api:v1
# Pull it back
docker pull registry.example.com/demo-01/backend/api:v1Tìm endpoint của bạn
GET /projects/{id}/registry/endpoint trả về endpoint của bạn và một ví dụ docker pull sao-chép-dán, nên bạn không bao giờ phải tự dựng đường dẫn.Repository công khai và riêng tư
Một repo private (mặc định) yêu cầu một thông tin đăng nhập registry hợp lệ cho mọi lần kéo và đẩy. Một repo public cho phép kéo ẩn danh — không cần đăng nhập — trong khi đẩy vẫn cần một vai trò ghi.
Đổi mức hiển thị từ phần đầu của repo trong console, hoặc bằng PATCH:
curl -s -X PATCH "$BASE/projects/demo-01/registry/repos/backend" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"public":true}'Pull secret theo từng service-account
Để cho một workload Kubernetes — bao gồm một triển khai Kinetic hoặc một Dev Box — kéo từ một repo riêng tư, hãy cấp cho nó một image pull secret. Endpoint registry-key trả về một dockerconfigjson hoàn chỉnh được dựng từ thông tin đăng nhập của service account:
{
"auths": {
"registry.example.com": {
"username": "<sa-id>",
"password": "<registry-key>",
"auth": "<base64("<sa-id>:<registry-key>")>"
}
}
}Tạo một Kubernetes pull secret từ nó và tham chiếu nó từ các pod của bạn:
# Save the returned dockerconfigjson to a file, then:
kubectl create secret generic registry-pull \
--type=kubernetes.io/dockerconfigjson \
--from-file=.dockerconfigjson=dockerconfig.json
# Reference it from a pod / deployment:
# spec.imagePullSecrets:
# - name: registry-pullCấp lại sẽ xoay key
Vì API key bên dưới được lưu dạng băm và chỉ hiển thị một lần, việc cấp một registry key tạo một key mới cho service account đó. Cấp lại sẽ vô hiệu hóa mọi secret được dựng từ key trước đó — hãy tạo lại các pull secret phụ thuộc sau khi xoay. DùngDELETE …/registry-key để thu hồi.Tag & image
Trang chi tiết của một repo có một mục con Images liệt kê mỗi image:tag cùng kích thước, digest và nguồn (Build cho một build trong cụm,Pushed cho một docker push). Danh sách được đồng bộ từ catalog của registry, nên một tag vừa đẩy sẽ xuất hiện tự động.
Để xóa một tag đơn (manifest của registry bị loại bỏ):
curl -s -X DELETE \
"$BASE/projects/demo-01/registry/repos/backend/images/api/tags/v1" \
-H "Authorization: Bearer $TOKEN"Xóa toàn bộ repo (DELETE …/registry/repos/{repo}) sẽ loại bỏ tất cả image của nó và các blob bên dưới và chạy thu gom rác.
Build trong cụm với Kaniko
Build biến mã nguồn trong một Dev Box thành một image có tag trong một repo — không cần Docker cục bộ. Backend tar context của bạn ra khỏi Dev Box đang chạy, tải nó lên object storage, và chạy một Job Kaniko trong namespace project của bạn để đẩy kết quả thẳng vào registry.
- Đặt mã nguồn của bạn trong một Dev Box. Hãy đảm bảo có một
Dockerfileở gốc context (context mặc định là/home/coder/project). Dev Box phải đang chạy, vì context được exec-tar ra khỏi nó. - Khởi chạy một build. Trên mục con Builds của repo, nhấp New build, chọn tên image, Dev Box và đường dẫn context. Để trống tag để tự sinh một cái.
- Theo dõi log. Trang chi tiết build phát trực tiếp log của Job Kaniko và hiển thị trạng thái khi nó chạy.
- Build lại. Dùng Rebuild để chạy lại với cùng thiết lập, hoặc sửa các trường của build trước. Khi thành công, hàng image được gắn tag
source=buildvà liên kết ngược về build.
Tạo một build qua API:
curl -s -X POST "$BASE/projects/demo-01/registry/builds" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"repoId": "backend",
"imageName": "api",
"devboxId": "<devbox-id>",
"contextPath": "/home/coder/project"
}'| Field | Type | Description |
|---|---|---|
repoId | string | Repo mà image đã build được đẩy vào. |
imageName | string | Tên image trong repo (vd. api). |
devboxId | string | Dev Box đang chạy có mã nguồn là context của build. |
contextPath | string | Thư mục bên trong Dev Box dùng làm context của build (mặc định /home/coder/project). |
tag | string | Tùy chọn. Tự sinh khi bỏ trống. |
dockerfile | string | Tùy chọn. Đường dẫn tương đối so với context; mặc định là một Dockerfile ở gốc context. |
buildArgs | object[] | Tùy chọn. Tham số lúc build dưới dạng các cặp { key, value }. |
Cần một Dockerfile
Nếudockerfile bị bỏ trống thì backend tự dò một Dockerfile ở gốc context; nếu không tìm thấy thì build trả về 400 yêu cầu tham số đó.Triển khai một image đã build
Khi một image đã ở trong registry của bạn, hãy triển khai nó với Kinetic bằng cách tham chiếu đường dẫn kéo đầy đủ của nó, hoặc chạy nó bên trong một Dev Box. Với một repo riêng tư, hãy gắn một pull secret để workload có thể xác thực:
# Image reference to give Kinetic:
registry.example.com/demo-01/backend/api:v1Repo công khai không cần secret — Kinetic và cụm có thể kéo ẩn danh.
REST API
Tất cả route đều nằm dưới https://api.<base-domain>/api/v1. Đọc chấp nhận bất kỳ thành viên project nào; ghi đòi hỏi owner / editor / registry.admin. Các ví dụ giả định $BASE và $TOKEN đã được đặt.
BASE=https://api.example.com/api/v1
TOKEN=<your-session-token>Endpoint & repo
# Registry endpoint + a pull example
curl -s "$BASE/projects/demo-01/registry/endpoint" \
-H "Authorization: Bearer $TOKEN"
# List repos (id, public, imageCount, sizeBytes, pullPath prefix, createdAt)
curl -s "$BASE/projects/demo-01/registry/repos" \
-H "Authorization: Bearer $TOKEN"
# Create a repo
curl -s -X POST "$BASE/projects/demo-01/registry/repos" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"id":"backend","public":false}'
# Get one repo with its images
curl -s "$BASE/projects/demo-01/registry/repos/backend" \
-H "Authorization: Bearer $TOKEN"
# Make it public / private
curl -s -X PATCH "$BASE/projects/demo-01/registry/repos/backend" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"public":true}'
# Delete a tag
curl -s -X DELETE \
"$BASE/projects/demo-01/registry/repos/backend/images/api/tags/v1" \
-H "Authorization: Bearer $TOKEN"
# Delete a whole repo (all images + blobs + GC)
curl -s -X DELETE "$BASE/projects/demo-01/registry/repos/backend" \
-H "Authorization: Bearer $TOKEN"Registry key (pull secret)
# Is a key issued for this SA?
curl -s "$BASE/projects/demo-01/service-accounts/<sa-id>/registry-key" \
-H "Authorization: Bearer $TOKEN"
# Issue / return a one-time dockerconfigjson (mints a new SA key)
curl -s -X POST \
"$BASE/projects/demo-01/service-accounts/<sa-id>/registry-key" \
-H "Authorization: Bearer $TOKEN"
# Revoke
curl -s -X DELETE \
"$BASE/projects/demo-01/service-accounts/<sa-id>/registry-key" \
-H "Authorization: Bearer $TOKEN"Build
# List builds
curl -s "$BASE/projects/demo-01/registry/builds" \
-H "Authorization: Bearer $TOKEN"
# Create a build (see fields above)
curl -s -X POST "$BASE/projects/demo-01/registry/builds" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"repoId":"backend","imageName":"api","devboxId":"<devbox-id>","contextPath":"/home/coder/project"}'
# Get one build (status + log)
curl -s "$BASE/projects/demo-01/registry/builds/<bid>" \
-H "Authorization: Bearer $TOKEN"
# Re-run a build
curl -s -X POST "$BASE/projects/demo-01/registry/builds/<bid>/rebuild" \
-H "Authorization: Bearer $TOKEN"Hóa đơn & hạn mức
Lưu trữ registry được tính vào hạn mức Disk của project: tổng kích thước của tất cả image trong mọi repo được cộng vào mức sử dụng đĩa của bạn bên cạnh bucket và Dev Box volume. CPU và bộ nhớ của một build đang chạy được tính vào hạn mức tính toán của bạn trong khi nó chạy.
Cưỡng chế vượt hạn mức là tự động
- Nếu một build đẩy một image khiến project của bạn vượt hạn mức đĩa, image vừa build sẽ bị tự động xóa (registry delete + GC) và một dòng được thêm vào log của build:
image deleted: exceeds disk quota. - Nếu một build đang chạy đẩy CPU/bộ nhớ của bạn vượt hạn mức, vòng lặp tính phí sẽ chấm dứt Job Kaniko và build được đánh dấu
terminated.
Xử lý sự cố
Cạm bẫy thường gặp
- 401 / thử thách Bearer khi đẩy hoặc kéo — Docker đang bị yêu cầu xác thực. Hãy chạy
docker login registry.<base-domain>với một id service-account và registry key hợp lệ. Truy cập ẩn danh chỉ hoạt động với repo công khai, chỉ-kéo. - Đẩy bị từ chối (403) — kéo có thể thành công trong khi đẩy thất bại khi service account của bạn thiếu vai trò ghi. Đẩy đòi hỏi owner / editor /
registry.admin. - Đăng nhập được nhưng thông tin đăng nhập sau đó thất bại — registry key đã được cấp lại, vốn xoay API key bên dưới. Hãy cấp một thông tin đăng nhập mới và dựng lại mọi pull secret phụ thuộc.
- 413 / layer lớn bị từ chối — ingress cho phép body lớn, nhưng nếu bạn đặt một proxy của riêng mình trước registry, hãy tăng giới hạn body-size và read/send timeout của nó cho các layer lớn.
- Build không khởi chạy được — Dev Box phải đang chạy (context được exec-tar ra khỏi nó) và một
Dockerfilephải tồn tại ở gốc context, hoặc truyềndockerfilemột cách tường minh.
Mẹo
Tận dụng tối đa Registry
- Dùng một service account cho mỗi pipeline để đẩy/kéo, để bạn có thể xoay hoặc thu hồi registry key của nó mà không ảnh hưởng các workload khác.
- Hãy giữ repo private theo mặc định; chỉ chuyển sang public khi việc kéo ẩn danh thực sự cần thiết.
- Ưu tiên build trong cụm hơn Docker cục bộ — context đến thẳng từ Dev Box của bạn và image được đẩy giúp bạn, kèm theo một log đầy đủ.
- Hãy xóa các tag cũ để thu hồi hạn mức đĩa trước khi nó kích hoạt tự động xóa các image mới.