• docker镜像的创建commit及dockerfile


    在docker 1.3版本以前使用attach进入容器会经常出现卡死的情况,之后官方退出了exec命令,从宿主机进入,但是从其他远程主机进入使用ssh服务来维护是用户熟悉的方法。所以这里来创建一个带有ssh服务的镜像。基于docker commit命令和dockerfile创建。

    基于commit命令

    commit命令格式为docker commit CONTAINER [REPOSITORY[:TAG]],用户提交对容器的修改,并生成新的镜像。

    首先使用ubuntu镜像来创建一个容器,尝试使用ssh命令无效。

    # docker run -it ubuntu /bin/bash

    因为ubuntu官方镜像中没有软件包的缓存文件,使用apt-get update更新即可,也可以修改源来配置。然后安装ssh。

    # apt-get update

    # apt-get install ssh -y

    运行ssh需要目录/var/run/sshd存在,创建启动服务

    # mkdir -p /var/run/sshd

    # /usr/sbin/sshd -D &

    然后可以看到已经运行,netstat命令可能也没有,安装即可apt-get install net-tools

    此处还需要修改ssh服务的安全登录配置,取消pam登录限制,如下图注释即可。

    然后复制需要登录的公钥信息(这里为本地主机)。使用ssh-keygen可以生成。

    复制id_rsa.pub的内容到容器中的/root/.ssh/authorized_keys

    创建ssh服务执行文件,然后退出容器

    # vim /run.sh

    # chmod +x run.sh

    使用docker commit保存修改的容器,然后运行

    # docker commit CONTAINER ID ssh:ubuntu

    # docker run -d -p :22 ssh:ubuntu /run.sh

    最后可以在宿主机上通过随机生成的32779端口来访问登录容器了:

    使用dockerfile创建镜像

    创建一个目录sshd_ubuntu,分别创建文件如下:

    authorized_keys文件内容同样的复制

    # cat /root/.ssh/id_rsa.pub > authorized_keys

    然后编写Dockerfile文件如下,源自行修改即可:

    FROM ubuntu:latest

    MAINTAINER from whychz@ubuntu.com by boss yan

    RUN rm -rf /etc/apt/sources.list

    RUN echo 'deb-src http://archive.ubuntu.com/ubuntu xenial main restricted' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted' >> /etc/apt/sources.list

    RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted' >> /etc/apt/sources.list

    RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial universe' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list

    RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list

    RUN echo 'deb http://archive.canonical.com/ubuntu xenial partner' >> /etc/apt/sources.list

    RUN echo 'deb-src http://archive.canonical.com/ubuntu xenial partner' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted' >> /etc/apt/sources.list

    RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe' >> /etc/apt/sources.list

    RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse' >> /etc/apt/sources.list

    RUN apt-get update

    RUN apt-get install -y openssh-server

    RUN mkdir -p /var/run/sshd

    RUN mkdir -p /root/.ssh

    RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd

    ADD authorized_keys /root/.ssh/authorized_keys

    ADD run.sh /run.sh

    RUN chmod 755 /run.sh

    EXPOSE 22

    CMD ["/run.sh"]

    然后使用docker build创建镜像。最后的"."(点)表示当前目录中的Dockerfile

    # docker build -t ubuntu:sshserver .

    执行完成之后docker images查看镜像

    最后运行容器,ssh测试是否成功

    # docker run -d -p :22 ubuntu/sshserver --name ssh

    # ssh 192.168.2.189 -p 32782 可以看到通过ssh已经进来了容器

    Dockerfile介绍

    Dockerfile是一个文本格式的配置文件,可以使用Dockerfile快速创建自定义的镜像。

    基本结构

    Dockerfile由一行行命令语句组成,支持#注释。一般分为四个部分:基础镜像,维护者信息,镜像操作指令和容器启动时执行指令。

    一开始必须指明所基于的镜像,接下来会说明维护者信息。后面则是镜像的操作,比如RUN指令,每运行一条,镜像会添加新的一层,并提交。最后是CMD指令,来指定运行容器时的操作命令。

    指令

    FROM

    格式为 FROM <image>或 FROM <image>:tag。指明所基于的镜像。

    必须为第一条指令,如果在一个Dockerfile文件里创建多个镜像可多次使用,每个镜像一次。

    MAINTAINER

    格式为 MAINTAINER <name>,指定维护者信息

    RUN

    运行指定的命令

    RUN命令有两种格式

    1. RUN <command>

    2. RUN ["executable", "param1", "param2"]

    第一种后边直接跟shell命令,在linux操作系统上默认 /bin/sh -c。第二种是类似于函数调用。

    可将executable理解成为可执行文件,后面就是两个参数。

    两种写法比对:

    RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME

    RUN ["/bin/bash", "-c", "echo hello"]

    注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层。

    多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。RUN书写时的换行符是

    CMD

    容器启动时要运行的命令

    语法有三种格式

    1. CMD ["executable","param1","param2"] 使用exec执行,推荐方式

    2. CMD ["param1","param2"] 提供给ENTRYPOINT默认参数

    3. CMD command param1 param2 在/bin/sh中执行,提供需要交互的应用

    举例说明两种写法:

    CMD [ "sh", "-c", "echo $HOME"]

    CMD [ "echo", "$HOME" ]

    这里边包括参数的一定要用双引号,不能是单引号。原因是参数传递后,docker解析的是一个JSON array。

    每个dockerfile只能有一条CMD命令。指定了多条就只有最后一条会被执行。如果启动容器时候制定了运行的命令,则也会覆盖掉CMD指定的命令。

    EXPOSE

    格式为EXPOSE <port>[<port>...]

    例如:EXPOSE 22 80 433

    告诉docker服务器容器暴露的端口号

    ENV

    格式为ENV<key><value>

    指定环境变量,会被后续的RUN指令使用,并在容器内保持运行

     

    ADD

    格式为<src><dest>

    将指定的<src>到容器中的<dest>。<src>可以是dockerfile所在目录的一个相对路径,可以是一个url,也可以是一个tar文件(自动解压为目录)

    COPY

    又是一个复制命令

    语法如下:

    1. COPY <src>... <dest>

    2. COPY ["<src>",... "<dest>"]

    与ADD的区别是COPY的<src>只能是本地文件,其他用法一致

    ENTRYPOINT

    格式为:

    1. ENTRYPOINT ["executable", "param1", "param2"]

    2. ENTRYPOINT command param1 param2

    配置容器启动后执行的命令,不可被docker run覆盖。每个Dockerfile中只能有一个ENTRTPOINT,指定多个时,只有最后一个生效。

    VOLUME

    格式为:

    VOLUME ["/data"]

    可实现挂载功能,可以将内地文件夹或者其他容器种得文件夹挂在到这个容器种

    ["/data"]可以是一个JsonArray ,也可以是多个值。所以如下几种写法都是正确的

    VOLUME ["/var/log/"]

    VOLUME /var/log

    VOLUME /var/log /var/db

    一般的使用场景为需要持久化存储数据时

    容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失,所以当数据需要持久化时用这个命令。

    USER

    设置启动容器的用户,可以是用户名或UID,下面的两种写法是正确的:

    USER daemo

    USER UID

    如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行。也可以在之前创建所需要的用户,如:RUN useradd user1,临时获取权限不推荐sudo而使用gosu。

    WORKDIR

    格式:WORKDIR /path/to/workdir

    对后续的RUN,CMD,ENTRYPOINT,COPY,ADD配置工作目录。如果不存在则会创建,也可以设置多次

    如:

    WORKDIR /a

    WORKDIR b

    WORKDIR c

    RUN pwd

    结果是/a/b/c

    WORKDIR也可以解析环境变量

    如:

    ENV DIRPATH /path

    WORKDIR $DIRPATH/$DIRNAME

    RUN pwd

    pwd的执行结果是/path/$DIRNAME

    ONBUILD

    格式:ONBUILD [INSTRUCTION]

    这个命令只对当前镜像的子镜像生效。

    比如当前镜像为A,在Dockerfile种添加:

    ONBUILD RUN ls -al

    这个 ls -al 命令不会在A镜像构建或启动的时候执行,但是如果有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

    镜像的创建

    docker build [path],命令会读取指定路径下的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此建议一般放置Dockerfile目录为空目录。指定镜像的标签信息使用-t选项。如上面例子的docker build -t ubuntu:sshserver .

  • 相关阅读:
    [BZOJ] 1623: [Usaco2008 Open]Cow Cars 奶牛飞车
    [BZOJ] 3631: [JLOI2014]松鼠的新家
    [BZOJ] 1775: [Usaco2009 Dec]Vidgame 电视游戏问题
    [BZOJ] 1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场
    [Codeforces] #432 div.2 (Virtual)
    [BZOJ] 1819: [JSOI]Word Query电子字典
    [Codeforces] #436 E. Fire
    [Codeforces] #436 D. Make a Permutation!
    [Codeforces] #436 C. Bus
    [Codeforces] #436 B. Polycarp and Letters
  • 原文地址:https://www.cnblogs.com/whych/p/9540124.html
Copyright © 2020-2023  润新知