Test yourself
Advanced container security
Final exam · 41 questions · answers explained as you pick
Container internals
7 questions
01An audit script compares
/proc/1/ns/* with /proc/$P/ns/* for a container started with default settings on Docker 29.8.2. Seven links differ and the user link matches. The draft finding reads "someone started this container with --userns host". What is the accurate reading?Incorrect — Docker does not create a user namespace by default. The lab's default nginx container listed systemd as the first process in its user namespace, the host's.
Correct — Seven private namespaces plus the host user namespace is the default shape. Only userns-remap or rootless Docker change the user row.
Incorrect — User namespaces nest. The namespaces lesson created one as root with
unshare --user and mapped UID 0 to 100000.Incorrect — Docker 29.8.2 with runc 1.5.1 gives each container its own time namespace, with both offsets set to zero.
02A vendor image passes every image scan your pipeline runs. A host audit later finds that its container sees the host's systemd as PID 1. Where does that setting live, and how do you confirm it without trusting the container?
Incorrect — Images carry no namespace settings. Sharing is chosen when the container is created, which is why an image scan never sees it.
Incorrect — An entrypoint cannot leave its PID namespace. The namespace is set up by the runtime before the entrypoint runs.
Incorrect — The lab's other containers on the same daemon had private PID namespaces. The choice is per container.
Correct —
--pid host is a run-time option recorded in HostConfig, and the host-side inode comparison proves it independently.03A web container has
--memory 512m and never restarted. Its memory.events shows oom_kill 3, and docker events replays three oom events but no die. The on-call engineer closes the alert because "the container is still up, so nothing was killed". What happened?Correct — The OOM killer picks a victim inside the group that hit
memory.max. When the victim is not PID 1, the container keeps running and its exit code never changes.Incorrect — The lab saw
oom_kill climb to 948 while stress-ng kept running and later exited 0. The event does not depend on PID 1 dying.Incorrect —
max counts how often usage hit the limit; oom_kill counts processes the OOM killer killed. Swapped pages would show in memory.swap.current.Incorrect — A container that reaches its own
memory.max gets an OOM kill inside its own group. A host-wide out-of-memory condition is a different event.04A container on the lab VM was started with no resource flags at all. A bug in its job runner starts a runaway process tree. On this host, what stops the tree from taking every process slot on the machine?
Incorrect — Memory and CPU read
max in an unlimited container, but the lab read pids.max as 6326 in the same container.Incorrect — There is no built-in limit of 100. The value the lab read came from systemd, not from Docker.
Correct — Each
docker-<id>.scope inherits systemd's DefaultTasksMax (6326 on this VM). It contains the tree, but a few thousand per container can still hurt, so set --pids-limit.Incorrect — The cgroup namespace changes how paths look from inside. It sets no limit on how many tasks the group may create.
05A runtime escape like CVE-2024-21626 is announced while one host still runs an unpatched runc. Container A runs as root and container B as
USER 10001; both show 0 0 4294967295 in /proc/self/uid_map. If both were exploited the same way, what could each process change on the host?Incorrect — An escape keeps the UID the process already had. The lesson's point is that the UID is fixed when the container starts.
Incorrect — B could use the descriptor too. What it could change afterwards was limited by UID 10001's own permissions.
Correct — With the identity map there is no user namespace, so the numbers cross unchanged. That is why running as non-root cut the damage of Leaky Vessels.
Incorrect — Both are in the default set of 14. Even with every capability dropped, root still owns every root-owned file.
06A nightly fleet sweep reads
CapBnd (the bounding set) from /proc/<pid>/status on the host for every container on a kernel 7.0 host. Which value identifies a container started with --privileged?Correct — That is all 41 capabilities this kernel defines (
cap_last_cap is 40). The lab read it as the effective set of a root process in a --privileged container, together with Seccomp: 0; the bounding set is the same.Incorrect — That is the default 14 plus bit 21,
CAP_SYS_ADMIN: a --cap-add SYS_ADMIN container. Worth a look, but not privileged.Incorrect — That would be the first 32 capabilities only. Kernel 7.0 defines 41, and
--privileged grants all of them.Incorrect — That mask covers only 38 capabilities. On this kernel a privileged container shows all 41.
07A service runs as
USER 10001 with --cap-add SYS_ADMIN "for a FUSE mount that never got built". The image still contains a setuid-root debug helper, and the container has no security options. A reviewer says the added capability is harmless because a non-root process cannot use it. What is missing from that argument?Incorrect — That is true for ordinary binaries. The setuid helper is the way up into the bounding set.
Incorrect —
--cap-drop ALL empties the bounding set, but the helper still becomes effective UID 0, which owns every root-owned file.Incorrect — The lab ran the setuid copy under the default profile and it came up with
euid=0. seccomp does not block that.Correct — A program that becomes root at
execve gets the bounding set. --security-opt no-new-privileges makes execve ignore the setuid bit.7 questions · explanations appear as you answer
Minimal & secure images
8 questions
01A public GitHub repository builds with
docker/build-push-action and passes NPM_TOKEN as a build argument used only in the builder stage. docker history --no-trunc of the pushed final image shows no token. Security asks where else the token can be read. Which list is right?Incorrect —
mode=max provenance records the build request, arguments included. The lab found the fake token four times in a max attestation of a clean final image.Correct — The action adds
mode=max provenance for public repositories. The log prints the RUN line with the value substituted, buildx history keeps the argument, and the attestation travels with the image to anyone who can pull it.Incorrect — The final stage's history had zero hits in the lab. The builder stage's history leaks, but only when that stage is built as its own image.
Incorrect —
mode=min exports only the final result's layers and had no hits in the lab. mode=max cache keeps intermediate layers, not build arguments.02A team moved its credentials to
RUN --mount=type=secret,id=npmrc and RUN --mount=type=ssh, and still builds with --provenance=mode=max and a mode=max cache export. An auditor asks what the max attestation now records about those credentials. What did the lab find?Incorrect — The lab searched the attestation for the token and for a line of the private key and found neither.
Incorrect — The request recorded only identifiers. No path and no hash of the secret appeared.
Correct — The request showed
"secrets":[{"id":"npmrc"}] and "ssh":[{"id":"default","optional":true}], which is useful for audit and reveals nothing.Incorrect — The mounts are recorded, by id. The attestation shows that they were used, not what they held.
03A Go service used to build in the Debian-based
golang image and run on Debian slim. It now copies the same binary onto gcr.io/distroless/static-debian13:nonroot, and the container fails with exec /app: no such file or directory. The code uses net and os/user. What is the cause?Correct — Go turns cgo on when it finds a C compiler, and code using
net or os/user then links against glibc. file on the artifact shows dynamically linked and names the interpreter.Incorrect — distroless static ships
/etc/ssl/certs/ca-certificates.crt, and a missing CA bundle shows up as an x509 error at request time, not at exec.Incorrect — A root-owned file with mode 0755 is executable by any UID. Permission problems report
permission denied.Incorrect — distroless has no shell, so shell form would fail. The lab ran exec-form entrypoints on distroless without trouble.
04A Dockerfile copies the whole context, including
.env, and a later step deletes it. A reviewer proposes docker build --squash so the deleted file and the old apt lists disappear from the image. What does that do on a default Docker 29 install?Incorrect — That was the legacy builder's experimental feature. BuildKit built the same four layers in the lab.
Incorrect — The flag was accepted, not refused. The build completed with a warning.
Incorrect — The lab ran on the containerd store and the history still showed every layer.
Correct — The warning says squash is removed with BuildKit and names multi-stage as the replacement, and keeping
.env out of the context means no layer ever holds it.05A nightly job rescans stored Syft SBOMs and reports no urllib3 finding for a Python release.
trivy image on the same digest reports a fixable urllib3 CVE with no package path. Where is that urllib3, and what removes the finding for good?Incorrect — The finding is real: the package is present. VEX records exploitability decisions, not scanner mistakes.
Correct — BuildKit's Syft read
pip/_vendor/bom.cdx.json, standalone Syft did not, and a multi-stage build without pip in the runtime image removes the code and the finding.Incorrect — Debian packages carry a path and appear in Syft's SBOM. These findings had no path because they came from pip's bundled SBOM.
Incorrect — The requirements file pinned only Flask and Werkzeug. The urllib3 Trivy found is the copy pip bundles for itself.
06After the March 2026 trivy-action compromise, a team checks its workflows. One used
aquasecurity/trivy-action pinned to a full commit SHA from early 2024. The team concludes it was safe because a SHA cannot be moved. What does the provenance lesson say?Correct — Pins to commits older than April 2025 were still exposed because the pinned code pulled in another action by tag. A pin covers what it names.
Incorrect — A pin does not reach into what the pinned code fetches. That code fetched a helper by tag.
Incorrect — The reverse: Trivy images referenced by digest were not affected, while workflows using the action by tag ran the stealer.
Incorrect — GitHub runs exactly the commit a SHA names. The exposure came from what that commit fetched.
07A production host deploys whatever
registry.example.com/app:1.4 points to, on the grounds that only CI can push there. A leaked token lets someone push an unreviewed build under that tag. Which control stops that image from running?Incorrect — Docker Content Trust was removed from the CLI in 29.0. The lab set the variable, the pull succeeded, and
docker trust no longer exists.Incorrect — The leaked token is a CI credential. A registry checks credentials, not provenance; presence is not approval.
Correct — Resolve once, verify the digest against a key or identity the deploy trusts, and run exactly that digest so the tag cannot move in between.
Incorrect — The pushed image targets the same platform. Platform selection says nothing about who built it.
08A release job runs
docker push registry/app:2.0, then cosign sign --key ci.key registry/app:2.0. Another pipeline occasionally pushes to the same tag. What is wrong with the order?Incorrect — A Cosign signature covers a digest. The tag is resolved once, when the sign command runs.
Incorrect — Signing happens after the push, on the digest the registry stored. Signing earlier signs a candidate nobody can verify yet.
Incorrect — Verifying by tag resolves the tag again. Both steps can then refer to different images than the one tested.
Correct — Take the digest from the push output or
--metadata-file, and sign, attest, verify and promote that digest.8 questions · explanations appear as you answer
Hardening the container
7 questions
01A policy check flags a Redis container as "runs as root" because
docker image inspect shows an empty Config.User. On the host, ps shows redis-server running as UID 999. Which reading is right?Incorrect — No user namespace is involved on a default host. The host's
ps shows the real numeric UID of the process.Incorrect —
Config.User is the image's USER. The image has none, and the switch happens in the entrypoint.Correct — That pattern needs SETUID and SETGID for a moment at start, so it still relies on dropped capabilities, no-new-privileges and the default profiles.
Incorrect — Only a setuid or setgid bit changes the UID at
execve. Here the entrypoint switches user explicitly.02A platform team wants Docker Engine itself to refuse any container that would run as UID 0, the way Kubernetes refuses one under
runAsNonRoot. What can plain Docker do?Correct — The lab turned a USER 10001 image back into root with
--user 0. userns-remap and rootless Docker change what UID 0 means instead of refusing it.Incorrect — no-new-privileges stops setuid and file-capability gains at
execve. It does not refuse root containers.Incorrect — USER is a default.
--user and Compose user: replace it.Incorrect — Remapped containers still run as root inside; that root maps to an unprivileged host UID. Nothing is refused.
03Stock
nginx:1.30-alpine with --read-only exits 1. The log shows an info line, can not modify /etc/nginx/conf.d/default.conf, then mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system). Which change keeps the root filesystem read-only and lets it start?Incorrect — Volume options protect volumes. Without
--read-only every image path is writable again.Correct — The lab started nginx that way and it served the page. The
default.conf line is optional and can stay.Incorrect — The edit is an optional IPv6 tweak. A writable, executable volume over the config directory is exactly where an intruder would stage changes.
Incorrect — Error 30 is EROFS, a read-only mount. No capability makes a read-only mount writable.
04A fleet check looks for containers on the approved strict seccomp profile by searching
HostConfig.SecurityOpt for the path /etc/docker/seccomp/strict.json. It finds none, though several teams start containers with --security-opt seccomp=/etc/docker/seccomp/strict.json. Why?Incorrect —
null is what a container on the builtin profile shows. A custom profile is recorded.Incorrect — The lab's custom-profile container did not show
builtin; it showed the profile itself.Incorrect — The lab read the value from
SecurityOpt. There was no separate path field to find.Correct — The lab's custom container showed
seccomp={"defaultAction":...} inline. Compare or hash that JSON against the profile you approved.05A stricter seccomp profile is
default.json with chmod removed. On the arm64 lab VM, chmod inside the container still works. What explains it?Incorrect — The profile content is sent with each
docker run. Removing the whole chmod family in the next step did take effect immediately.Correct — The lab removed
chmod, fchmod, fchmodat and fchmodat2, and only then did chmod fail. Which call a binary makes depends on the architecture and the C library.Incorrect — Docker's profile is an allow-list over every architecture in
archMap. An unmatched call is refused, not let through.Incorrect — Capabilities can open extra rules in the default profile, but a name you removed is gone. The real cause is a different system call.
06You are writing a custom AppArmor profile for a service and want to learn what it needs before you enforce anything. Which procedure gives you the list without breaking the service?
Incorrect — An unconfined process is not checked by any profile, so nothing is logged for it.
Incorrect — Docker generates and loads only docker-default. Custom profiles are loaded with
apparmor_parser, and an unknown name stops the container from starting.Correct — Complain mode logs what it would refuse as
apparmor="ALLOWED" and allows it; reload in enforce mode afterwards. aa-logprof can propose rules from those lines.Incorrect — docker-default's explicit denies are exactly the ones AppArmor does not log, unless written
audit deny.07An engineer debugging a host issue runs a container with
--pid=host --cap-add SYS_PTRACE and tries to attach to host PID 1. It fails with Permission denied, and the kernel log shows apparmor="DENIED" operation="ptrace" profile="docker-default". They propose adding seccomp=unconfined. What is going on?Correct — The log names AppArmor. That denial is the last wall between a host-PID container and host processes, so it should stay.
Incorrect — The profile allows
ptrace from kernel 4.8 and opens more tracing calls with CAP_SYS_PTRACE. The denial in the log came from AppArmor.Incorrect — Sharing a namespace does not change the capability sets. The lab container ran as root and held the added capability.
Incorrect — The freezer pauses a group; it is not an access control. The kernel log names the profile that refused.
7 questions · explanations appear as you answer
Hardening the daemon & host
5 questions
01On a Docker 29.8 rootless host, a monitoring container runs with
--net=host. ss -ltnp on the host shows its listener owned by python3 in the host's namespace. A reviewer quotes an older guide: under rootless, --net=host only shares RootlessKit's namespace, so it is harmless. What is correct?Incorrect — gvisor-tap-vsock carries bridge traffic. The lab's
--net=host listener sat in the host namespace and the host reached it directly.Incorrect — Rootless Docker 29.5 and later accepts
--net=host; the lab ran a Python server that way.Incorrect — The listener was on
0.0.0.0:8081. Sharing the namespace means sharing the whole stack.Correct — The container shares the host network namespace. Ports below 1024 still need the sysctl, because the container is not RootlessKit.
02After a host moves to rootless Docker,
docker exec app cat /proc/self/attr/current prints runc (unconfined), where the rootful container printed docker-default (enforce). Security asks whether hardening went backwards. What is the accurate answer?Incorrect —
docker info on the rootless daemon listed rootless and no apparmor under Security Options. The profile is not applied.Correct — Container root is now your login UID and other UIDs are subordinate IDs, but the MAC layer is gone, so keep non-root images and dropped capabilities.
Incorrect — The lesson lists AppArmor as the layer that no longer applies. seccomp and the capability set stay.
Incorrect — Ubuntu's rootlesskit profile is
flags=(unconfined) with a userns rule. It names the binary and restricts nothing.03To avoid the docker group, an administrator gives developers a sudo rule that allows only
/usr/bin/docker as root. A reviewer calls this a sandbox, since the developers can run nothing else. What does the rule actually give you?Incorrect — A rule that names only
/usr/bin/docker allows any arguments, --privileged and host mounts included.Incorrect — The daemon sees a client on its socket running as root. The lab ran
sudo docker ps normally.Correct — The journal records the account and the full command line. The daemon still does whatever the API request asks, as root.
Incorrect — An empty docker group removes one path to the socket. A sudo rule for docker is another path with the same power.
04After
"userns-remap": "default" is enabled on a Docker 29 host, a VPN container started with --network=host and a hardware tool started with --privileged both fail with daemon errors. What is the cause, and what do the workarounds cost?Correct — The lab got "privileged mode is incompatible with user namespaces" and "cannot share the host's network namespace". With
--userns=host the map is the identity map again.Incorrect — The data root did move to
/var/lib/docker/<uid>.<gid>, but the errors name privileged mode and the host network, not missing images.Incorrect — The lab's
--privileged container was refused with exit 125 until --userns=host was added.Incorrect — Remapping does disable the containerd store, but these refusals come from the user namespace itself, whichever store is in use.
05A shared build host runs userns-remap so that two tenants' containers "cannot touch each other". Tenant A's container runs as root and tenant B's also runs as root. What does remapping guarantee here?
Incorrect — All containers on a remapped daemon share one range. Root in every container is the same host UID.
Incorrect — Separate namespaces with the same mapping still land on the same host UIDs for shared files.
Incorrect — Remapped root holds capabilities only over objects its user namespace owns. It cannot write a root-owned host path, as the lab showed.
Correct — Remapping separates containers from the host, not from each other, and it does nothing about a kernel bug or access to the socket.
5 questions · explanations appear as you answer
Runtime & network hardening
7 questions
01An inventory script runs
docker inspect -f '{{.NetworkSettings.IPAddress}}' web and now errors on Docker 29. What changed, and what replaces it?Incorrect — The field is gone for every container on Docker 29, whichever network it uses.
Incorrect —
HostConfig holds what was requested. Assigned addresses stay under NetworkSettings, per network.Correct — The lesson reads it with
{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}.Incorrect — Templates read nested fields fine. The field the old template names no longer exists.
02A host drops
169.254.169.254 for all containers with a rule appended to DOCKER-USER. After the daemon is switched to "firewall-backend": "nftables", containers can read the metadata service again. Why, and where does the policy go now?Incorrect — The nftables backend has no DOCKER-USER chain at all. Rule order inside it is not the problem.
Correct — Docker never touches a table it did not create, and a drop in any nftables base chain is final regardless of priority.
Incorrect — Under iptables the lab showed DOCKER-USER rules surviving a daemon restart. The change here is the backend.
Incorrect — Container traffic to an outside address is forwarded by the kernel. The lab dropped it again with its own nftables table.
03Two databases receive their root passwords through
*_FILE variables backed by Compose secrets: one postgres, one MySQL. A host sweep of /proc/<pid>/environ for the main processes finds a password in one of them. Which, and why?Correct — The postgres entrypoint exports the value only in its init process and unsets it before the server starts; MySQL's PID 1 keeps it.
Incorrect — The lab found zero PASS variables in the postgres server's environment, because the entrypoint unsets them first.
Incorrect — Whether the value stays in the running process depends on the image. postgres clears it.
Incorrect —
/proc/<pid>/environ is read from the process's own memory, not from the container config, and it can still hold a value the image exported.04A team rotates the postgres password by writing a new value into the Compose secret's backing file and restarting the database. Clients that read the new file are now rejected with
password authentication failed. What is wrong with the procedure?Incorrect — The secret is a read-only bind mount of the host file. The new contents were what the clients read.
Incorrect — Ownership affects who can open the file. Here the server started fine and rejected the new password.
Incorrect — A bind mount shows the current file. The issue is when postgres reads it.
Correct — Changing the file is not rotation. Change the credential at the source and make the consumer re-read, or use short-lived credentials from a secrets manager.
05A sidecar is started with
--ipc=host "for shared-memory performance". It runs as a non-root user with every capability dropped. What does that flag expose?Incorrect — That is
--uts=host. The IPC namespace covers shared memory and message queues.Incorrect — Shared memory is opened with ordinary permissions, not capabilities. The lab read the marker without any added capability.
Correct — The lab wrote a marker to the host's
/dev/shm and read it from a --ipc=host container.Incorrect — That is
--pid=host. Each share hands over a different subsystem.06A container with
--restart unless-stopped is running a miner it dropped into /tmp, and it holds an open connection out. The on-call engineer wants to run docker restart to stop it quickly and look afterwards. What should happen first?Incorrect — The layer survives a stop, but live memory, open sockets and the process environment do not.
Correct — Freeze first, record what
docker rm and the disconnect would destroy, then capture /proc/<pid>, docker cp, diff, export and commit, and set --restart=no before anything is removed.Incorrect — The attacker owns the container's userspace, so its tools can lie. A paused container refuses exec anyway, which is why capture runs from the host.
Incorrect — A restart re-runs the entrypoint, loses live memory and may fire the attacker's persistence.
07For a suspected memory-only payload, an analyst runs
docker checkpoint create on the arm64 lab host and it does not work. What does the forensics lesson say about memory capture on Docker 29?Correct — CRIU supports arm64 as well as x86_64, but the lab VM installs neither CRIU nor an experimental daemon, so the course stops at filesystem, log, socket and
/proc evidence.Incorrect — Pausing is part of containment. Checkpoint itself is still experimental on Docker 29.
Incorrect — The rootless lesson lists
docker checkpoint among the features that do not work in rootless mode.Incorrect — Commit captures the writable filesystem layer. Memory is not part of an image.
7 questions · explanations appear as you answer
Escape paths & defense
7 questions
01A container audit reads
CapEff: 00000000a80425fb, Seccomp: 2, apparmor=docker-default and NoNewPrivs: 0. The draft report says the zero means the container was started with extra privileges. What is the correct reading?Incorrect — seccomp state is the
Seccomp line, and 2 means filter mode.Incorrect — A privileged container shows
CapEff: 000001ffffffffff and Seccomp: 0. This one has the default set.Incorrect — AppArmor state is read from the profile, here docker-default in enforce mode.
Correct — Three of the four controls are on by default; this one needs
--security-opt no-new-privileges or "no-new-privileges": true in daemon.json.02A VPN client container is run with
--privileged because it creates a tun interface. In the manifest review, what should replace the flag?Incorrect — A read-only root does nothing about full capabilities, no seccomp, no AppArmor and host devices.
Incorrect — Interfaces need
NET_ADMIN. SYS_ADMIN is the broadest capability and the one mount escapes need.Correct — The lab created an interface with NET_ADMIN alone, and a single device node replaces exposing all of
/dev.Incorrect — That turns off a layer and still leaves the tun device missing. Grant the one capability and the one device.
03A backup agent mounts
-v /:/host:ro. A reviewer says the read-only flag makes it safe. What does :ro change, and what does it leave?Incorrect — The lab read a root-only mode-600 marker through a
:ro root mount.Correct —
:ro reduces a host bind mount; it does not make one safe. Mount only the directory the agent needs, read-only.Incorrect — Container root still owns every root-owned file, so dropping capabilities does not close the read of root-owned secrets.
Incorrect — The lab's write through
/:/host:ro failed with "Read-only file system". The flag works; it just is not enough.04A change request asks for
--cap-add SYS_MODULE on a monitoring agent. The requester argues that Docker's default seccomp profile blocks the module syscalls anyway, so the capability is inert. What did the lab on Engine 29.8.2 show?Correct — With the capability added,
rmmod reached the kernel and failed only because the named module did not exist. The capability is the lock.Incorrect — That is a misreading of the profile. It has allowed those syscalls to a CAP_SYS_MODULE holder since at least 2017 (Engine 17.03), and v0.2.3 still does.
Incorrect — Adding the one capability was enough in the lab, with
Seccomp: 2 still in place.Incorrect — The lab showed AppArmor refusing mounts. For the module syscalls it showed the call reaching the kernel; do not count on another layer.
05A vulnerability scanner flags CVE-2022-0492 (cgroup v1
release_agent) as critical on a fleet of Docker 29 hosts. On each host, uname -r prints 7.0.0-34-generic and stat -fc %T /sys/fs/cgroup prints cgroup2fs. How should you rate it?Incorrect — Even on vulnerable kernels, Docker's default seccomp and AppArmor profiles blocked stock containers, and these kernels carry the fix.
Incorrect — Delegation is a cgroup v2 mechanism. The flaw was in cgroup v1.
Incorrect — Remapping is not what closes it here: the kernels carry the fix, and cgroup v2 has no
release_agent file.Correct — The kernel version is the decisive fact; cgroup v2 is a second reason. Keep the default profiles and keep tracking the kernel version.
06A compliance check must prove that a workload runs under gVisor. The engineer shows
uname -r from inside the container printing 4.19.0-gvisor. What is the reliable proof?Incorrect — A compromised container can print whatever it likes. Output from inside is easy to read and easy to fake.
Correct — The runtime is part of how the container was started, recorded by the daemon outside the container.
Incorrect —
dmesg is reported by the Sentry too, so it has the same weakness as uname.Incorrect — That shows the runtime is registered on the daemon, not that this container uses it.
07A team on cloud VMs without nested virtualization installs Kata Containers and runs
docker run --runtime=kata app. It fails. What does the sandboxes lesson say Kata needs?Incorrect — gVisor and Kata are different designs. Kata runs a guest kernel in a micro-VM, which needs hardware virtualization.
Incorrect — There is no bare
kata runtime name unless you register one in daemon.json.Correct — The lab VM had no
/dev/kvm and no nested virtualization flags, so Kata could not run there.Incorrect —
runsc install registers gVisor. Kata is registered with runtimeType set to its containerd shim.7 questions · explanations appear as you answer