Ngân hàng đề — Google Cloud Associate Cloud Engineer
Tìm thấy 449 câu.
- A Labels
- B Guest attributes
- C Namespaces
- D key-value pairs
- E instance attributes
Xem giải thích
Đáp án
A và C — Labels và Namespaces.
Vì sao đúng
Đề hỏi cách phân biệt mức sử dụng tài nguyên theo đội và theo phòng ban trong một cụm GKE. Kubernetes có đúng hai cơ chế cho việc này, và chúng bổ sung cho nhau.
⚠ Điểm mấu chốt — namespace phân vùng, label phân loại:
NAMESPACE
↓
Chia CỤM thành các vùng ảo
↓
→ mỗi đội một namespace
→ ĐẶT HẠN MỨC được: ResourceQuota
→ PHÂN QUYỀN được: RBAC theo namespace
→ tên tài nguyên chỉ cần duy nhất
TRONG namespace
LABEL
↓
Cặp khoá-giá trị gắn vào ĐỐI TƯỢNG
team: data-platform
dept: engineering
env: production
↓
→ cắt lớp theo NHIỀU CHIỀU
→ xuyên qua ranh giới namespace
⚠ Vì sao cần cả hai để phân tích chi phí:
GKE cost allocation
↓
Bật tính năng này → billing export
có thêm cột namespace và label
↓
Truy vấn BigQuery:
GROUP BY namespace → chi phí theo ĐỘI
GROUP BY labels.dept → chi phí theo PHÒNG BAN
↓
→ namespace cho ranh giới cứng
→ label cho các chiều mềm
⚠ Namespace còn cho phép ĐẶT TRẦN, label thì không:
ResourceQuota trong namespace:
requests.cpu: "20"
requests.memory: 40Gi
pods: "50"
↓
→ đội này KHÔNG vượt được trần
LimitRange:
mặc định request/limit cho mỗi container
↓
→ ngăn pod không khai request
chiếm hết node
Xem thêm câu #12565 (cùng lô): hỏi về cơ chế nhóm tài nguyên của Google Cloud → đáp án là Labels. Ở câu này phạm vi là bên trong cụm Kubernetes, nên có thêm Namespaces. Hai câu nhất quán, chỉ khác tầng.
Vì sao các phương án khác sai
-
D (key-value pairs) — đây là phương án gần nhất và về hình thức thì label chính là cặp khoá-giá trị, nhưng "key-value pairs" là mô tả chung chung, không phải tên một tính năng. Tên tính năng là Labels.
-
B (Guest attributes) — metadata của VM Compute Engine, không phải cơ chế của Kubernetes.
-
E (instance attributes) — không phải tên tính năng nào của GKE.
Ghi nhớ
⚠ Namespace ↔ Label trong Kubernetes — bảng phải thuộc: | | Namespace | Label | |---|---|---| | Bản chất | phân vùng ảo của cụm | cặp khoá-giá trị trên đối tượng | | Số chiều | MỘT — mỗi đối tượng một namespace | NHIỀU chiều cùng lúc | | Đặt hạn mức | CÓ — ResourceQuota | KHÔNG | | Phân quyền RBAC | CÓ | không trực tiếp | | Chọn đối tượng | — | label selector | | Dùng chung | namespace cho đội, label cho các chiều khác |
Từ khoá nhận diện:
"phân tích chi phí theo đội trong GKE" → namespace + label "đặt trần CPU/RAM cho một đội" → ResourceQuota trong namespace "Service chọn Pod nào" → label selector "chi phí tài nguyên GCP theo đội" → label của Google Cloud "ghi chú không dùng để chọn" → annotation
| Label ↔ Annotation ↔ Selector | Nội dung |
|---|---|
| Label | dùng để CHỌN và NHÓM — có giới hạn độ dài |
| Annotation | siêu dữ liệu tự do, không chọn được, chứa được nhiều |
| Selector | matchLabels, matchExpressions |
| Ai dùng selector | Service, Deployment, NetworkPolicy, PodAffinity |
| Bẫy | đổi label của Pod → Service mất Pod đó |
| ResourceQuota — các trường hay dùng | Trường |
|---|---|
requests.cpu / requests.memory |
tổng tài nguyên yêu cầu |
limits.cpu / limits.memory |
tổng trần |
pods |
số pod tối đa |
persistentvolumeclaims |
số PVC |
count/deployments.apps |
đếm theo loại đối tượng |
| Kèm theo | LimitRange đặt mặc định cho container |
| GKE cost allocation — cách bật và dùng | Bước |
|---|---|
| Bật | gcloud container clusters update <ten> --enable-cost-allocation |
| Kết quả | billing export có cột namespace và label của workload |
| Phân tích | truy vấn BigQuery, GROUP BY namespace |
| Bổ sung | label ở cấp cụm cho chiều phòng ban |
| Xem nhanh | Cost Table trong console |
| Tách bạch đội trong GKE — từ mềm tới cứng | Cách |
|---|---|
| Namespace + RBAC + ResourceQuota | mềm, cùng cụm |
| Node pool riêng + taint/toleration | tách theo node |
| Cụm riêng cho mỗi đội | cứng nhất, đắt nhất |
| Project riêng | tách cả chi phí lẫn quyền |
| Chọn theo | mức độ tin cậy giữa các đội |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Namespace đang dùng bao nhiêu | kubectl describe resourcequota -n <ns> | | Pod nào thuộc đội nào | kubectl get pods -l team=data --all-namespaces | | Chi phí theo namespace | truy vấn billing export trong BigQuery |
Và một điều cần biết trước khi hứa hẹn báo cáo chi phí theo đội: namespace tách được tài nguyên của workload, nhưng không tách được chi phí hạ tầng dùng chung — node chưa lấp đầy, control plane, load balancer. Phần chi phí đó vẫn phải phân bổ theo một quy tắc do bạn chọn, và nên thống nhất quy tắc ấy với các đội trước khi gửi báo cáo đầu tiên.
- A gcloud container clusters create with --enable-autoscaling flag and --min-nodes and max-nodes parameters.
- B gcloud kubernetes clusters create with --enable-autoscaling flag and --min-nodes and max-nodes parameters.
- C kubectl clusters create with --enable-autoscaling flag and --min-nodes and max-nodes parameters.
- D kubectl containers create with --enable-autoscaling flag and --min-nodes and max-nodes parameters.
Xem giải thích
Đáp án
A — gcloud container clusters create với cờ --enable-autoscaling cùng --min-nodes và --max-nodes.
Vì sao đúng
Google Kubernetes Engine nằm trong nhóm lệnh gcloud container — một cái tên lịch sử, có từ trước khi dịch vụ được đổi tên thành GKE.
⚠ Điểm mấu chốt — cú pháp đầy đủ:
gcloud container clusters create ten-cum \
--zone=us-central1-a \
--num-nodes=3 \
--enable-autoscaling \
--min-nodes=1 \
--max-nodes=10
↓
container → nhóm lệnh của GKE
clusters → nhóm con
create → động từ
⚠ Vì sao là container chứ không phải kubernetes:
Dịch vụ vốn tên "Google Container Engine"
↓
Đổi tên thành Google Kubernetes Engine
↓
⚠ Nhưng nhóm lệnh gcloud GIỮ NGUYÊN
là `container` để không phá script cũ
↓
→ KHÔNG có `gcloud kubernetes`
→ đây là bẫy quen thuộc trong đề thi
⚠ gcloud ↔ kubectl — ranh giới rất rõ:
gcloud container ...
↓
Quản lý CHÍNH CỤM:
tạo, xoá, nâng cấp, node pool,
autoscaling của NODE
kubectl ...
↓
Quản lý ĐỐI TƯỢNG BÊN TRONG cụm:
pod, deployment, service,
HPA (autoscaling của POD)
↓
⚠ kubectl KHÔNG tạo được cụm
⚠ Ba tầng co giãn của GKE — đừng lẫn:
Cluster Autoscaler → thêm/bớt NODE
(gcloud, --enable-autoscaling)
HPA → thêm/bớt POD
(kubectl autoscale)
VPA → chỉnh request/limit của pod
Node auto-provisioning → tự tạo NODE POOL mới
Vì sao các phương án khác sai
-
B (
gcloud kubernetes clusters create) — đây là phương án dễ chọn nhầm nhất vì tên dịch vụ đúng là Kubernetes Engine, nhưng không có nhómgcloud kubernetes. -
C (
kubectl clusters create) —kubectlkhông tạo được cụm; nó chỉ nói chuyện với một cụm đã tồn tại. -
D (
kubectl containers create) — sai cả công cụ lẫn cú pháp.
Ghi nhớ
⚠ Lệnh GKE hay dùng — bảng phải thuộc: | Lệnh | Việc | |---|---| | gcloud container clusters create | tạo cụm | | --enable-autoscaling --min-nodes --max-nodes | cluster autoscaler | | gcloud container clusters get-credentials <ten> | lấy kubeconfig để dùng kubectl | | gcloud container clusters resize | đổi số node thủ công | | gcloud container clusters upgrade | nâng cấp phiên bản | | gcloud container node-pools create | thêm node pool | | gcloud container clusters delete | xoá cụm |
Từ khoá nhận diện:
"tạo cụm GKE" →
gcloud container clusters create"co giãn NODE" →--enable-autoscaling(cluster autoscaler) "co giãn POD" →kubectl autoscale(HPA) "triển khai ứng dụng" →kubectl apply"gcloud kubernetes" → KHÔNG TỒN TẠI
| Ba chế độ vận hành GKE | Nội dung |
|---|---|
| Autopilot | Google quản lý node — trả tiền theo pod, khuyến nghị |
| Standard | bạn quản lý node pool — linh hoạt hơn |
| Zonal ↔ Regional | regional có control plane nhiều zone |
| Tạo Autopilot | gcloud container clusters create-auto |
| Autopilot | không cần cấu hình autoscaling node |
| Ba tầng co giãn — nhắc lại | Tầng |
|---|---|
| Cluster Autoscaler | NODE — theo pod đang chờ lên lịch |
| HPA | số POD — theo CPU, RAM, chỉ số tuỳ chỉnh |
| VPA | request/limit của pod |
| Node auto-provisioning | tự tạo node pool mới khi cần loại máy khác |
| Cẩn thận | HPA và VPA cùng chỉnh CPU dễ xung đột |
| Bước sau khi tạo cụm | Bước |
|---|---|
| 1 | gcloud container clusters get-credentials <ten> --zone=<zone> |
| 2 | kubectl get nodes để xác nhận |
| 3 | kubectl apply -f deployment.yaml |
| 4 | kubectl expose hoặc dùng Service/Ingress |
| Lưu ý | thiếu bước 1 thì kubectl trỏ vào cụm khác hoặc báo lỗi |
| Cấu hình nên bật cho cụm production | Nội dung |
|---|---|
| Regional cluster | control plane nhiều zone |
| Workload Identity | pod dùng service account của GCP, không cần khoá |
| Private cluster | node không có IP công khai |
| Shielded GKE nodes | chống rootkit |
| Node auto-upgrade và auto-repair | bật mặc định, đừng tắt |
| Cost allocation | phân tích chi phí theo namespace |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Cụm có bật autoscaling không | gcloud container clusters describe <ten> → autoscaling | | Vì sao node không tăng | kubectl describe pod → sự kiện FailedScheduling; và quota CPU của Region | | kubectl đang trỏ vào đâu | kubectl config current-context |
Và một nguyên nhân rất hay gặp khi cluster autoscaler "không chịu" thêm node: hết hạn mức CPU hoặc IP ở Region đó. Autoscaler báo lỗi trong sự kiện của cụm chứ không dừng hẳn, nên triệu chứng bên ngoài chỉ là pod nằm mãi ở trạng thái Pending — kiểm tra quota trước khi đi tìm lỗi trong cấu hình.
- A In the K_Configuration environment variable
- B In the container startup script
- C In the service startup script
- D In the VM instance metadata
Xem giải thích
Đáp án
A — Trong biến môi trường K_CONFIGURATION.
Vì sao đúng
Cloud Run tự động đưa vào mỗi container một bộ biến môi trường có tiền tố K_ (K là Knative), và K_CONFIGURATION chính là tên cấu hình đã tạo ra container đó.
⚠ Điểm mấu chốt — bốn biến Cloud Run tự đặt:
K_SERVICE → tên SERVICE
K_REVISION → tên REVISION đang chạy
K_CONFIGURATION → tên CONFIGURATION ← đề này
PORT → cổng phải lắng nghe (mặc định 8080)
↓
Đọc trong code:
Python: os.environ["K_CONFIGURATION"]
Java: System.getenv("K_CONFIGURATION")
Go: os.Getenv("K_CONFIGURATION")
⚠ Ba khái niệm của Knative — quan hệ với nhau:
SERVICE
→ điểm cuối ổn định, một URL
↓
CONFIGURATION
→ bản khai "phiên bản mong muốn"
→ mỗi lần deploy sinh một revision
↓
REVISION
→ ảnh chụp BẤT BIẾN của một lần triển khai
→ nơi lưu lượng thật sự chạy tới
↓
Lưu lượng chia được giữa nhiều revision
⚠ Vì sao biết được tên này lại hữu ích:
Ứng dụng ghi log kèm K_REVISION
↓
→ biết lỗi thuộc phiên bản nào
→ so sánh tỉ lệ lỗi giữa hai revision
khi đang chia lưu lượng (canary)
↓
Ghi kèm K_SERVICE
→ phân biệt log giữa các dịch vụ
Vì sao các phương án khác sai
-
B (trong container startup script) — đây là phương án gần nhất về mặt "chỗ nào trong container", nhưng Cloud Run không đặt thông tin này vào script khởi động; nó truyền qua biến môi trường.
-
C (trong service startup script) — cũng không có cơ chế nào như vậy trong Cloud Run.
-
D (trong VM instance metadata) — Cloud Run là dịch vụ không máy chủ, người dùng không truy cập metadata của VM theo cách của Compute Engine.
Ghi nhớ
⚠ Biến môi trường Cloud Run tự đặt — bảng phải thuộc: | Biến | Nội dung | |---|---| | K_SERVICE | tên service | | K_REVISION | tên revision đang chạy | | K_CONFIGURATION | tên configuration | | PORT | cổng phải lắng nghe — BẮT BUỘC dùng | | CLOUD_RUN_JOB, CLOUD_RUN_TASK_INDEX | dành cho Cloud Run job | | Lưu ý | đừng hard-code cổng 8080, luôn đọc PORT |
Từ khoá nhận diện:
"tên configuration/revision trong Cloud Run" → biến
K_*"cổng phải lắng nghe" → biếnPORT"chỉ số của task trong job" →CLOUD_RUN_TASK_INDEX"thông tin về VM" → metadata server — của Compute Engine, không phải Cloud Run "bí mật, mật khẩu" → Secret Manager, gắn làm biến hoặc volume
| Service ↔ Configuration ↔ Revision | Nội dung |
|---|---|
| Service | URL ổn định, chứa nhiều revision |
| Configuration | bản khai phiên bản mong muốn |
| Revision | BẤT BIẾN, sinh ra mỗi lần deploy |
| Traffic split | chia lưu lượng giữa các revision |
| Rollback | chuyển 100% lưu lượng về revision cũ |
| Truyền cấu hình vào Cloud Run | Cách |
|---|---|
--set-env-vars KEY=VALUE |
biến môi trường |
--update-env-vars |
thêm mà không xoá cái cũ |
--set-secrets KEY=secret:version |
Secret Manager thành biến |
--set-secrets /path=secret:version |
Secret thành file |
--service-account |
danh tính chạy dịch vụ |
| Lưu ý | mỗi lần đổi cấu hình sinh REVISION MỚI |
| Triển khai từng phần (canary) trên Cloud Run | Bước |
|---|---|
| 1 | gcloud run deploy --no-traffic --tag=canary |
| 2 | Thử qua URL có tag |
| 3 | gcloud run services update-traffic --to-tags=canary=10 |
| 4 | Theo dõi tỉ lệ lỗi theo K_REVISION |
| 5 | Tăng dần tới 100%, hoặc rollback |
| Cloud Run — giới hạn cần nhớ | Nội dung |
|---|---|
| Thời gian tối đa mỗi request | tới 60 phút |
| Concurrency | tới 1000 request/instance |
| Min instances | giảm khởi động nguội, có phí giữ chỗ |
| CPU always allocated | cho tác vụ nền |
| Cloud Run job | cho tác vụ chạy rồi kết thúc |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Revision nào đang nhận lưu lượng | gcloud run services describe <ten> --region=<r> | | Biến môi trường thực tế | cùng lệnh trên, xem containers.env | | Log của một revision | Logs Explorer, lọc resource.labels.revision_name |
Và một thói quen rất đáng có ngay từ dòng log đầu tiên của ứng dụng Cloud Run: ghi kèm K_REVISION vào mọi bản ghi. Khi đang chia lưu lượng giữa hai phiên bản và tỉ lệ lỗi nhích lên, đó là thứ duy nhất cho bạn biết lỗi đến từ phiên bản nào — nếu không có, bạn chỉ thấy một biểu đồ xấu đi mà không biết nên quay lui hay không.
- A Compute Engine
- B App Engine Standard
- C Cloud Run
- D Anthos
Xem giải thích
Đáp án
C — Cloud Run.
Vì sao đúng
Đề cho bốn ràng buộc, và Cloud Run là dịch vụ duy nhất thoả cả bốn: viết bằng C++, đội đã dùng container, có tác vụ chạy tới 20 phút, và giảm tối đa công vận hành.
⚠ Điểm mấu chốt — bốn ràng buộc ánh xạ thẳng vào Cloud Run:
"viết bằng C++"
→ Cloud Run chạy BẤT KỲ ngôn ngữ nào
miễn là đóng gói thành container
"đã dùng container rồi"
→ không phải học công nghệ mới
"có file mất tới 20 PHÚT"
→ Cloud Run cho tới 60 PHÚT mỗi request
→ thừa sức
"giảm công vận hành"
→ không máy chủ, tự co giãn,
co về 0 khi rảnh
⚠ Kiến trúc hoàn chỉnh cho đề này:
Tải file lên Cloud Storage
↓
Cloud Storage notification
↓
Pub/Sub topic
↓
Pub/Sub PUSH subscription
↓
Cloud Run service (C++ trong container)
↓
⚠ Đặt ackDeadline đủ dài
và bật retry cho subscription
⚠ Vì sao App Engine Standard không dùng được:
App Engine Standard
↓
Chỉ hỗ trợ MỘT SỐ NGÔN NGỮ:
Python, Java, Node.js, Go, PHP, Ruby
↓
⚠ KHÔNG có C++
↓
Và request có giới hạn thời gian
ngắn hơn nhiều
↓
→ loại ngay từ ràng buộc ngôn ngữ
Vì sao các phương án khác sai
-
A (Compute Engine) — chạy được C++ và không giới hạn thời gian, nhưng công vận hành cao nhất: phải quản lý máy, vá lỗi, co giãn thủ công. Ngược với yêu cầu "giảm tối đa công vận hành".
-
B (App Engine Standard) — không hỗ trợ C++, và thời gian xử lý mỗi request bị giới hạn ngắn.
-
D (Anthos) — nền tảng cho môi trường lai và đa đám mây, phức tạp hơn hẳn nhu cầu ở đây; công vận hành lớn.
Ghi nhớ
⚠ Bốn lựa chọn tính toán — bảng phải thuộc: | Dịch vụ | Công vận hành | Ngôn ngữ | Thời gian tối đa | |---|---|---|---| | Cloud Run | rất thấp | bất kỳ (container) | tới 60 phút | | Cloud Run functions | rất thấp | một số ngôn ngữ | tới 60 phút (gen2) | | App Engine Standard | thấp | danh sách cố định | ngắn | | App Engine Flexible | trung bình | container | dài hơn | | GKE | cao | bất kỳ | không giới hạn | | Compute Engine | cao nhất | bất kỳ | không giới hạn |
Từ khoá nhận diện:
"đã dùng container + giảm vận hành" → Cloud Run "ngôn ngữ ngoài danh sách chuẩn" → Cloud Run, không phải App Engine Standard "tác vụ chạy rồi kết thúc, không phục vụ request" → Cloud Run job "cần kiểm soát Kubernetes chi tiết" → GKE "cần cấu hình máy chủ, giấy phép riêng" → Compute Engine
| Cloud Run — giới hạn cần thuộc | Nội dung |
|---|---|
| Thời gian mỗi request | tối đa 60 phút |
| Bộ nhớ | tới 32 GiB |
| CPU | tới 8 vCPU |
| Concurrency | tới 1000 request/instance |
| Co về 0 | không có request thì không tính tiền |
| Min instances | giảm khởi động nguội, có phí |
| Cloud Run service ↔ Cloud Run job | Nội dung |
|---|---|
| Service | phản hồi HTTP hoặc Pub/Sub push — như đề này |
| Job | chạy tới khi xong rồi thoát — batch, ETL |
| Job có | --tasks, --parallelism, CLOUD_RUN_TASK_INDEX |
| Kích hoạt job | Cloud Scheduler, Workflows, hoặc thủ công |
| Chọn service khi | có nguồn sự kiện đẩy tới |
| Ghép Pub/Sub với Cloud Run — điều dễ sai | Nội dung |
|---|---|
ackDeadlineSeconds |
phải dài hơn thời gian xử lý — tối đa 600s |
| Xử lý lâu hơn 600s | ack ngay rồi xử lý nền, hoặc dùng Cloud Run job |
| Retry | bật, kèm dead-letter topic |
| Xác thực | push subscription dùng OIDC token + roles/run.invoker |
| Trùng lặp | Pub/Sub là at-least-once → xử lý phải bất biến (idempotent) |
| Từ Cloud Storage tới xử lý — ba cách kích hoạt | Cách |
|---|---|
| Pub/Sub notification | như đề này, linh hoạt nhất |
| Eventarc | chuẩn hoá sự kiện, đẩy thẳng tới Cloud Run |
| Cloud Run function trigger | đơn giản, ít bước |
| Chọn Pub/Sub khi | đã dùng Pub/Sub cho dịch vụ khác |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Có file nào xử lý quá lâu không | log của Cloud Run, xem latency | | Có thông điệp bị thử lại nhiều lần | dead-letter topic và chỉ số của subscription | | Chi phí thực tế | billing export, so Cloud Run với phương án VM |
Và một chi tiết quyết định thành bại của kiến trúc này: ackDeadlineSeconds của subscription phải dài hơn thời gian xử lý thật. Với những file mất tới 20 phút mà deadline chỉ vài chục giây, Pub/Sub sẽ gửi lại thông điệp trong khi bản đầu vẫn đang chạy — kết quả là cùng một file bị xử lý nhiều lần, tốn tiền và có thể sinh dữ liệu trùng.
- A app.yaml
- B cron.yaml
- C batch.yaml
- D job.yaml
Xem giải thích
Đáp án
B — cron.yaml
Vì sao đúng
App Engine khai báo các tác vụ chạy theo lịch trong một tệp riêng tên cron.yaml, triển khai tách khỏi mã ứng dụng.
⚠ Điểm mấu chốt — cấu trúc tệp:
cron:
- description: "cong viec theo gio"
url: /tasks/hourly-batch
schedule: every 1 hours
timezone: Asia/Ho_Chi_Minh
target: worker
↓
Đề nói job chạy 2 giờ một lần
thay vì 1 giờ
↓
→ sửa dòng `schedule`
từ "every 2 hours" thành "every 1 hours"
⚠ Triển khai tách khỏi ứng dụng:
gcloud app deploy cron.yaml
↓
⚠ KHÔNG phải `gcloud app deploy` thường
→ lịch là cấu hình RIÊNG
↓
Cùng nhóm với các tệp cấu hình khác:
dispatch.yaml → định tuyến
index.yaml → chỉ mục Datastore
queue.yaml → hàng đợi tác vụ
⚠ Cú pháp lịch của App Engine — riêng, không phải cron Unix:
every 1 hours
every 5 minutes
every day 09:00
every monday 09:00
1st,3rd monday of month 09:00
every 2 hours from 10:00 to 14:00
↓
⚠ Đọc như tiếng Anh, KHÔNG phải "0 * * * *"
→ đây là điểm khác biệt hay bị hỏi
⚠ Cách App Engine chạy job:
Tới giờ
↓
App Engine gửi HTTP GET tới `url`
↓
Kèm header X-Appengine-Cron: true
↓
⚠ Bảo vệ endpoint:
chỉ nhận request có header này
hoặc đặt trong /_ah/ và chặn từ ngoài
Vì sao các phương án khác sai
-
A (
app.yaml) — đây là phương án gần nhất và là tệp cấu hình chính của App Engine (runtime, scaling, biến môi trường, handler), nhưng lịch chạy không khai ở đây. -
C (
batch.yaml) — không tồn tại tệp cấu hình nào tên như vậy. -
D (
job.yaml) — cũng không tồn tại trong App Engine (đó là tên quen thuộc của Kubernetes).
Ghi nhớ
⚠ Các tệp cấu hình của App Engine — bảng phải thuộc: | Tệp | Việc | |---|---| | app.yaml | cấu hình chính: runtime, scaling, handler, biến môi trường | | cron.yaml | tác vụ theo LỊCH | | dispatch.yaml | định tuyến URL tới service nào | | index.yaml | chỉ mục hỗn hợp của Datastore | | queue.yaml | cấu hình Task Queue | | Triển khai | gcloud app deploy <tệp>.yaml cho từng tệp |
Từ khoá nhận diện:
"job chạy sai chu kỳ trong App Engine" →
cron.yaml"URL nào đi tới service nào" →dispatch.yaml"truy vấn Datastore báo thiếu chỉ mục" →index.yaml"lịch cho dịch vụ KHÁC App Engine" → Cloud Scheduler "runtime, scaling" →app.yaml
| Cú pháp lịch của App Engine | Ví dụ |
|---|---|
every N minutes/hours |
every 30 minutes |
every day HH:MM |
every day 09:00 |
every monday 09:00 |
theo thứ trong tuần |
1st,3rd monday of month 09:00 |
theo tuần trong tháng |
every N hours from HH:MM to HH:MM |
trong khung giờ |
timezone |
nên khai rõ — mặc định UTC |
| Cloud Scheduler — người kế nhiệm hiện đại | Nội dung |
|---|---|
| Cú pháp cron Unix | 0 * * * * — khác App Engine cron |
| Đích | HTTP, Pub/Sub, App Engine |
| Xác thực | OIDC/OAuth token tới Cloud Run, Cloud Run functions |
| Thử lại | cấu hình được |
| Dùng khi | kiến trúc không dựa trên App Engine |
| Lệnh | gcloud scheduler jobs create http ... |
| Bảo vệ endpoint chạy theo lịch | Cách |
|---|---|
Header X-Appengine-Cron: true |
chỉ App Engine đặt được |
Đường dẫn /_ah/ |
không truy cập được từ ngoài |
login: admin trong app.yaml |
giới hạn quyền |
| Với Cloud Scheduler | OIDC token + roles/run.invoker |
| Nguy hiểm | endpoint mở → ai cũng kích được job |
| Gỡ lỗi job theo lịch | Việc |
|---|---|
| Xem lần chạy gần nhất | console App Engine → Cron jobs |
gcloud app deploy cron.yaml đã chạy chưa |
lỗi hay gặp: sửa tệp mà quên triển khai |
| Job chạy nhưng lỗi | xem log của chính endpoint |
| Múi giờ sai | thiếu trường timezone |
| Job chạy trùng | thời gian xử lý dài hơn chu kỳ |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Lịch hiện tại là gì | gcloud app describe và console → Cron jobs | | Job có chạy không | log, lọc theo đường dẫn của endpoint | | Job có bị chồng lấn | so thời gian xử lý với chu kỳ |
Và một nguyên nhân rất hay gặp khi "sửa cron.yaml rồi mà lịch vẫn như cũ": quên chạy gcloud app deploy cron.yaml. Tệp lịch không đi kèm lần triển khai ứng dụng thông thường, nên sửa trong kho mã mà không triển khai riêng thì cấu hình đang chạy vẫn là bản cũ — và không có lỗi nào báo cho bạn biết.
- A app.yaml
- B cron.yaml
- C index.yaml
- D dispatch.yaml
Xem giải thích
Đáp án
C — index.yaml
Vì sao đúng
Triệu chứng trong đề là dấu hiệu kinh điển của thiếu chỉ mục hỗn hợp (composite index) trong Datastore: truy vấn trên MỘT thuộc tính chạy tốt, truy vấn trên HAI thuộc tính trở lên không trả về gì.
⚠ Điểm mấu chốt — Datastore có hai loại chỉ mục:
CHỈ MỤC TỰ ĐỘNG (built-in)
↓
Datastore tự tạo cho TỪNG thuộc tính
↓
→ truy vấn một thuộc tính LUÔN chạy
CHỈ MỤC HỖN HỢP (composite)
↓
Kết hợp NHIỀU thuộc tính
hoặc thuộc tính + thứ tự sắp xếp
↓
⚠ PHẢI KHAI trong index.yaml
⚠ Không khai → truy vấn KHÔNG chạy
⚠ Nội dung tệp:
indexes:
- kind: NguoiDung
properties:
- name: quoc_gia
- name: diem
direction: desc
↓
Triển khai riêng:
gcloud datastore indexes create index.yaml
↓
⚠ Xây chỉ mục mất THỜI GIAN với dữ liệu lớn
— trạng thái "Building" trước khi "Serving"
⚠ Vì sao Datastore bắt buộc như vậy:
Datastore KHÔNG quét bảng
↓
Mọi truy vấn đều đọc từ CHỈ MỤC
↓
→ hiệu năng phụ thuộc KÍCH THƯỚC KẾT QUẢ,
không phụ thuộc kích thước dữ liệu
↓
→ đổi lại: truy vấn nào cũng phải có
chỉ mục tương ứng, khai trước
Xem thêm câu #12586 (cùng lô): cùng bốn phương án nhưng hỏi về job chạy sai chu kỳ → đáp án là
cron.yaml. Hai câu nhất quán, khoá khác nhau vì triệu chứng khác nhau.
Vì sao các phương án khác sai
-
A (
app.yaml) — đây là phương án dễ chọn nhầm vì là tệp cấu hình chính, nhưng nó khai runtime, scaling và handler; không liên quan tới chỉ mục Datastore. -
B (
cron.yaml) — khai tác vụ theo lịch. -
D (
dispatch.yaml) — khai định tuyến URL tới service nào.
Ghi nhớ
⚠ Bốn tệp cấu hình App Engine — bảng phải thuộc: | Tệp | Việc | Triệu chứng khi sai | |---|---|---| | app.yaml | runtime, scaling, handler | ứng dụng không chạy đúng | | cron.yaml | tác vụ theo lịch | job chạy sai chu kỳ | | index.yaml | chỉ mục Datastore | truy vấn nhiều thuộc tính không ra kết quả | | dispatch.yaml | định tuyến URL | request tới nhầm service | | queue.yaml | Task Queue | tác vụ nền không chạy |
Từ khoá nhận diện:
"truy vấn nhiều thuộc tính không ra dữ liệu" →
index.yaml"job sai chu kỳ" →cron.yaml"URL đi nhầm service" →dispatch.yaml"đổi runtime, số instance" →app.yaml"chỉ mục đang xây" → chờ trạng thái Serving
| Chỉ mục Datastore/Firestore | Nội dung |
|---|---|
| Tự động | mỗi thuộc tính đơn, cả hai chiều |
| Hỗn hợp | nhiều thuộc tính, hoặc kèm sắp xếp — phải khai |
| Triển khai | gcloud datastore indexes create index.yaml |
| Dọn chỉ mục thừa | gcloud datastore indexes cleanup index.yaml |
| Trạng thái | Building → Serving |
| Chi phí | chỉ mục tốn dung lượng và làm chậm GHI |
| Cách tìm ra chỉ mục còn thiếu | Cách |
|---|---|
| Chạy thử ở môi trường phát triển | emulator tự sinh index.yaml |
| Đọc thông báo lỗi | thường kèm sẵn định nghĩa chỉ mục cần thêm |
| Console | Datastore → Indexes, xem trạng thái |
| Sau khi thêm | đợi Serving rồi thử lại |
| Lưu ý | ứng dụng thật có thể im lặng trả rỗng |
| Giới hạn truy vấn của Datastore | Nội dung |
|---|---|
| Bất đẳng thức chỉ trên MỘT thuộc tính | ràng buộc quan trọng nhất |
OR không hỗ trợ trực tiếp (bản cũ) |
phải tách nhiều truy vấn |
| Không có JOIN | thiết kế phi chuẩn hoá |
| Sắp xếp phải khớp chỉ mục | thứ tự thuộc tính có ý nghĩa |
| Tối đa 200 chỉ mục hỗn hợp mỗi project |
| Firestore ↔ Datastore | Nội dung |
|---|---|
| Firestore in Datastore mode | tương thích API Datastore cũ |
| Firestore in Native mode | đồng bộ thời gian thực, SDK di động |
| Chọn một lần | không đổi được sau khi tạo |
| Khuyến nghị mới | Native mode cho ứng dụng mới |
| Chỉ mục | cả hai đều cần chỉ mục hỗn hợp |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chỉ mục nào đang có | console → Datastore → Indexes | | Chỉ mục xây xong chưa | trạng thái Serving | | Truy vấn cần chỉ mục nào | chạy trên emulator, đọc index.yaml nó sinh ra |
Và một điều khiến lỗi này khó lần ra hơn hẳn các lỗi khác: truy vấn thiếu chỉ mục có thể trả về danh sách rỗng thay vì báo lỗi, tuỳ thư viện và cấu hình. Ứng dụng chạy bình thường, không có ngoại lệ nào, chỉ là màn hình không có dữ liệu — nên khi gặp "truy vấn nhiều điều kiện không ra gì", hãy mở index.yaml trước khi đi tìm lỗi trong mã.
-
A
gsutil rewrite -s Coldline gs://PATH_TO_OBJECT
-
B
gcloud storage rewrite -s Coldline gs://PATH_TO_OBJECT
-
C
gsutil newclass -s Coldline gs://PATH_TO_OBJECT
-
D
gcloud storage newclass -s Coldline gs://PATH_TO_OBJECT
Xem giải thích
Đáp án
A — gsutil rewrite -s Coldline gs://PATH_TO_OBJECT
Vì sao đúng
Đổi lớp lưu trữ (storage class) của đối tượng đã có được thực hiện bằng lệnh rewrite với cờ -s.
⚠ Điểm mấu chốt — rewrite ghi lại đối tượng với lớp mới:
gsutil rewrite -s coldline gs://bucket/duong-dan
↓
-s : storage class đích
↓
Ghi lại đối tượng TẠI CHỖ
→ giữ nguyên tên, giữ nguyên metadata
→ KHÔNG phải tải xuống rồi tải lên
Đổi cả bucket:
gsutil -m rewrite -s coldline -r gs://bucket
↓
-m : chạy song song
-r : đệ quy
⚠ Bốn lớp lưu trữ và tiêu chí chọn:
STANDARD → truy cập thường xuyên
không phí lưu tối thiểu
NEARLINE → khoảng 1 lần/tháng
tối thiểu 30 ngày
COLDLINE → khoảng 1 lần/quý
tối thiểu 90 ngày
ARCHIVE → dưới 1 lần/năm
tối thiểu 365 ngày
↓
Càng lạnh: LƯU rẻ hơn, ĐỌC đắt hơn
⚠ ⚠ Cái bẫy chi phí phải biết trước khi chạy lệnh:
Nearline có THỜI GIAN LƯU TỐI THIỂU 30 NGÀY
↓
Đổi sang Coldline TRƯỚC khi đủ 30 ngày
↓
→ bị tính PHÍ XOÁ SỚM cho số ngày còn thiếu
↓
⚠ Đổi hàng loạt hàng triệu đối tượng
có thể sinh hoá đơn bất ngờ rất lớn
Vì sao các phương án khác sai
-
B (
gcloud storage rewrite -s Coldline ...) — đây là phương án gần nhất, vàgcloud storageđúng là công cụ thế hệ mới thay chogsutil, nhưng động từrewritekhông thuộcgcloud storage. Ở đó dùnggcloud storage objects update --storage-class=. -
C và D (
newclass) — không có động từnewclasstrong cả hai công cụ.
Ghi nhớ
⚠ Lệnh đổi lớp lưu trữ — bảng phải thuộc: | Công cụ | Lệnh | |---|---| | gsutil | gsutil rewrite -s <lớp> gs://... | | gcloud storage | gcloud storage objects update gs://... --storage-class=<lớp> | | Đổi hàng loạt | gsutil -m rewrite -s <lớp> -r gs://bucket | | Lớp MẶC ĐỊNH của bucket | gcloud storage buckets update gs://b --default-storage-class=<lớp> | | Tự động theo tuổi | Object Lifecycle Management |
Từ khoá nhận diện:
"đổi lớp lưu trữ của đối tượng đã có" →
gsutil rewrite -s"tự động chuyển lớp theo tuổi" → lifecycle rule "không biết mẫu truy cập" → Autoclass "xem lớp hiện tại" →gsutil stat"đổi lớp mặc định cho file mới" →buckets update --default-storage-class
| Bốn lớp lưu trữ — bảng so sánh | Nội dung |
|---|---|
| Standard | truy cập thường xuyên, không có thời gian tối thiểu |
| Nearline | ~1 lần/tháng, tối thiểu 30 ngày |
| Coldline | ~1 lần/quý, tối thiểu 90 ngày |
| Archive | <1 lần/năm, tối thiểu 365 ngày |
| Điểm chung | cùng độ bền, cùng độ trễ truy cập mili giây |
| Khác nhau ở | giá LƯU và phí TRUY XUẤT |
| Ba loại phí dễ bị bỏ sót | Phí |
|---|---|
| Early deletion fee | xoá/đổi lớp trước thời gian tối thiểu |
| Retrieval fee | đọc dữ liệu từ lớp lạnh |
| Operation fee | mỗi thao tác API — rewrite cũng tính |
| Egress | truyền ra khỏi Google Cloud |
| Vì vậy | tính trước khi đổi hàng loạt |
| Object Lifecycle Management — cách tự động hoá | Nội dung |
|---|---|
SetStorageClass |
tự chuyển lớp theo tuổi |
Delete |
tự xoá |
| Điều kiện | age, createdBefore, numNewerVersions, matchesPrefix |
| Đặt bằng | gcloud storage buckets update gs://b --lifecycle-file=rule.json |
| Ưu điểm | không phải chạy lệnh thủ công, không quên |
| Autoclass — khi không biết mẫu truy cập | Nội dung |
|---|---|
| Cơ chế | Google tự chuyển lớp theo mức truy cập thật |
| Không có phí truy xuất, không có phí xoá sớm | ưu điểm lớn |
| Đổi lại | phí quản lý theo số đối tượng |
| Bật | --enable-autoclass khi tạo bucket |
| Hợp với | dữ liệu có mẫu truy cập khó đoán |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đối tượng đang ở lớp nào | gsutil stat gs://bucket/obj → Storage class | | Đối tượng đã đủ tuổi tối thiểu chưa | cùng lệnh trên → Creation time | | Bucket có lifecycle rule gì | gcloud storage buckets describe gs://b --format="value(lifecycle)" |
Và một việc nên làm trước khi chạy rewrite trên cả bucket: kiểm tra tuổi của các đối tượng. Chuyển hàng triệu file Nearline mới tạo hôm qua sang Coldline sẽ kích hoạt phí xoá sớm cho gần trọn 30 ngày của từng file — và khoản đó hoàn toàn tránh được chỉ bằng cách đặt một lifecycle rule rồi để nó tự chạy khi dữ liệu đủ tuổi.
- A gsutil metadata gs://BUCKET_NAME/OBJECT_NAME
- B gsutil stat gs://BUCKET_NAME/OBJECT_NAME
- C gsutil list gs://BUCKET_NAME/OBJECT_NAME
- D gsutil describe gs://BUCKET_NAME/OBJECT_NAME
Xem giải thích
Đáp án
B — gsutil stat gs://BUCKET_NAME/OBJECT_NAME
Vì sao đúng
stat là lệnh của gsutil dành riêng cho việc đọc siêu dữ liệu của một đối tượng, và nó in ra đúng hai thứ đề cần: thời gian tạo và content type.
⚠ Điểm mấu chốt — kết quả của gsutil stat:
gs://bucket/anh.png:
Creation time: Mon, 02 Sep 2026 03:14:07 GMT
Update time: Mon, 02 Sep 2026 03:14:07 GMT
Storage class: STANDARD
Content-Length: 102400
Content-Type: image/png
Hash (crc32c): ...
Hash (md5): ...
ETag: ...
Generation: 1725247647123456
Metageneration: 1
⚠ Vì sao stat hợp với script hơn ls -L:
gsutil ls -L gs://...
↓
Cũng in metadata, nhưng:
- thiết kế để LIỆT KÊ nhiều đối tượng
- tốn thêm thao tác API
↓
gsutil stat gs://...
↓
- MỘT đối tượng, MỘT lần gọi
- đầu ra ổn định, dễ cắt bằng awk/grep
- MÃ THOÁT khác 0 nếu không tồn tại
↓
→ hợp với vòng lặp trong shell script
⚠ Dùng trong script:
if gsutil -q stat "gs://bucket/$f"; then
gsutil stat "gs://bucket/$f" \
| awk -F': +' '/Creation time|Content-Type/{print $2}'
else
echo "khong ton tai"
fi
Vì sao các phương án khác sai
-
C (
gsutil list ...) — đây là phương án gần nhất về ý định, nhưng động từ đúng của gsutil làls, không phảilist. Vàlsmặc định chỉ in tên; muốn có metadata phải thêm-L. -
A (
gsutil metadata ...) — không có động từmetadata. -
D (
gsutil describe ...) —describelà động từ củagcloud, không phải củagsutil.
Ghi nhớ
⚠ Lệnh gsutil hay dùng — bảng phải thuộc: | Lệnh | Việc | |---|---| | gsutil stat gs://b/obj | siêu dữ liệu MỘT đối tượng | | gsutil ls gs://b | liệt kê | | gsutil ls -L gs://b/obj | liệt kê kèm metadata đầy đủ | | gsutil cp / mv / rm | sao chép, di chuyển, xoá | | gsutil rsync -r | đồng bộ thư mục | | gsutil setmeta -h "Content-Type:..." | sửa metadata | | gsutil du -sh gs://b | tổng dung lượng | | gsutil -m | chạy song song — nhanh hơn nhiều |
Từ khoá nhận diện:
"xem metadata một đối tượng trong script" →
gsutil stat"liệt kê kèm chi tiết" →gsutil ls -L"sửa Content-Type" →gsutil setmeta"describe" → động từ của gcloud, KHÔNG có trong gsutil "list" → gsutil dùngls
gsutil ↔ gcloud storage |
Nội dung |
|---|---|
gcloud storage |
công cụ THẾ HỆ MỚI, nhanh hơn đáng kể |
gsutil stat |
↔ gcloud storage objects describe |
gsutil ls |
↔ gcloud storage ls |
gsutil cp |
↔ gcloud storage cp |
gsutil rsync |
↔ gcloud storage rsync |
| Khuyến nghị | dùng gcloud storage cho việc mới |
| Đề thi | vẫn hỏi cả hai — phải thuộc cả hai |
| Các trường metadata quan trọng | Trường |
|---|---|
Creation time |
thời điểm tạo |
Content-Type |
quyết định trình duyệt hiển thị hay tải về |
Storage class |
lớp lưu trữ |
Generation |
phiên bản của đối tượng — dùng cho versioning |
Metageneration |
số lần metadata thay đổi |
Cache-Control |
ảnh hưởng CDN và trình duyệt |
Hash crc32c, md5 |
kiểm tra toàn vẹn |
| Sửa metadata mà không tải lại file | Lệnh |
|---|---|
gsutil setmeta -h "Content-Type:text/html" gs://b/obj |
đổi kiểu nội dung |
-h "Cache-Control:public, max-age=3600" |
điều khiển cache |
-h "x-goog-meta-tac-gia:an" |
metadata tuỳ chỉnh |
| Áp hàng loạt | gsutil -m setmeta ... gs://b/** |
| Lưu ý | setmeta cũng tính là một thao tác ghi |
| Viết script với gsutil — điều nên nhớ | Nội dung |
|---|---|
gsutil -q stat |
kiểm tra tồn tại bằng MÃ THOÁT |
gsutil -m |
song song, dùng khi xử lý nhiều file |
| Đầu ra dạng JSON | dùng gcloud storage objects describe --format=json |
| Phân trang | ls trên bucket rất lớn nên lọc bằng tiền tố |
| Chi phí | mỗi lệnh là một thao tác API có tính tiền |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đối tượng có tồn tại không | gsutil -q stat gs://... && echo co | | Kiểu nội dung có đúng không | gsutil stat → Content-Type | | Có bao nhiêu phiên bản | gsutil ls -a gs://b/obj khi bật versioning |
Và một lỗi rất hay gặp khi phục vụ tệp tĩnh từ Cloud Storage: Content-Type sai. File HTML tải lên bằng công cụ không đoán đúng kiểu sẽ mang application/octet-stream, và trình duyệt tải nó về thay vì hiển thị — gsutil stat là cách nhanh nhất để phát hiện, còn gsutil setmeta sửa được mà không cần tải lại file.
- A Generate a new SSH key pair. Give the private key to each member of your team. Configure the public key in the metadata of each instance.
- B Ask each member of the team to generate a new SSH key pair and to send you their public key. Use a configuration management tool to deploy those keys on each instance.
- C Ask each member of the team to generate a new SSH key pair and to add the public key to their Google account. Grant the ג€compute.osAdminLoginג€ role to the Google group corresponding to this team.
- D Generate a new SSH key pair. Give the private key to each member of your team. Configure the public key as a project-wide public SSH key in your Cloud Platform project and allow project-wide public SSH keys on each instance.
Xem giải thích
🧩 Phân tích chi tiết nội dung câu hỏi
Câu hỏi này thuộc chủ đề quản lý truy cập SSH an toàn vào các instance trên Google Compute Engine (GCE) trong Google Cloud Platform (GCP).
- Bối cảnh: Mọi nhân viên công ty đều có tài khoản Google. Nhóm vận hành (operational team) cần quản lý số lượng lớn instance trên Compute Engine. Mỗi thành viên chỉ cần quyền admin truy cập server (không phải quyền khác).
- Yêu cầu bảo mật từ security team:
- Triển khai credentials (xác thực) phải hiệu quả về mặt vận hành (operationally efficient).
- Phải xác định được ai đã truy cập instance cụ thể (audit trail rõ ràng).
- Mục tiêu: Tìm giải pháp SSH access tốt nhất, tránh phân phối key thủ công (dễ mất an toàn, khó scale, khó audit).
Giải pháp lý tưởng phải tận dụng tích hợp IAM và OS Login của GCP để tự động hóa, scale lớn và ghi log truy cập qua Cloud Audit Logs. 📘 (Kiến thức dựa trên GCP docs cập nhật 2024-2026: OS Login là best practice cho enterprise SSH management).
✅ Đáp án đúng và lý do lựa chọn
Đáp án đúng: Ask each member of the team to generate a new SSH key pair and to add the public key to their Google account. Grant the ג€compute.osAdminLoginג€ role to the Google group corresponding to this team.
Lý do:
- 🛠️ Tận dụng OS Login: Thành viên thêm public key vào Google account → GCP tự động sync key vào metadata instance khi SSH (không cần config thủ công per instance).
- 🔐 Quyền chính xác: Role
roles/compute.osAdminLogin(haycompute.osAdminLoginlegacy) cho phép SSH với quyền sudo admin, phù hợp "administrative access". - 👥 Scale và group management: Gán role cho Google Group → dễ quản lý hàng trăm user, thêm/xóa tự động.
- 📊 Audit trail: Cloud Audit Logs ghi đầy đủ "ai (user email), khi nào, instance nào" truy cập → đáp ứng yêu cầu security.
- ⚡ Hiệu quả vận hành: Không deploy key thủ công, scale lớn dễ dàng, tích hợp Google accounts sẵn có.
- 📘 Nguồn: GCP OS Login Docs & IAM Roles for Compute (cập nhật 2025: OS Login v2 hỗ trợ key rotation tự động).
❌ Giải thích tất cả các phương án (đúng/sai)
-
[SAI] Generate a new SSH key pair. Give the private key to each member of your team. Configure the public key in the metadata of each instance.
- ❌ Vấn đề scale: Phải config public key per instance metadata → với "large number of instances", tốn công deploy thủ công (không efficient).
- ❌ An toàn kém: Chia sẻ private key → rủi ro leak, khó thu hồi nếu member rời team.
- ❌ Không audit: Không track "ai" cụ thể truy cập (chỉ biết có key nào đó).
- 🧩 Phù hợp: Chỉ nhỏ lẻ, không enterprise.
-
[SAI] Ask each member of the team to generate a new SSH key pair and to send you their public key. Use a configuration management tool to deploy those keys on each instance.
- ❌ Vẫn thủ công: Dùng tool (như Ansible/Chef) deploy key per instance → phức tạp với large scale, dễ lỗi config.
- ❌ Quản lý kém: Thu thập key thủ công → bottleneck ở admin, khó rotate/revoke.
- ❌ Audit hạn chế: Logs chỉ SSH generic, không link trực tiếp user Google account.
- 🛠️ Tốt hơn option 1 nhưng vẫn outdated so với OS Login.
-
[ĐÚNG] Ask each member of the team to generate a new SSH key pair and to add the public key to their Google account. Grant the ג€compute.osAdminLoginג€ role to the Google group corresponding to this team.
- ✅ Hoàn hảo: Xem lý do ở phần trên. Tự động, secure, auditable, scale.
- 🌟 Best practice GCP 2026: OS Login thay thế SSH metadata keys hoàn toàn.
-
[SAI] Generate a new SSH key pair. Give the private key to each member of your team. Configure the public key as a project-wide public SSH key in your Cloud Platform project and allow project-wide public SSH keys on each instance.
- ❌ Rủi ro cao: Project-wide key → ai có private key đều access TẤT CẢ instance trong project (vi phạm least privilege).
- ❌ Không phân biệt user: Không biết "ai" truy cập cụ thể, chỉ biết key chung.
- ❌ Chia sẻ private key: Dễ compromise toàn bộ project.
- 📘 Deprecated: GCP khuyến cáo migrate khỏi project-wide keys sang OS Login từ 2023.
Kết luận: Giải pháp đúng tận dụng IAM + OS Login – tiêu chuẩn gold của GCP cho SSH enterprise! 🚀 (Nguồn bổ sung: GCP Security Best Practices).
- A 0.0.0.0/0
- B 10.0.0.0/8
- C 172.16.0.0/12
- D 192.168.0.0/16
Xem giải thích
🧩 Phân tích chi tiết nội dung câu hỏi
Câu hỏi yêu cầu tạo một VPC tùy chỉnh (custom VPC) trong AWS với một subnet duy nhất, và dải địa chỉ (CIDR block) của subnet này phải lớn nhất có thể.
- VPC là Virtual Private Cloud, một mạng ảo cô lập trong AWS, nơi bạn có thể khởi chạy các tài nguyên như EC2 instances.
- Subnet là một khối con của VPC, và ở đây chỉ có một subnet duy nhất, nghĩa là toàn bộ dải CIDR của VPC sẽ được dùng cho subnet đó (không chia nhỏ).
- Yêu cầu chính: Chọn dải CIDR lớn nhất có thể tuân thủ quy tắc của AWS VPC. AWS chỉ cho phép sử dụng các dải private IPv4 theo chuẩn RFC 1918 (không dùng public IP để tránh xung đột).
- Giới hạn AWS VPC (cập nhật đến 2026): VPC hỗ trợ CIDR từ /16 đến /28 cho IPv4, nhưng có thể lớn hơn như /8 nếu là private range. Subnet phải nằm trong VPC CIDR, và với một subnet, dải lớn nhất sẽ là toàn bộ VPC CIDR. ✅ Không dùng 0.0.0.0/0 vì đó là toàn bộ không gian IP (không private).
✅ Đáp án đúng: 10.0.0.0/8
- Lý do chọn: Đây là dải private IPv4 lớn nhất theo RFC 1918, cung cấp 16.777.216 địa chỉ IP (từ 10.0.0.0 đến 10.255.255.255). AWS VPC hỗ trợ đầy đủ CIDR /8 này cho custom VPC, và với một subnet duy nhất, bạn có thể dùng toàn bộ dải làm subnet. Điều này tối ưu hóa số lượng IP khả dụng nhất. 🛠️ Hoàn hảo cho nhu cầu "lớn nhất có thể"!
📋 Giải thích tất cả các phương án (đúng/sai)
Dưới đây là phân tích từng lựa chọn, giữ nguyên văn bản gốc bằng tiếng Anh. Mỗi phương án được đánh giá dựa trên kích thước dải IP và tính hợp lệ cho AWS VPC/subnet:
-
❌ 0.0.0.0/0
Sai vì đây là dải toàn bộ không gian IPv4 (hơn 4 tỷ địa chỉ), không phải private range theo RFC 1918. AWS cấm sử dụng cho VPC/subnet vì sẽ xung đột với toàn bộ internet và public IP. Không thể tạo VPC với dải này. 🚫 -
✅ 10.0.0.0/8
Đúng như đã giải thích ở trên. Dải lớn nhất trong private ranges (16 triệu IP), AWS hỗ trợ đầy đủ cho VPC và subnet duy nhất. Đây là lựa chọn tối ưu. 🏆 -
❌ 172.16.0.0/12
Sai vì tuy là private range hợp lệ (RFC 1918, từ 172.16.0.0 đến 172.31.255.255), nhưng chỉ có 1.048.576 địa chỉ IP – nhỏ hơn rất nhiều so với 10.0.0.0/8. Không phải lựa chọn lớn nhất. 📉 -
❌ 192.168.0.0/16
Sai vì là private range nhỏ nhất (RFC 1918, từ 192.168.0.0 đến 192.168.255.255), chỉ 65.536 địa chỉ IP. AWS hỗ trợ, nhưng không đáp ứng yêu cầu "lớn nhất có thể". Phù hợp cho mạng nhỏ, không phải trường hợp này. 🔍
📘 Tài liệu tham khảo (cập nhật AWS 2026)
- AWS VPC User Guide: CIDR Blocks for VPCs – Xác nhận hỗ trợ RFC 1918 ranges, /8 lớn nhất là 10.0.0.0/8.
- RFC 1918: Address Allocation for Private Internets – Định nghĩa private ranges chuẩn.
- AWS VPC Limits: Quotas – VPC IPv4 CIDR lên đến /16 mặc định, nhưng custom hỗ trợ /8 (không thay đổi đến 2026).
- Kiểm tra thực tế: Tạo VPC qua AWS Console/CLI với
10.0.0.0/8thành công, subnet full range. 🧪