Inside the Driver Container: A First Look

Tớ tò mò mở Web Terminal trên một Dedicated all-purpose compute và lục lọi xem mình đang đứng ở đâu, filesystem được tổ chức thành những vùng nào, mỗi vùng phục vụ việc gì.

What I Actually Did

Thực ra câu chuyện bắt đầu có thể đơn giản hơn bạn nghĩ.

Trước đây, tớ từng triển khai Data Platform as a Service và Notebook Interactive Service, đồng thời gặp không ít vấn đề mà tớ đã ghi lại trong các note về Stack Intergration. Vì thế, tớ khá tò mò và thực sự ngưỡng mộ cách Databricks xây dựng trải nghiệm platform của họ. Có nhiều thứ khác xa với những gì tớ từng nghĩ, từng biết và đôi khi bị đóng khung vào.

Cho đến khi trực tiếp trở thành user của Databricks, tớ mới hiểu rõ hơn cảm giác một platform được tích hợp sâu đến mức nào. Databricks hỗ trợ người dùng rất nhiều thứ, gần như đến tận răng. Dĩ nhiên, không phải tính năng nào cũng hoàn hảo, nhưng tớ hiểu rằng xây dựng một Platform Service để phục vụ nhiều loại workload luôn đi kèm những đánh đổi giữa tính tổng quát, mức độ kiểm soát và trải nghiệm người dùng.

Nhưng khi chuyển sang Dedicated access mode và mở Web Terminal, tớ bắt đầu nhìn thấy nhiều chi tiết thú vị hơn mong đợi. Nó mở ra một góc quan sát khác về môi trường thực thi phía sau một Spark application trên Databricks.

Và tình cờ tớ tìm thấy tính năng Web Terminal trên All-purpose clusters. Ban đầu, tớ không thấy tính năng này có gì đặc biệt, bởi phần lớn các cụm tớ thường sử dụng đều ở Standard access mode. Tuy nhiên, khi chuyển sang Dedicated mode, tớ mở ra và khá ngạc nhiên rẳng tớ tìm được nhiều thứ hay ho, trầm trồ hơn tớ nghĩ. Chính lúc này, tớ cũng mới thực sự nghiêm túc đi phân biệt rõ ràng sự khác nhau giữa cách Spark được provide trên các notebook ở các mode khác nhau như ở Databricks Interactive Runtime.

Để tìm hiểu, tớ thực hiện một số thao tác quan sát trên một All-purpose compute ở Dedicated access mode:

  1. Khởi tạo compute và start như bình thường.
  2. Attach notebook, chạy một số cell PySpark hoặc Scala để runtime thực sự đi vào trạng thái hoạt động, với SparkContext và language session đã được khởi tạo.
  3. Mở Web Terminal của compute và chỉ quan sát: liệt kê thư mục, đọc cấu hình, script, log, kiểm tra process và các port đang mở.

Tớ không gọi API control plane, không decompile và không sửa đổi runtime hay không decompile bất cứ thứ gì hoặc thực sự mở connection tới bất cứ đâu. Note này là bản ghi lại những gì tớ quan sát được qua những command cơ bản như ls, cùng các giả thuyết về môi trường thực thi mà Spark application và JVM driver đang hoạt động bên trong. Mục tiêu là nhận diện cấu trúc của driver container, các process, file cấu hình, script, log và những thành phần runtime có thể quan sát được từ môi trường này.

Đây chưa phải là phần giải thích toàn bộ về kiến trúc, vòng đời của một interactive session hay cơ chế thực thi command trên Databricks, những phần đó tớ sẽ thực hiện tìm hiểu ở các note khác. Thay vì thế, tớ muốn bắt đầu từ một câu hỏi cơ bản hơn trước khi đọc process tree hay cố gắng hiểu tên một class: tớ thực sự đang đứng ở đâu và nơi tớ đứng đang thực sự có những gì?

Where Am I Standing?

Web Terminal là một product surface được Databricks document chính thức: shell chạy với quyền root bên trong container của driver node, và được proxy qua port 7681 trên Spark driver. Nghe thì phức tạp, nhưng trước khi bắt đầu lục lọi file, config hay process, tớ nghĩ mình cần xác định rõ một chuyện: tớ đang đứng ở đâu trong toàn bộ runtime của Databricks?

