背景

在一次构建中

发现配置的 cache 没生效,未能重用缓存,导致每次都去 npm 源拉取,浪费时间、白白占用带宽。

原因:单纯用这个 cache 是不行的,这个 cache 是在同一个 pipeline 中生效,复用缓存本质上需要给每个 runner 挂载持久化的 .pnpm-store。

而我自己的 k0s + kaniko 构建服务是可以成功使用 pnpm store 的。

所以探索一个可以给公司服务开启 pnpm store 缓存的方案。

步骤

k8s 配置

  1. 将 .pnpm-store 挂载到 pvc 里(可以忽略 pip 的),并开启权限规则:

    imagePullPolicy: IfNotPresent
    replicas: 1
    
    # 替换为你的 GitLab URL
    gitlabUrl: https://gitlab.xxx.xxx/
    # 替换为你的 GitLab Runner Token
    runnerRegistrationToken: glrt-xxxx
    
    # 挂载 PVC 到 Runner
    runners:
      config: |
        [[runners]]
          [runners.kubernetes]
            namespace = "{{.Release.Namespace}}"
            # PVC 挂载配置
            [[runners.kubernetes.volumes.pvc]]
              name = "pnpm-store-pvc"
              mount_path = "/pnpm-store"
            [[runners.kubernetes.volumes.pvc]]
              name = "pip-cache-pvc"
              mount_path = "/root/.cache/pip"
    
          [runners.cache]
            Type = "local"
            Path = "/cache"
            Shared = true
    
      # PVC 缓存配置
      cache:
        pvc:
          - name: pnpm-store-pvc
            mount_path: /pnpm-store
          - name: pip-cache-pvc
            mount_path: /root/.cache/pip
    rbac:
      create: true
      rules:
        - apiGroups: [""]
          resources: ["pods/exec"]
          verbs: ["create", "get"]
        - apiGroups: [""]
          resources: ["secrets"]
          verbs: ["get", "list", "create", "patch", "delete", "update"]
        - apiGroups: [""]
          resources: ["pods"]
          verbs: ["get", "list", "watch", "create", "delete"]
        - apiGroups: [""]
          resources: ["persistentvolumeclaims"]
          verbs: ["get", "list", "watch"]
    
    serviceAccount:
      name: default # 使用已有的 ServiceAccount(留空自动生成)
      create: false # 如果已有 ServiceAccount,设为 false
  2. 配置 pv

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pnpm-store-pv
      namespace: gitlab-runner
    spec:
      storageClassName: manual
      capacity:
        storage: 50Gi
      accessModes:
        # 单节点实际允许多Pod挂载
        - ReadWriteMany
      hostPath:
        path: "/home/data/pnpm-store"
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pnpm-store-pvc
      namespace: gitlab-runner
    spec:
      storageClassName: manual
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 50Gi

前端关注

  1. gitlab-ci.yaml 中声明 PNPM_STORE_PATHvariables 环境变量

# .gitlab-ci.yml

# 增加这个:
variables:
  PNPM_STORE_PATH: /pnpm-store

# ... 你的其他配置
  1. 在对应阶段中,增加指定 store-dir、指定 tags

# .gitlab-ci.yml

variables:
  PNPM_STORE_PATH: /pnpm-store

# 其他配置

stages:
  - test

test:
  stage: test
  image: node:22-alpine
  before_script:
    - npm i -g corepack@latest && corepack enable
  script:
    - pnpm i --store-dir $PNPM_STORE_PATH # 1. 增加这一行,指定 pnpm 的 store 路径
  tags:
    - npmcache                            # 2. 目前在 npmcache 这个 tag 上启用 pnpm-store 缓存
  1. 提交代码,就可以看到 CI 中会跨项目重用 pnpm-store