Docker教程三:构建镜像以及私有仓库

前言: 上篇已经对docker的命令有了个说明,已经可以对docker做基本的操作了。那么接下来就是如何更加深入的了解docker。

一、构建镜像

目前的方式,都是去pull别人的镜像,肯定不是自己想要。那么如何来构建自己想要的镜像呢?

有以下两种方式:

  • docker commit   # 通过容器构建
  • docker build    # 通过Dockfile构建

1、commit

这种方式很简单,就是先创建一个容器。然后修改容器内部达到自己想要的状态。再提交成新镜像。就跟vmware创建快照类似。

# docker commit 容器id 新容器名:版本号     # 提交镜像    -m           # 描述信息    --author # 作者信息

2、build

这种方式是广为流行的一种方式,这是利用编写脚本来编译镜像。就是基于一个基础镜像,然后执行各种预定义的命令,以及容器启动参数,以及端口映射。都可以在配置文件里配置。使用此方式还有个好处就是“有迹可循”,通过查看Dockerfile文件,知道目标镜像是如何构建的。

下面先来个小列子:

# mkdir httpd && cd httpd    # 创建目录

# vim Dockerfile                        # 编写文件

# Version: 0.0.1                                                  # 标示版本号FROM centos:6                                                     # 定义从哪个镜像开始MAINTAINER DonTony "xutao3653@sina.com"                           # 作者信息RUN yum -y install httpd                                          # 开始执行命令RUN echo 'Hi, I am your container' > /var/www/html/index.htmlRUN service httpd startEXPOSE 80                                                     # 映射80端口

# docker build -t="webserver/httpd:v1" .       # 构建镜像,注意最后的点.

上面的例子是:从centos6镜像开始,首先安装httpd,然后定义首页内容,在启动服务。最后映射端口。

那么上面的各个指令都有什么含义呢?见下面

FROM用法:FROM :说明:这个设置基本的镜像,为后续的命令使用,所以应该作为Dockerfile的第一条指令。例:FROM centos:6PS:如果没有指定 tag ,则默认tag是latest,如果都没有则会报错。MAINTAINER用法:MAINTAINER 说明:MAINTAINER命令用来指定维护者的姓名和联系方式例:MAINTAINER DonTony "xutao3653@sina.com"RUN用法:RUN  (the command is run in a shell - `/bin/sh -c`) OR RUN ["executable", "param1", "param2" ... ]  (exec form)说明:RUN命令会在上面FROM指定的镜像里执行任何命令,然后提交(commit)结果,提交的镜像会在后面继续用到。等价于:docker run image commanddocker commit container_id例:RUN yum -y install httpdENTRYPOINT用法:ENTRYPOINT cmd param1 param2 OR ENTRYPOINT ["echo", "Whale you be my container"]说明:ENTRYPOINT 命令设置在容器启动时执行命令例:ENTRYPOINT ["service","httpd","start"]USER用法:USER 说明:用来指定运行用户例:USER nobodyEXPOSE 用法:EXPOSE  [...]说明:EXPOSE 命令可以设置一个端口在运行的镜像中暴露在外例:EXPOSE 80也可以通过run容器的时候指定:-p 80ENV用法:ENV  说明:ENV命令设置一个环境变量例:ENV name test也可以通过run容器的时候指定:--env name="test"ADD用法:ADD   是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url 是container中的绝对路径说明:从src复制文件到container的dest路径:例:ADD http://192.168.1.121/pkg/apache-tomcat-8.0.20.tar.gz /home/app/apache-tomcat-8.0.20.tar.gzPS;支持网络路径VOLUME 用法:VOLUME [""]说明:创建一个挂载点用于共享目录例:VOLUME ["/data"]WORKDIR 用法:WORKDIR 说明:配置RUN, CMD, ENTRYPOINT 命令设置当前工作路径例:WORKDIR /rootPS:可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令CMD用法:有三种格式:CMD ["executable","param1","param2"] (like an exec, preferred form)CMD ["param1","param2"] (as default parameters to ENTRYPOINT)CMD command param1 param2 (as a shell)说明:CMD 设定运行镜像时的默认命令例:CMD /etc/init.d/httpd startPS:运行docker run 时不提供COMMAND就会执行到。一个Dockerfile里只能有一个CMD,如果有多个,只有最后一个生效。

