Unregistry – gửi trực tiếp “docker push” lên máy chủ mà không cần registry
(github.com/psviderski)- Unregistry là một công cụ mã nguồn mở cho phép truyền Docker image trực tiếp tới máy chủ từ xa mà không cần registry bên ngoài
- Với lệnh
docker pussh, image được truyền qua SSH một cách hiệu quả, bỏ qua các layer đã tồn tại sẵn - Giải quyết độ phức tạp và sự kém hiệu quả của Docker Hub truyền thống, registry tự vận hành, và cách save/load
- Đây là lợi thế lớn cho triển khai môi trường production, CI/CD, và môi trường mạng cô lập khi cần chuyển image nhanh và an toàn
- Cài đặt, cách dùng, yêu cầu đều rất đơn giản, không cần vận hành thêm dịch vụ hay mở cổng
Giới thiệu Unregistry và các ưu điểm chính
- Unregistry là một image registry gọn nhẹ lưu trữ và cung cấp image trực tiếp từ storage của Docker daemon
- Khi dùng lệnh
docker pussh, có thể chuyển image thẳng tới máy chủ Docker từ xa qua SSH mà không cần registry bên ngoài - Trong quá trình truyền, các layer đã có sẵn trên máy chủ sẽ được bỏ qua để chỉ truyền phần cần thiết một cách nhanh chóng
Vấn đề của cách triển khai Docker image truyền thống
- Khi build image ở local rồi chuyển lên máy chủ, các lựa chọn thường là như sau
- Docker Hub/GitHub Container Registry: mã có thể bị lộ ra bên ngoài, hoặc phát sinh chi phí nếu dùng kho riêng tư
- Registry tự vận hành: tăng gánh nặng vận hành dịch vụ riêng, bảo mật và quản lý storage
- Save/Load: luôn phải truyền toàn bộ image nên kém hiệu quả
- Rebuild trực tiếp trên máy chủ: tốn thời gian, lãng phí tài nguyên máy chủ và gây khó khăn khi debug
Giải pháp Unregistry
-
Chỉ với một lệnh
docker pussh myapp:latest user@serverlà có thể truyền trực tiếp mà không cần kho trung gian -
Không cần cấu hình registry bổ sung, mở cổng, chuẩn bị storage hay đăng ký dịch vụ
-
Quy trình truyền
- Kết nối SSH tunnel tới máy chủ từ xa
- Tạm thời chạy container unregistry
- Kết nối một cổng local ngẫu nhiên với cổng của unregistry
- Dùng docker push để chỉ truyền các layer chưa tồn tại (có thể dùng ngay)
- Kết thúc container unregistry và SSH tunnel
-
Cách làm này đơn giản và hiệu quả như
rsync -
Dự án này được phát triển từ Uncloud nhằm đơn giản hóa sự phức tạp trong quá trình triển khai container lên nhiều Docker host
Ví dụ sử dụng
Truyền image trực tiếp tới môi trường triển khai
- Build ở local rồi push thẳng lên máy chủ production
docker build --platform linux/amd64 -t myapp:1.2.3 .docker pussh myapp:1.2.3 deploy@prod-serverssh deploy@prod-server docker run -d myapp:1.2.3
Pipeline CI/CD
- Hỗ trợ build và triển khai mà không có sự phức tạp của registry
- Có thể dùng truyền trực tiếp trong GitHub Action YAML, v.v.
Homelab, môi trường mạng cô lập không có Internet
- Truyền image an toàn vào mạng tách biệt mà không cần công khai image lên Internet
Cách sử dụng
- Tài khoản người dùng SSH phải có khả năng dùng lệnh docker trên máy từ xa
- Hỗ trợ thêm các tùy chọn như SSH private key hoặc cổng SSH tùy chỉnh
- Cũng hỗ trợ truyền image đa nền tảng (nếu dùng nền tảng containerd)
Yêu cầu
Môi trường local
- Docker CLI (hỗ trợ plugin, 19.03+)
- OpenSSH client
Máy chủ từ xa
- Docker phải được cài đặt và đang chạy
- Người dùng ssh phải có quyền với docker, và khi cần phải có thể chạy
sudo dockerkhông cần mật khẩu - Hiệu năng được cải thiện khi dùng containerd image store
- Cần thêm cấu hình sau vào
/etc/docker/daemon.jsonrồi khởi động lại docker{ "features": { "containerd-snapshotter": true } }
- Cần thêm cấu hình sau vào
Cách dùng nâng cao
Dùng như một registry standalone ở local
- Có thể dễ dàng vận hành unregistry như một local registry mà không cần thêm component nào
- Có thể deploy và push bằng lệnh Docker
Tận dụng tùy chọn SSH tùy chỉnh
- Có thể dùng file cấu hình SSH để thiết lập chi tiết phù hợp với các điều kiện như xác thực bổ sung, cổng, v.v.
Đóng góp và cộng đồng
- Nếu phát hiện lỗi, có thể tạo GitHub issue
- Có thể thảo luận về tính năng, roadmap và chi tiết triển khai trong cộng đồng Discord của Uncloud
Nguồn cảm hứng và các dự án mã nguồn mở tham khảo
- Spegel: lấy cảm hứng từ cách hiện thực registry container image P2P dựa trên containerd
- Docker Distribution: được dùng làm nền tảng cho phần hiện thực registry thực tế
Tóm tắt
- Unregistry là công cụ giúp chuyển Docker image trực tiếp tới máy chủ từ xa một cách nhanh và dễ dàng, loại bỏ gánh nặng thiết lập và quản lý registry
- Mang lại lợi thế mạnh trong nhiều kịch bản như triển khai production, CI/CD, mạng cô lập, v.v.
- Rất phù hợp khi máy chủ và quản trị viên chỉ muốn di chuyển image một cách đơn giản, không cần quy trình rườm rà
1 bình luận
Ý kiến trên Hacker News
Tôi không muốn khuyến nghị dùng Homebrew trên Linux xét về đặc tính máy chủ, ranh giới bảo mật và khía cạnh hardening; dù bản cài cho Linux có tồn tại, nó vẫn tạo cảm giác như được thêm vào sau này, và cách nó hoạt động giống một con chim bồ câu trên bàn cờ hơn là một trình quản lý gói thực thụ
Tôi thấy đây là một ý tưởng hay, rất hợp với những nơi đã dùng sẵn công cụ triển khai kiểu push như Ansible trên hệ thống, và cũng phù hợp như một kỹ thuật triển khai hotfix cho các công ty không có Docker registry được hỗ trợ 24/7; tôi đang tự hỏi nó có tích hợp gọn gàng với hệ công cụ OCI như buildah hay không, hay là cả hai phía đều cần cài đầy đủ Docker; tôi vẫn chưa đào sâu hẳn nhưng dự định sẽ làm, và tôi từng cảm thấy skopeo thiếu khả năng bootstrap registry riêng trên máy chủ từ xa để hoạt động trong kiểu môi trường này
Máy chủ từ xa cần containerd dùng được (Docker và Kubernetes cũng dùng containerd), còn phía client thì bất kỳ thứ gì hiểu được registry API đều có thể dùng (OCI Distribution spec: https://github.com/opencontainers/distribution-spec); Unregistry tái sử dụng mã Docker registry chính thức cho lớp API nên cho cảm giác giống registry của Docker Hub; có thể dùng skopeo, crane, regclient, BuildKit và các công cụ OCI registry khác, nhưng để dùng chúng thì cần chạy trực tiếp unregistry trên host từ xa; lệnh
docker pusshcó vai trò tận dụng Docker cục bộ để tự động hóa toàn bộ luồng này; nó là một script bash nên đáng để xem qua https://github.com/psviderski/unregistry/blob/main/docker-pussh, và cũng rất dễ tự chỉnh sửa theo ý mìnhCả hai bên đều cần docker daemon; cách này dùng một phương thức khéo léo là chia sẻ layer qua ssh giữa hai daemon
Tôi nghĩ lệnh
pusshrất dễ nhớ, tự giải thích tốt, và là một cách chơi chữ hay khi chỉ khác lệnh chuẩn hiện có đúng một ký tự“pussh” cũng ổn, nhưng trong tự động hóa thì một bí danh rõ ràng hơn như “docker push-over-ssh” có lẽ sẽ tốt hơn; người mới nhìn “pussh” lần đầu có thể tưởng là lỗi gõ và gây ra nhầm lẫn không cần thiết; sẽ hay hơn nếu hỗ trợ cả bản ngắn lẫn bản cờ đầy đủ
Có lời giải thích đùa rằng thêm một chữ 's' là để gợi “sssh”, còn người khác thì bảo chỉ là gõ nhầm thôi
Tên “pussh” có thể xung đột với lệnh khác
Tôi nghĩ chức năng như thế này lẽ ra phải tồn tại từ lâu rồi và nó rất ngầu; Docker registry tự thân vẫn có giá trị, nhưng nhìn chung đã trở nên quá phức tạp và xa rời tinh thần hacker
Dự án và cách tiếp cận này rất ấn tượng; tôi đã chán các registry đắt đỏ đến mức từng tự host thứ như Zot(https://zotregistry.dev), nhưng cách này trông có vẻ đơn giản hơn nhiều trong một số trường hợp sử dụng; tôi mong các dịch vụ private registry dễ dùng, giá rẻ và tính phí theo mức sử dụng sẽ phổ biến hơn
Tôi nghĩ Docker lẽ ra ngay từ đầu phải hoạt động như thế này; ý tưởng rất hay
docker save -o my-app.tar my-app:latest, rồi nạp bằngdocker load -i /path/to/my-app.tar; kết hợp với công cụ tự động hóa như ansible thì có thể tự làm điều mà Unregistry đang tự động hóa; tuy nhiên repo GitHub cũng nói rằng cách save/load có nhược điểm là phải truyền toàn bộ image mỗi lần, và việc quản lý image cũng tiện hơn so với quản lý file archiveTôi rất vui khi thấy sự quay trở lại với self-hosting bằng các công cụ như thế này và hệ công cụ SSH; đây có vẻ là một sản phẩm được làm rất tốt, và tôi định sẽ tự thử dùng
Nhờ công cụ này mà tôi mới biết đến dự án uncloud, và nó trông giống một giải pháp triển khai máy chủ kiểu dokku mà tôi từng muốn, nhưng mạnh hơn, nên khá thú vị
Tôi cũng đồng cảm với phản hồi rằng uncloud rất hợp với nhu cầu của mình; nếu có câu hỏi gì thì cứ thoải mái hỏi trên Discord
Cũng nên tham khảo https://skateco.github.io/, một dịch vụ có cách tiếp cận tương tự
Gợi ý Portainer; tôi đang vận hành ổn trên hai máy AWS EC2 bằng Portainer Community Edition và Portainer Agent; tính năng stack (dựa trên docker compose) đặc biệt là điểm mạnh, và trên một EC2 thì portainer agent chạy Caddy dưới dạng container để đảm nhiệm vai trò load balancer và reverse proxy
Đây là một ý tưởng mới mẻ, chỉ là kiểu làm này gắn khá chặt với triển khai dịch vụ nên khi deploy và scale, ví dụ như red/green deployment, sẽ cần thêm logic nhận biết “push”; nghĩ lại thì tôi nhận ra đây chính là dạng vai trò mà uncloud đã hiện thực trong kiến trúc của nó; nhưng cuối cùng vẫn là trade-off, và nếu bạn coi trọng sự đơn giản trên một máy Hetzner VM thì chỉ cần build image cục bộ thôi cũng đã là một lựa chọn đủ hài lòng