繁体   English   中英

通过 kubernetes/skaffold 将私有 npm 存储库拉到 docker 容器

[英]Pulling private npm repository to docker container through kubernetes/skaffold

我是 skaffold、k8s、docker 集的新手,我在本地集群上构建应用程序时遇到了麻烦。

我有一个代码存储库试图提取私有 NPM package 但是在构建它时会丢失 .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-args”和 npm 秘密(不安全的方式)
  • 用“--secret”和 npm 秘密(更好的方法)
  • 直接复制.npmrc文件, npm install后立即删除

当我尝试使用 kubernetes/skaffold 构建它时,就会出现问题。 运行后,似乎没有找到任何 args、env 变量,甚至 .npmrc 文件。 在检查 dockerfile 中的线索时,我能够确定没有任何内容从清单(定义的参数、.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: .

几点注意事项:

  • 无论我在哪里复制和粘贴它(在 auth、manifest、skaffold 和 ~/ 目录中),我都找不到 .npmrc 文件
  • 我也想让它在生产中半可用(相当可重复使用),这样如果可能的话我不需要进行彻底的检修(但如果这是不好的做法,我想听听更多关于它的信息)
  • 我已经能够使其与 skaffold.yaml 文件中的 buildArgs 一起使用,但我不确定这将如何转化为生产环境,因为我无法将构建参数从 kubernetes 传递给 Z05B6063C41A21430 '不安全,应该使用秘密)
  • 清单中的参数也抛出此错误(如果参数被注释掉,服务器运行):
 - 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 分为三个级别:

  1. 您启动映像构建的本地系统
  2. Docker 构建填充图像,然后将该图像存储在某处
  3. 加载并开始运行该映像的 Kubernetes 集群

Docker 不参与#3。 (这只是部分正确,因为一些集群也使用 Docker 来运行容器,但这是一个隐藏的细节并且也在发生变化。)

有两个地方可以传达秘密:

  • 在图像构建时(步骤 #1 到 #2):您可以使用 Docker --build-args或使用--secret安装机密(都需要 Buildkit)
  • 在部署时(步骤 #3):您使用 Kubernetes 机密或配置映射,它们与映像构建分开配置

Skaffold 支持传递构建时机密,例如您的 npm 密码,带有 Docker 的--build-args--secret标志,尽管它们略有重命名。

buildArgs支持 Go 风格的模板,因此您可以将MYSECRET等环境变量引用为{{.MYSECRET}}

build:
  local:
    useBuildkit: true
  artifacts:
    - image: auth
      context: auth
      docker:
        buildArgs:
          MYSECRET: "{{.MYSECRET}}"

然后您可以在Dockerfile MYSECRET

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指令。 此字段用于提供命令行 arguments 提供给图像的入口点,可能是node 如果你想在集群上运行的容器中引用一个秘密,你可以使用SecretConfigMap

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM