创建镜像
使用docker镜像时,如果作为测试使用,可以直接从docker仓库中下载现成的镜像使用。如果在生产环境中使用,为了满足自己的需求性及安全方面的考虑,最好使用自己制作的镜像。创建docker镜像的方法主要由三种,基于已有镜像的容器创建,基于本地模板导入,基于dockerfile创建。
基础镜像:在创建自己的镜像前,需要在docker hub上下载一些基础镜像,基础镜像可以选择BusyBox、Alphine、Debian/Ubuntu、Centos/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
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创建镜像的指令
(1)FROM
FROM指令用于指定创建镜像的基础镜像,如果基础镜像本地不存在,则会去docker hup上下载。
格式:FROM
任何Dockerfile中的第一条指令必须为FROM指令,如果在同一个Dockerfile中创建多个镜像,可以使用多个FROM指令。
(2)MAINTAINER
MAINTAINER指令用于指定维护者信息,该信息会写入生成镜像的Author属性域中。
格式:MAINTAINER [email protected]
(3)RUN
RUN指令用于运行指定命令
格式:RUN
RUN [“executable”,”param1”,”param2”]
前一个指令将在shell终端中运行命令;后一个指令则使用exec执行,不会启动shell环境,由于后一个指令会被解析为JSON数组,因此必须用双引号。
指定使用其他终端类型可以通过第二种指令实现。每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像,当命令较长时可以使用”\”换行。
(4)CMD
CMD指令用来指定启动容器时默认执行的命令。
格式: CMD [“executable”,”param1”,”param2”]
CMD command param1 param2
CMD [“param1”,”param2”]
第一种格式是使用exec执行,是推荐使用的方式,第二种在”/bin/sh”中执行,提供给需要交互的应用,第三种是提供给ENTRYPOINT的默认参数。
每个Dockerfile只能有一条CMD命令,如果指定了多条命令,只有最后一条会被执行,如果用户启动容器时手动指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。
(5)LABEL
LABEL指令用来指定生成镜像的元数据标签信息。
格式为:LABEL
(6)EXPOSE
EXPOSE用于声明镜像内服务所监听的端口。
格式:EXPOSE
该指令只是起到申明作用,并不会自动完成端口映射。
(7)ENV
指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。
格式:ENV
ENV
指定的环境变量在运行容器时可以通过再次指定环境变量覆盖掉。
(8)ADD
该命令将复制指定的
格式:ADD
(9)COPY
COPY指令复制本地的
格式:COPY
COPY路径也支持正则。
(10)ENTRYPOINT
指定镜像默认入口命令,该入口命令会在启动容器时作为根命令执行,所有的传入值作为该命令的参数。
格式:ENTRYPOINT [“executable”,”param1”,”param2”]
ENERYPOINT command param1 param2
第一种格式使用exec调用执行,第二种格式在shell中执行
每个Dockerfile中只能有一个ENTYPOINT,当指定多个时,只有最后一个生效,在创建启动容器时也可以被”--entrypoint”参数覆盖掉。
(11)VOLUME
创建一个数据卷挂载点
格式:VOLUME [“/data”]
可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和要保存的数据。
(12)USER
指定运行容器时的用户名或UID
格式:USER daemon
当容器不需要管理员权限时,可以通过该命令指定运行用户,并且可以在之前创建所需要的用户。
(13)WORKDIR
WORKDIR指令用于为后续的RUN、CMD和ENTRYPOINT指令配置工作目录。
格式:WORKDIR /path/to/workdir
可以使用多个WORKDIR指令,如果后续命令参数是相对路径,则会基于之前命令指定的命令。
(14)ARG
指定一些镜像内使用的参数,这些参数在执行docker build命令时才以--build-arg
格式:ARG
(15)ONBUILD
ONBUILD用于配置所创建的镜像为其他镜像的基础镜像。
格式:ONBUILD [INSTRUCTION]
(16)STOPSIGNAL
指定所创建镜像启动的容器接受退出的信号值。
(17)HEALTHCHECK
配置所启动容器如何进行健康检查
格式:HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE
选项:--interval=DURATION 多久检查一次,默认为30s
--timeout=DURATION 没次检查等待结果的超时时间,默认为30S
--retries=N 如果失败了,重试几次才最中确定失败,默认为3
第一种格式是根据所执行命令返回值是否为0来判断,第二种格式为禁止基础镜像中的健康检查。
(18)SHELL
指定其他命令使用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
Welcome to nginx!
......