Luyện Phỏng Vấn IT — 2000+ Câu Hỏi Phỏng Vấn IT Có Đáp Án 2026

Danh mục

Docker & Kubernetes iconDocker & Kubernetes

Docker đóng gói app cùng runtime, dependencies và cấu hình cần thiết vào container image để chạy nhất quán giữa local, CI và production. Nó giảm lỗi kiểu chạy được trên máy tôi nhưng lỗi trên server.

Điểm cần hiểu trong interview: Docker không phải VM nhẹ. Container chia sẻ kernel host, khởi động nhanh hơn VM, nhưng vẫn cần quản lý image size, security, secrets, network, storage và lifecycle rõ ràng.

Image là template bất biến gồm filesystem layers, metadata và command mặc định. Container là runtime instance được tạo từ image, có process, network namespace và writable layer riêng.

Một image có thể chạy thành nhiều container. Khi container bị xóa, thay đổi trong writable layer mất nếu không dùng volume hoặc lưu dữ liệu ra hệ thống bền vững.

Mỗi instruction trong Dockerfile tạo layer hoặc metadata step. Docker có thể reuse cache nếu instruction và context liên quan không đổi. Vì vậy thứ tự Dockerfile ảnh hưởng tốc độ build rất nhiều.

Pattern phổ biến: copy lockfile/package metadata trước, install dependencies, sau đó mới copy source. Nếu copy toàn bộ source trước khi install, mỗi thay đổi code nhỏ có thể phá cache dependency.

COPY copy file/folder từ build context vào image. ADD cũng copy nhưng có thêm behavior như tự giải nén local tar archives và hỗ trợ URL trong một số trường hợp.

Trong production Dockerfile, ưu tiên COPY vì rõ ràng và ít bất ngờ hơn. Chỉ dùng ADD khi thật sự cần tính năng đặc biệt của nó, ví dụ giải nén tar local có chủ đích.

Bind mount map trực tiếp path từ host vào container, phù hợp local development vì sửa file host thấy ngay trong container. Docker volume do Docker quản lý, phù hợp dữ liệu bền vững như database data.

Bind mount phụ thuộc cấu trúc host và dễ ghi đè file trong image. Volume portable hơn trong Docker context, nhưng vẫn cần backup nếu chứa dữ liệu quan trọng.

Docker Compose mô tả và chạy nhiều containers bằng một file cấu hình, thường dùng cho local development hoặc môi trường nhỏ. Nó giúp app, database, cache, broker chạy cùng network và cấu hình nhất quán.

Compose không thay thế Kubernetes cho orchestration production lớn. Nhưng nó rất hữu ích để onboarding dev, chạy integration tests và mô phỏng dependencies của app.

Kubernetes orchestration containers trên cluster: scheduling, service discovery, rolling update, self-healing, scaling, config/secrets, storage abstraction và API thống nhất để quản lý workloads.

Kubernetes không tự động làm app tốt hơn. App vẫn phải có health endpoint, graceful shutdown, cấu hình resource, observability, database strategy và thiết kế stateless/stateful phù hợp.

Pod là đơn vị deploy nhỏ nhất trong Kubernetes, chứa một hoặc nhiều containers chia sẻ network namespace, volumes và lifecycle. Containers trong cùng Pod có thể gọi nhau qua localhost.

Thông thường một Pod chứa một app container chính. Nhiều containers trong cùng Pod chỉ nên dùng khi chúng cần phối hợp chặt, ví dụ sidecar proxy, log shipper hoặc helper chia sẻ volume.

ConfigMap lưu cấu hình không nhạy cảm như feature flags, endpoint nội bộ hoặc app settings. Secret lưu dữ liệu nhạy cảm như token, password, key, thường được base64-encoded trong manifest và cần bảo vệ bằng RBAC/encryption at rest.

Không nên coi Secret manifest là an toàn nếu commit vào Git plain text. Production nên dùng external secret manager hoặc sealed/encrypted secret workflow phù hợp.

Namespace chia tài nguyên trong cùng cluster theo môi trường, team hoặc domain. Nó giúp quản lý names, RBAC, quotas, network policies và cleanup theo phạm vi.

Namespace không phải ranh giới security tuyệt đối như cluster riêng. Với tenant có yêu cầu isolation mạnh, cần RBAC, NetworkPolicy, Pod Security, quotas và đôi khi cluster tách biệt.

