频道栏目
首页 > 系统 > Linux > 正文

Docker之镜像管理及Dockerfile解析

2018-09-29 15:02:14           
收藏   我要投稿

目录

一、镜像工作原理

二、镜像管理

二、Dockerfile

三、构建部署Nginx

四、构建部署Java网站

镜像:

1. 一个分层存储的文件:

优点:易于扩展、优化存储空间

2. 一个软件的环境

3. 一个镜像可以用于创建多个容器

4. 一种标准化的交付

一、镜像工作原理

镜像不是一个单一的文件,而是有多层构成。可以通过 docker history 查看镜像中各层内容及大小,每层对应着 Dockerfile中的一条指令。

$ docker history nginx:1.14

IMAGE CREATED CREATED BY SIZE COMMENT

86898218889a 3 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B

3 weeks ago /bin/sh -c #(nop) STOPSIGNAL [SIGTERM] 0B

3 weeks ago /bin/sh -c #(nop) EXPOSE 80/tcp 0B

3 weeks ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22B

3 weeks ago /bin/sh -c set -x && apt-get update && apt… 53.7MB

3 weeks ago /bin/sh -c #(nop) ENV NJS_VERSION=1.14.0.0.… 0B

3 weeks ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.14.0-… 0B

3 weeks ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B

3 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B

3 weeks ago /bin/sh -c #(nop) ADD file:e6ca98733431f75e9… 55.3MB

容器其实是在镜像的最上面加了一层读写层,在运行的容器中有文件改动时,会先从镜像里把要写的文件复制到容器自己的文件系统中,都会写到这个读写层。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高了磁盘利用率。

若想持久化这些改动,可以通过 docker commit 将容器保存成一个新的镜像。

二、镜像管理

常用选项:

$ docker image --help

OPTIONS DESCRIBE

ls/images 列出镜像

pull 从仓库拉取镜像到本地

push 从本地上传镜像到仓库

inspect 显示详情

history 镜像历史信息

import 导入tar归档的容器文件系统创建镜像

save 保存一个镜像到tar归档文件

load 从tar归档或标准输入导入镜像

rm 移除一个或多个镜像

build 从Dockerfile构建镜像

tag 创建一个引用源镜像标记目标镜像

Example:

从仓库拉取镜像

docker pull nginx:1.14

保存镜像到tar归档文件

$ docker image save nginx:1.14 > myweb.tar

从tar归档或标准输入导入镜像

$ docker image load < myweb.tar

引用源镜像标记目标镜像

$ docker image tag nginx:1.14 web:v1

$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

tomcat latest 41a54fe1f79d 2 weeks ago 463MB

nginx 1.14 86898218889a 3 weeks ago 109MB

web v1 86898218889a 3 weeks ago 109MB

centos 7 5182e96772bf 7 weeks ago 200MB

centos latest 5182e96772bf 7 weeks ago 200MB

二、Dockerfile

官方仓库虽然有数十万的镜像资源,但在绝大多数情况下都不符合我们的需求,通常我们都会自己构建镜像。Dockfile 是一种被 Docker 程序解释的脚本, Dockerfile 由一条一条的指令组成,每条指令对应 Linux 下面的一条命令。Docker 程序将这些 Dockerfile 指令翻译真正的Linux命令。Docker 程序将读取 Dockerfile,根据指令生成定制的 image。

*注意:每一条指令就相当于给镜像加了一层,一个镜像不能超过 127 层,请惜字如金!

官方文档:https://docs.docker.com/engine/reference/builder/

常用指令:

OPTIONS DESCRIBE

FROM 基于哪个镜像构建新镜像

MAINTAINER(弃用) 镜像维护者信息

LABEL 同上,但用法更加灵活

RUN 构建镜像时运行的Shell命令

COPY 拷贝文件或目录到镜像中

CMD 运行容器时执行,如果有多个CMD指令,最后一个生效

ENTRYPOINT 运行容器时执行,如果有多个CMD指令,最后一个生效。可单独使用,也可与CMD配合使用

USER 为RUN、CMD、ENTRYPOINT执行指令指定运行用户

EXPOSE 声明容器运行的服务端口

WORKDIR 为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录

VOLUME 指定挂载点,使容器中的一个目录具有持久化存储数据的功能

ENV 设置环境变量

ENTRYPOINT与CMD的区别在于ENTRYPOINT可以使用CMD作为参数,通常都是用作启动后台服务。

先来一个简单的 Dockerfile

创建一个工作目录,在工作目录下创建一个py脚本

FROM 指明以 centos:latest 作为基础镜像

COPY 指明复制源文件 test.py 到容器的 /tmp 目录下,test.py没指明路径,会运行 build 命令的当前目录下查找。

CMD 在容器启动时运行的命令

$ mkdir work

$ cd work/

$ cat test.py

#!/usr/bin/env python

print 'hello,container!'

$ cat Dockerfile

# Description: test image

FROM centos:latest

LABEL maintainer="Qukecheng "

COPY test.py /tmp

CMD python /tmp/test.py

docker build 命令是根据上下文自动构建镜像。构建上下文指定位置PATH或文件集URL,PATH是本地文件系统上的目录,URL是一个Git仓库地址。

构建由 Docker 守护程序运行,而不是CLI。构建过程第一件事是将整个上下文(递归)发送到守护进程。建议空目录作为上下文,并将 Dockerfile 保存在该目录下,目录中仅包含构建 Dockerfile 所需的文件,比如刚刚创建的 work 目录。

