Mạng Linux & Container/Publish port — DNAT và docker -p
12/21
Bài 12 / 21~13 phútContainer NetworkingMiễn phí lượt xem

Publish port — DNAT và docker -p

Inbound publish port: docker -p 8080:80 → DNAT PREROUTING + FORWARD, tự port-forward iptables, pitfall bind 127.0.0.1 vs 0.0.0.0.

TL;DR: docker run -p 8080:80 không “mở firewall ma thuật” — nó map gói tới host:8080 thành container_ip:80. Kernel đổi đích bằng DNAT trên nat PREROUTING (sớm, trước routing đầy đủ), rồi gói forward qua bridge/veth vào netns app. Reply nhờ conntrack reverse-NAT. Path: client → host:port → DNAT → FORWARD → bridge → container. Pitfall kinh điển: publish chỉ 127.0.0.1:8080 (demo localhost OK, LAN/WAN chết) hoặc có DNAT mà FORWARD DROP (counter nat tăng, gói vẫn không vào container).

Staging smoke: junior docker run -d -p 8080:80 my-api, curl localhost:8080 trên máy dev xanh. PM cầm laptop cùng Wi‑Fi, gõ http://<IP-LAN-máy-dev>:8080 — timeout. Junior soi ufw status và bảo “firewall chặn”. Bạn hỏi: “docker port / ss -lntp | grep 8080 listen địa chỉ nào?” · “iptables -t nat -L -n -v rule DNAT match 127.0.0.1 hay 0.0.0.0?” · “gói từ laptop đi PREROUTING + FORWARD, không phải INPUT tới process host.” App trong container sống; publish bind loopback hoặc thiếu path forward — không phải “API chưa start”.

Khái niệm DNAT/port forward đã có ở Foundations — NAT; hook/chain ở M1 — iptables. Bài 04 SNAT là chiều ra (đổi nguồn POSTROUTING). Bài này trace + implement chiều vào — đúng mapping docker -p.

Bài này faded: lab worked dựng DNAT PREROUTING + FORWARD; bạn tự điền rule khi chỉ có DNAT mà FORWARD DROP, và tự chọn bind 127.0.0.1 vs 0.0.0.0 trước khi đối chiếu.

1. Analogy — Chuông ngoài toà → phòng cụ thể

Nhớ netns = căn hộ, bridge = switch hành lang, SNAT = tem số toà khi ra đường. Publish port là chiều khách gõ cửa từ ngoài:

  1. Khách chỉ biết số toà + nhánh chuông (host:8080) — không biết số phòng nội bộ (10.10.0.10:80).
  2. Lễ tân đổi đích trên sổ: “nhánh 8080 → phòng 10, cổng trong 80” — đúng DNAT.
  3. Đổi sổ lúc khách vừa bước vào sảnhPREROUTING (sớm), không đợi xong mới đoán “có phải thư cho host process không”.
  4. Bảo vệ đi kèm: cho phép đi xuyên hành lang tới phòng (FORWARD), không chỉ “mở quầy lễ tân” (INPUT).
Đời thườngLinux / Docker publish
Số toà + nhánh chuônghost_ip:8080 (hoặc 0.0.0.0:8080)
Số phòng + cổng trongcontainer_ip:80
Đổi đích trên sổ lúc vào sảnhDNAT nat PREROUTING
Cho đi xuyên hành langfilter FORWARD ACCEPT path
Sổ cuộc gọi hai chiềuconntrack reverse map
Chỉ mở chuông trong căn (localhost)Bind publish 127.0.0.1
Chuông mặt tiền / mọi cổngBind 0.0.0.0 (mặc định -p 8080:80)
💡 Cách nhớ

Ra đổi nguồn (SNAT/POSTROUTING). Vào đổi đích (DNAT/PREROUTING).
docker -p = khai nhánh chuông ngoài → phòng container — không phải “app tự listen trên host”.

2. Đường gói inbound: client → host:port → DNAT → container

2.1 Topology giả định (tiếp SNAT / mini-challenge)

