Grafana-Feishu 镜像拉取故障排障记录
Grafana-Feishu 镜像拉取故障排障记录
在 logging 命名空间部署 grafana-feishu 时,Pod 一直无法正常启动。
最初使用的镜像为:
1 | image: allanchain/grafana-feishu:latest |
Pod 状态表现为:
ErrImagePullImagePullBackOff
通过 kubectl describe pod 查看事件后,发现核心报错为:
- 节点从 Docker Hub 拉取
allanchain/grafana-feishu:latest超时 - 报错类似:
failed to resolve referenceHead "https://registry-1.docker.io/v2/...": dial tcp ...:443: i/o timeout
这说明问题不在 Deployment 语法,而在于 集群节点无法访问 Docker Hub。
第一阶段:尝试本地打包镜像并传到节点
思路
因为本地电脑可以成功 docker pull allanchain/grafana-feishu:latest,所以最开始的思路是:
- 在本地把镜像拉下来
docker save成 tar 包- 把 tar 包传到 Kubernetes 节点
- 在节点上执行
docker load
遇到的问题
在服务器上执行:
1 | docker load -i /root/grafana-feishu.tar |
结果提示:
1 | Command 'docker' not found |
说明当前登录的机器 prod-server-ci 并不是容器运行时节点,或者至少这台机器上没有 Docker CLI。
进一步分析后确认:
- Pod 实际被调度到的节点是:
cn-shanghai.10.71.45.249cn-shanghai.10.71.45.250
- 镜像拉取动作发生在这些节点上的 kubelet/container runtime
- 因此,应该把镜像导入到 实际运行 Pod 的节点,而不是随便一台运维机
再次遇到的问题
尝试用 scp 把 tar 包传到节点,但传不过去。说明:
- 节点可能不开放 SSH
- 或者当前机器到节点网络不通
- 或者该集群环境不适合走"手工 SSH 上节点导入镜像"这条路
于是放弃了手工上传节点镜像的方案。
第二阶段:改走阿里云 ACR 镜像仓库
既然集群节点无法访问 Docker Hub,那更合理的办法是:
- 在本地把镜像推送到阿里云 ACR
- 再让集群从 ACR 拉取镜像
初始误区
一开始把 ACR 仓库地址当成 SSH 主机来用,尝试:
1 | scp grafana-feishu.tar xxx@xxx-registry.cn-shanghai.cr.aliyuncs.com:/root/ |
结果报错:
1 | ssh: connect to host ... port 22: Network is unreachable |
后来明确了:
ACR 是镜像仓库,不是给 ssh/scp 登录的机器。
正确用法应该是:
docker logindocker tagdocker push
第三阶段:推送镜像到 ACR
登录仓库
本地执行:
1 | docker login --username=xxx http://xxx-registry.cn-shanghai.cr.aliyuncs.com/ |
虽然中间有一条 Docker Desktop 凭据提示异常,但最终结果是:
1 | Login Succeeded |
说明登录态已经成功建立。
第一次推送失败
先尝试打 tag 并推送到:
1 | xxx-registry.cn-shanghai.cr.aliyuncs.com/logging/grafana-feishu:latest |
执行:
1 | docker tag allanchain/grafana-feishu:latest xxx-registry.cn-shanghai.cr.aliyuncs.com/logging/grafana-feishu:latest |
结果失败,报错:
repository does not exist or may require authorizationinsufficient_scope: authorization failed
说明这个仓库路径不对,或者当前账号对该 repo 没有权限。
第二次推送成功
改成:
1 | docker tag allanchain/grafana-feishu:latest xxx-registry.cn-shanghai.cr.aliyuncs.com/xxx/grafana-feishu:latest |
这次成功:
1 | latest: digest: sha256:... |
至此确认,正确可用的仓库地址为:
1 | xxx-registry.cn-shanghai.cr.aliyuncs.com/xxx/grafana-feishu:latest |
第四阶段:Kubernetes 改用 ACR 地址,但仍然失败
修改镜像地址
将 Deployment 中的镜像改为:
1 | image: xxx-registry.cn-shanghai.cr.aliyuncs.com/xxx/grafana-feishu:latest |
然后执行 rollout。
新问题:仍然拉不到镜像
Pod 事件显示:
- 不是鉴权失败
- 而是网络超时
核心报错:
1 | Head "https://xxx-registry.cn-shanghai.cr.aliyuncs.com/v2/.../manifests/latest": |
这说明:
集群节点到 ACR 公网地址的 443 也不通。
也就是说:
- Docker Hub 不通
- ACR 公网地址也不通
但用户进一步确认后发现:
集群节点能访问的是 ACR 内网 / VPC 地址,而不是公网地址
第五阶段:切换到 ACR VPC 内网地址
确认正确的内网仓库地址为:
1 | xxx-registry-vpc.cn-shanghai.cr.aliyuncs.com |
因此,Deployment 中镜像地址应改成:
1 | image: xxx-registry-vpc.cn-shanghai.cr.aliyuncs.com/xxx/grafana-feishu:latest |
第六阶段:切到 VPC 地址后,网络问题解决,但出现认证问题
这一步 Pod 事件发生了变化。不再是 i/o timeout,而是:
FailedToRetrieveImagePullSecretpull access deniedinsufficient_scope: authorization failed
典型报错为:
1 | Unable to retrieve some image pull secrets (acr-secret) |
以及:
1 | pull access denied, repository does not exist or may require authorization: |
这说明:
- 网络已经通了
- 现在真正的问题变成了:
- Pod 想使用
acr-secret - 但
logging命名空间下根本没有这个 Secret - 所以 kubelet 拿不到认证信息去拉私有仓库
- Pod 想使用
第七阶段:确认根因 —— acr-secret 不存在
执行检查:
1 | kubectl -n logging get secret acr-secret |
返回:
1 | Error from server (NotFound): secrets "acr-secret" not found |
至此彻底破案:
根因
Deployment 模板里已经引用了:
1 | imagePullSecrets: |
但实际上 logging 命名空间里并没有这个 Secret,导致:
- kubelet 无法获取镜像仓库认证信息
- 拉取私有仓库镜像失败
- ACR 返回
insufficient_scope
第八阶段:创建正确的 imagePullSecret
正确做法是用 VPC 地址 创建 docker-registry Secret:
1 | kubectl -n logging create secret docker-registry acr-secret \ |
关键点:
--docker-server必须与 Deployment 中实际使用的镜像域名一致- 也就是必须写成:
xxx-registry-vpc.cn-shanghai.cr.aliyuncs.com - 不能再写公网地址
第九阶段:最终修复成功
在 Secret 创建完成后,执行:
1 | kubectl -n logging rollout restart deployment/grafana-feishu |
这次成功。
说明此时整条链路已经打通:
- 镜像已成功推送到阿里云 ACR
- Deployment 已改为使用 ACR VPC 内网镜像地址
- 集群节点可以访问该 VPC 地址
acr-secret已存在,且可供 kubelet 获取- 私有仓库拉取认证成功
grafana-feishuDeployment 成功完成滚动重启
总结
| 阶段 | 问题 | 解决方案 |
|---|---|---|
| 1 | Docker Hub 超时 | 改用国内镜像仓库 |
| 2-3 | 不了解 ACR 用法 | 使用 docker login/tag/push |
| 4 | ACR 公网不通 | 切换到 VPC 内网地址 |
| 5-8 | imagePullSecret 缺失 | 创建正确的 docker-registry Secret |
核心教训:排查镜像拉取问题时,要分清是网络问题还是认证问题,逐层排查。