$ docker build --help

$ docker build -t myimage:v1 ./

Sending build context to Docker daemon 3.072kB

Step 1/4 : FROM centos:latest

---> 5182e96772bf

Step 2/4 : LABEL maintainer="Qukecheng "

---> Running in 804c23af5fb3

Removing intermediate container 804c23af5fb3

---> 2409cc31df3f

Step 3/4 : COPY test.py /tmp

---> 02f2546571b9

Step 4/4 : CMD python /tmp/test.py

---> Running in f3ce25242fca

Removing intermediate container f3ce25242fca

---> 72ff3d4714ca

Successfully built 72ff3d4714ca

Successfully tagged myimage:v1

使用刚刚生成的镜像,启动一个容器

$ docker container run --rm myimage:v1

hello,container!

还需要注意的是:

1. 一次 RUN 指令形成新的一层,进程让shell命令都写在一行,减少镜像层,一个镜像是不能超过 127 层的,在使用 RUN 指令时,可以在每条 shell 命令的结尾用转义换行 "\"。

2. 一次 RUN 形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减少镜像大小。比如 yum 之后,清一下缓存。

三、构建部署Nginx

$ tree web/

web/

├── base

│ └── Dockerfile_nginx

└── project

├── Dockerfile_nginx

└── nginx.conf

$ mkdir -pv web/{base,project}

$ cd web/base/

$ touch Dockerfile_nginx

Nginx

$ cat Dockerfile_nginx

FROM centos:latest

LABEL maintainer="Qukecheng "

RUN yum install -y gcc gcc-c++ make \

openssl-devel pcre-devel gd-devel libxslt-devel \

iproute net-tools telnet wget curl && \

yum clean all && \

rm -rf /var/cache/yum/*

RUN wget http://nginx.org/download/nginx-1.14.0.tar.gz && \

tar -zxf nginx-1.14.0.tar.gz && \

cd nginx-1.14.0 && \

./configure --prefix=/usr/local/nginx \

--with-http_ssl_module \

--with-http_v2_module \

--with-http_realip_module \

--with-http_image_filter_module \

--with-http_gunzip_module \

--with-http_gzip_static_module \

--with-http_secure_link_module \

--with-http_stub_status_module \

--with-stream \

--with-stream_ssl_module && \

make -j $(grep processor /proc/cpuinfo | wc -l) && make install && \

cd / && rm -rf nginx-1.14.0*

ENV PATH $PATH:/usr/local/nginx/sbin

WORKDIR /usr/local/nginx

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

开始构建镜像

$ docker build -t nginx1.14 -f Dockerfile_nginx ./

$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

nginx1.14 latest 2b3cd8303924 10 minutes ago 323MB

centos latest 5182e96772bf 7 weeks ago 200MB

有了基础镜像,就可以基于这个镜像封装项目到镜像了

项目镜像

$ cd project/

$ touch Dockerfile_nginx nginx.conf

$ cat Dockerfile_nginx

FROM nginx1.14

COPY nginx.conf /usr/local/nginx/conf/

$ cat nginx.conf

user nobody;

worker_processes 1;

error_log logs/error.log info;

events {

worker_connections 4096;

}

http {

include mime.types;

default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"';

sendfile on;

keepalive_timeout 65;

server {

listen 80;

server_name localhost;

charset utf-8;

access_log logs/host.access.log main;

location / {

root html;

index index.html index.htm;

}

}

}

$ docker build -t nginx:v1 -f Dockerfile_nginx ./

部署网站

$ docker network create web

$ docker volume create wwwroot

$ docker container run -d --name web_nginx -p 88:80 --network lnmp -v wwwroot:/usr/local/nginx/html nginx:v1

四、构建部署Java网站

Java 程序依赖于 JDK 环境,我们可以把 JDK 放在宿主机上,容器以挂载形式使用,减少镜像大小及提高性能。

$ tar -zxf jdk-8u91-linux-x64.tar.gz

$ sudo mv jdk1.8.0_91/ /usr/local/jdk1.8

$ tree java/

java/

├── apache-tomcat-8.5.16.tar.gz

└── Dockerfile

0 directories, 2 files

$ cd java/

$ cat Dockerfile

FROM centos:latest

LABEL maintainer="Qukecheng "

ENV VERSION=8.5.16

ENV JAVA_HOME=/usr/local/jdk

RUN yum install wget curl unzip iproute net-tools -y && \

yum clean all && \

rm -rf /var/cache/yum/*

COPY . /

RUN tar zxf apache-tomcat-${VERSION}.tar.gz && \

mv apache-tomcat-${VERSION} /usr/local/tomcat && \

rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* && \

mkdir /usr/local/tomcat/webapps/ROOT && \

echo '

Hello,Tomcat!

' > /usr/local/tomcat/webapps/ROOT/status.html && \

sed -i '1a JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"' /usr/local/tomcat/bin/catalina.sh && \

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATH $PATH:/usr/local/tomcat/bin

WORKDIR /usr/local/tomcat

EXPOSE 8080

CMD ["catalina.sh", "run"]

$ docker build -t tomcat8:latest ./

$ docker container run -d --name tomcat_srv -p 89:8080 -v /usr/local/jdk1.8/:/usr/local/jdk tomcat8:latest

上一篇:SecureCRT脚本环境类(python)
下一篇:phpstudy部署https
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站