Where am I standing — Web Terminal vantage pointControl plane · not visible from hereControl planenot visible from hereYOU ARE HERE · Web Terminal · root shell · :7681 · Driver container · root, but only in hereYOU ARE HEREWeb Terminal · root shell · :7681FUSE mounts · /dbfs · /Volumes · /Workspace · Driver container · root, but only in hereFUSE mounts/dbfs · /Volumes · /WorkspaceRuntime image · scripts · jars · conf · logs · Driver container · root, but only in hereRuntime imagescripts · jars · conf · logsLive processes · Chauffeur · DriverDaemon · kernel · Driver container · root, but only in hereLive processesChauffeur · DriverDaemon · kernelIAM token readiness · :5657 · Owner unknown · container, sidecar or off-node?IAM token readiness:5657Storage proxy · :9210 · role unclear · Owner unknown · container, sidecar or off-node?Storage proxy:9210 · role unclearSafeSpark sandbox · :7100 · :8000 · Owner unknown · container, sidecar or off-node?SafeSpark sandbox:7100 · :8000Worker nodes · executors · seen via Spark onlyWorker nodesexecutors · seen via Spark onlyproxy :7681ls · catps · ss · /procport seen, no PIDhypothesisUDF RPCSpark :7077Driver node (cloud VM) · seen indirectlyDriver container · root, but only in hereOwner unknown · container, sidecar or off-node?LegendInside the container 3You are here 1Endpoint, owner unknown 3Not visible from here 2
Chỗ tớ đứng khi mở Web Terminal

Mặc dù có thể có thông tin về một số port và client gọi tới một số servcie bên ngoài. Tuy nhiên không có bằng chứng chính xác về việc nó được dựng trên node, bên ngoài container hay hẳn bên ngoài nốt. Còn có một điều cần nhớ là tớ đang quan sát từ bên trong driver container, không phải toàn bộ cluster. Quyền root ở đây cũng chỉ nằm trong phạm vi container đó. Những gì thuộc về host, worker hay control plane thì vẫn cần những cách khác để xác minh.

First Look: How the Filesystem Is Organized

Lần ls đầu tiên không cho ra một "thư mục Spark" đơn lẻ. Thứ hiện ra là vài vùng khá tách biệt, mỗi vùng phục vụ một việc. Gom lại theo những gì tớ đã thực sự mở ra đọc:

/databricks/
├─ spark/
│  ├─ scripts/nimbus/dbr_entry_point.py   bootstrap: điểm vào khi platform giao node cho DBR
│  ├─ dbconf/hadoop/core-site.xml         filesystem scheme → implementation của Databricks
│  └─ logs/                               log của Spark (master, driver-side)
├─ driver/
│  ├─ conf/dynamicSparkConfig.conf.json   config động, chủ yếu ở scope session
│  └─ preload_class.lst                   danh sách class preload để giảm latency lúc đầu
├─ chauffeur/
│  └─ logs/                               log của lớp supervisor đứng ngoài Driver JVM
├─ jars/                                  Spark + com.databricks.* đóng chung thành runtime bundle
├─ hadoop-safety-jars/                    jar shadow class Hadoop gốc, chặn bypass filesystem
└─ common/conf/deploy.conf                config deploy chung của runtime

/dbfs   /Volumes   /Workspace              FUSE mount: path quen thuộc, phía sau là service boundary
/proc                                      trạng thái sống: PID, cmdline, parent–child

Sơ đồ này là cách tớ gom lại sau khi đọc, không phải liệt kê đầy đủ. Nhưng chỉ chừng đó đã đủ thấy runtime chia thành mấy loại thư mục rất khác nhau:

VùngVí dụ đã thấyPhục vụ việc gìĐọc sâu ở đâu
Bootstrapspark/scripts/nimbus/, các start_*.shBiến một node vừa được giao thành runtime: chuẩn bị disk, chạy init script, mở service nềnLifecycle
Runtime codejars/, hadoop-safety-jars/, preload_class.lstSpark đã được fork/bundle cùng code Databricks, cộng lớp shadow để chặn đường vòngArchitecture
Configcore-site.xml, dynamicSparkConfig.conf.json, deploy.confConfig theo process, allocation và session; một phần bị pin để user không ghi đèArchitecture
Service state & logchauffeur/logs/, spark/logs/Dấu vết của các service sống lâu: start, health, command, lỗiLifecycle
Data path/dbfs, /Volumes, /WorkspaceCho open() / pandas dùng path quen thuộc, nhưng mỗi lần đọc có thể đi qua service và credential boundaryArchitecture
Live state/proc, port đang listenThứ gì đang chạy ngay lúc này, ai sinh ra aiArchitecture