ObjectVai tròVí dụ
Netns c1“Container” chạy app10.10.0.10/24, listen :80
c1-eth0 / veth-c1Veth pairpeer host master br0
br0Bridge + gateway10.10.0.1/24
Host publishCổng “mặt tiền”TCP 8080 → DNAT 10.10.0.10:80
Netns ext (lab)Client “ngoài” giả lập192.0.2.2 → hit host 192.0.2.1:8080
flowchart LR
    subgraph EXT["Client / netns ext"]
        CURL["curl host:8080"]
    end
    subgraph HOST["Init / host netns"]
        IN["iface in"]
        PRE["nat PREROUTING DNAT"]
        FW["filter FORWARD"]
        BR["br0"]
        V["veth-c1"]
    end
    subgraph C1["Netns c1"]
        ETH["c1-eth0 10.10.0.10"]
        APP["app :80"]
    end
    CURL --> IN
    IN --> PRE
    PRE -->|"dst becomes 10.10.0.10:80"| FW
    FW --> BR
    BR --> V
    V --> ETH
    ETH --> APP

2.2 Từng bước L3 (request)

  1. Client gửi TCP tới host_publish_ip:8080 (trên lab: 192.0.2.1:8080).
  2. nat PREROUTING: rule DNAT đổi destination thành 10.10.0.10:80. Conntrack ghi mapping.
  3. Routing host: đích giờ là IP trên bridge domain → không local-delivery thuần cho process host trên :8080 → path forward ra br0 / veth.
  4. filter FORWARD: policy/rule phải ACCEPT path vào container (và reply RELATED,ESTABLISHED). DROP ở đây = timeout dù DNAT “đúng trên giấy”.
  5. Bridge + veth: frame vào netns c1; app accept trên :80 (trong netns container, không phải ss trên host — bài 01).
  6. Reply: conntrack un-DNAT (client vẫn thấy src là host:8080, không thấy tự nói chuyện với 10.10.0.10).

Vì sao “mở INPUT 8080” không đủ?
Sau DNAT, gói không còn là “traffic tới daemon host listen 8080” theo mental model firewall cổ điển. Path chính là PREROUTING (nat) → FORWARD (filter) → bridge. UFW/rule chỉ soi INPUT dễ publish Docker — đã map ở M1 iptables §4.4.

2.3 SNAT vs DNAT — một bảng chốt

SNAT / MASQUERADE (bài 04)DNAT (bài này)
Đổi fieldSourceDestination
Chiều điển hìnhContainer / host ra ngoàiClient vào service nội bộ
Chain nat cổ điểnPOSTROUTINGPREROUTING
CLI Docker gắnEgress bridge (Engine MASQUERADE)docker run -p / publish
Câu hỏi debug“Container curl WAN?”“Ngoài hit host:port vào app?”

3. docker -p 8080:80 map rule gì?

3.1 Cú pháp publish (đủ dùng hằng ngày)

CLIÝ nghĩa
-p 8080:80Host mọi iface (0.0.0.0) cổng 8080 → container cổng 80
-p 127.0.0.1:8080:80Chỉ loopback host 127.0.0.1:8080 → container :80
-p 10.0.0.5:8080:80Chỉ bind IP host đó
-p 80 / -PHost port ngẫu nhiên / mọi EXPOSE — vẫn cùng cơ chế DNAT/proxy

Survey trên host có Docker (đọc, đừng xoá mù):

# What did Engine publish?
docker port <container>
ss -lntp | grep -E '8080|docker-proxy' || true

# NAT: DNAT / chain DOCKER thường sống ở đây
sudo iptables -t nat -L PREROUTING -n -v
sudo iptables -t nat -L DOCKER -n -v 2>/dev/null || true

# Filter path vào container
sudo iptables -L FORWARD -n -v
sudo iptables -L DOCKER -n -v 2>/dev/null || true

3.2 Mapping mental model → object Engine

Object bài / netfilterDocker bridge điển hình
DNAT host:808010.10.0.10:80Rule trong chain DOCKER (nat), jump từ PREROUTING
FORWARD ACCEPT vào container:80Rule filter DOCKER / DOCKER-FORWARD (+ DOCKER-USER trước)
App listen trong netnsProcess trong container; docker exec / nsenter để ss
Host-local curl localhost:8080Thường docker-proxy userland và/hoặc rule nat bổ sung — không chỉ “một dòng PREROUTING”
📌 docker-proxy vs pure DNAT

