Nâng cao
7 phút đọc4 tháng 6, 2026305

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.

N

Nguyễn Nhật Long

@nguyennhatlong1303

Kernel Images: Chạy Chrome trên Cloud cho Web Automation và AI Agent

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.

DockerUnikernel (Unikraft)
Setup complexityThấp, quen thuộcCao hơn, cần Kraft CLI
Cold startVài giây**< 20ms**
Resource khi idleVẫn consume RAM/CPUGần như 0 (sleep mode)
Session snapshotKhông cóCó - restore y nguyên state
Phù hợp vớiDev, testing, self-hostedProduction, 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:

Terminal
1# Clone repo về
2git clone https://github.com/kernel/kernel-images
3cd kernel-images
4
5# Build image
6cd images/chromium-headful
7IMAGE=kernel-docker ./build-docker.sh
8
9# 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:

JavaScript
1const { chromium } = require('playwright');
2
3// Connect tới browser đang chạy trong container
4const browser = await chromium.connectOverCDP('ws://localhost:9222');
5const context = await browser.newContext();
6const page = await context.newPage();
7
8await page.goto('https://example.com');
9await page.screenshot({ path: 'screenshot.png' });
10
11await browser.close();

Với Puppeteer thì tương tự:

JavaScript
1const puppeteer = require('puppeteer-core');
2
3const browser = await puppeteer.connect({
4 browserWSEndpoint: 'ws://localhost:9222',
5});
6
7const page = await browser.newPage();
8await page.goto('https://example.com');
9
10const title = await page.title();
11console.log('Page title:', title);
12
13await 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

Terminal
1curl -sSfL https://get.kraftkit.sh | sh

Bước 2: Config credentials

Terminal
1export UKC_METRO=<region> # ví dụ: fra0, lon1...
2export UKC_TOKEN=<secret> # lấy từ Unikraft Cloud console

Bước 3: Build unikernel image

Terminal
1IMAGE=your-ukc-username/chromium-headless-test:latest \
2 images/chromium-headless/build-unikernel.sh

Bước 4: Deploy

Terminal
1# Headless version
2IMAGE=your-ukc-username/chromium-headless-test:latest \
3 images/chromium-headless/run-unikernel.sh
4
5# 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:

TEXT
1Deployed successfully!
2
3├───────── name: kernel-cu
4├───────── uuid: 0cddb958...
5├──────── metro: fra0
6├──────── 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.

Python
1# Ví dụ với Python Playwright
2from playwright.async_api import async_playwright
3
4async def run_agent_task(task: str, browser_endpoint: str):
5 async with async_playwright() as p:
6 # Connect tới managed browser
7 browser = await p.chromium.connect_over_cdp(browser_endpoint)
8 page = await browser.new_page()
9
10 # Agent logic ở đây
11 await page.goto('https://target-site.com')
12 # ... LLM decides what to do next ...
13
14 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-hostedKernel Hosted
ControlToàn quyềnLimited
CostInfrastructure costSubscription/usage fee
MaintenanceTự loKernel lo
ScalabilityTự scaleManaged auto-scale
Setup timeVà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.

NN

Nguyễn Nhật Long

@nguyennhatlong1303

Nguyễ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è!