2019-07 第十二、十七章 深入Dockerfile构建镜像和容器开发环境介绍

生成镜像的方法:

A . 从container生成

方法1.  # docker commit              这是把container的变更,提交给新image

方法2.  # docker export   >  tarball   

     # cat tarball | docker import -      同1

B. 从image生成

方法1.  # docker save -o tarball  registry/reposiry/image                这是从registry的db到本地FS文件

    modify the tarball

    docker load -i tarball                           这是从本地FS文件装在镜像,到本地image的db

C. 从Dockerfile生成

1.  和A,B比,优点: 可追踪image的定义,可升级image中软件版本、几乎不消耗存储、通过阅读Dockerfile代替docker inspect来检视镜像/container的内容

2. 命令: docker build -t    [-f Dockerfile] <构建目录>  [options]    

        不指定-f选项时,在当前目录下自动搜索Dockerfile。 指定-f选项时,需要是构建目录的相对路径,且位于构建目录的子目录内

3. 原理: 

        docker build命令是传令官;

        构建目录(一般是当前目录 . )下所有内容是build镜像的素材, 由docker build传给docker daemon,存在/var/lib/docker下------

                如果要排除一些文件、目录不传给docker daemon,就把它们列入构建目录下的.dockerignore文件

        Dockerfile里每一行是docker daemon执行的指令;

        docker damon是真正执行build镜像的工人。

        这些被执行的命令是在build 镜像是执行的

        每执行一个Dockerfile的命令,生成一个中间镜像,和数据缓存;下次再docker build时,会重用最后一条没有改变过的指令的中间层容器,来节省时间------

                如果要不留中间层容器:docker build --force-rm=true

                如果要从头build不使用缓存和中间层:docker build --no-cache=true

4. 镜像的定制基于哪些素材:

        a. 基础镜像 -- 由FROM命令指定,本地有优先用本地的,没有就去registry拉取;强制拉取的选项是 --pull=true

            FROM        永远的底格指令

        b. 文件素材 -- 须位于构建目录之下

            ADD / COPY    不会使用docker build生成的临时层,而是检索docker build传给docker daemon的“文件系统”。

                ADD   <相对Dockerfile的目录路径>    <去往容器的文件的绝对路径>

        c. 通信接口 -- 端口

            EXPOSE        暴露容器内端口。这个端口可以用于容器连接,或者影射给主机的socket,映射关系可以由docker port察看,宿主机docker-proxy监听宿主机的映射端口(netstat -tupln)。

                    映射给主机指定的socket地址: docker run -p  <主机ip:主机端口>:<被暴露的容器端口>。 主机IP默认是0.0.0.0

                    映射给主机随机的随机的端口:  docker run -P    <被暴露的容器端口>

                    容器连接

        d. 修改基础镜像

            RUN        比如创建文件、安装软件

        e. 修改后续的build镜像的环境变量

            ENV  =        可以在docker run  时由选项-e = 覆盖

        f. 自定义键值,作为镜像的标签

            LABEL  =        可以一行定义多个,用空格分开,这样避免多个容器层被创建。

                    LABEL的key的定义没有限制,但推荐使用开发者可控域名的反向顺序的DNS格式:比如: LABEL net.linuxtoys.mylabel=xxx

                    容器的LABEL可以用docker inspect检视,也可以用docker ps -a --filter “label==”来筛选容器

                    也可以用docker images --filter “label==”来筛选镜像

        g. 景象启动时的默认命令

            ENTRYPOINT        默认的运行命令,可以在docker run  时由选项--entrypoint="xxx" 覆盖

            CMD                        默认的ENTRYPOINT的运行参数,可以在docker run时 由 最后的参数覆盖



基于Dockerfile设计容器的原则

1. 一个容器只干一件事

容器连接或K8S编排,实现共享服务

2. 让构建目录尽可能小,否则用.dockerignore文件排除不想包含的文件

目的是减少传递构建目录给docker daemon的时间,也节省/var/lib/docker的空间

3. 高效合理地组织Dockerfile的RUN命令

一行生成一个中间层。

所以,多命令在一行,可以节省空间。但是其中任何命令失败了,下次build还得全部build这一行,浪费时间。

其实合理组织RUN命令,是Docker镜像合理分层的手段。Docker镜像是一种特殊的FS:Union FS,是一系列中间层叠加在基础镜像(也是之前叠加产物)上的结果。docker pull 拉取的,实际是本地已有镜像之上的叠加层。所以Dockerfile的RUN命令,不仅影响开发,也影响拉取使用的效率。

4. ENTRYPOINT命令最先去做清理工作,比如删除上次kill/stop时僵死的进程.pid文件

5. 最佳实践

https://docs.docker.com/engine/reference/builder/                

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ 


容器开发和运行环境的种类

1. 运行在VirtualBox、KVM上的虚拟机镜像Vagrant,它已经配置好了Docker、K8S等容器开发运行需要的软件(CDK3.9 )

https://developers.redhat.com/products/cdk/download 

https://access.redhat.com/downloads/content/293/ver=3.9/rhel---7/3.9/x86_64/product-software 

https://access.redhat.com/documentation/en-us/red_hat_container_development_kit/3.9/ 

2. 运行于Openshift之上 (K8S的包装)

1) 开发者专用的上游项目--容器内的Openshift-- Openshift Origin。 搭建

step1.  install redhat7

step2. install docker、kubernetes、etcd

step3. 配置K8S集群

step4. 禁用SELinux

step5. 信任docker registry

step6. 启动docker服务

step7. 拉取、运行Opeshift/origin容器

step8. 打开后台运行的Origin容器的Bash Shell

Step9. 纯Openshift操作,建立项目、app(也就是容器镜像)、pods(启动容器)

2)Ansible搭建的Openshift (NNIT ENET用的),即K8S集群

3)基于AWS、GCE的Openshift

你可能感兴趣的:(2019-07 第十二、十七章 深入Dockerfile构建镜像和容器开发环境介绍)