Docker镜像

镜像的分层结构

仓库是用来存放镜像的,镜像是用来初始化容器的

rhel>oel> centos ubuntu debian系统

红帽和centos的区别

1.Centos是的克隆版本,是把redhat的源代码拿来编译然然后发行的发行版本。但是基本的命令和使用方法是一样。
2.centos是免费的版本,不向用户提供任何的服务,你么用户在使用工程中出现的各种问题,Centos是不负责任的。而redhat对某些服务是提供收费的,在所提供的服务中出现问题。redhat是负责解决的。
3.CentOS独有的yum命令支持在线升级,可以即时更新系统,不像RedHat那样需要花钱购买支持服务!也就是说redhat的服务是需要收费的,而Centos是完全免费的。
4.CentOS修正了许多RedHat AS的BUG。

Linux-> kernel-> diy->app不容的系统内核都是相同的(版本可能不同)但是文件系统不同

.共享宿主机的kernel
.base镜像提供的是最小的Linux发行版
.同一docker主机支持运行多种Linux发行版
.采用分层结构的最大好处是:共享资源

Copy-on-Write 可写容器层正常我们对容器进行写操作都是container这一层,下面都是只读的,但是当我们想修改下面image镜像层的时候,他是会将东西拷贝到container中然后在进行修改。
容器层以下所有镜像层都是只读的docker从上往下依次查找文件容器层保存镜像变化的部分,并不会对镜像本身进行任何修改一个镜像最多127层


镜像的构建

docker commit 构建新镜像三部曲
·运行容器

通过docker ps查看运行的容器


·修改容器
·将容器保存为新的镜像
缺点:
·效率低、可重复性弱、容易出错
·使用者无法对镜像进行审计,存在安全隐患

首先我们拉取一个新的镜像

[root@server1~]# docker pull busybox 
Using default tag:latest 
latest:Pulling from library/busybox
0669bedaf1fb:Pull complete Digest:sha256:b26cd013274a657b86e706210ddd5cc1f82f50155791199d29b9e86e935ce135
Status:Downloaded newer image for busybox:latest 
docker.io/library/busybox:latest

同样的我们还可以拉取其他的比如ubuntu、centos、rhel等,可以通过docker images查看打大小,但是rhel一般没有官方的,我们可以拉取别人设置的

[root@server1~]# docker pull richxsl/rhel7
[rootdserver1~]# docker images 
REPOSITORY                 TAGIMAGE                 IDCREATED                SIZE 
nginx                    latested21b7a8aee        94 days ago                127MB 
busybox                  latest83aa35ga1c793      weeks ago                  1.22MB 
game                    2048latest19299002fdbe    3 years ago                55.5MB 
richxsl/rhel7             latest9c7b3825758a      5 years ago                245MB

我们可以进行测试并查看内核版本

[root@server1~]# docker run -it --rm richxsl/rhel7 bash
[ root@ aca1620f134b/]# uname-r
3.10.0-957.e17.×8664
[ root@ aca1620f134b/]# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 7.0(Maipo)

docker ps -a 可以获取所有的容器不用-a的话只是运行的容器

我们通过如下进入镜像

[root@server1~]# docker run -it busybox

然后我们可以创建10个文件

/#touch file1
/#1s 
bin    etc    home    root    tmp    var dev file1    proc sys usr

我们可以通过ctrl+D 退出,但是我们退出的话我们的容器就会被停掉,我们可以通过docker ps -a查看状态

然后我们可以通过容器的ID或者名字再次打开容器,然后通过attach连入容器

[root@server1 ~]# docker start 68097c1dd5bb
68097c1dd5bb
[root@server1~]# docker attach 68097c1dd5bb

我们也可以使用ctrl+P+Q快捷键让容器在后台运行不退出

像上述我们创建的文件都是在镜像的文件系统里面,他不会创建到本地的默认文件系统中

我们可以通过commit加上ID号将文件系统保存然在后面也可以给他起个名字

