<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>jenkins on </title>
    <link>/tags/jenkins/</link>
    <description>Recent content in jenkins on </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sat, 14 Nov 2026 14:30:00 +0800</lastBuildDate><atom:link href="/tags/jenkins/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>用 OIDC 替换 Jenkins 流水线里的 AWS access key</title>
      <link>/posts/jenkins-oidc-aws-credentials/</link>
      <pubDate>Sat, 14 Nov 2026 14:30:00 +0800</pubDate>
      
      <guid>/posts/jenkins-oidc-aws-credentials/</guid>
      <description>背景 这台 Jenkins（2.580.2）是非生产环境的构建机，控制器在办公网里，出公网只走办公室的出口地址，AWS 那边访问不到它。上面几十个流水线推镜像到 ECR 时，都绑定凭据库里同一把长期 access key。这把 key 背后的 IAM 用户有 ECR、ECS、S3、Lambda 的全权限，还是两个 EKS 集群的管理员，所以任何一个作业，以及任何能改动某个作业的人，都能用上这些权限。key 轮换过，但只要还是长期 key，它从构建日志、备份、workspace 或者控制器上共享的 ~/.docker/config.json 里漏出去一次，就又是长期有效的。
这次的目标是让 Jenkins 里不再存 AWS key：每次构建拿一份只属于这个作业的角色、最长 1 小时的临时凭据。动手前定了几条约束，后面的做法基本都是从这里推出来的：
没切换的作业行为一点不变。同一个 Jenkinsfile 往往同时服务 qa、staging 和生产分支，生产分支要等搬离这台 Jenkins 之后再处理，在那之前继续用原来的 key。 AWS 访问不到 Jenkins，签发方（issuer）的公开文件要放在别处。 一个作业一个作业地切，每切一个都能单独验证和回退。 第一批只处理只用 AWS 登录 ECR 和推镜像的 QA、STG 作业，最后切了 59 个。还用到 ECS、EKS 的作业以及生产构建另外处理，不在这篇里。
一次构建怎么换到临时凭据 Jenkins 这边用 oidc-provider 插件（这里装的是 234.vca_b_26b_f4b_dda_）。它提供一种凭据类型「OpenID Connect id token as file」：流水线绑定这个凭据时，插件用自己保管的私钥现签一个 JWT，写进一个临时文件。AWS CLI 读到 AWS_ROLE_ARN 和 AWS_WEB_IDENTITY_TOKEN_FILE 这两个环境变量，就会自己调 sts:AssumeRoleWithWebIdentity，整个过程不需要任何 key。</description>
    </item>
    
    <item>
      <title>Jenkins 部署从 push 改成 pull：VM 按 digest 自己拉镜像</title>
      <link>/posts/jenkins-vm-push-to-pull-deploy/</link>
      <pubDate>Fri, 06 Nov 2026 17:20:00 +0800</pubDate>
      
      <guid>/posts/jenkins-vm-push-to-pull-deploy/</guid>
      <description>背景 一条典型的 Jenkins 加 VM 部署链路是这样的：Jenkins 构建镜像、推到私有仓库，然后用凭据库里的一把 SSH key 登录目标 VM，把 docker-compose.yml、.env 和部署脚本拷过去，再执行 sudo docker compose up -d。每个环境有几台 VM，同一把 key 能登录这个环境的所有目标机，登录用户有免密 sudo。
这条链路好用的地方很实在：部署就是流水线的最后一个 stage，成败当场可见，回滚就是拿旧 tag 再跑一次。它的问题在信任的分布上。Jenkins 控制器同时握着源码、构建、凭据和通往每台 VM 的登录通道，能控制它的人就能以 root 身份登录所有目标机。
这篇讨论把最后一步反过来：VM 定时去拉「现在应该跑哪个镜像」，自己完成部署，Jenkins 不再登录 VM。讨论有三个前提：服务跑在 VM 上的 Docker Compose 里，短期内不迁 K8s；CI 继续用 Jenkins；目标是缩小 CI 被攻破时的影响面，构建本身是否可信只在讲验签时带到。
push 链路里，信任集中在 Jenkins 控制器 集中的地方有四处，前两处来自 Jenkins 本身，后两处来自部署脚本的常见写法。
登录凭据和解密它的 key 在同一台机器上 Jenkins 的凭据是加密存放的。按 Jenkins 开发者文档，加密用的 key 在 $JENKINS_HOME/secrets/，保护这些 key 的 master key 也在这个目录里，所以拿到控制器的文件系统，就能把凭据全部解出来。Controller Isolation 文档还提到，跑在 built-in node 上的构建对控制器文件系统的访问权限和 Jenkins 进程相同，官方建议把 built-in node 的执行器设为 0。如果构建还跑在控制器上，能改 Jenkinsfile 的人离凭据库只差一步。</description>
    </item>
    
  </channel>
</rss>
