前言

我们经常会在Dockerfile中使用git clone 仓库

FROM maven:3.6.0-jdk-8-alpine AS build

RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories \
      && apk add --no-cache git

RUN git clone https://私库

如果仓库是公开的也没有什么问题,如果是私库的话,我们会面临以下问题

  • 使用https clone会让我们输入用户名和密码
  • 使用ssh方式,每次docker build 就会新创建一个镜像,生成的ssh就会不一样这很麻烦

解题思路

docker每次build生成新的镜像ssh不同,是因为每次都会去新创建ssh key,那我们能不能把本地打docker机器的私key 拷贝进Docker呢

FROM ubuntu

RUN apt-get update

RUN apt-get install -y git
# 创建ssh文件夹
RUN mkdir /root/.ssh/

# 复制私key
ADD id_rsa /root/.ssh/id_rsa

# 创建 known_hosts文件
RUN touch /root/.ssh/known_hosts
# 添加key
RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts
# clone仓库
RUN git clone git@bitbucket.org:User/repo.git

这么做最大的坏处就是,只要能拿到你的docker images,那么就可以从docker图层检索到你的私钥

怎么解决私钥安全呢,有以下几种思路

  • Docker分层构建
FROM alpine as intermediate

LABEL stage=intermediate

# 将SSH_KEY作为秘钥传参
ARG SSH_KEY

RUN apk update && \
    apk add --update git && \
    apk add --update openssh

# 1. 创建SSH文件夹
# 2.填充私钥文件。
# 3.设置权限
# 4. 将github添加到主机列表
RUN mkdir -p /root/.ssh/ && \
    echo "$SSH_KEY" > /root/.ssh/id_rsa && \
    chmod -R 600 /root/.ssh/ && \
    ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts

# Clone a repository 
RUN git clone git@github.com:user/repository.git

FROM alpine

# Copy across the files from our `intermediate` container
RUN mkdir files
COPY --from=intermediate /repository /repository

构建

MY_KEY=$(cat ~/.ssh/id_rsa)
docker build --build-arg SSH_KEY="$MY_KEY" --tag clone-example .

验证镜像里没有ssh key

docker run -ti --rm clone-example cat /root/.ssh/id_rsa

删除机器构建中间镜像

docker rmi -f $(docker images -q --filter label=stage=intermediate)
  • 使用BuildKit 使ssh密钥作为永远不会写入映像的挂载来传递:
FROM ubuntu as clone

RUN apt-get update \
 && apt-get install -y git

RUN mkdir /root/.ssh/ \
 && touch /root/.ssh/known_hosts \
 && ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts

RUN --mount=type=secret,id=ssh_id,target=/root/.ssh/id_rsa \
    git clone git@bitbucket.org:User/repo.git

构建

DOCKER_BUILDKIT=1 docker build -t your_image_name \
  --secret id=ssh_id,src=$(pwd)/id_rsa .
  • 或者先在机器上clone下仓库 然后添加到Dockerfile
git clone git@github.com/user/xxx.git

FROM ubuntu
COPY test test

使用token

以github为例子,我们可以创建访问token

然后使用git clone https://MY_TOKEN@github.com/user-or-org/repo方式进行clone,可能会有人提出token泄露的问题,我们可以采取上面的方式,使用变量传入,分阶段构建等。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