docker使用四(创建docker镜像)

创建镜像

   使用docker镜像时,如果作为测试使用,可以直接从docker仓库中下载现成的镜像使用。如果在生产环境中使用,为了满足自己的需求性及安全方面的考虑,最好使用自己制作的镜像。创建docker镜像的方法主要由三种,基于已有镜像的容器创建,基于本地模板导入,基于dockerfile创建。

基础镜像:在创建自己的镜像前,需要在docker hub上下载一些基础镜像,基础镜像可以选择BusyBoxAlphineDebian/UbuntuCentos/Fedora等操作系统,选择基础镜像一般选择较为小巧的镜像。

一、基于已有镜像的容器创建

创建容器的命令格式:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] [flags]

常用选项:

          -a (--author=””) 作者信息

         -c (--change=””) 提交时执行dockerfile指令,包括CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等。

         -m (-message=””) 提交信息

         -p (--pause=true) 提交时暂停容器运行

1、基于已有镜像容器创建镜像

# 创建一个容器
root@docker-server:~# docker run -it ubuntu:16.04 /bin/bash
# 在容器中创建一个测试文件夹
root@63b4307c45f0:/# mkdir /test/dayi123 -p
# 使用docker commit 创建一个新的镜像
root@docker-server:~# docker commit -m "create new file" -a "dayi123" 63b4307c45f0 testubuntu:1.0
sha256:0be200520abd7965bb64303db3ea3150237cd849196dd5e9a3d009d34970d5b3

2、创建镜像为镜像添加ssh服务

#利用现有的centos镜像创建一个容器,并执行/bin/bash进入容器
root@docker-server:~# docker run  -it centos:6.5 /bin/bash
#进入容器后安装openssh-server
[root@3349fc93dfe9 /]# yum install openssh-server
#安装完成后运行sshd服务
[root@3349fc93dfe9 /]# /usr/sbin/sshd -D &    
[1]31
# 查看服务已经运行
[root@3349fc93dfe9 /]# ss -tanl
State      Recv-Q Send-Q      Local Address:Port  Peer Address:Port 
LISTEN     0       128                  :::22                  :::*     
LISTEN     0       128                   *:22                  *:* 
#修改ssh服务的安全登录配置,取消pam登录限制
[root@3349fc93dfe9 /]# sed -i "s/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g" /etc/pam.d/sshd
# 在root目录下创建ssh目录,并复制需要登录的公钥信息
[root@3349fc93dfe9 /]# mkdir /root/.ssh -p
[root@3349fc93dfe9 /]# vi /root/.ssh/authorized_keys
[root@3349fc93dfe9 /]# cat /root/.ssh/authorized_keys 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1pd5p34qkLQGts8UvNUQWYu8zx7T5M2W+h2l/IMS9wy9BrVtQisTnMF+zi3CTR9Mgzumch7rHBjpJa/imTGISfwx0gQ9RY6dWiPXt7sUVSIPcXXNdml6wtLcvMTbPxnVg/S4GVN8OsiQNBEFWzvrR9RFrCGtwI9z8Ayg5q1HVNehBHtLND1wEahspojo9QnFyKa9GZDpsl4V2r/JlD3zBeUjtcrFQKtJ4jpg/VYWzEbQBmv9amRuOmhl2S0V5xpPJ948SAgnd70aT1WHHC8P8LdvllDcgSVaZwPMZS4hwsvSDvgDjgOH6K1fcnXzu6BlAXS/pFsZIQh4Ns0asf8pz root@docker-server
#创建启动ssh服务的脚本文件run.sh
[root@3349fc93dfe9 /]# vi /run.sh
[root@3349fc93dfe9 /]# cat /run.sh 
#!/bin/bash
/usr/sbin/sshd -D
[root@3349fc93dfe9 /]# chmod +x run.sh 
[root@3349fc93dfe9 /]# exit
#使用安装ssh服务的镜像创建容器
root@docker-server:~# docker commit 3349fc93dfe9 sshd:centos
sha256:98a492fad9d8ea556d8aef740dcb508a6f985d500f26d6696874f41f6852e92e
#查看镜像已经生成
root@docker-server:~# docker images
REPOSITORY    TAG         IMAGE ID      CREATED             SIZE
sshd         centos      98a492fad9d8  4 seconds ago       514MB
# 使用刚生成的镜像创建容器,并映射端口到容器内的22端口
root@docker-server:~# docker run -it -p 10022:22 -d sshd:centos /bin/bash /run.sh
af9c50e166cb5d3273bd6378474c34cd432eb2fd4c68986d7d93ba9c9472710a
# 查看创建的容器已经运行端口已经映射
root@docker-server:~# docker ps
CONTAINER ID    IMAGE               COMMAND               CREATED             STATUS              PORTS                   NAMES
af9c50e166cb        sshd:centos         "/bin/bash /run.sh"   6 seconds ago       Up 5 seconds        0.0.0.0:10022->22/tcp   gracious_colden
#使用ssh登录刚创建的容器,验证ssh登录是否正常
root@docker-server:~# ssh 10.0.0.16 -p 10022
The authenticity of host '[10.0.0.16]:10022 ([10.0.0.16]:10022)' can't be established.
RSA key fingerprint is SHA256:kFGUqwSd9WSJWB59LXlsAiVSbaZ6i9cjTKaGKxVXwsU.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[10.0.0.16]:10022' (RSA) to the list of known hosts.
[root@af9c50e166cb ~]#