下面给出一个实际的例子吧(仅作为测试演示!):构建一个tomcat环境

# Version: 0.0.1FROM centos:6MAINTAINER DonTony "xutao3653@sina.com"RUN yum install -y vim tar lrzsz openssh openssh-server wget lrzszRUN useradd appRUN echo "test.com"|passwd --stdin appRUN echo "test.com_root"|passwd --stdin rootRUN ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_keyRUN ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_keyRUN sed -ri 's/session    required     pam_loginuid.so/# session    required     pam_loginuid.so/g' /etc/pam.d/sshdRUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.sshWORKDIR /home/appADD http://192.168.1.121/pkg/jdk1.8.0_40.tar.gz /home/app/jdk1.8.0_40.tar.gzRUN tar zxf /home/app/jdk1.8.0_40.tar.gz -C /home/app/ADD http://192.168.1.121/pkg/apache-tomcat-8.0.20.tar.gz /home/app/apache-tomcat-8.0.20.tar.gzRUN tar zxf /home/app/apache-tomcat-8.0.20.tar.gz -C /home/app/RUN rm -fr /home/app/*.tar.gzRUN echo "### For jdk ### " >> .bash_profileRUN echo "export JAVA_HOME=/home/app/jdk1.8.0_40" >> /home/app/.bash_profileRUN echo "export JAVA_BIN=/home/app/jdk1.8.0_40/bin" >> /home/app/.bash_profileRUN echo "export PATH=$PATH:/home/app/jdk1.8.0_40/bin" >> /home/app/.bash_profileRUN echo "export CLASSPATH=.:/home/app/jdk1.8.0_40/lib/dt.jar:/home/app/jdk1.8.0_40/lib/tools.jar" >> /home/app/.bash_profileRUN echo "export JAVA_HOME JAVA_BIN PATH CLASSPATH" >> /home/app/.bash_profileRUN chown -R app.app /home/appEXPOSE 22CMD /usr/sbin/sshd -DEXPOSE 8080

好了,多构建几次,便就理解了。

二、私有仓库

每次去公网pull镜像?上面构建的镜像如何给别的机器使用?这些都是遗留问题。那么就可以利用registry来构建自己企业内部的私有仓库来解决这些问题吧。

使用私有仓库有许多优点:

  1. 节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可;
  2. 提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。

接下来我们就大致说一下如何在本地搭建私有仓库。

首先在需要部署仓库的机器上pull镜像

docker pull registry

然后启动容器(默认情况下,会将仓库存放于容器内的/tmp/registry目录下,这样如果容器被删除,则存放于容器中的镜像也会丢失,所以我们一般情况下会指定本地一个目录挂载到容器内的/tmp/registry下,如下:)

docker run -d -p 5000:5000 -v /root/my_registry:/tmp/registry registry

1463465575200

成功启动容器。

现在看/root/my_registry里面是空的,等一会push之后再看。

下面就是pull一个需要提交的镜像了。比如nginx

docker pull nginx

pull下来之后,需要改tag

docker tag nginx 10.20.161.77:5000/nginx

ok了,现在可以push到仓库了。

docker push 10.20.161.77:5000/nginx

会出现如下提示:

1463465588975

因为Docker从1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动docker server时增加启动参数为默认使用http访问。

解决办法:

vim /etc/sysconfig/docker

增加如下:

INSECURE_REGISTRY='--insecure-registry 10.20.161.77:5000'

重启docker

systemctl restart docker

启动仓库容器

1463465605213

再次push成功

1463465617532

用url的方式查看私有仓库镜像

curl http://10.20.161.77:5000/v1/search

1463465637428

出现刚刚push的镜像则成功。

现在私有仓库就可以使用了。不过在使用前还是记得修改docker的配置文件,增加10.20.161.77:5000

1463465655576

关键字:docker

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部