Docker đóng gói app + dependencies vào container để chạy nhất quán ở mọi môi trường — containers nhẹ hơn VMs vì share host OS kernel; docker-compose thiết yếu cho local dev stack.

  • Docker tạo isolated containers chứa app và dependencies.
  • Containers vs VMs: VMs virtualize hardware (heavyweight, có OS riêng, boot minutes); containers share host OS kernel (lightweight, start milliseconds, MB vs GB).
  • Layered filesystem (Union FS): Docker image là stack of read-only layers, container thêm writable layer trên cùng — layers được cache và shared giữa images, kéo image nhanh khi layers đã có.
  • Copy-on-write: khi container modify file từ image layer, Docker copy file lên writable layer trước khi modify.
  • Networking: Bridge network (default, containers communicate qua virtual network); Host network (container dùng host network stack trực tiếp, performance tốt hơn); Overlay network (multi-host, dùng trong Docker Swarm/K8s).
  • Volumes: bind mounts (link host directory vào container cho dev mode); named volumes (Docker-managed storage, persist data cho database); tmpfs mounts (in-memory, không persist). docker-compose: define multi-container apps với YAML — services, networks, volumes; docker-compose up để start toàn bộ stack; essential cho local development với database + app + cache.
  • Production: Docker + Kubernetes (K8s) cho orchestration, auto-scaling, self-healing; Docker + ECS/Cloud Run cho managed container services.