二、基于本地模板导入

   用于可以直接从一个操作系统模板文件导入一个镜像,导入的镜像可以使从别的主机导出的镜像,也可以使用OpenVZ提供的模板来创建。

导入镜像命令格式:docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

# 导入一个redis镜像 
root@docker-server:~# docker import redis_run.tar dayi123/redis:1.1  
sha256:62cd458bd1200e36ffdcf2176cd3ead21e744b3e6d19ffdc4d980819d4b4134d
root@docker-server:~# docker images
REPOSITORY       TAG         IMAGE ID          CREATED             SIZE
dayi123/redis    1.1          62cd458bd120    5 seconds ago       104MB
# 也可以使用如下的方法导入
root@docker-server:~# cat nginx_run.tar | docker import - dayi123/nginx:1.1
sha256:54eb4a4e69027e2bc857d35a2f58965d87f9d9f73b877fb7af3e0fcdb71546d4

三、使用Dockerfile创建镜像

1、dockerfile基本结构

       dockerfile是一个文本格式的配置文件,dockerfile由一行行命令语句组成,并且支持以“#”号开头的注释行。dockerfile一般有四部分组成,分别时基础镜像信息,维护者信息,镜像操作指令和容器启动时执行指令。dockerfile结构如下:

#第一行必须指令基于的基础镜像 
From ubutu 
#维护者信息 
MAINTAINER docker_user [email protected] 
#镜像的操作指令 
apt/sourcelist.list 
RUN apt-get update && apt-get install -y ngnix 
RUN echo "\ndaemon off;">>/etc/ngnix/nignix.conf 
#容器启动时执行指令 
CMD /usr/sbin/ngnix

2、dockerfile创建镜像的指令

1FROM

     FROM指令用于指定创建镜像的基础镜像,如果基础镜像本地不存在,则会去docker hup上下载。

    格式:FROM <image>

 任何Dockerfile中的第一条指令必须为FROM指令,如果在同一个Dockerfile中创建多个镜像,可以使用多个FROM指令。

2MAINTAINER

   MAINTAINER指令用于指定维护者信息,该信息会写入生成镜像的Author属性域中。

 格式:MAINTAINER [email protected]

3RUN

   RUN指令用于运行指定命令

 格式:RUN <command>

             RUN [“executable”,”param1”,”param2”]

   前一个指令将在shell终端中运行命令;后一个指令则使用exec执行,不会启动shell环境,由于后一个指令会被解析为JSON数组,因此必须用双引号。

   指定使用其他终端类型可以通过第二种指令实现。每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像,当命令较长时可以使用”\”换行。

4CMD

   CMD指令用来指定启动容器时默认执行的命令。

 格式: CMD [“executable”,”param1”,”param2”]

            CMD command param1 param2

            CMD [“param1”,”param2”]

   第一种格式是使用exec执行,是推荐使用的方式,第二种在”/bin/sh”中执行,提供给需要交互的应用,第三种是提供给ENTRYPOINT的默认参数。

   每个Dockerfile只能有一条CMD命令,如果指定了多条命令,只有最后一条会被执行,如果用户启动容器时手动指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。

5LABEL

    LABEL指令用来指定生成镜像的元数据标签信息。

 格式为:LABEL <key>=<value> <key2>=<value2>......

6EXPOSE

   EXPOSE用于声明镜像内服务所监听的端口。

