|
| 1 | +# go build问题 |
| 2 | + |
| 3 | +## 构建过程 |
| 4 | + |
| 5 | +执行构建命令 |
| 6 | + |
| 7 | +```shell |
| 8 | +go build -o rpc |
| 9 | +``` |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +`Dockerfile` 内容 |
| 14 | + |
| 15 | +```dockerfile |
| 16 | +FROM alpine:3.20 |
| 17 | + |
| 18 | +WORKDIR /app |
| 19 | + |
| 20 | +# 时区、证书等基础环境 |
| 21 | +RUN apk add --no-cache ca-certificates tzdata && \ |
| 22 | + update-ca-certificates |
| 23 | + |
| 24 | +# 拷贝可执行文件 |
| 25 | +COPY rpc /app/rpc |
| 26 | + |
| 27 | +# 拷贝配置文件 |
| 28 | +COPY etc ./etc |
| 29 | + |
| 30 | +# 暴露端口 |
| 31 | +EXPOSE 8080 |
| 32 | + |
| 33 | +# 运行命令 |
| 34 | +ENTRYPOINT ["/app/rpc"] |
| 35 | +``` |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | +## 报错 |
| 40 | + |
| 41 | +发布到k8s中后pod报错 |
| 42 | + |
| 43 | +```shell |
| 44 | +$ k logs -f demo-rpc-7bd9d76d7f-2fbf9 |
| 45 | +exec /app/rpc: no such file or directory |
| 46 | +``` |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +## 原因 |
| 51 | + |
| 52 | +`go build -o rpc` 这会导致: |
| 53 | + |
| 54 | +- **CGO 默认开启** |
| 55 | + |
| 56 | +- 二进制 **动态链接 glibc** |
| 57 | + |
| 58 | +- 生成的 ELF 需要: |
| 59 | + |
| 60 | + ```shell |
| 61 | + /lib64/ld-linux-x86-64.so.2 |
| 62 | + ``` |
| 63 | + |
| 64 | +但运行镜像是 |
| 65 | + |
| 66 | +``` |
| 67 | +FROM alpine:3.20 |
| 68 | +``` |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | +Alpine 用的是 **musl libc**,它只有: |
| 73 | + |
| 74 | +``` |
| 75 | +/lib/ld-musl-x86_64.so.1 |
| 76 | +``` |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | +❌ **glibc 的动态链接器根本不存在** |
| 81 | + |
| 82 | +所以内核在 exec 时直接失败 |
| 83 | + |
| 84 | +``` |
| 85 | +no such file or directory |
| 86 | +``` |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | +正确构建命令 |
| 91 | + |
| 92 | +:::tip 说明 |
| 93 | + |
| 94 | +以下命令效果是: |
| 95 | + |
| 96 | +- 禁用 CGO |
| 97 | +- 生成 **纯 Go 静态二进制** |
| 98 | +- 不依赖 glibc / musl / 动态链接器 |
| 99 | + |
| 100 | +::: |
| 101 | + |
| 102 | +```shell |
| 103 | +CGO_ENABLED=0 \ |
| 104 | +GOOS=linux \ |
| 105 | +GOARCH=amd64 \ |
| 106 | +go build -o rpc |
| 107 | +``` |
| 108 | + |
| 109 | + |
| 110 | +## 总结 |
| 111 | + |
| 112 | +### Go 二进制 × libc × 镜像 关系对照图 |
| 113 | + |
| 114 | +```shell |
| 115 | +ASCII┌──────────────────────────────────────────────────────────────┐ |
| 116 | +│ Go 编译产物类型 │ |
| 117 | +├───────────────┬──────────────────┬───────────────────────────┤ |
| 118 | +│ 编译方式 │ 二进制类型 │ 关键依赖 │ |
| 119 | +├───────────────┼──────────────────┼───────────────────────────┤ |
| 120 | +│ CGO_ENABLED=1 │ 动态链接 ELF │ glibc / musl + ld.so │ |
| 121 | +│ CGO_ENABLED=0 │ 静态链接 ELF │ ❌ 无 libc 依赖 │ |
| 122 | +└───────────────┴──────────────────┴───────────────────────────┘ |
| 123 | +``` |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | +### libc 与 Linux 发行版关系 |
| 128 | + |
| 129 | +```shell |
| 130 | +┌───────────────┬────────────────────┬─────────────────────────┐ |
| 131 | +│ 发行版 │ 使用的 libc │ 动态链接器路径 │ |
| 132 | +├───────────────┼────────────────────┼─────────────────────────┤ |
| 133 | +│ Debian / Ubuntu│ glibc │ /lib64/ld-linux-x86-64… │ |
| 134 | +│ CentOS / RHEL │ glibc │ /lib64/ld-linux-x86-64… │ |
| 135 | +│ Alpine │ musl │ /lib/ld-musl-x86_64.so.1│ |
| 136 | +│ scratch │ ❌ 无 libc │ ❌ 无 │ |
| 137 | +└───────────────┴────────────────────┴─────────────────────────┘ |
| 138 | +``` |
| 139 | + |
| 140 | + |
| 141 | + |
| 142 | +### 为什么 Alpine 常见 `no such file or directory` |
| 143 | + |
| 144 | +```shell |
| 145 | +你在 Ubuntu 上编译: |
| 146 | +┌──────────────────────────┐ |
| 147 | +│ rpc (ELF) │ |
| 148 | +│ 需要: │ |
| 149 | +│ /lib64/ld-linux-x86-64… │ ← glibc |
| 150 | +└──────────┬───────────────┘ |
| 151 | + │ COPY |
| 152 | + ▼ |
| 153 | +┌──────────────────────────┐ |
| 154 | +│ Alpine 容器 │ |
| 155 | +│ /lib/ld-musl-x86_64.so.1 │ |
| 156 | +│ ❌ 没有 glibc │ |
| 157 | +└──────────┬───────────────┘ |
| 158 | + ▼ |
| 159 | + exec 失败 |
| 160 | + ❌ no such file or directory |
| 161 | +``` |
| 162 | + |
| 163 | +⚠️ **报错不是“文件不存在”,而是“解释器不存在”** |
| 164 | + |
| 165 | + |
| 166 | + |
| 167 | +### 镜像 × Go 编译方式推荐矩阵(重点) |
| 168 | + |
| 169 | +```shell |
| 170 | +┌───────────────┬──────────────┬────────────────────────────┐ |
| 171 | +│ 镜像 │ Go 编译方式 │ 是否推荐 │ |
| 172 | +├───────────────┼──────────────┼────────────────────────────┤ |
| 173 | +│ Ubuntu │ CGO=1 │ ✅ 可用(镜像大) │ |
| 174 | +│ Ubuntu │ CGO=0 │ ✅ 推荐 │ |
| 175 | +│ Alpine │ CGO=1 │ ⚠️ 极易踩坑 │ |
| 176 | +│ Alpine │ CGO=0 │ ✅ 强烈推荐 │ |
| 177 | +│ scratch │ CGO=1 │ ❌ 绝对不行 │ |
| 178 | +│ scratch │ CGO=0 │ ✅ 最优(最小镜像) │ |
| 179 | +└───────────────┴──────────────┴────────────────────────────┘ |
| 180 | +``` |
| 181 | + |
| 182 | + |
| 183 | + |
| 184 | + |
| 185 | + |
| 186 | + |
| 187 | + |
0 commit comments