Dockerfile định nghĩa image theo từng layer — đặt COPY package.json + RUN npm install trước COPY source để tận dụng cache; dùng non-root USER và .dockerignore cho security và performance.

  • Dockerfile là script định nghĩa cách build Docker image.
  • Layer caching optimization: Docker cache mỗi instruction layer — nếu layer không thay đổi, dùng cache từ previous build.
  • Đặt instructions ít thay đổi trước: FROM → COPY package*.json → RUN npm install → COPY . . — nếu source code thay đổi nhưng package.json không, Docker reuse cached npm install layer (tiết kiệm 1-2 phút). .dockerignore: exclude node_modules, .git, .env, build artifacts — tránh copy không cần thiết vào build context, giảm build time.
  • Security — non-root user: mặc định container chạy root (risk nếu có vulnerability); thêm RUN addgroup -S appgroup && adduser -S appuser -G appgroup; USER appuser trước CMD — principle of least privilege.
  • Health checks: HEALTHCHECK --interval=30s --timeout=3s CMD wget -q -O /dev/null http://localhost:3000/health || exit 1 — Docker/K8s biết container có healthy không để route traffic.
  • CMD vs ENTRYPOINT: ENTRYPOINT định nghĩa executable không thể override (docker run image args — args được pass vào ENTRYPOINT); CMD là default args có thể override; dùng kết hợp ENTRYPOINT ['node'] CMD ['server.js'] — có thể đổi file chạy nhưng không đổi runtime.
  • Multi-line RUN với && và cleanup: RUN apt-get update && apt-get install -y ... && rm -rf /var/lib/apt/lists/* — clean trong cùng layer tránh layer to.

Docker đóng gói ứng dụng và dependencies vào container, đảm bảo chạy giống nhau trên mọi máy (dev, staging, production).

Frontend dev cần biết:

  1. Dockerfile multi-stage — stage 1 build app, stage 2 chỉ copy file build sang nginx/node, giảm image từ 1GB xuống ~100MB.
  2. docker-compose.yml để chạy frontend + backend + database cùng lúc bằng docker-compose up.
  3. .dockerignore loại node_modules.next tránh copy file thừa

Lưu ý quan trọng: environment variables phải inject lúc runtime (docker run -e), không hardcode vào image vì image dùng chung cho nhiều môi trường.

ENTRYPOINT định nghĩa executable chính của container. CMD cung cấp default arguments hoặc command mặc định có thể override khi chạy container. Dùng cùng nhau khi image có một binary chính và cần default args.

Ví dụ:

ENTRYPOINT ["python", "-m", "app"]
CMD ["--host", "0.0.0.0", "--port", "8000"]

Nếu image là tool CLI, ENTRYPOINT giúp người dùng truyền args ngắn gọn.

Nếu image cần linh hoạt command, chỉ dùng CMD có thể dễ override hơn.

Multi-stage build tách stage build và stage runtime. Stage build chứa compiler, dev dependencies và artifacts tạm; stage runtime chỉ copy output cần chạy. Kết quả là image nhỏ hơn, ít surface security hơn và deploy nhanh hơn.

Ví dụ:

FROM node:22-alpine AS build
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build

FROM node:22-alpine AS runtime
WORKDIR /app
COPY --from=build /app/.next ./.next
COPY --from=build /app/package.json ./package.json
CMD ["node", "server.js"]

Không nên ship cả compiler, source test và cache build nếu runtime không cần.

.dockerignore loại file khỏi build context trước khi gửi cho Docker builder. Nó giúp build nhanh hơn, cache ổn định hơn và tránh đưa secrets, logs, node_modules local hoặc artifacts lớn vào context.

Nên ignore .git, local env files, test output, coverage, build artifacts không cần, dependency folder local và file backup. Nếu build context quá lớn, Dockerfile tốt vẫn có thể build chậm vì builder phải nhận quá nhiều dữ liệu.

Container có network namespace riêng. Service bên trong có thể listen trên port 8000, nhưng host chỉ truy cập được nếu publish port hoặc cùng network có service khác gọi bằng container/service name.

Ví dụ:

bash
docker run --rm -p 8080:8000 my-api

8080:8000 nghĩa là host port 8080 trỏ vào container port 8000.

Trong Docker Compose, services cùng network thường gọi nhau bằng tên service, không gọi localhost.

Env vars phù hợp cấu hình không nhạy cảm hoặc secret đã được inject từ secret manager. Không nên commit .env chứa production secrets. Với Compose, có thể dùng env_file cho local và secrets/file mount cho dữ liệu nhạy cảm.

Ví dụ Compose local:

yaml
services:
  api:
    image: my-api
    env_file:
      - .env.local
    environment:
      NODE_ENV: development

Production nên dùng secret manager của platform, rotation policy và least privilege.

Image không được chứa secret baked-in ở build time.

HEALTHCHECK cho Docker biết container process còn sống chưa đủ, app có thật sự healthy hay không. Nó có thể gọi endpoint nội bộ, kiểm tra port hoặc chạy command nhẹ.

Ví dụ:

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:8000/health || exit 1

Healthcheck không nên nặng hoặc phụ thuộc hệ thống ngoài quá xa.

Với Kubernetes, thường dùng probes thay vì chỉ dựa vào Docker healthcheck.

Tag là tên tham chiếu dễ đọc như app:1.2.0 hoặc app:latest, có thể bị trỏ lại image khác. Digest là content-addressed reference theo hash, bất biến theo nội dung image.

Production nên tránh phụ thuộc latest. Dùng version tag rõ ràng và trong môi trường yêu cầu reproducibility cao có thể pin digest để đảm bảo đúng artifact được deploy.

Container app nên log ra stdout/stderr để platform thu thập, thay vì ghi file log local khó gom. State quan trọng nên lưu ở database, object storage, queue hoặc volume được backup, không phụ thuộc writable layer của container.

Container nên được thiết kế stateless càng nhiều càng tốt để scale, restart và rolling update dễ hơn. Nếu container cần state, phải có strategy rõ cho persistence, backup, migration và recovery.

Deployment quản lý stateless replicas và rolling updates, tạo ReplicaSet phía dưới. ReplicaSet đảm bảo số Pod replicas nhưng hiếm khi tạo trực tiếp. StatefulSet dùng cho workloads cần identity ổn định, persistent storage và thứ tự rollout. DaemonSet chạy một Pod trên mỗi node phù hợp, ví dụ log agent hoặc node exporter.

Chọn workload theo lifecycle và state. API stateless dùng Deployment, database/queue stateful cân nhắc StatefulSet hoặc managed service, node-level agent dùng DaemonSet.

ClusterIP expose service nội bộ trong cluster. NodePort mở port trên nodes. LoadBalancer yêu cầu cloud/load balancer provider tạo load balancer bên ngoài. ExternalName map service sang DNS name ngoài cluster.

Ví dụ ClusterIP:

yaml
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 8000

Phần quan trọng là selector phải match labels của Pods, nếu không Service sẽ không có endpoints.

Ingress định nghĩa rule HTTP/HTTPS để traffic từ ngoài cluster đi vào Services bên trong, thường dựa trên host/path. Ingress chỉ là Kubernetes resource; cần Ingress Controller như nginx, Traefik hoặc cloud controller để thực thi rule.

Khác với Service LoadBalancer expose một Service trực tiếp, Ingress thường gom nhiều route/domain qua một entrypoint và xử lý TLS, path routing, host routing. Cần cấu hình DNS, certificate và controller đúng thì traffic mới vào được app.

Readiness probe quyết định Pod đã sẵn sàng nhận traffic chưa. Liveness probe quyết định container có cần restart không. Startup probe bảo vệ app khởi động chậm để liveness không giết quá sớm.

Ví dụ:

yaml
readinessProbe:
  httpGet:
    path: /ready
    port: 8000
livenessProbe:
  httpGet:
    path: /health
    port: 8000
startupProbe:
  httpGet:
    path: /health
    port: 8000
  failureThreshold: 30
  periodSeconds: 2

Không dùng liveness để check dependency xa như database nếu lỗi tạm thời sẽ khiến app restart liên tục.

Requests là lượng tài nguyên scheduler dùng để đặt Pod lên node. Limits là trần runtime container được phép dùng. CPU limit có thể gây throttling; memory vượt limit thường bị OOMKilled.

Ví dụ:

yaml
resources:
  requests:
    cpu: 250m
    memory: 256Mi
  limits:
    cpu: 1000m
    memory: 512Mi

Không đặt requests quá thấp để nhồi node nếu app latency-sensitive.

Cần đo thực tế bằng metrics rồi điều chỉnh.

HPA tự tăng/giảm số replicas dựa trên metrics như CPU, memory hoặc custom/external metrics. Nó cần Deployment/scale target, metrics pipeline và requests phù hợp để tính utilization có nghĩa.

Ví dụ:

bash
kubectl autoscale deployment api --cpu-percent=70 --min=2 --max=10

HPA không tự giải quyết cold start, DB bottleneck hoặc queue backlog nếu metric sai.

Với queue-based workloads, custom metrics như queue length thường tốt hơn CPU.

Deployment rolling update thay Pods cũ bằng Pods mới dần dần. Để ít downtime cần readiness probe đúng, maxUnavailable thấp, maxSurge phù hợp, graceful shutdown và app xử lý SIGTERM.

Ví dụ:

yaml
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 0
    maxSurge: 1

Nếu readiness probe báo ready quá sớm hoặc shutdown không drain request, rolling update vẫn có thể gây lỗi dù Kubernetes strategy nhìn đúng.

Labels là key-value metadata gắn lên objects. Selectors cho Service, Deployment, NetworkPolicy hoặc kubectl chọn đúng objects. Nếu labels/selectors sai, Service không route traffic hoặc Deployment không quản lý Pods đúng.

Ví dụ:

yaml
metadata:
  labels:
    app: api
    tier: backend
spec:
  selector:
    matchLabels:
      app: api

Label taxonomy nên nhất quán từ đầu: app, component, version, environment, team.

Đừng dùng label tùy hứng cho routing/automation quan trọng.

PersistentVolume là storage resource trong cluster. PersistentVolumeClaim là yêu cầu storage từ workload. StorageClass định nghĩa cách provision storage động như disk type, reclaim policy hoặc provisioner.

Ví dụ PVC:

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
spec:
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 10Gi

Stateful app cần backup, restore, resize và migration strategy.

PVC chỉ cấp storage, không tự giải quyết durability của dữ liệu.

Job chạy task đến khi hoàn tất, phù hợp migration, batch processing, one-off import. CronJob tạo Jobs theo lịch, phù hợp cleanup định kỳ, report hoặc sync data.

Ví dụ CronJob:

yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cleanup
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: cleanup
              image: my-cleanup:1.0.0

Cần cấu hình concurrency policy, retry/backoff và deadline để tránh job chồng lên nhau hoặc chạy vô hạn.

Init container chạy xong trước app containers. Nó phù hợp chuẩn bị file/config, chờ dependency nội bộ, chạy migration nhẹ có kiểm soát hoặc setup permission cho volume.

Ví dụ:

yaml
initContainers:
  - name: wait-db
    image: busybox:1.36
    command: ["sh", "-c", "until nc -z db 5432; do sleep 2; done"]

Không nên dùng init container để che lỗi kiến trúc như app không retry được dependency.

App production vẫn nên tự retry/backoff hợp lý.

imagePullPolicy quyết định kubelet kéo image khi nào: Always, IfNotPresent, hoặc Never. Nếu dùng tag mutable như latest, behavior dễ khó đoán và rollback khó hơn.

Production nên dùng immutable version tags hoặc digest, private registry có auth rõ ràng, image scanning trong CI và retention policy. Khi rollout, đổi tag/digest trong manifest để Kubernetes tạo ReplicaSet mới.

Helm là package manager/template engine cho Kubernetes, phù hợp chart tái sử dụng, values theo môi trường và dependency packaging. Kustomize patch YAML gốc bằng overlays, không dùng template language, tích hợp sẵn với kubectl apply -k.

Helm mạnh khi phân phối app/platform package. Kustomize đơn giản khi team muốn giữ manifest gần Kubernetes YAML chuẩn. Nhiều tổ chức dùng cả hai: Helm cho vendor charts, Kustomize hoặc GitOps overlay cho cấu hình môi trường.

Các lệnh cơ bản: xem Pod, describe events, logs container, exec vào container nếu có shell, xem rollout và endpoints Service. Thứ tự tốt là kiểm status, events, logs, config, network, resource.

Ví dụ:

bash
kubectl get pods -n app
kubectl describe pod api-123 -n app
kubectl logs api-123 -n app --previous
kubectl get endpoints api -n app

--previous hữu ích khi container restart.

Nếu image tối giản không có shell, dùng ephemeral debug container khi policy cho phép.

Docker Compose phù hợp local development, integration tests và môi trường nhỏ cần chạy nhiều services nhanh. Kubernetes phù hợp production hoặc platform cần orchestration, scaling, self-healing, rollout, service discovery và policy mạnh.

Không cần đưa mọi dự án nhỏ lên Kubernetes nếu team chưa cần complexity đó. Nhưng app đã container hóa tốt bằng Docker thường dễ đưa vào Kubernetes hơn nếu image stateless, config qua env/secret, health endpoints và logs chuẩn.