格式:EXPOSE <port>

   该指令只是起到申明作用,并不会自动完成端口映射。

7ENV

  指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。

  格式:ENV <key><value>

               ENV <key>=<value>

    指定的环境变量在运行容器时可以通过再次指定环境变量覆盖掉。

8ADD

  该命令将复制指定的<src>路径下的内容到容器中<dest>路径下

  格式:ADD <src> <dest>

    <src>可以时Dockerfile所在目录的一个相对路径,也可以是一个URL,还可以时tar文件,若果是tar文件,则会自动解压到<dest>目录下。路径支持正则格式。

9COPY

    COPY指令复制本地的<src>(为dockerfile所在目录的相对路径,文件或目录)下的内容到镜像中的<dest>下,目标路径不存在时,会自动创建。

 格式:COPY <src> <dest>

   COPY路径也支持正则。

10ENTRYPOINT

   指定镜像默认入口命令,该入口命令会在启动容器时作为根命令执行,所有的传入值作为该命令的参数。

 格式:ENTRYPOINT [“executable”,”param1”,”param2”]

             ENERYPOINT command param1 param2

  第一种格式使用exec调用执行,第二种格式在shell中执行

  每个Dockerfile中只能有一个ENTYPOINT,当指定多个时,只有最后一个生效,在创建启动容器时也可以被”--entrypoint”参数覆盖掉。

11VOLUME

    创建一个数据卷挂载点

 格式:VOLUME [“/data”]

   可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和要保存的数据。

12USER

  指定运行容器时的用户名或UID

  格式:USER daemon

     当容器不需要管理员权限时,可以通过该命令指定运行用户,并且可以在之前创建所需要的用户。

13WORKDIR

     WORKDIR指令用于为后续的RUNCMDENTRYPOINT指令配置工作目录。

  格式:WORKDIR /path/to/workdir

  可以使用多个WORKDIR指令,如果后续命令参数是相对路径,则会基于之前命令指定的命令。

14ARG

  指定一些镜像内使用的参数,这些参数在执行docker build命令时才以--build-arg<varname>=<value>格式传入

  格式:ARG<name>[=<default value>]

15ONBUILD

     ONBUILD用于配置所创建的镜像为其他镜像的基础镜像。

  格式:ONBUILD [INSTRUCTION]

16STOPSIGNAL

    指定所创建镜像启动的容器接受退出的信号值。

17HEALTHCHECK

    配置所启动容器如何进行健康检查

  格式:HEALTHCHECK [OPTIONS] CMD command

               HEALTHCHECK NONE

  选项:--interval=DURATION 多久检查一次,默认为30s

               --timeout=DURATION 没次检查等待结果的超时时间,默认为30S

               --retries=N 如果失败了,重试几次才最中确定失败,默认为3

  第一种格式是根据所执行命令返回值是否为0来判断,第二种格式为禁止基础镜像中的健康检查。

18SHELL

    指定其他命令使用shell时的默认shell类型。

    格式:SHELL [“executable”,”parameters”]

    默认值:[“/bin/sh”,”-c”]

3、创建镜像

  编写完dockerfile后,可以通过docker build命令来创建镜像。

  命令格式:docker build [OPTIONS] PATH | URL | -

  常用选项:-t 指定生成镜像的标签信息

                      -f 指定非内容路径下的Dockerfile

  创建过程:命令读取指定路径下(包括子目录)所有的Dockefile,并且把目录下所有内容发送到服务端,由服务端创建镜像。另外可以通过创建.dockerignore文件(每一行添加一个匹配模式)让docker忽略指定目录或者文件

4、使用dockerfil创建镜像

1)使用dockerfile创建ssh镜像

创建工作目录:

#创建工作目录
root@docker-server:/home/dayi123# mkdir sshd_ubuntu
root@docker-server:/home/dayi123# cd sshd_ubuntu

创建dockerfile文件,文件内容如下:

#设置基础镜像
FROM ubuntu:16.04
#作者信息
MAINTAINER dayi123 [email protected]
#更新系统
RUN apt-get update
#安装ssh服务
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
#设置ssh服务自启动
CMD ["/run.sh"]

如果基础镜像为centos,其他操作配置相同,dockerfile内容如下:

#设置基础镜像
FROM centos:6
#作者信息
MAINTAINER dayi123 [email protected]
#安装ssh服务
RUN rpm --rebuilddb
RUN yum install openssh-server -y 
#更新系统
RUN rpm --rebuilddb
RUN yum -y update
RUN mkdir -p /root/.ssh
#生成ssh配置文件
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
#设置文件权限以及用户密码
RUN chmod 755 /run.sh
RUN chmod 600 /etc/ssh/ssh_host_rsa_key
RUN echo dayi123 | passwd --stdin root
#对外开放的端口
EXPOSE 22
#设置ssh服务自启动
CMD ["/run.sh"]

创建run.sh文件,内容如下:

root@docker-server:/home/dayi123/sshd_ubuntu# cat run.sh 
#!/bin/bash 
/usr/sbin/sshd -D

创建镜像:

root@docker-server:/home/dayi123/sshd_ubuntu# docker build -t sshd:ubuntu16.04 .
Sending build context to Docker daemon  4.608kB
Step 1/12 : FROM ubuntu:16.04
 ---> 70b70c987e8f
Step 2/12 : MAINTAINER dayi123 [email protected]

查看创建的镜像:

root@docker-server:/home/dayi123/sshd_ubuntu# docker images
REPOSITORY   TAG         IMAGE ID            CREATED             SIZE
sshd        ubuntu16.04   39bff62c2248        20 minutes ago      256MB

验证创建的镜像

#利用刚创建的镜像创建一个容器并给映射端口
root@docker-server:/home/dayi123/sshd_ubuntu# docker run -d -p 22222:22 sshd:ubuntu16.04 
05775c46eff631f97cf24637c12a00deac1a1f0a428dc981ab1e030bd79da03f
#通过ssh登录验证
root@docker-server:/home/dayi123/sshd_ubuntu# ssh 10.0.0.16 -p 22222
The authenticity of host '[10.0.0.16]:22222 ([10.0.0.16]:22222)' can't be established.
ECDSA key fingerprint is SHA256:pP8aSQDFA8kNdkqQVARFp+BW93mFkIwxmw4bBQjnVZg.
Are you sure you want to continue connecting (yes/no)? yes
......

2)使用刚创建的带有sshd服务的centos镜像创建nginx镜像

创建工作目录

[root@ansible-server docker]# mkdir nginx_centos
[root@ansible-server docker]# cd nginx_centos/

创建dockerfile文件内容如下:

[root@ansible-server nginx_centos]# cat Dockerfile 
#基础镜像
FROM sshd:centos6.9
#作者信息
MAINTAINER dayi123 [email protected]
#设置工作目录并安装基础软件包
WORKDIR /usr/local/src
RUN yum -y install gcc zlib zlib-devel openssl openssl-devel pcre pcre-devel make wget
#下载解压nginx
RUN wget http://nginx.org/download/nginx-1.14.0.tar.gz
RUN tar -zxvf nginx-1.14.0.tar.gz
#编译安装nginx
WORKDIR nginx-1.14.0
RUN ./configure --prefix=/usr/local/nginx --with-pcre --with-http_ssl_module && make && make install
#启动nginx
RUN /usr/local/nginx/sbin/nginx
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
ADD run.sh /usr/local/sbin/run.sh
RUN chmod 755 /usr/local/sbin/run.sh
CMD ["/usr/local/sbin/run.sh"]
#对外开放22、80、443端口
EXPOSE 22
EXPOSE 80
EXPOSE 443

创建启动的脚本文件:

#启动脚本文件同时启动sshd服务和nginx服务
[root@ansible-server nginx_centos]# cat run.sh 
#!/bin/bash
/usr/sbin/sshd &
/usr/local/nginx/sbin/nginx

创建镜像:

[root@ansible-server nginx_centos]# docker build -t nginx:centos .

使用刚才创建的镜像创建容器并测试:

#创建容器
[root@ansible-server nginx_centos]# docker run -d -P httpd:centos
#查看映射的端口
[root@ansible-server nginx_centos]# docker ps
CONTAINER ID   IMAGE            COMMAND                     CREATED       STATUS     PORTS              NAMES
92ee03494be5   httpd:centos    "/usr/local/sbin/run…"   9 minutes ago       Up 9 minutes        0.0.0.0:32775->22/tcp, 0.0.0.0:32774->80/tcp, 0.0.0.0:32773->443/tcp   adoring_feynman
#测试nginx
[root@ansible-server nginx_centos]# curl http://127.0.0.1:32774
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
......


猜你喜欢

转载自blog.csdn.net/dayi_123/article/details/80557511