Với client ngoài host, path kernel DNAT PREROUTING + FORWARD là lõi cần hiểu. Với curl trên chính host, Engine historically hay có process docker-proxy listen host port rồi nối vào container — vẫn cùng ý publish, thêm một lớp host-local. Lab dưới tái DNAT + FORWARD bằng tay và dùng netns ext để gói thật sự đi PREROUTING (không phụ thuộc docker-proxy).

3.3 Vì sao phải DNAT sớm (PREROUTING)?

Routing decision sau PREROUTING tách: gói cho local process vs forward. Publish cần client gõ IP host + port host, nhưng app chỉ listen IP container. Đổi đích sớm → routing thấy 10.10.0.10 → forward vào bridge. Nếu chỉ “mở port” trên host mà không DNAT, không có process host accept :8080 (trừ docker-proxy) — hoặc process host khác ăn nhầm port.

4. Worked lab — port forward tay (không Docker)

Chạy trên Linux có netns + iptables + sudo (+ python3 cho HTTP nhỏ). macOS/Docker Desktop không cùng view ip netns.

4.1 Skeleton: container netns + bridge + client “ngoài”

# --- cleanup leftovers ---
sudo ip netns del c1 2>/dev/null || true
sudo ip netns del ext 2>/dev/null || true
sudo ip link del br0 2>/dev/null || true
sudo ip link del veth-ext 2>/dev/null || true

# --- bridge + "container" c1 ---
sudo ip netns add c1
sudo ip link add br0 type bridge
sudo ip link set br0 up
sudo ip addr add 10.10.0.1/24 dev br0

sudo ip link add veth-c1 type veth peer name c1-eth0
sudo ip link set c1-eth0 netns c1
sudo ip link set veth-c1 master br0
sudo ip link set veth-c1 up

sudo ip netns exec c1 ip link set lo up
sudo ip netns exec c1 ip link set c1-eth0 up
sudo ip netns exec c1 ip addr add 10.10.0.10/24 dev c1-eth0
sudo ip netns exec c1 ip route add default via 10.10.0.1

# --- "external" client on another L3 leg (hits PREROUTING on host) ---
sudo ip netns add ext
sudo ip link add veth-ext type veth peer name ext0
sudo ip link set ext0 netns ext
sudo ip link set veth-ext up
sudo ip addr add 192.0.2.1/24 dev veth-ext

sudo ip netns exec ext ip link set lo up
sudo ip netns exec ext ip link set ext0 up
sudo ip netns exec ext ip addr add 192.0.2.2/24 dev ext0

# Sanity: LAN container + gateway
sudo ip netns exec c1 ping -c 1 10.10.0.1

4.2 App listen trong container

# HTTP on :80 inside c1 (background). Bind all addresses in THAT netns.
sudo ip netns exec c1 python3 -m http.server 80 --bind 0.0.0.0 >/tmp/c1-http.log 2>&1 &
sleep 0.5

# Control: host reaches container IP directly (gateway path — NOT testing publish yet)
curl -sS -o /dev/null -w "direct:%{http_code}\n" --connect-timeout 3 http://10.10.0.10:80/ || true

4.3 Predict — trước DNAT

Thử đoán trước khi chạy

Từ netns ext, chạy curl http://192.0.2.1:8080/ trước khi thêm bất kỳ rule NAT/FORWARD publish. Host có IP 192.0.2.1 trên veth-ext; chưa có process listen host :8080, chưa DNAT.
Đoán: success hay fail? Viết một lý do cơ chế (listen? DNAT? FORWARD?) trước §4.4.

# Expect fail (connection refused / timeout) before publish rules
sudo ip netns exec ext curl -sS -o /dev/null -w "before:%{http_code}\n" \
  --connect-timeout 3 http://192.0.2.1:8080/ || echo "before:fail"

4.4 Bật forward + DNAT + FORWARD path

sudo sysctl -w net.ipv4.ip_forward=1

# DNAT: packets to host:8080 on the "uplink" -> container:80
sudo iptables -t nat -A PREROUTING -i veth-ext -p tcp --dport 8080 \
  -j DNAT --to-destination 10.10.0.10:80

