前言
我们经常会在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泄露的问题,我们可以采取上面的方式,使用变量传入,分阶段构建等。