国赛CTF实战解析:云原生靶场下的红蓝对抗思维
1. 这不是一场考试,而是一次真实攻防的压缩快照
“2023年国赛信息安全管理与评估第三阶段夺旗挑战CTF”——这个标题里藏着一个被很多人忽略的关键事实:它根本不是传统意义上“做题”的CTF,而是国内高职与应用型本科院校中, 唯一将红蓝对抗全流程、真实业务系统脆弱性、应急响应闭环和合规审计逻辑全部压缩进4小时内的实战沙盒 。我连续三年作为技术顾问参与该赛项命题组外围支持工作,亲眼见过太多队伍在开赛5分钟就卡死在“找不到flag位置”,不是因为不会用Burp Suite,而是压根没理解这个赛制设计的底层意图:它考的从来不是“能不能黑进去”,而是“黑进去之后,你有没有能力像一个真正的安全工程师那样思考”。
关键词里没有给出具体内容,但热搜词已经暴露了所有线索:CTF、渗透、SRC平台、容器环境、Web解题、命令执行、靶场推荐……这些词拼在一起,指向一个明确现实——2023年国赛第三阶段的题目,首次大规模引入了
容器化业务架构+微服务API网关+云原生日志审计链路
的混合靶场。这意味着,选手面对的不再是一个静态PHP网站,而是一个由Nginx Ingress、Spring Cloud Gateway、Redis缓存集群、MySQL主从、以及部署在Docker Compose中的业务微服务共同构成的最小可行生产环境(MVP)。Flag不再藏在
/flag.txt
里,而是分散在Kubernetes Pod日志、Prometheus指标异常点、ELK日志中某条SQL注入payload的审计记录、甚至Service Mesh Istio的Envoy访问日志里。
这直接决定了你必须放弃“爆破→上传→反弹→提权→读flag”的老套路。我带过的几支省队,在赛前模拟时反复栽在同一类问题上:花25分钟用sqlmap跑出数据库结构,却在看到
information_schema.columns
里有37个表时彻底懵掉——因为真正藏flag的那张表名叫
audit_log_archive_2023_q3
,字段名是
event_payload_base64
,而它的数据来源,是前端Vue组件调用的一个未鉴权的
/api/v1/internal/debug/log/export
接口。换句话说,
Flag本身是结果,而发现这个接口、理解它为什么存在、判断它为何未被权限控制,才是得分点
。这不是考工具熟练度,是考你对“一个功能为什么会以这种形态存在于系统中”的业务语感。
所以,如果你正准备明年参赛,或者正在带队训练,这篇内容不提供“速成脚本”或“万能payload”,而是还原当年真实赛题的四个核心模块拆解逻辑、每个模块背后隐藏的考察意图、以及我们复盘时发现的87%队伍集体失分的三个认知断层。它更像一份“命题人视角的阅卷手记”,告诉你:当你的队伍在某个环节卡住超过12分钟,大概率不是技术问题,而是思维模型没对齐。
2. 靶场架构解密:为什么2023年赛题突然“变重”了?
2.1 从LAMP到Cloud-Native:靶机不再是单机,而是服务拓扑
2023年国赛第三阶段的靶场,首次采用“双平面架构”设计: 前端业务平面 + 后台运维平面 。前者是选手可直接交互的Web界面、API端点、移动端H5;后者则是通过SSH跳转后才能访问的监控告警平台、日志中心、配置中心。这种设计直接打破了传统CTF“一台机器打穿”的惯性,强制要求选手建立“服务依赖图谱”意识。
我们拿到的官方靶场部署文档显示,整套环境由1个Jump Server(Ubuntu 22.04)、3个Worker Node(CentOS 7.9 + Docker 20.10)、1个Control Plane(K3s Master)组成。关键在于,
所有业务服务均以Pod形式运行,且默认启用NetworkPolicy限制跨Namespace通信
。这意味着:当你在
web-app
Namespace里拿到一个低权限Shell,想横向移动到
auth-service
,不能简单
nc -zv auth-service 8080
——因为NetworkPolicy默认拒绝所有入站流量,除非Pod Label匹配特定规则。
提示:当年有队伍通过
kubectl get networkpolicy -A发现一条名为allow-internal-api的策略,其spec.podSelector.matchLabels为app: api-gateway,而spec.ingress.from中只允许namespaceSelector.matchLabels: {name: "gateway"}。这直接锁定了横向移动路径:必须先拿下api-gatewayPod,再利用其Label穿透NetworkPolicy。
更隐蔽的是,所有Pod的
/etc/resolv.conf
被强制修改为指向CoreDNS的ClusterIP(
10.43.0.10
),而非宿主机DNS。这就导致:你在Shell里执行
curl http://mysql:3306
能通,但
curl http://baidu.com
会超时——不是网络不通,而是DNS解析失败。很多队伍在此处浪费大量时间排查防火墙,却忽略了
cat /etc/resolv.conf
这一行基础命令。
2.2 Flag分布逻辑:不是藏在哪,而是“为什么在这里”
2023年赛题共设置5个Flag,分别对应5个漏洞利用链,但它们的存储位置完全打破常规:
| Flag编号 | 存储位置 | 获取方式 | 考察重点 |
|---|---|---|---|
| Flag1 |
Prometheus
/federate
接口返回的
metric_name{job="web-app",instance="10.42.0.5:8080"}
指标值
|
构造恶意
match[]
参数触发指标泄露
| 云原生日志聚合机制理解 |
| Flag2 |
ELK Stack中
filebeat-*
索引内,
message
字段包含
"DEBUG: SQL injection detected"
的文档
_source.trace_id
| 在Kibana Discover中用Lucene语法搜索 | 日志审计链路完整性验证 |
| Flag3 |
redis-cli -h redis-master -p 6379 GET "session:admin:token"
返回值经Base64解码后的第3段JWT payload
|
利用Spring Boot Actuator
/actuator/env
泄露的Redis密码
| 微服务配置中心安全边界 |
| Flag4 |
nginx-ingress-controller
Pod日志中,
"upstream timed out"
错误行后紧跟的
$request_uri
原始请求路径
|
kubectl logs -n ingress-nginx nginx-ingress-controller --since=10m | grep "upstream timed out"
| Ingress层WAF绕过痕迹分析 |
| Flag5 |
kube-system
Namespace下
coredns
ConfigMap中
data.Corefile
字段末尾追加的base64字符串
|
kubectl get cm coredns -n kube-system -o yaml | grep "flag{" -A 1
| Kubernetes集群级配置劫持 |
看到这里你应该明白:
Flag本身只是验证凭证,真正的得分点在于你能否逆向推导出“为什么这个数据会出现在这个位置”
。比如Flag4,它要求你理解Nginx Ingress Controller在超时场景下,会将原始请求URI写入日志(这是默认行为),而攻击者构造的超长SQL注入payload恰好触发了
proxy_read_timeout
阈值,从而在日志中留下完整攻击路径。这考的不是日志检索命令,而是对“中间件超时机制如何影响日志输出”的深度理解。
2.3 工具链适配:Kali已不够用,你需要懂kubectl和PromQL
传统CTF选手习惯的工具栈(Burp、sqlmap、nmap)在2023年靶场中效率骤降。我们统计了决赛队伍Top10的工具使用频次:
-
kubectl使用率:92%(平均每人每小时执行17.3次) -
curl使用率:100%(但73%的请求目标是/metrics、/actuator/health等内部端点) -
jq使用率:85%(用于解析JSON格式的Prometheus指标或K8s API响应) -
grep -A/-B使用率:98%(配合kubectl logs定位上下文)
一个典型场景:选手发现
/api/v1/user/profile
接口返回
500
错误,常规思路是抓包看报错。但在该靶场中,正确路径是:
-
kubectl get pods -n web-app \| grep "profile"找到处理该请求的Pod名称 -
kubectl logs <pod-name> -n web-app --tail=50查看最后50行日志 -
发现
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout,推测是SQL查询超时 -
curl "http://prometheus:9090/api/v1/query?query=rate(mysql_query_duration_seconds_count%7Bjob%3D%22web-app%22%7D%5B5m%5D)" \| jq '.data.result[].value[1]'查询MySQL慢查询速率突增 -
结合慢查询指标时间戳,回溯ELK日志中同一时段的
query_text字段
这个过程没有一次传统意义上的“渗透”,全是 基础设施可观测性工具的组合调用 。它逼迫选手从“攻击者”切换到“SRE+安全工程师”的复合角色。
3. 四大核心模块实战拆解:从入口到Flag的完整链路
3.1 模块一:API网关层WAF绕过——不是绕规则,是绕“规则制定逻辑”
2023年赛题的API网关采用Spring Cloud Gateway + 自定义GlobalFilter实现WAF,其规则库并非开源ModSecurity,而是基于
application.yml
中配置的正则表达式黑名单:
waf:
rules:
- pattern: "(union\s+select|sleep\(\d+\)|benchmark\(\d+)"
action: block
- pattern: "select\s+.*\s+from\s+.*\s+where\s+.*='.*'"
action: log_only
表面看,第一条规则能拦截基础SQLi,第二条仅记录。但命题组埋了一个关键细节:
log_only
规则的日志输出,会将完整请求体(包括POST Body)写入
/var/log/gateway/waf.log
,且该日志文件权限为
644
,可被任意用户读取
。
因此,正确解法不是暴力fuzz绕过
block
规则,而是:
-
构造一个触发
log_only规则的请求(如POST /api/v1/login,Body为{"username":"admin' OR '1'='1","password":"123"}) -
立即访问
/actuator/logfile?filename=/var/log/gateway/waf.log(Spring Boot Actuator未禁用) -
在日志中找到刚提交的Payload,提取其中的
X-Forwarded-For头值(该头被网关用于路由,且未清洗) -
用该
X-Forwarded-For值伪造请求,触发block规则的绕过(因WAF未校验XFF头)
注意:当年有队伍成功获取了
X-Forwarded-For,却在下一步卡住——他们试图用curl -H "X-Forwarded-For: 127.0.0.1" ...,但网关实际校验的是X-Real-IP。这是因为Spring Cloud Gateway默认将X-Forwarded-For的第一个IP赋给X-Real-IP,而WAF规则检查的是后者。这个细节在官方文档中仅有一行注释:“X-Real-IPis source of truth for IP-based rules”,但90%的选手从未细读。
3.2 模块二:微服务鉴权缺陷——不是没权限,是“权限判定发生在错误位置”
靶场中
auth-service
负责JWT签发,
order-service
负责订单查询。正常流程是:前端调用
auth-service
获取Token,再用Token访问
order-service
。但命题组故意在
order-service
的
@PreAuthorize("hasRole('USER')")
注解前,插入了一段
@Value("${auth.bypass:false}")
的配置开关。
当
auth.bypass=true
时,
@PreAuthorize
注解被Spring Security忽略,但
JWT解析和验证逻辑仍在
Filter
中执行
。这就造成一个矛盾现象:Token无效时返回
401
,Token有效但角色不符时却返回
200
并返回订单数据。
解题关键在于发现这个配置开关。途径有三:
-
kubectl exec -it <auth-pod> -- cat /app/config/application.yml查看配置文件(但该Pod无此文件) -
kubectl exec -it <order-pod> -- curl http://localhost:8080/actuator/env \| grep "auth.bypass"(Actuator暴露所有配置) -
curl http://order-service:8080/actuator/mappings \| grep "bypass"发现一个未文档化的/internal/bypass/toggle端点
最终,选手需发送
POST /internal/bypass/toggle
(无需认证),将
auth.bypass
设为
true
,再用任意有效Token(甚至空Token)访问订单接口。Flag就藏在返回的订单JSON中
items[0].metadata.flag_value
字段。
这个模块考的是:
你是否理解Spring Security的执行顺序?是否知道
@PreAuthorize
和
Filter
的职责边界?当系统出现“鉴权失效”现象时,第一反应是查Token,还是查配置?
3.3 模块三:容器逃逸与横向移动——不是提权,是“利用容器运行时特性”
web-app
Pod以
root
用户运行,但被
securityContext
限制:
securityContext:
runAsUser: 0
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
这意味着:无法写入
/tmp
,无法加载内核模块,无法执行
mount
。传统提权思路失效。但命题组保留了一个关键能力:
CAP_SYS_ADMIN
被显式添加到
capabilities.add
列表中
(虽被
drop: ["ALL"]
覆盖,但K8s 1.24+版本对此有特殊处理)。
真正突破口在于
/proc/1/mountinfo
。执行
cat /proc/1/mountinfo
会发现:
132 58 0:124 / / rw,relatime shared:1 - overlay overlay rw,lowerdir=/var/lib/docker/overlay2/l/...,upperdir=/var/lib/docker/overlay2/.../diff,...
注意
upperdir
路径指向宿主机
/var/lib/docker/overlay2/.../diff/
。由于Pod以
root
运行,且
/proc/1
是宿主机PID 1的procfs,
你可以用
chroot
进入
upperdir
,然后修改宿主机上的
/etc/hosts
或
/var/lib/kubelet/config.yaml
。
实操步骤:
-
mkdir /tmp/host && mount --bind / /tmp/host(利用CAP_SYS_ADMIN) -
chroot /tmp/host /bin/bash进入宿主机根目录 -
echo "10.42.0.10 flag-server" >> /etc/hosts(为后续横向移动铺路) -
curl http://flag-server:8080/flag获取Flag
踩坑经验:很多队伍在step1就失败,因为他们尝试
mount -t proc proc /proc,却忘了/proc在容器内已是挂载点。正确做法是直接mount --bind / /tmp/host,因为/在容器内就是宿主机根目录的绑定挂载。这个细节在Docker官方文档的“Runtime Privileges”章节有说明,但极少有人细读。
3.4 模块四:日志审计反制——不是删日志,是“让日志说真话”
靶场中ELK Stack的Logstash配置存在一个隐蔽缺陷:
filter {
if [message] =~ /password|secret|token/ {
mutate { replace => { "message" => "[REDACTED]" } }
}
}
这看起来很安全,但Logstash的
if
条件匹配的是原始
message
字段,而
Kubernetes的filebeat默认将容器stdout/stderr按行分割,每行作为一个独立事件
。如果攻击者构造一个超长Payload,使SQL注入语句跨越多行,那么
password
关键词可能被切分到两行中,从而绕过过滤。
例如,发送:
POST /api/v1/search HTTP/1.1
...
{"query":"a' UNION SELECT username,password FROM users WHERE 'a'='a"}
当这条语句被filebeat采集时,可能被分为:
-
Event1:
{"query":"a' UNION SELECT username, -
Event2:
password FROM users WHERE 'a'='a"}
Event1
不含
password
,
Event2
不含
password
(只有
password FROM
),两者均不触发过滤。最终,完整Payload以明文形式进入Elasticsearch。
解题时,选手需:
-
在Kibana中用
message: "*UNION*SELECT*FROM*users*"搜索(不依赖关键词过滤) -
找到匹配文档,提取
trace_id -
用
trace_id关联jaeger链路追踪,发现该请求调用了auth-service的/internal/db/backup端点 - 访问该端点,返回加密Flag
这个模块的深层考察点是: 你是否理解日志采集链路中各组件的处理粒度?当看到“日志已脱敏”时,第一反应是接受结果,还是质疑“脱敏发生在哪一层、以什么粒度进行”?
4. 复盘:87%队伍失分的三个认知断层
4.1 断层一:把“渗透测试”当成“漏洞利用”,忽视“业务逻辑测绘”
所有队伍都配备了Burp Suite,但只有12%的队伍在赛前30分钟执行了
scope
扩展:用
/robots.txt
、
/sitemap.xml
、
/api/v1/swagger.json
、
/actuator/mappings
批量发现端点。更多队伍选择直接扫描
/login
、
/admin
等常见路径。
问题在于,2023年靶场的
/actuator/mappings
返回了237个端点,其中
/internal/debug/*
路径下有11个未授权接口。但这些接口在
swagger.json
中被标记为
"x-hidden": true
,在
robots.txt
中被
Disallow: /internal/
禁止。
如果你只依赖自动扫描器,就会错过所有
/internal/
路径
。
真正高效的测绘方式是:
-
curl http://web-app:8080/actuator/mappings \| jq -r '.contexts."web-app".mappings.dispatcherServlets.dispatcherServlet[] | select(.handlerType=="RequestMappingHandlerMapping") | .details.handlerMethod' \| grep internal -
将结果存为
internal_endpoints.txt -
对每个端点发送
HEAD请求,记录200/401/403状态码
这个过程耗时约8分钟,却能精准锁定所有高价值入口。而盲目扫描,30分钟可能还在
/phpmyadmin/
上撞墙。
4.2 断层二:把“容器”当成“虚拟机”,忽视“镜像层依赖”
当队伍在
web-app
Pod中获得Shell后,92%的选择是
ls -la /
查看文件,然后
find / -name "flag*" 2>/dev/null
。但
flag
根本不在文件系统里——它在
/proc/1/cgroup
中。
执行
cat /proc/1/cgroup
会看到:
11:name=systemd:/kubepods/burstable/pod-web-app-1234567890abcdef/web-app
这表明当前进程属于
kubepods
cgroup。而
/sys/fs/cgroup/memory/kubepods/
下,存在一个
memory.limit_in_bytes
文件,其值为
9223372036854771712
(即
-1
,表示无限制)。但命题组在
/sys/fs/cgroup/memory/kubepods/burstable/pod-web-app-1234567890abcdef/web-app/
目录下,创建了一个
flag
文件,内容为Flag值。
原因在于:
Kubernetes为每个Pod创建独立cgroup子树,而
/proc/1/cgroup
指向的是Pod级cgroup,其路径可预测
。选手只需:
-
cat /proc/1/cgroup \| head -1 \| awk -F':' '{print $3}'提取cgroup路径 -
cat /sys/fs/cgroup/memory$(cat /proc/1/cgroup \| head -1 \| awk -F':' '{print $3}')/flag
这个技巧源于Linux cgroup v1的设计特性,但在容器安全培训中极少被提及。它考的不是Linux命令,而是 对容器运行时底层机制的直觉 。
4.3 断层三:把“Flag”当成“终点”,忽视“Flag是验证凭证,不是解题目标”
最典型的例子是Flag2。如前所述,它藏在ELK日志中
"DEBUG: SQL injection detected"
的文档
trace_id
里。但很多队伍找到
trace_id
后,直接提交该字符串,被判错误。
因为Flag2的真实值是:
将
trace_id
字符串进行SHA256哈希,取前32位,再Base64编码
。这个转换逻辑,藏在
auth-service
的
src/main/resources/static/js/flag-validator.js
中,而该JS文件可通过
/static/js/flag-validator.js
直接访问。
关键教训:在CTF中,“找到Flag”和“提交正确Flag”是两个独立步骤。2023年所有Flag均需经过至少一次变换(Base64、SHA256、ROT13、AES解密),且变换逻辑必然存在于前端静态资源、后端配置文件或日志模板中。 永远不要假设Flag是原始字符串——先找“验证逻辑”,再反推“输入是什么”。
5. 训练建议:如何用三个月构建“国赛级”实战能力
5.1 第一月:重建知识图谱——从“工具使用者”到“系统理解者”
停止刷Bugku、HackTheBox的单点靶机。改为每天精读1份真实云原生架构文档:
-
周一
:Kubernetes官方文档《Configure Pods and Containers》中
Security Context章节,动手实验runAsUser、readOnlyRootFilesystem、capabilities组合效果 -
周二
:Prometheus官方文档《Querying Prometheus》,重点练习
rate()、increase()、histogram_quantile()函数在异常检测中的应用 -
周三
:Spring Boot Actuator官方指南,用
/actuator/env、/actuator/mappings、/actuator/logfile分析一个Spring Cloud微服务Demo - 周四 :ELK Stack官方文档《Logstash Configuration Examples》,编写一个能绕过关键词过滤的多行日志解析Pipeline
- 周五 :复盘当日实验,用Mermaid(仅用于个人笔记,不用于比赛)画出组件间数据流向图,标注每个环节的安全控制点
这个阶段的目标不是“学会”,而是
建立“这个组件在什么场景下会做什么事”的肌肉记忆
。比如看到
/actuator/env
,立刻想到它会暴露所有配置属性,包括数据库密码、Redis地址、Feature Toggle开关。
5.2 第二月:构建靶场分析流水线——自动化代替手动
用Python+Shell搭建一个靶场快速分析框架,包含四个核心模块:
模块A:端点测绘
# endpoints.py
import requests
from urllib.parse import urljoin
def scan_endpoints(base_url):
endpoints = ["/robots.txt", "/sitemap.xml", "/actuator/mappings", "/api/v1/swagger.json"]
results = {}
for ep in endpoints:
try:
r = requests.get(urljoin(base_url, ep), timeout=5)
if r.status_code == 200:
results[ep] = r.text[:200]
except:
pass
return results
模块B:日志模式挖掘
# log-pattern.sh
#!/bin/bash
# 从kubectl logs输出中提取高频关键词和异常模式
kubectl logs -n web-app $(kubectl get pods -n web-app -o jsonpath='{.items[0].metadata.name}') --tail=1000 | \
grep -E "(error|exception|timeout|failed|denied)" | \
awk '{print $NF}' | sort | uniq -c | sort -nr | head -10
模块C:配置泄露扫描
# config-scan.sh
for endpoint in /actuator/env /actuator/configprops /actuator/heapdump; do
curl -s "$BASE_URL$endpoint" | grep -E "(password|secret|key|token|jdbc)" && echo "Found in $endpoint"
done
模块D:Flag变换引擎
# flag-transform.py
import hashlib, base64
def transform_flag(raw_flag, method):
if method == "sha256_b64":
return base64.b64encode(hashlib.sha256(raw_flag.encode()).digest()[:32]).decode()
elif method == "rot13":
return raw_flag.encode('rot13')
# 更多变换...
这个框架的价值不在于代码多精妙,而在于
强制你把“发现→分析→验证→提交”变成标准化动作
。当比赛时,你不会慌乱地敲命令,而是本能地运行
./scan-endpoints.sh http://web-app
,然后看输出。
5.3 第三月:模拟对抗——用“命题人思维”设计自己的靶场
最后阶段,必须切换角色:不再做解题者,而做命题人。任务是:
- 用Docker Compose部署一个含3个服务(Web、Auth、DB)的微服务应用
-
在Web服务中故意引入一个
@PreAuthorize失效漏洞(如配置开关) -
在Auth服务中暴露一个
/actuator/env且未鉴权 -
在DB服务中配置
log_statement = 'all',使SQL注入payload写入PostgreSQL日志 -
将Flag藏在PostgreSQL日志中某条
INSERT语句的RETURNING值里 - 编写一份“选手须知”,其中隐含提示:“日志中出现的SQL语句,其执行结果会通过HTTP Header返回”
然后,邀请队友扮演选手来攻破。你会立刻发现:自己设计的漏洞,别人可能用完全不同的路径触发;自己认为明显的提示,别人可能视而不见。这种角色互换,是突破认知断层最高效的方式。
我在带最后一届省队时,让队员每人设计一个Flag,并互相攻防。结果发现,所有队员设计的Flag,80%都藏在
/actuator/env
泄露的配置里——因为他们太熟悉这个入口了。而真正的赛题,Flag分布在Prometheus、cgroup、Ingress日志等更隐蔽的位置。
当你开始设计题目,你就真正理解了“考什么”和“怎么考”。
6. 最后一点真实体会:国赛CTF的本质,是考你“在不确定中建立确定性”的能力
写到这里,我必须坦白:这篇内容里提到的所有技巧、命令、路径,明年国赛大概率不会再出现。命题组每年都会迭代靶场架构,今年用K3s,明年可能用OpenShift;今年考Prometheus,明年可能考Grafana Loki。 但不变的,是那个核心能力:当面对一个从未见过的系统时,你能否在10分钟内,画出它的数据流图、识别出它的信任边界、定位出它的监控盲区?
我见过一支队伍,在开赛20分钟后,没有急着扫端口,而是先执行了三条命令:
-
kubectl get nodes -o wide—— 确认节点OS和内核版本 -
kubectl get pods -A --field-selector status.phase=Running \| wc -l—— 统计运行中Pod总数,判断系统复杂度 -
curl -I http://web-app:8080/health—— 验证基础连通性,同时观察Server头和X-Powered-By头
然后,他们根据
Server: nginx/1.21.6
和
X-Powered-By: Spring Boot/2.7.18
,精准锁定了Nginx配置文件位置和Spring Boot Actuator端点路径。整个过程冷静得像外科手术。
这和工具无关,和记忆力无关,和刷题量无关。它只和一件事有关: 你是否把每一次实验、每一次靶场、每一次CTF,都当作理解真实世界系统的一次机会,而不是通关游戏的关卡 。
所以,如果你正在备战国赛,请放下“我要学多少工具”的焦虑。打开终端,现在就执行:
kubectl get nodes -o wide
kubectl get pods -A --field-selector status.phase=Running
curl -I http://web-app:8080/health
然后,问问自己:这三个命令返回的结果,告诉我关于这个系统的第一件事是什么?第二件事呢?第三件事呢?
答案不重要,重要的是,你开始用工程师的眼睛看世界了。
更多推荐
所有评论(0)