# Forward path into / out of container (lab-simple)
sudo iptables -A FORWARD -i veth-ext -o br0 -p tcp -d 10.10.0.10 --dport 80 -j ACCEPT
sudo iptables -A FORWARD -i br0 -o veth-ext -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Verify rules + counters later
sudo iptables -t nat -L PREROUTING -n -v
sudo iptables -L FORWARD -n -v

Thử lại từ client “ngoài”:

sudo ip netns exec ext curl -sS -o /dev/null -w "after:%{http_code}\n" \
  --connect-timeout 3 http://192.0.2.1:8080/
# Expect HTTP 200 from python http.server

# Counters should move on DNAT + FORWARD lines
sudo iptables -t nat -L PREROUTING -n -v
sudo iptables -L FORWARD -n -v

Đọc chứng cứ: pkts trên rule DNAT tăng khi curl từ ext = gói khớp publish. curl trực tiếp 10.10.0.10:80 từ host không cần DNAT — đừng nhầm hai path.

⚠️ Lab vs production policy

Rule FORWARD lab hẹp theo lab iface (veth-ext/br0). Host Docker siết qua chain DOCKER* / DOCKER-USER. Đừng copy ACCEPT rộng lên prod; học đủ mảnh (DNAT + FORWARD), siết có chủ đích (M1).

5. Fade — FORWARD DROP và bind loopback

5.1 Tự chẩn: chỉ DNAT, FORWARD chết

Tự điền — trước khi xem đáp án

Lab §4 đang after:200. Ai đó hardening:

sudo iptables -P FORWARD DROP
# (giả sử xoá hết rule FORWARD lab; DNAT PREROUTING vẫn còn)
sudo iptables -D FORWARD -i veth-ext -o br0 -p tcp -d 10.10.0.10 --dport 80 -j ACCEPT 2>/dev/null || true
sudo iptables -D FORWARD -i br0 -o veth-ext -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true

Triệu chứng: curl http://10.10.0.10:80/ từ host có thể vẫn OK (tuỳ path local); từ ext, curl http://192.0.2.1:8080/ fail.
Viết ra: (1) table/chain nào giết inbound publish? (2) hai hướng rule tối thiểu để lab sống lại mà không -P FORWARD ACCEPT toàn cục? Không mở đáp án dưới trước.

Đáp án fade (đối chiếu):

  1. filter FORWARD — DNAT đổi đích xong gói vẫn phải forward vào br0; policy DROP + không ACCEPT khớp = chết. Nat table còn ≠ traffic vào app.
  2. Khôi phục lab: ACCEPT veth-ext → br0 dport 80 tới 10.10.0.10; ACCEPT br0 → veth-ext RELATED,ESTABLISHED. Rồi curl lại từ ext.
sudo iptables -A FORWARD -i veth-ext -o br0 -p tcp -d 10.10.0.10 --dport 80 -j ACCEPT
sudo iptables -A FORWARD -i br0 -o veth-ext -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo ip netns exec ext curl -sS -o /dev/null -w "recovered:%{http_code}\n" \
  --connect-timeout 3 http://192.0.2.1:8080/

5.2 Tự chọn: 127.0.0.1 hay 0.0.0.0?

Tự chọn — trước đáp án

Với mỗi yêu cầu, ghi publish bind nào (127.0.0.1:8080:80 vs 8080:80 / 0.0.0.0) và một câu vì sao:

  1. Dev chỉ cần hit API từ browser trên cùng máy Docker; cấm máy khác trong quán cà phê đụng port.
  2. Demo sprint: tester mang laptop, hit http://<IP-LAN-máy-dev>:8080 trong phòng họp.
  3. Production edge: reverse proxy trên cùng host nối 127.0.0.1:8080; Internet chỉ nói chuyện với proxy :443.

Viết xong mới đối chiếu bảng dưới.

Nhu cầuChọnVì sao
(1) Chỉ localhost dev127.0.0.1:8080:80Không listen mặt LAN — giảm surface khi cafe Wi‑Fi
(2) Demo LAN8080:80 (0.0.0.0)Client khác host phải tới IP LAN + port publish
(3) Proxy cùng host127.0.0.1:8080:80 (phổ biến)App không public thô; TLS/terminate ở proxy

