为什么平常安装进虚拟机的centos都是好几个G,为什么docker中的centos镜像之类一般只有几百兆?
因为docker中的系统镜像是一个精简的os,rootfs可以很小,只需要包括最基本的命令,工具和程序库就行,因为底层直接用kernel,自己只需要提供rootfs就行,由此可见对于不同的linux发行版,bootfs基本一致,rootfs会有差别,因此不同的发行版可以公用;
镜像的特性
镜像是分层的,
Dcoker的镜像是通过联合文件系统(union filesytem)实现的boofs: 用于系统引导的文件系统,包含bootloader和kernel,容器启动完成后会被卸载以节省内存资源;
rootfs:位于bootfs之上,表现为Docker容器的根文件系统

图1
从现实生活中可以看成这样;下层均是仅读的;而上层文件可覆盖下层文件;从顶层看如图2所示;

镜像和容器的关系
简单来说,从仓库pull的是镜像,这是一种状态;
在docker run 镜像之后,镜像变成了另外一种状态container容器;
镜像和容器之间是可以相互转换的
从容器转换为容器: docker run xxx镜像
从容器转换为镜像: docker commit 容器名或id -t 镜像:tag
根据Dockerfile生成: docker build -t 镜像:tag .
镜像的导入导出: docker save -o nginx.tar nginx:latest
docker load -i nginx.tar
容器转换为镜像
(1) 可以先运行一个容器
镜像如果要运行,则必须要有工作在前台的守护进程至少一个
docker pull centos:6.8 //拉取基础镜像
(测试:docker run -name test centos:6.8 运行后即会退出)
docker run --name mysql centos:6.8(为基础镜像,启动即会退出)
网易蜂巢镜像库:c.163yun.com
centos选择public/centos
下载centos镜像:docker pull hub.c.163.com/public/centos:6.7-tools
运行此镜像:docker run --name mysql -d hub.c.163.com/public/centos:6.7-tools
进入到此镜像:docker exec -it mysql /bin/bash
安装mysqlserver: yum -y install mysql mysql-server
运行数据库:service mysqld start
chkconfig mysqld on
数据库设置
mysqladmin -uroot password 123
mysql -uroot -p
创建数据库:
create database shangguigu
show datbase
exit
(2)可以将运行的容器转换为镜像
将正在运行的容器mysql转换为镜像
docker commit mysql mysql:5.1
(3) 再次启动镜像为容器
运行生成的镜像:
docker run -name my-mysql -d msql:5.1或者imageid
到此容器下:
docker exec -it container_id /bin/bash
service mysqld start
mysql -uroot -p
123
show databases;
exit;
镜像的制作,Dockerfile
Dockerfile常用字段如下:
1,FROM (指定基础镜像)
可位于远方仓库,也可位于本地
example:
FROM centos:7.2
FROM centos
2,MAINTAINER (用来指定你镜像创建者信息)
example :
MAINTAINER hurui "hurui196@pingan.com.cn"
3,RUN(安装软件用)
example:
RUN cd /tmp && curl -L 'http://xxx.tar.gz'
4,CMD (设置container 启动时执行的操作)
example:
CMD echo "Hello World!"
***注意有多条时只执行最后一条
5,ENTRYPOINT (设置container 启动时执行的操作)
example:
ENTRYPOINT ls -l
****注意如果 cmd 和 entrypoint 同时存在时,如果均命令完整,则只执行最后一条;否则为搭配执行;
6,USER (设置container容器的用户)
设置指令,设置启动容器的用户,默认是root用户;
example:
USER daemon = ENTRYPOINT ["memcached","-u","daemon"]
7,EXPOSE(指定容器需要映射到宿主机器的端口):
8,ENV(用于设置环境变量)
example:
ENV JAVA_HOME /path/to/java/dirent
9,ADD(从src复制文件到container的dest路径)
example:
ADD <src> <dest>
<src>可以是相对路径,绝对路径,或者是url地址;
<dest>是container中的绝对路径,如果是压缩包会解压
10,COPY(从src复制文件到container的dest路径)(源文件是什么复制过来就是什么)
不支持url下载和解压;
10,VOLUME (指定挂载点)
设置指令,使容器中的一个目录具有持久化存贮数据的功能,改目录可以被容器本身使用,也可以共享给其他容器使用;
example:
From base;
VOLUME ["/tmp/data"]
11,WORKDIR(切换目录):设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效;
example: WORKDIR /p1 WORKDIR p2 RUN vim a.txt ==RUN cd /p1/p2 && vim a.txt
12,ONBUILD(在镜像中执行):ONBUILD指定的命令在构建镜像时并不执行,而是在它的子镜像中执行;
example:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注意,一般容易混淆的是copy,add的区别,cmd和entrypoint区别
add支持的类型比较广,可以是链接和压缩包,会自动下载或解压缩至目标目录;而copy原文件是什么即是什么;
cmd和entrypoint一般搭配使用;
cmd在docker run执行时会被指定的命令覆盖;而entrypoint在docker run时如果没有指定--entrypoint,一般不会被覆盖;在shell格式下时会被忽略,在Exec格式下时会被当做为追加参数;
docker run busybox --rm -it --image=busybox /bin/ps
docker run -it nginx --entrypoint “echo hello world”
dockerfile示例:
FROM hub.c.163.com/public.centos:6.7
MAINTAINER husir@163.com.cn
ADD ./apache-tomcat-7.0.42.tar.gz /root
ADD ./jdk-7u25-linux-x64.tar.gz /root
ENV JAVA_HOME /root/jdk1.7.0_25
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 8080
ENTRYPOINT /root/apache-tomcat-7.0.42/bin/startup.sh && taif /root/apache-tomcat-7.0.42/logs/catalina.out
将Dockerfile转换为镜像:
docker build -t tomcat:v1.0 .
docker images
docker run --name tomcat -p 80:8080 -d tomcat:v1.0