3. 环境准备:安装Cosign、配置Docker/containerd、搭建本地测试Registry、安装Rekor本地实例

本章是实战课程的基石。在正式进行签名、验证和故障排查之前,必须搭建一套完整的本地实验环境。我们将依次安装 Cosign 签名工具、配置容器运行时(Docker 或 containerd)、部署本地 Registry 以及安装 Rekor 实例。这套环境将模拟生产中的供应链信任链路,同时避免对公网服务的依赖。

环境概览:所有组件均部署在同一台 Linux 主机(推荐 Ubuntu 22.04+ 或 CentOS 8+)上。主机需具备 4GB 以上内存、20GB 可用磁盘空间,并已安装 Go 1.19+ 和 Docker Engine。

3.1 安装 Cosign

Cosign 是 Sigstore 项目下的容器镜像签名工具,支持密钥对、密钥管理服务(KMS)以及硬件安全模块(HSM)。我们采用官方推荐的二进制安装方式,确保版本一致。

3.1.1 下载并验证 Cosign 二进制

# 下载最新稳定版(v2.2.4 为例)
wget "https://github.com/sigstore/cosign/releases/download/v2.2.4/cosign-linux-amd64"

# 赋予执行权限并移动到系统路径
chmod +x cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign

# 验证安装
cosign version

3.1.2 生成签名密钥对

Cosign 支持多种密钥生成方式。我们使用 cosign generate-key-pair 命令创建本地密钥对,用于后续镜像签名。

# 生成密钥对(默认存储在 ~/.cosign/ 目录下)
cosign generate-key-pair

# 查看生成的密钥文件
ls -la ~/.cosign/
# 输出示例:
# -rw------- 1 user user  528 Mar 15 10:00 cosign.key
# -rw-r--r-- 1 user user  178 Mar 15 10:00 cosign.pub
密钥安全提醒:cosign.key 是私钥,必须严格保护,切勿提交到版本控制系统。生产环境中建议使用 KMS 或硬件密钥管理。

3.2 配置 Docker / containerd 运行时

容器运行时需要正确配置以支持镜像签名验证。Docker 和 containerd 的配置方式略有不同,但核心目标一致:让运行时在拉取镜像时能够调用 Cosign 进行验证。

3.2.1 Docker 配置

Docker 通过 ~/.docker/config.json 或系统级 /etc/docker/daemon.json 集成 Cosign。我们采用 containerd 作为底层运行时(Docker 默认已集成),但需要额外配置策略。

# 编辑 Docker daemon 配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<- 'EOF'
{
  "features": {
    "containerd-snapshotter": true
  }
}
EOF

# 重启 Docker 服务
sudo systemctl restart docker

# 验证配置生效
docker info | grep -i containerd

3.2.2 containerd 独立配置

如果直接使用 containerd(如 Kubernetes 节点),需在 /etc/containerd/config.toml 中启用镜像签名验证插件。

# 备份原始配置
sudo cp /etc/containerd/config.toml /etc/containerd/config.toml.bak

# 编辑配置,添加 cosign 验证器
sudo tee -a /etc/containerd/config.toml <<- 'EOF'

[plugins."io.containerd.grpc.v1.cri".image_decryption]
  key_model = "node"

[plugins."io.containerd.grpc.v1.cri".registry]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"]
      endpoint = ["http://localhost:5000"]

  [plugins."io.containerd.grpc.v1.cri".registry.configs]
    [plugins."io.containerd.grpc.v1.cri".registry.configs."localhost:5000".tls]
      insecure_skip_verify = true
EOF

# 重启 containerd
sudo systemctl restart containerd
配置对比:Docker 配置更简洁,适合开发环境;containerd 配置更细粒度,适合生产 Kubernetes 集群。两者均需确保本地 Registry 的 TLS 配置正确。

3.3 搭建本地测试 Registry

本地 Registry 用于存储签名后的镜像,避免依赖 Docker Hub 或第三方仓库。我们使用 Docker 官方 Registry 镜像,并配置为 HTTP 模式(开发环境)或 HTTPS 模式(生产模拟)。

3.3.1 启动 Registry 容器

# 创建持久化存储目录
mkdir -p /data/registry

# 启动 Registry(HTTP 模式,开发测试用)
docker run -d \
  --name local-registry \
  --restart=always \
  -p 5000:5000 \
  -v /data/registry:/var/lib/registry \
  registry:2

# 验证 Registry 是否运行
curl -X GET http://localhost:5000/v2/_catalog
# 预期输出:{"repositories":[]}

3.3.2 配置 Docker 信任 HTTP Registry

Docker 默认只信任 HTTPS Registry。对于本地 HTTP Registry,需要在 Docker daemon 配置中添加 insecure-registries。

