Kernel Images: Chạy Chrome trên Cloud cho Web Automation và AI Agent
Browsers-as-a-service cho automation và AI agent - sandboxed Chrome, live view, video replay, chạy được cả trên Docker lẫn unikernel.
Nguyễn Nhật Long
@nguyennhatlong1303
Mình đang làm một dự án cần scrape dữ liệu từ mấy trang web có JavaScript nặng, lại cần chạy headful browser (không phải headless) để bypass một số anti-bot detection. Setup local thì ổn, nhưng khi deploy lên server thì bắt đầu đau đầu: cài Chrome trên Linux server, manage dependencies, handle session isolation giữa các request, rồi còn phải debug khi browser crash mà không có GUI để nhìn vào...
Rồi mình tìm thấy kernel-images. Cái project này giải quyết đúng cái pain point đó - Browsers-as-a-service cho automation và web agent.
Kernel Images là gì và nó làm được gì
Về cơ bản, Kernel cung cấp sandboxed Chrome browser mà bạn có thể connect vào từ Playwright hoặc Puppeteer thông qua Chrome DevTools Protocol (CDP). Thay vì tự manage browser lifecycle trên server của mình, bạn chỉ cần connect tới endpoint của Kernel là xong.
Nhưng cái thú vị không chỉ ở đó. Project này còn có:
- Remote GUI / Live view streaming: Bạn có thể xem browser đang làm gì theo thời gian thực, không cần SSH vào server rồi chạy VNC hay gì đó phức tạp
- Configurable live view: Set read-only mode, custom window dimensions - tiện cho việc monitoring mà không muốn ai đó vô tình click lung tung
- Video replay: Record lại toàn bộ session, sau này debug rất tiện, đặc biệt khi automation fail ở production mà bạn không có mặt để xem
Theo kinh nghiệm của mình, cái video replay này cực kỳ có giá trị. Không ít lần automation chạy ngon trên local nhưng fail ở production vì một popup xuất hiện bất ngờ hay layout thay đổi - có video replay thì debug trong vài phút thay vì ngồi đoán mò.
Hai cách chạy: Docker và Unikernel
Đây là phần mình thấy khá thú vị về mặt kỹ thuật. Kernel Images hỗ trợ hai deployment mode với trade-off khá khác nhau:
Cái unikernel implementation build on top của base Docker image, nên không phải hai thứ hoàn toàn tách biệt - nó kế thừa và extend lên.
| Docker | Unikernel (Unikraft) | |
|---|---|---|
| Setup complexity | Thấp, quen thuộc | Cao hơn, cần Kraft CLI |
| Cold start | Vài giây | **< 20ms** |
| Resource khi idle | Vẫn consume RAM/CPU | Gần như 0 (sleep mode) |
| Session snapshot | Không có | Có - restore y nguyên state |
| Phù hợp với | Dev, testing, self-hosted | Production, high-scale, latency-sensitive |
Chạy với Docker - nhanh nhất để thử
Nếu bạn chỉ muốn test nhanh, Docker là con đường đơn giản nhất:
1# Clone repo về2git clone https://github.com/kernel/kernel-images3cd kernel-images45# Build image6cd images/chromium-headful7IMAGE=kernel-docker ./build-docker.sh89# Run với WebRTC enabled (để dùng live view)10IMAGE=kernel-docker ENABLE_WEBRTC=true ./run-docker.sh
Sau khi container chạy lên, bạn có thể connect Playwright vào CDP endpoint:
1const { chromium } = require('playwright');23// Connect tới browser đang chạy trong container4const browser = await chromium.connectOverCDP('ws://localhost:9222');5const context = await browser.newContext();6const page = await context.newPage();78await page.goto('https://example.com');9await page.screenshot({ path: 'screenshot.png' });1011await browser.close();
Với Puppeteer thì tương tự:
1const puppeteer = require('puppeteer-core');23const browser = await puppeteer.connect({4 browserWSEndpoint: 'ws://localhost:9222',5});67const page = await browser.newPage();8await page.goto('https://example.com');910const title = await page.title();11console.log('Page title:', title);1213await browser.disconnect();
Anh em lưu ý: dùng connectOverCDP hoặc connect thay vì launch - vì browser đã được launch sẵn trong container rồi, mình chỉ connect vào thôi.
Deploy lên Unikernel - đây mới là phần hay
Unikernel là một concept khá niche nhưng rất powerful cho workload kiểu này. Thay vì chạy full OS trong container, unikernel chỉ bundle đúng những gì application cần - kết quả là boot cực nhanh và footprint cực nhỏ.
Kernel dùng Unikraft làm nền tảng. Setup cần thêm vài bước:
Bước 1: Cài Kraft CLI
1curl -sSfL https://get.kraftkit.sh | sh
Bước 2: Config credentials
1export UKC_METRO=<region> # ví dụ: fra0, lon1...2export UKC_TOKEN=<secret> # lấy từ Unikraft Cloud console
Bước 3: Build unikernel image
1IMAGE=your-ukc-username/chromium-headless-test:latest \2 images/chromium-headless/build-unikernel.sh
Bước 4: Deploy
1# Headless version2IMAGE=your-ukc-username/chromium-headless-test:latest \3 images/chromium-headless/run-unikernel.sh45# Hoặc headful version (có GUI)6IMAGE=your-ukc-username/chromium-headful-test:latest \7 VOLIMPORT_PREFIX=official \8 images/chromium-headful/run-unikernel.sh
Khi deploy xong, Kraft CLI sẽ print ra thông tin instance:
1Deployed successfully!2│3├───────── name: kernel-cu4├───────── uuid: 0cddb958...5├──────── metro: fra06├──────── state: starting
Cái "sleep mode" và session snapshot - killer feature
Mình thấy cái này hay ở chỗ: khi unikernel không có network activity, nó tự động vào standby mode và consume gần như 0 resource. Nhưng quan trọng hơn là state được snapshot lại.
Nghĩa là gì? Khi browser "ngủ", toàn bộ state của nó - auth cookies, local storage, đang mở tab nào, scroll position, zoom level - được lưu lại. Khi có request mới đến, nó restore lại y nguyên trạng thái đó trong vòng dưới 20ms.
Đây là game changer cho một số use case:
- AI agent workflows: Agent đang ở giữa một flow phức tạp, cần pause và resume sau - không phải login lại từ đầu
- Multi-step automation: Automation cần chờ email confirmation hay approval từ người dùng - browser sleep trong lúc chờ, resume khi có trigger
- Session reuse: Nhiều task cần share cùng browser state (đã login, đã điền form một phần) - snapshot và restore thay vì setup lại từ đầu
Với cold restart dưới 20ms, bạn có thể design hệ thống theo kiểu event-driven: mỗi event trigger một browser instance, xử lý xong thì sleep, không cần giữ browser chạy idle 24/7.
Dùng cho AI Agent - đây là trend đang lên
Repo này mention explicitly về "web agents" - và đây là use case mình nghĩ sẽ ngày càng phổ biến. Với sự phát triển của các framework như LangChain, AutoGen, hay CrewAI, ngày càng nhiều AI agent cần khả năng interact với browser để:
- Fill form, click button, navigate website
- Extract thông tin từ trang web dynamic
- Thực hiện multi-step workflow trên web app
Thay vì mỗi agent tự manage browser của nó (rất messy khi scale), bạn có thể dùng Kernel như một browser pool - agent request một browser session, làm việc, rồi trả lại.
1# Ví dụ với Python Playwright2from playwright.async_api import async_playwright34async def run_agent_task(task: str, browser_endpoint: str):5 async with async_playwright() as p:6 # Connect tới managed browser7 browser = await p.chromium.connect_over_cdp(browser_endpoint)8 page = await browser.new_page()910 # Agent logic ở đây11 await page.goto('https://target-site.com')12 # ... LLM decides what to do next ...1314 await browser.close()
Mình thấy pattern này clean hơn nhiều so với việc spawn browser process trực tiếp trong application code.
Một vài điểm cần lưu ý khi dùng
Project này vẫn đang active develop (176 commits, 44 pull requests đang open). Một số thứ cần để ý:
Về networking: Khi chạy Docker locally, đảm bảo port 9222 (CDP) và port cho WebRTC không bị conflict hay firewall block.
Về resource: Headful Chrome tốn RAM đáng kể - tính khoảng 200-500MB per instance tùy workload. Nếu chạy nhiều concurrent session, cần plan capacity cẩn thận.
Về security: Browser sandbox trong Docker không hoàn toàn isolate như VM. Nếu bạn đang build tool cho người dùng untrusted, cần review kỹ security model.
Về headless vs headful: Repo có cả hai variant. Headless nhanh hơn và tốn ít resource hơn, nhưng một số trang web detect và block headless browser. Headful thường bypass được tốt hơn nhưng cần nhiều resource hơn.
Self-hosted hay dùng hosted service?
Kernel có cả hosted service (sign up tại link trong repo) và self-hosted option qua Docker/unikernel. Trade-off khá rõ:
Với team nhỏ hoặc side project, hosted service có thể cost-effective hơn vì không cần ops overhead. Với enterprise hoặc có compliance requirement, self-hosted sẽ là lựa chọn tất nhiên.
| Self-hosted | Kernel Hosted | |
|---|---|---|
| Control | Toàn quyền | Limited |
| Cost | Infrastructure cost | Subscription/usage fee |
| Maintenance | Tự lo | Kernel lo |
| Scalability | Tự scale | Managed auto-scale |
| Setup time | Vài giờ | Vài phút |
Mình đang lean về self-hosted vì dự án của mình có requirement về data locality - không muốn browser traffic đi qua third-party infrastructure. Nhưng nếu bạn đang prototype hoặc cần ship nhanh, hosted service để thử trước là hợp lý.
Repo hiện có 905 stars và đang grow - community khá active với 44 PRs. Nếu bạn đang làm gì đó liên quan đến web automation, AI agent, hay cần managed browser infrastructure, đây là project đáng để bookmark và theo dõi.
Nguyễn Nhật Long
@nguyennhatlong1303Nguyễn Nhật Long is a Senior Frontend Engineer and Frontend Team Leader with 7 years of experience building real-time fintech platforms. Specializing in React, Next.js, TypeScript, and React Native, shipping 10+ products across Web, Mobile, Telegram Mini-Apps, and Web3.
Thấy hay? Chia sẻ cho bạn bè!