Tương đương lab (ý tưởng, không bắt buộc gõ hết): DNAT match thêm -d 127.0.0.1 chỉ bắt loopback; match không giới hạn dest IP (hoặc -d IP LAN) = publish “mặt tiền”. Docker: -p 127.0.0.1:8080:80 vs -p 8080:80.

6. Pitfall tổng hợp + map Docker

Nhầm 1: “curl localhost xanh ⇒ publish OK cho cả team.”
✅ Localhost chỉ chứng minh path loopback / proxy host. Client LAN/WAN cần bind 0.0.0.0 (hoặc IP đúng iface) + path PREROUTING + FORWARD.

Nhầm 2: “Chỉ cần DNAT, không cần FORWARD.”
✅ Sau DNAT gói forward vào netns. FORWARD DROP / mất rule DOCKER* = publish chết; counter nat có thể vẫn tăng.

Nhầm 3: “Soi ss trên host thấy app listen :80.”
✅ App listen trong netns container. Host thấy docker-proxy / rule nat, không phải PID app (trừ host network mode).

Nhầm 4: “SNAT và DNAT cùng một nút ‘bật NAT’.”
SNAT egress đổi source POSTROUTING; publish đổi dest PREROUTING. Hai chiều, hai field.

Nhầm 5: “iptables -t nat -F cho sạch.”
✅ Xoá publish + MASQUERADE Docker hàng loạt. Policy thêm: DOCKER-USER, không flush mù.

# Cleanup THIS lesson (rules + netns). Adjust if you re-added FORWARD lines.
sudo iptables -t nat -D PREROUTING -i veth-ext -p tcp --dport 8080 \
  -j DNAT --to-destination 10.10.0.10:80 2>/dev/null || true
sudo iptables -D FORWARD -i veth-ext -o br0 -p tcp -d 10.10.0.10 --dport 80 -j ACCEPT 2>/dev/null || true
sudo iptables -D FORWARD -i br0 -o veth-ext -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true

# Stop http.server in c1 if still running (best-effort)
sudo ip netns exec c1 pkill -f "http.server 80" 2>/dev/null || true

sudo ip netns del c1 2>/dev/null || true
sudo ip netns del ext 2>/dev/null || true
sudo ip link del br0 2>/dev/null || true
sudo ip link del veth-ext 2>/dev/null || true
Docker / runtimeObject bài này
-p 8080:80DNAT host 8080 → container 80
-p 127.0.0.1:8080:80Publish chỉ loopback
Chain nat DOCKERRule DNAT Engine inject
filter DOCKER / FORWARDCho gói vào veth/container
docker-proxyLớp host-local listen (bổ sung)
“LAN không vào được, localhost được”Bind 127.0.0.1 hoặc firewall path PREROUTING
flowchart TB
    A["Symptom: client cannot hit host:8080"] --> B{"App listen inside container netns?"}
    B -->|"no"| APP["Fix process bind / port in netns"]
    B -->|"yes"| C{"nat PREROUTING / DOCKER DNAT match port?"}
    C -->|"no"| DNAT["Add/fix DNAT or docker -p"]
    C -->|"yes"| D{"FORWARD / DOCKER accept path?"}
    D -->|"DROP"| FW["Fix FORWARD or DOCKER-USER"]
    D -->|"yes"| E{"Publish bind 127.0.0.1 only?"}
    E -->|"yes + client remote"| BIND["Republish 0.0.0.0 or correct IP"]
    E -->|"no"| NEXT["tcpdump veth/br0 — next lesson"]

📚 Deep Dive — man page & docs

📚 Deep Dive — tài liệu gốc

Spec / reference:

Ghi chú: Backend nftables: cùng mental model hook/table; survey nft list ruleset. Lab dùng iptables cho khớp docs Docker phổ biến.

Liên hệ các bài khác

Tóm tắt

  • Publish port = DNAT (đổi đích) trên nat PREROUTING + filter FORWARD vào bridge/container; reply nhờ conntrack.
  • docker -p 8080:80 ≈ map host:8080 → container_ip:80 (chain DOCKER / docker-proxy trên Engine).
  • Đường gói: client → host:port → DNAT → FORWARD → br0/veth → app trong netns.
  • 127.0.0.1:hostPort:containerPort chỉ loopback; omit IP / 0.0.0.0 = publish mọi iface — pitfall demo localhost.
  • Pitfall: tin curl localhost, DNAT không FORWARD, nhầm SNAT/DNAT, flush nat Docker.
  • Fade: tự chẩn FORWARD DROP + tự chọn bind loopback vs all-interfaces.

