AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

curl —— HTTP 客户端的瑞士军刀

一句话定义

curl 是命令行 HTTP / HTTPS / FTP 客户端。在运维和开发场景里它的真正用途是**"用最简单的方式发一个请求看响应"**——调 REST API、看响应头、验 TLS、测连通性、下载文件。

典型场景

训练营文档里 curl 出场 54 次,主要在:

  • 测 K8s service 通不通:curl http://svc.ns.svc.cluster.local
  • 调 apiserver REST API:curl -k https://10.0.24.28:6443/healthz
  • 下载安装脚本:curl -fsSL https://get.docker.com | bash
  • 看响应头:curl -I https://example.com
  • 调 Prometheus / Grafana 验证:curl -s http://prom:9090/api/v1/query?query=up

核心 8 个 flag(90% 用法)

curl -i URL                            # 显示响应头 + 响应体(最常用)
curl -I URL                            # 只看响应头(HEAD 请求)
curl -v URL                            # verbose,看完整请求 + 响应(排错最强)
curl -s URL                            # silent,不显示进度条(脚本必加)
curl -L URL                            # follow redirect(跟随 3xx)
curl -k URL                            # 不验证 TLS 证书(仅限调试自签证书)
curl -o file URL                       # 写到文件(指定文件名)
curl -O URL                            # 用 URL 末段做文件名

记忆方法:-fsSL 是 shell 脚本下载的标配组合:

curl -fsSL https://get.helm.sh/helm-v3.14.0-linux-amd64.tar.gz | tar -xz
  • -f —— fail:HTTP 错误(4xx / 5xx)退出码非 0(脚本必加,不加的话 404 会把错误页当成内容下载)
  • -s —— silent:不显示进度
  • -S —— show-error:silent 模式下错误还是显示
  • -L —— follow redirect

看响应头(最常用排错动作)

$ curl -I https://example.com
HTTP/2 200
content-type: text/html
content-length: 1234
last-modified: Mon, 26 May 2026 14:00:00 GMT
server: ECS (sec/12AB)

-I 发 HEAD 请求。看:

  • 状态码(200 / 301 / 404 / 502 ...)
  • content-type 对不对
  • cache-control / expires 缓存策略
  • server 服务端是啥
  • x-* 自定义头(K8s service mesh 经常加 x-trace-id 这种)

注意:有的服务对 HEAD 和 GET 行为不一致,HEAD 报 405 但 GET 正常。这时改用 curl -i URL 或 curl -sD - URL -o /dev/null(只看 header,body 丢掉)。


verbose 模式 -v —— 看完整握手