# 编辑 /etc/docker/daemon.json
sudo tee /etc/docker/daemon.json <<- 'EOF'
{
  "insecure-registries": ["localhost:5000"],
  "features": {
    "containerd-snapshotter": true
  }
}
EOF

# 重启 Docker
sudo systemctl restart docker

# 测试推送镜像
docker pull alpine:latest
docker tag alpine:latest localhost:5000/alpine:test
docker push localhost:5000/alpine:test
# 预期输出:推送成功,无 TLS 错误
生产建议:生产环境务必配置 HTTPS 证书。可使用 mkcert 生成自签名证书,或使用 Let's Encrypt 获取合法证书。

3.4 安装 Rekor 本地实例

Rekor 是 Sigstore 的透明日志系统,用于记录签名元数据。本地 Rekor 实例允许我们在离线环境中测试签名验证流程,避免依赖公共 Rekor 服务。

3.4.1 使用 Docker Compose 部署 Rekor

Rekor 依赖 Trillian(Merkle 树实现)和 MySQL 数据库。我们使用官方 Docker Compose 文件快速部署。

# 创建 Rekor 部署目录
mkdir -p /opt/rekor && cd /opt/rekor

# 下载官方 Docker Compose 文件
wget https://raw.githubusercontent.com/sigstore/rekor/main/docker-compose.yml

# 启动所有服务(后台运行)
docker-compose up -d

# 检查服务状态
docker-compose ps
# 预期输出:rekor-server、trillian-log-server、trillian-log-signer、mysql 均处于 Up 状态

3.4.2 验证 Rekor 服务

# 查看 Rekor 服务日志
docker-compose logs rekor-server

# 测试 Rekor API 是否可用
curl -X GET http://localhost:3000/api/v1/log
# 预期输出:包含 logID、treeSize 等信息的 JSON

# 查看 Rekor 版本
curl -X GET http://localhost:3000/api/v1/version
# 预期输出:{"version": "1.3.5"}(版本号可能不同)

3.4.3 配置 Cosign 使用本地 Rekor

Cosign 默认使用公共 Rekor 服务(rekor.sigstore.dev)。我们需要设置环境变量,使其指向本地实例。

# 设置环境变量(可写入 ~/.bashrc 永久生效)
export REKOR_HOST=http://localhost:3000
export TUF_URL=http://localhost:3000

# 验证配置
cosign verify --rekor-url http://localhost:3000 --help | grep rekor
# 预期输出:显示 rekor-url 相关参数
注意:本地 Rekor 实例的数据不会持久化到公共网络。重启容器后,之前的签名记录将丢失。生产环境应配置持久化存储和备份策略。

3.5 环境验证清单

完成上述安装后,执行以下验证步骤,确保所有组件正常工作。

组件 验证命令 预期结果
Cosign cosign version 显示版本号 v2.2.4+
Docker docker info 显示 containerd 已启用
本地 Registry curl localhost:5000/v2/_catalog 返回 JSON 列表
Rekor curl localhost:3000/api/v1/log 返回 logID 和 treeSize
密钥对 ls ~/.cosign/ 包含 cosign.key 和 cosign.pub

3.6 环境架构总览

下图展示了本地实验环境的整体架构,以及各组件之间的交互关系。

本地供应链信任实验环境架构图 本地供应链信任实验环境架构 开发者 / CI Cosign CLI 本地 Registry Rekor 透明日志 Docker / containerd 推送签名镜像 记录签名元数据 拉取镜像 验证签名 说明:Cosign 对镜像签名后,将镜像推送至本地 Registry,同时将签名元数据记录到 Rekor。 容器运行时拉取镜像时,可查询 Rekor 验证签名是否有效。

3.7 常见安装问题与排查

在环境准备过程中,可能会遇到以下典型问题。提前了解有助于快速定位故障。

问题现象 可能原因 解决方案
cosign: command not found 二进制未加入 PATH 检查 /usr/local/bin 是否存在,或使用路径
Docker 推送报 TLS 错误 未配置 insecure-registries 在 daemon.json 中添加 "insecure-registries": ["localhost:5000"]
Rekor 服务无法启动 MySQL 连接失败或端口冲突 检查 docker-compose logs mysql,确保 3306 端口未被占用
Cosign 签名时连接 Rekor 超时 环境变量 REKOR_HOST 未设置或指向错误 执行 export REKOR_HOST=http://localhost:3000 并验证
最佳实践:建议将环境变量写入 ~/.bashrc 或 ~/.zshrc,避免每次新开终端都需要重新设置。同时,使用 docker-compose logs -f 实时监控 Rekor 和 Registry 的日志输出。