7. Tự kiểm tra

Tự kiểm tra
Q1
Liệt kê hai mảnh netfilter tối thiểu (ngoài app đang listen trong netns) để client ngoài hit host:8080 vào container:80. Thiếu mỗi mảnh triệu chứng gần đúng là gì?
(1) nat PREROUTING DNAT map host:8080 → container_ip:80 — thiếu: không có (hoặc sai) path publish; connection refused/timeout tùy có docker-proxy hay không. (2) filter FORWARD ACCEPT path vào bridge/container (và reply established) — thiếu: DNAT có thể khớp nhưng gói DROP trước khi vào netns. Cả hai + app listen đúng netns mới đủ mental model publish.
Q2
Trace một request từ client ngoài tới host:8080 publish vào 10.10.0.10:80: object/hook nào lần lượt, và field IP nào bị DNAT đổi?
Client → iface host → nat PREROUTING DNAT đổi destination (và thường port) thành 10.10.0.10:80 → routing host chọn forward ra br0 → filter FORWARD → bridge/veth → netns container → app :80. Source client giữ nguyên trên request (conntrack lo reverse khi reply). Không đổi source kiểu SNAT ở bước publish chính.
Q3
docker run -p 8080:80 khác -p 127.0.0.1:8080:80 ở điểm bind nào? Kịch bản nào xanh localhost mà LAN fail?
-p 8080:80 publish trên 0.0.0.0 (mọi iface host). -p 127.0.0.1:8080:80 chỉ loopback. Kịch bản fail: dev curl localhost OK; máy khác trong LAN curl IP LAN:8080 timeout/refuse vì không có listener/DNAT cho địa chỉ non-loopback.
Q4
Vì sao sau DNAT, debug chỉ iptables -L INPUT (filter) dễ bỏ sót root cause publish?
Publish cổ điển đi PREROUTING nat rồi FORWARD, không terminate như service host thuần trên INPUT. INPUT xanh/đỏ không chứng minh path DNAT+forward vào container. Cần -t nat -L PREROUTING/DOCKER -n -vFORWARD / chain Docker + counter khi reproduce.
Q5
Fade: DNAT PREROUTING còn, pkts DNAT tăng khi client thử, nhưng app không nhận connection. Bạn nghi chain nào trước và vì sao counter nat tăng vẫn tương thích?
Nghi filter FORWARD (DROP/policy/rule thiếu) hoặc isolation Docker chặn sau NAT. DNAT chạy sớm trên PREROUTING — counter nat tăng chứng minh gói khớp map port, không chứng minh gói đã được forward ACCEPT tới veth/container. Bước tiếp: iptables -L FORWARD -n -v / chain DOCKER, tcpdump trên br0/veth.
Q6
Phân biệt nhanh publish DNAT bài này với MASQUERADE egress bài 04 — đổi field nào, chain nat nào, chiều nào?
DNAT publish: đổi destination, thường PREROUTING, chiều vào (client → host:port → container). MASQUERADE/SNAT: đổi source, thường POSTROUTING, chiều ra (container → Internet). Nhớ: vào đổi đích, ra đổi nguồn.
Q7
Junior flush iptables -t nat -F trên host Docker đang chạy nhiều -p. Hệ quả publish/egress nào, và chỗ đúng để siết policy user là gì?
Mất rule DNAT publish và thường cả MASQUERADE egress bridge → container không vào được từ ngoài và có thể không ra Internet. Chỗ siết policy khuyến nghị: chain DOCKER-USER (filter), không flush mù nat/filter Engine. Khôi phục: restart Docker/engine networking hoặc tái tạo container/publish theo runbook — đừng improvise một nửa rule.

Bài tiếp theo: Debug container networking — nsenter và tcpdump

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Bài này có giúp bạn hiểu bản chất không?

Hỏi đáp về bài này

Chưa có câu hỏi

Đặt câu hỏi

Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).

Đặt câu hỏi đầu tiên

Bài tiếp theo

Debug container networking — nsenter và tcpdump