$ curl -v https://example.com
*   Trying 93.184.215.14:443...
* Connected to example.com (93.184.215.14) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* ...
* Server certificate:
*  subject: CN=www.example.org
*  start date: Mar 15 00:00:00 2026 GMT
*  expire date: Apr 15 23:59:59 2027 GMT
*  issuer: CN=DigiCert ...
*  SSL certificate verify ok.
> GET / HTTP/2
> Host: example.com
> User-Agent: curl/8.4.0
> Accept: */*
>
< HTTP/2 200
< content-type: text/html
...

* —— curl 内部 / TLS / 连接信息 > —— 发出的请求行 / 头 < —— 收到的响应行 / 头 (无前缀) —— 响应体

排错黄金动作:

curl -v URL 2>&1 | grep -E '^[*<>]'        # 只看握手 + 头,过滤 body

-vvv 更详细(TLS 内部状态、debug 信息)。


发不同方法 / 数据

POST JSON

curl -X POST https://api.example.com/users \
  -H 'Content-Type: application/json' \
  -d '{"name":"alice","email":"a@e.com"}'

短写:

curl -X POST https://api.example.com/users \
  -H 'Content-Type: application/json' \
  -d @user.json                                  # 从文件读 body

form 表单

curl -X POST https://example.com/login \
  -d 'user=admin&pass=123'                       # application/x-www-form-urlencoded

multipart(含文件上传)

curl -X POST https://example.com/upload \
  -F 'file=@./data.csv' \
  -F 'name=mydata'

PUT / DELETE / PATCH

curl -X DELETE https://api.example.com/users/1
curl -X PUT https://api.example.com/users/1 -d '{"name":"bob"}'
curl -X PATCH https://api.example.com/users/1 -d '{"email":"new@e.com"}'

自定义 header

curl -H 'Authorization: Bearer xxx' \
     -H 'X-Request-ID: 12345' \
     https://api.example.com/me

-H 可以多次出现。

看请求体编码

curl -X POST https://httpbin.org/post -d 'a=1&b=2' | jq
# httpbin 回显你发了什么,验证 curl 写对没

TLS 相关

-k / --insecure:忽略证书验证

curl -k https://10.0.24.28:6443/healthz        # K8s apiserver 自签证书

仅限调试。生产用 -k = 自欺欺人地认为通了。

指定 CA / client cert

curl --cacert /etc/kubernetes/pki/ca.crt \
     --cert /etc/kubernetes/pki/admin.crt \
     --key /etc/kubernetes/pki/admin.key \
     https://10.0.24.28:6443/api/v1/namespaces

K8s apiserver 接受这种 client cert 认证,等价于 admin 用户。

看证书指纹

curl -vI https://example.com 2>&1 | grep -E "subject:|expire date"

或者用 openssl 更直接:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates -fingerprint

强制 TLS 版本

curl --tlsv1.2 --tls-max 1.2 https://example.com
curl --tlsv1.3 https://example.com

排查"是不是新版 TLS 兼容性问题"用。


重试 / 超时(脚本必备)

curl -fsSL \
  --connect-timeout 10 \
  --max-time 60 \
  --retry 3 \
  --retry-delay 2 \
  --retry-max-time 60 \
  https://github.com/.../release.tar.gz
flag含义
--connect-timeoutTCP 建连超时(秒)
--max-time整个请求总超时
--retry N失败重试 N 次
--retry-delay S每次重试间隔(默认指数退避)
--retry-all-errors默认只对部分错误重试,加这个对所有

裸 curl URL 不加超时默认能等几分钟,脚本里会让 CI 卡死。


看耗时(性能排查)

curl -s -o /dev/null -w '\nDNS: %{time_namelookup}s\nConn: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n' \
  https://example.com

或者写成 alias:

alias curl-time='curl -s -o /dev/null -w "DNS: %{time_namelookup}\nConn: %{time_connect}\nTLS: %{time_appconnect}\nStart: %{time_starttransfer}\nTotal: %{time_total}\n"'

排查"这次请求慢,慢在哪一段":

  • time_namelookup —— DNS 解析
  • time_connect —— TCP 建连
  • time_appconnect —— TLS 握手完成
  • time_pretransfer —— 等待发送(含 TLS)
  • time_starttransfer —— 收到第一个字节(TTFB)
  • time_total —— 整个完成

训练营典型场景

1. 装机时下载脚本

curl -fsSL https://get.docker.com | bash                       # 装 Docker
curl -fsSL https://raw.githubusercontent.com/.../install.sh | bash

⚠️ 生产不建议 curl | bash —— 不可审计、被 MITM 就完了。教程图省事可以,正式安装应该先下载、看完、再跑。

2. 测 K8s apiserver

# 从节点上测
curl -k https://10.0.24.28:6443/healthz                        # 应该返回 "ok"
curl -k https://10.0.24.28:6443/version
curl -k https://10.0.24.28:6443/api/v1/namespaces \
  -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"

3. pod 内部测 service

# 在一个 pod 里
curl -v http://myservice.mynamespace.svc.cluster.local
curl -v http://myservice                     # 同 ns 内简写

# 测 ClusterIP(不一定行,取决于 selector / endpoints)
curl http://10.96.0.10:53                    # CoreDNS service IP

4. 调 Prometheus

# 查指标
curl -s 'http://prom:9090/api/v1/query?query=up' | jq

# 看 targets
curl -s http://prom:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, health}'

# Pushgateway 推指标
curl -X POST -d 'my_metric 42' http://pushgateway:9091/metrics/job/myjob

5. 下载 K8s 二进制

VERSION=v1.28.0
curl -fsSLo /usr/local/bin/kubectl \
  "https://dl.k8s.io/release/${VERSION}/bin/linux/amd64/kubectl"
chmod +x /usr/local/bin/kubectl

6. 测 ingress

curl -H "Host: myapp.example.com" http://<ingress-ip>/
# 跳过 DNS,直接打到 ingress IP,host 头让 ingress 路由到正确 backend

常见踩坑

坑 1:脚本里 curl URL 不加 -fsSL,404 当成下载内容

curl https://github.com/.../release.tar.gz | tar -xz
# URL 错了返回 404 页面,tar 收到 HTML 然后报错
# 但 curl 退出码 0(HTTP 错误不算 curl 错误)

永远加 -f:

curl -fsSL https://github.com/.../release.tar.gz | tar -xz
# 404 → curl 返回非 0 → 管道也失败

坑 2:用 -X POST -d '' 但没设 Content-Type

curl -X POST https://api.example.com/data -d '{"x":1}'
# 默认 Content-Type: application/x-www-form-urlencoded
# 服务端期望 JSON → 解析失败

发 JSON 一定加:

curl -X POST https://api.example.com/data \
  -H 'Content-Type: application/json' \
  -d '{"x":1}'

坑 3:变量在 JSON 里被 shell 吃了

NAME=alice
curl -X POST URL -d '{"name":"$NAME"}'         # ❌ 单引号阻止变量展开,发出去是字面量
curl -X POST URL -d "{\"name\":\"$NAME\"}"     # ✅ 双引号,但要转义内部引号
curl -X POST URL -d "$(jq -n --arg n "$NAME" '{name:$n}')"   # ✅ jq 生成 JSON

含变量的 JSON 推荐用 jq 生成,少踩引号坑。

坑 4:跟随重定向时改 method

curl -X POST -L https://example.com/api
# 服务端 301 跳转 → curl 默认用 GET 跟随(不再是 POST)

要保持 method:

curl -X POST -L --post301 --post302 --post303 URL
# 或者更狠:
curl -X POST -L --location-trusted URL          # 跟随时甚至传 Authorization

坑 5:-d 把空格丢了

curl -d 'name=alice doe' URL
# 实际发 "name=alice doe" → 服务端可能拿到 "name=alice"

URL encode:

curl --data-urlencode 'name=alice doe' URL
# 发 name=alice%20doe

坑 6:进度条干扰 grep

curl URL | grep error
# 进度条混进 stderr 看着乱

加 -s:

curl -sS URL | grep error
# -s 关进度,-S 保留错误信息

坑 7:长时间不动卡死

curl https://slow-server.example.com
# 等了 5 分钟还没动

--max-time 30 或者 --connect-timeout 10,避免脚本卡死。

坑 8:-k 失败说"unable to get local issuer certificate"

curl https://internal.example.com
# curl: (60) SSL certificate problem: unable to get local issuer certificate

-k 通常能跳过,但更好的做法是把 CA 装到系统:

cp my-ca.crt /usr/local/share/ca-certificates/
update-ca-certificates
# 之后 curl 不需要 -k

K8s 内部 CA 在 /etc/kubernetes/pki/ca.crt。

坑 9:curl 在 alpine 容器里没装

sh: curl: not found

debian/ubuntu 默认有 curl 但 alpine 没。

apk add --no-cache curl       # alpine

或者用 wget(alpine 自带 BusyBox 版):

wget -qO- URL                 # 等价 curl -s URL

关联命令

  • wget —— 下载文件更专;curl 更强大、更通用
  • httpie —— 更人性化的 HTTP CLI(http GET URL)
  • dig —— curl 之前测 DNS 是否对
  • openssl s_client —— curl 之外测 TLS 握手
  • tcpdump —— curl 看不出来的网络层用 tcpdump
  • jq —— curl ... | jq 处理 JSON 返回
在 GitHub 上编辑此页