[rootaserver1 ~l# docker commit 68097cldd5bb busybox:v1
sha256:5364b27dfcc58107d4ffdd4375967229fe6495acd6846cc465240d9c9da7b1c8

我们再去查看

Lrootaserverl ~l# docker 1mages 
REPOSITORY             TAG        IMAGE             IDCREATED                SIZE 
busybox                V1       5364b27dfcc        52 seconds ago            1.22MB

然后我们去查看他们的共享分层

先查看原始的然后去查看我们的V1发现V1只是在原始的基础上又增加了一层

如果想删除正在运行的容器的时候必须使用-f,否则就需要先停掉

[root@server1 ~]# [root@server1~]# docker ps
CONTAINER ID     IMAGE    COMMAND    CREATED       STATUS            PORTS        NAMES
68097c1dd5bb     busybox    "sh"     5minutes ago   Up 3 minutes    goofy     montalcini
[rooteserver1~]# docker rm -f 68097c1dd5bb
68097c1dd5bb

我们也可以查看被的容器

这这个最新的nginx容器她的层数就比较多

我们创建一个dockerfile

[rooteserver1~]# mkdir docker
[root@server1~]# cd docker/
[rooteserver1 docker]#1s
[rooteserver1 docker]# vim Dockerfile
[rootaserver1 docker]#1s 
Dockerfile
[rooteserverl docker]# echo westos > testfile

我们在dockerfile写上如下

FROM busybox
CoPY testfile/

我们可以先将之前建立的容器删除

 [root@server1 docker]# docker rmi busybox:v1
 Untagged:busybox:v1
 Deleted:sha256:5364b27dfcc58107d4ffdd4375967229fe6495acd6846cc465240d9c9da7b1c8
 Deleted:sha256:f0fbc4cbf6b8591662317fc8f8d01abf01893fee1839ee8d9903d6faf1c17cb3

然后我们创建一个容器通过-t指定名字

[root@server1 docker]# docker build -t demo:v1 .

我们可以发现一共执行了两步显示from busybox,然后copy文件到/下

[rootaserver1 docker]#ls 
 Dockerfile testfile

  

通过commit方式提交的镜像我们不能查看到在镜像中做了什么

但是通过dockerfile创建的镜像我们可以很清楚的看到做了什么

 

我么也可以对dockerfile进行重新编写我们可以再添加一句

FROM busybox
CoPY testfile/
RUN echo helloworld > filel

然后我们再构建一个build

我们可以发现v2是再v1的基础上又增加一层

Dockerfile详解

·dockerfile常用指令
·FROM
指定base镜像,如果本地不存在会从远程仓库下载。
·MAINTAINER
设置镜像的作者,比如用户邮箱等。
·COPY
把文件从build context复制到镜像支持两种形式:COPY src dest和COPY["src","dest"]
src必须指定build context中的文件或目录

·ADD
用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到
dest,也可以自动下载URL并拷贝到镜像:
ADD html.tar/var/www ADD http://ip/html.tar/var/www

首先我们将1.16版本的nginx安装包放进我们的docker文件夹中,然后我们编辑dockerfile文件

  

FROM busybox 
ADD nginx-1.16.1.tar.gz /

然后我们build一个demo:v1

[rooteserver1 docker]# docker build -t demo:v1.
Sending build context to Docker daemon 1.036MB Step 1/2:FROM busybox
-->83aa35aalc79
Step 2/2:ADD nginx-1.16.1.tar.gz/
--->5c0bd187e65e 
Successfully built 5c0bd187e65e
[root@server1 docker]# docker run -it --rm demo:v1

运行docker run发现如下

 

·ENV
设置环境变量,变量可以被后续的指令使用:
ENV HOSTNAME sevrer1.example.com

FROM busybox 
ENV hostname server1
ADD nginx-1.16.1.tar.gz /

然后build一个v2

[root@server1 docker]# docker build -t demo:v2 .

   

  

·EXPOSE
如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80


·VOLUME
申明数据卷,通常指定的是应用的数据挂载点:
VOLUME ["/var/www/html"]编辑dockerfile'如下

FROM busybox 
ENV hostname server1
ADD nginx-1.16.1.tar.gz /
VOLUME ["/data"]

然后built一个v3

[root@server1 docker]# docker build -t demo:v3 .

  

[root@server1 docker]# docker run -it demo:v3
/ # ls
bin     dev     home             proc     sys     usr 
data    etc     nginx-1.16.1     root     tmp     var
/ # cd /data/
/data# 1s
/data # pwd
/data
/data# 1s
/data # touch filel

然后我们退出容器会发现容器挂载点

也就是只要容器识别到有VOUME这个卷他就自动给我们挂载上

这是我们在file1中写如内容然后去容器里面查看

[rooteserver1 data]# echo westos >> filel
[rooteserver1 data]# echo westos >> filel
[rooteserver1 data]# echo westos >> filel
[rooteserver1 datal# echo westos >> filel
[rooteserver1 _data]# cat filel westos
westos
westos
westos
westos
westos
[rootaserver1 datal# docker ps
CONTAINER ID IMAGE  COMMAND                               CREATED           ATATUS                 PORTS                                      NAMES
8ebaaef0b9e8         demo:v3          "sh"                                    3minutes ago         Up 3 minutes                                                              eloquen 
t_bouman
2ffa67974075        nginx            "nginx-g     'daemon of.."          6minutes ago         Up 6 minutes              0.0.0.0:32768->80/tcp              nginx
[rooteserver1 datal# docker attach 8e
/data# ls 
filel
/data#cat filel 
westos
westos
westos
westos
westos

默认挂载的文件都是读写的无论我们是在容器里面删除还是在宿主机中删除都会删除

我们可以通过 docker volume prune进行卷的删除(删掉没有被使用的卷)


·WORKDIR
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。如下我们通过workdir创建nginx目录

FROM busybox 
ENV hostname server1
WORKDIR /nginx
ADD nginx-1.16.1.tar.gz/nginx 
VOLUME ["/data"]

[root@server1 docker]# docker build -t demo:v4 .

 

·RUN
在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install-y vim

我们编辑dockerfile

  

[root@serverl docker]# docker build -t demo:v5 .

   

虽然我们没有指定file1和file2的路径但是我们使用WORKDIR,他就会相当于我们使用了cd功能默认后面的操作都在workdir中的目录中
·CMD与ENTRYPOINT
这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。docker run后面的参数可以传递给ENTRYPOINT指令当作参数。Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。

[root@server1 docker]#cat index.html
www.westos。org
[rooteserver1 docker]#1s Dockerfile index.html nginx-1.16.1.tar.gz testfile
[rooteserver1 docker]# docker cp index.html nginx:/usr/share/nginx/html/

我们可以编辑dockerfile

在最后添加上
CMD echo helloworld

[rooteserver1 docker]# docker build -t demo:v6 .
 [rooteserver1 docker]# docker run -it --rm demo:v6
 helloworld

也可以结合ENV,CMD echo $hostname

[rooteserver1 docker]# docker build -t demo:v7 .
 [rooteserver1 docker]# docker run -it --rm demo:v7
 server1

如果我们在后面加一个shell他就没有了输出结果

但是如果我们把CMD改成ENTRYPOINT echo $hostname

然后我们去build,docker built -t demo:v8 .然后run ,通过对比发现他不可以覆盖

Shell和exec格式的区别
#cat Dockerfile 
FROM busy box 
ENV name world 
ENTRYPOINT echo"hello,Sname"
Shell格式底层会调用/bin/sh-c来执行命令,可以解析变量,而下面的exec格式不会:
#cat Dockerfile 
FROM busybox 
ENV name world 
ENTRYPOINT ["/bin/echo","hello,$name"]

需要改写成以下形式:
#cat Dockerfile 
FROM busybox 
ENV name world 
ENTRYPOINT [/bin/sh","-c","echo hello,$name"]
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时
ENTRYPOINT会忽略任何CMD或dockerrun提供的参数。
#cat Dockerfile 
FROM busybox 
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world“]

FROM busybox 
ENV hostname server1
WORKDIR /nginx 
ADD nginx-1.16.1. tar. gz /nginx 
VOLUME ["/data"]
RUN touch filel
RUN touch file2
CMD ["/bin/sh", "-c", "echo $hgstname"]

然后built和run发现这种写法是对的,单纯的CMD ["$hgstname"]存在语法错误

我们在

然后built 和run

[root@serverl docker]# docker run -it --rm demo:v11
hello world
[root@server1 docker]# docker run-it--rm demo:v1l westos
hello westos
[rooteserver1 docker]# docker run-it--rm demo:v11 linux
hello linux

CMD是可以覆盖的

看下在运行容器时的区别:
#docker run--rm busybox:v1
hello world
#docker run--rm busybox:v1 linux
hello linux
官方推荐使用exec格式书写

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值