如何解决通过 kubernetes/skaffold 将私有 npm 存储库拉入 docker 容器
我是 skaffold、k8s、docker set 的新手,我在本地集群上构建应用程序时遇到了问题。
我有一个代码存储库,它试图提取私有 NPM 包,但在构建它时丢失了 .npmrc 文件或 npm 机密。
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@sh1ba%2fcommon - Not found
npm ERR! 404
npm ERR! 404 '@sh1ba/common@^1.0.3' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball,folder,http url,or git url.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2021-06-02T06_08_57_246Z-debug.log
unable to stream build output: The command '/bin/sh -c npm install' returned a non-zero code: 1. Please fix the Dockerfile and try again..
理想情况下,我希望避免将秘密硬编码到文件中,并使用 k8s 环境变量将密钥作为秘密传递给 docker。我可以(有点)使用 docker build 命令来做到这一点:
- 使用“--build-args”和 npm 秘密(不安全的方式)
- 使用“--secret”和 npm secret(更好的方法)
- 直接复制 .npmrc 文件,然后
npm install
立即将其删除
当我尝试使用 kubernetes/skaffold 构建它时出现问题。运行后,似乎没有找到任何 args、env 变量,甚至 .npmrc 文件。在检查 dockerfile 以获取线索时,我能够确定没有任何内容从清单(定义的 args、.npmrc 文件等)传递到 dockerfile。
以下是应用程序的清单:
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-depl
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
spec:
containers:
- name: auth
image: auth
env:
- name: NPM_SECRET
valueFrom:
secretKeyRef:
name: npm-secret
key: NPM_SECRET
args: ["--no-cache","--progress=plain","--secret","id=npmrc,src=.npmrc"]
这是 dockerfile 中的代码:
# syntax=docker/dockerfile:1.2
# --------------> The build image
FROM node:alpine AS build
WORKDIR /app
COPY package*.json .
RUN --mount=type=secret,mode=0644,id=npmrc,target=/app/.npmrc \
npm install
# --------------> The production image
FROM node:alpine
WORKDIR /app
COPY package.json .
COPY tsconfig.json .
COPY src .
COPY prisma .
COPY --chown=node:node --from=build /app/node_modules /app/node_modules
COPY --chown=node:node . /app
s
RUN npm run build
CMD ["npm","start"]
还有脚手架文件:
apiVersion: skaffold/v2alpha3
kind: Config
deploy:
kubectl:
manifests:
- ./infra/k8s/*
- ./infra/k8s-dev/*
build:
local:
push: false
artifacts:
- image: auth
context: auth
docker:
dockerfile: Dockerfile
sync:
manual:
- src: 'src/**/*.ts'
dest: .
一些注意事项:
- 无论我将 .npmrc 文件复制并粘贴到何处(在身份验证、清单、脚手架和 ~/ 目录中),我都无法找到它
- 我也想让它在生产中半可用(非常可重用),这样我就不需要在可能的情况下进行彻底的检修(但如果这是不好的做法,我想听听更多关于它的信息)
- 我已经能够使其与 skaffold.yaml 文件中的 buildArgs 一起使用,但我不确定这将如何转化为生产环境,因为我无法将构建 args 从 kubernetes 传递到 docker(并且我阅读了它不安全,应该使用秘密)
- 清单中的参数也抛出了这个错误(如果参数被注释掉,服务器就会运行):
- deployment/auth-depl: container auth terminated with exit code 9
- pod/auth-depl-85fb8975d8-4rh9r: container auth terminated with exit code 9
> [auth-depl-85fb8975d8-4rh9r auth] node: bad option: --progress=plain
> [auth-depl-85fb8975d8-4rh9r auth] node: bad option: --secret
- deployment/auth-depl failed. Error: container auth terminated with exit code 9.
任何见解都会令人惊叹,我已经摆弄这个太久了。
谢谢!
解决方法
构建镜像并将其部署到 Kubernetes 分为三个级别:
- 您开始构建映像的本地系统
- 填充图像然后将该图像存储在某处的 Docker 构建
- 加载并开始运行该映像的 Kubernetes 集群
#3 中没有涉及 Docker。 (这只是部分正确,因为一些集群也使用 Docker 来运行容器,但这是一个隐藏的细节,而且也在发生变化。)
您可以在两个地方交流秘密:
- 在映像构建时(第 1 步到第 2 步):您可以使用 Docker
--build-args
或使用--secret
挂载机密(都需要 Buildkit) - 在部署时(第 3 步):您使用 Kubernetes 机密或配置映射,它们与映像构建分开配置
Skaffold 支持使用 Docker 的 --build-args
和 --secret
标志传递构建时机密,例如您的 npm 密码,尽管它们略有重命名。
buildArgs
支持 Go 风格的模板,因此您可以将 MYSECRET
等环境变量引用为 {{.MYSECRET}}
:
build:
local:
useBuildkit: true
artifacts:
- image: auth
context: auth
docker:
buildArgs:
MYSECRET: "{{.MYSECRET}}"
然后您可以在您的 MYSECRET
中引用 Dockerfile
:
ARG MYSECRET
RUN echo MYSECRET=${MYSECRET}
请注意,除非您通过 ENV MYSECRET=${MYSECRET}
明确分配,否则 build-args 不会传播到您的容器中。
如果机密在本地文件中,您可以使用 skaffold.yaml
中的 secret
字段:
build:
local:
useBuildkit: true
artifacts:
- image: auth
context: auth
docker:
secret:
id: npmrc
src: /path/to/.npmrc
然后您将在 Dockerfile
中引用该机密:
RUN --mount=type=secret,mode=0644,id=npmrc,target=/app/.npmrc \
npm install
现在在您的 Deployment
中,您正在尝试为您的容器设置 args
:
args: ["--no-cache","--progress=plain","--secret","id=npmrc,src=.npmrc"]
args
字段会覆盖图像中设置的 CMD
指令。此字段用于提供提供给图像入口点的命令行参数,这可能是 node
。如果您想引用集群上正在运行的容器中的机密,您可以使用 Secret
或 ConfigMap
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。