Docker镜像常用命令

3

我有4张图片,它们不共享相同的基本图像:

image1 : FROM openjdk:8  
image2 : FROM mongo:3.6  
image3 : FROM ssh  
image4 : FROM ubuntu  

但是在某个时刻,我需要在它们所有的设备上执行相同的命令,例如:

RUN useradd -s /bin/bash -p $(openssl passwd -1 user) -d /home/user -m -G sudo user
USER user
WORKDIR /home/user

RUN mkdir -p /home/user/.ssh/ && \
    chmod 0700 /home/user/.ssh  && \
    touch /home/user/.ssh/authorized_keys && \
    chmod 600 /home/user/.ssh/authorized_keys && \
    touch /home/user/.ssh/config && \
    chmod 600 /home/user/.ssh/config

COPY ssh-keys/ /keys/
RUN cat /keys/id_rsa.pub >> /home/user/.ssh/authorized_keys
RUN cat /keys/config >> /home/user/.ssh/config

并且具有相同的目录结构:

image1  
--->ssh-keys  
------>config  
------>id_rsa  
------>id_rsa.pub  
--->Dockerfile

image2  
--->ssh-keys  
------>config  
------>id_rsa  
------>id_rsa.pub  
--->Dockerfile

image3  
--->ssh-keys  
------>config  
------>id_rsa  
------>id_rsa.pub  
--->Dockerfile

image4  
--->ssh-keys  
------>config  
------>id_rsa  
------>id_rsa.pub  
--->Dockerfile

有没有办法删除这些重复内容?
2个回答

1

Scratch并不包含任何东西,最好使用alpine作为基础镜像,并且从可重用部分中删除下面的命令。

RUN useradd -s /bin/bash -p $(openssl passwd -1 user) -d /home/user -m -G sudo user
USER user

由于这些命令因操作系统而异(基础镜像),在alpine等操作系统中可能无法正常工作。

因此我建议采用以下方式:

image1  
--->Dockerfile
image2  
--->Dockerfile
baseimage
--->ssh-keys  
------>config  
------>id_rsa  
------>id_rsa.pub  
--->Dockerfile

设计基础图像。
FROM alpine as sshconfig
WORKDIR /home/user

RUN mkdir -p /home/user/.ssh/ && \
    chmod 0700 /home/user/.ssh  && \
    touch /home/user/.ssh/authorized_keys && \
    chmod 600 /home/user/.ssh/authorized_keys && \
    touch /home/user/.ssh/config && \
    chmod 600 /home/user/.ssh/config
COPY ssh-keys/ /keys/
RUN cat /keys/id_rsa.pub >> /home/user/.ssh/authorized_keys
RUN cat /keys/config >> /home/user/.ssh/config

构建这个图像。
docker build -t sshconfig .

现在,接下来的Docker镜像将从这个sshconfig Docker基础镜像中复制。
镜像1
FROM ubuntu
# Add user
# change user

# copy ssh-config from base image
COPY --from=sshconfig /home/user/.ssh /home/user/.ssh

#for testing and verify keys
COPY --from=sshconfig /keys/ /keys/
# list keys copies form base image
RUN ls -lstrah /home/user/ /home/user/.ssh /keys/

1
很好,试一下并告诉我。 - Adiii
那么我就不用使用multi-stage-build吗?实际上,它之前的工作方式已经失效了,我需要重新测试。 - flywell
这是多阶段构建,但我们只是将基础镜像放到不同的构建目录中,以使事情更具可重用性,并避免在每个文件夹中都进行复制。 - Adiii
1
使用 alpine 只会增加基础镜像的大小,对于其他镜像实际上没有任何有用的作用。所有作者所做的就是打包文件(你不需要运行操作!) - joebeeson
抱歉,自周一以来我没有处理这个问题...复制已经完成,但是authorized_keysconfig为空。这是否与chmod 600有关? - flywell
1
是的,就是这样... COPY --from=sshconfig /keys/ /keys/ 也不太准确。 - flywell

1
你可能想考虑使用多阶段构建作为所有镜像的基础,并根据需要进行扩展;也许你的基础可以是以下内容:
FROM scratch

# I like to keep all my image files under a single directory
COPY rootfs/ /

然后,在您的其他 Dockerfile 中:
FROM your-base-image AS base
FROM openjdk:8

COPY --from=base / /

[...]

在多阶段构建中,只有特定的操作能够按照您的预期工作,但复制文件是其中一个应该能够正常工作的操作。

什么是“scratch”?我不知道“openjdk”,“mongo”或“ssh”的底层操作系统,也无法对它们进行控制! - flywell
1
这是一个解释:https://hub.docker.com/_/scratch/ - joebeeson
当我使用 scratch 时,我会遇到这个错误 OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown,但是当我扩展 alpine 时,我没有这个问题...你知道为什么吗? - flywell
FROM scratch 需要在另一个 FROM ... 之前 -- 请阅读我的回答中的链接以获取详细信息。如果您仍然遇到问题,您可能需要开启一个新的问题。 - joebeeson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接