通过kubernetes/skaffold将专用npm存储库拉入docker容器

通过kubernetes/skaffold将专用npm存储库拉入docker容器,docker,npm,kubernetes,skaffold,.npmrc,Docker,Npm,Kubernetes,Skaffold,.npmrc,我是Skafold、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

我是Skafold、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命令来完成:

  • 使用带有npm机密的“-build args”(不安全的方式)
  • 使用“-secret”和npm secret(更好的方法)
  • 直接复制.npmrc文件,
    npm install
当我尝试使用kubernetes/skaffold构建它时,问题就出现了。运行之后,似乎找不到任何args、env变量甚至.npmrc文件。在检查dockerfile中的线索时,我能够确定没有任何东西从清单(args defined、.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"]
还有skaffold文件:

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文件,我都找不到它(在auth、清单、skaffold和~/目录中)
  • 我还想让它在生产中半可用(相当可重用),这样如果可能的话,我就不需要进行彻底的检修(但如果这是一种不好的做法,我希望听到更多关于它的信息)
  • 我已经能够在skaffold.yaml文件中使用buildArgs,但我不确定这将如何转化为生产环境,因为我无法将buildArgs从kubernetes传递给docker(我了解到这是不安全的,应该使用机密)
  • 清单中的参数也抛出此错误(如果参数被注释掉,服务器将运行):
任何洞察都会令人惊讶,我已经摆弄这个太久了


谢谢大家!

为Kubernetes构建和部署映像分为三个级别:

  • 启动映像构建的本地系统
  • 填充图像然后将该图像存储到某个位置的Docker构建
  • 加载并开始运行该映像的Kubernetes群集
  • Docker没有参与#3。(这只是部分正确,因为一些集群也使用Docker来运行容器,但这是一个隐藏的细节,并且正在改变。)

    你可以在两个地方交流秘密:

    • 在映像生成时(步骤1到步骤2):您可以使用Docker
      --build args
      或将secrets与
      --secret
      一起装入(两者都需要Buildkit)
    • 在部署时(步骤#3):使用Kubernetes机密或配置映射,它们与映像构建分开配置
    Skaffold支持使用Docker的
    --build args
    --secret
    标志传递构建时机密,如您的npm密码,尽管它们稍微重命名

    支持Go样式模板,因此您可以将环境变量(如
    MYSECRET
    引用为
    {{.MYSECRET}}
    ):

    build:
      local:
        useBuildkit: true
      artifacts:
        - image: auth
          context: auth
          docker:
            buildArgs:
              MYSECRET: "{{.MYSECRET}}"
    
    然后您可以在
    Dockerfile
    中引用
    MYSECRET

    ARG MYSECRET
    RUN echo MYSECRET=${MYSECRET}
    
    RUN --mount=type=secret,mode=0644,id=npmrc,target=/app/.npmrc \
      npm install
    
    请注意,除非通过
    ENV MYSECRET=${MYSECRET}
    显式分配,否则生成参数不会传播到容器中

    如果机密在本地文件中,则可以使用
    skaffold.yaml
    中的字段:

    build:
      local:
        useBuildkit: true
      artifacts:
        - image: auth
          context: auth
          docker:
            secret:
              id:   npmrc
              src: /path/to/.npmrc
    
    然后,您可以在
    Dockerfile
    中引用该秘密:

    ARG MYSECRET
    RUN echo MYSECRET=${MYSECRET}
    
    RUN --mount=type=secret,mode=0644,id=npmrc,target=/app/.npmrc \
      npm install
    

    现在,在您的
    部署中
    ,您正试图为您的容器设置
    args

              args: ["--no-cache", "--progress=plain", "--secret", "id=npmrc,src=.npmrc"]
    

    args
    字段覆盖图像中设置的
    CMD
    指令。此字段用于提供提供给图像入口点的命令行参数,入口点可能是
    节点
    。如果要引用集群上正在运行的容器中的机密,请使用
    secret
    ConfigMap

    Hello@GerrySaporito,欢迎使用StackOverflow!看起来您在私有NPM包中放置了错误的URL。尝试在浏览器中输入此地址。您还将得到404答案-未找到。您必须拥有NPM软件包的正确地址。再看看。这是一个类似的问题。我不会撒谎,我不认为我能把事情做好。这是一个完美的答案,因为它对我所需要的一切都进行了彻底的解释。非常感谢你,在2.5天之后,多亏了你,我终于让它工作了!