Điều đáng chú ý nhất ở bước này: thư mục của DBR không tổ chức theo "Spark vs phần còn lại". Spark nằm lẫn trong jars/ cùng com.databricks.*; config Hadoop chuẩn bị redirect sang filesystem của Databricks; còn có hẳn một thư mục log riêng cho chauffeur, một thứ không tồn tại trong Spark open-source.

Second Look: What Is Running Right Now

Filesystem cho biết runtime được cài gì. Để biết runtime đang làm gì, tớ chuyển sang nhìn trạng thái sống: port nào đang listen, PID nào đứng sau port đó, rồi dùng ps, jps và /proc/<pid>/cmdline để lần ngược parent–child.

Kết quả rút gọn:

dbr_entry_point.py
  ├─ ChauffeurDaemon          supervisor + health/control API (:6060)
  │    └─ start_driver.sh
  │         └─ DriverDaemon   JVM giữ Spark driver sống lâu, nhận notebook command
  │              └─ Python kernel (ipykernel, chạy dưới user spark-<uuid>)
  └─ Spark Master             :7077, để worker đăng ký và executor được launch

Chỉ riêng cây này đã nói một điều mà notebook che đi: cái mình gọi là "driver" thật ra là ít nhất ba tầng process, có supervisor đứng ngoài, có JVM giữ SparkContext, và Python code của user chạy ở process riêng với user Linux quyền thấp hơn root. Trang Runtime Architecture from Process Signals đi lại bước này chi tiết, kèm bảng port.

Putting It Together: Six Kinds of Surface

Ghép filesystem và process lại, tớ tạm chia mọi thứ thấy được thành sáu nhóm theo việc chúng làm, không theo tên. Đây là mental map để đọc các trang sau, không phải sơ đồ chính thức của Databricks.

  1. Environment & bootstrap: dbr_entry_point.py, start script, init script, mount, local disk. Trả lời câu hỏi vì sao cluster đã "Running" mà notebook vẫn chưa dùng được ngay.
  2. Long-lived services: Chauffeur, DriverDaemon, Spark Master. Giữ Spark application sống qua nhiều cell, nhiều notebook, thay vì một lần spark-submit rồi thoát.
  3. Language sessions: Scala REPL trong Driver JVM, Python kernel ở process riêng. Mỗi notebook có namespace riêng nhưng mượn chung một SparkContext.
  4. Code & config: jars/, hadoop-safety-jars/, config theo scope. Nơi Databricks đổi behavior của Spark và khóa lại những gì user không được ghi đè.
  5. Storage & credential path: core-site.xml redirect scheme, FUSE mount, filesystem wrapper. Spark API, SQL table và open() của Python không nhất thiết đi cùng một đường.
  6. Health, load & observability: chauffeur/logs, spark/logs, health endpoint, load signal. Cách runtime báo lại cho platform biết nó đang ready, bận hay hỏng.

Gặp một tên lạ ở trang sau, chỉ cần hỏi trước nó thuộc nhóm nào trong sáu nhóm này.

What This Terminal Cannot Show

Thấy được hoặc suy ra được từ terminalNằm ngoài tầm nhìn
process, port, startup script, config, local health call, cấu trúc thư mụccontrol-plane scheduler và request flow chính xác
Spark Master và bề mặt deploy worker/executorcách cloud VM, network, disk được provision
session và application signal phía drivertrạng thái process phía worker, nội bộ executor
filesystem wrapper, endpoint liên quan credentialpolicy governance gốc và topology cấp credential
field load/health runtime để lộ rathuật toán autoscaling, threshold, cadence, quota

Bảng này không làm note yếu đi. Nó tách hai việc: học từ những gì thật sự nhìn thấy, và không kể câu chuyện control plane quá tự tin chỉ vì tên process nghe hợp lý.

Where to Go Next

My Summary

Trước khi mở terminal, tớ hình dung interactive compute là cluster + Driver + executor, và notebook bằng cách nào đó attach vào. Sau lần nhìn quanh đầu tiên, hình ảnh đúng hơn là: tớ đang đứng root trong driver container của một môi trường runtime dựng sẵn, nơi thư mục được chia thành bootstrap, runtime code, config, log, mount dữ liệu và trạng thái sống. Spark chỉ là lõi compute ở giữa.

Trang này chưa giải thích architecture. Nó chỉ trả lời "mình đang ở đâu, xung quanh có gì" để các trang sau không biến thành danh sách tên process lạ.

On this page