Docker-03-镜像和容器

一、Docker Image

1.1 什么是Image

  • image是一个文件和meta data的集合
  • 分层的,并且每一层都可以添加、改变、删除文件,成为一个新的image
  • 不同的image可以共享layer
  • image本身是read-only的

1.2 image的获取方式

  • 封装一个容器为镜像(最好不用此方式)
docker commit -m "commit message" container_id image_name 
  • 通过dockerfile创建
docker build -t image_name .
  • 通过pull命令拉取
sudo docker pull image_name

注:docker官方镜像地址  https://github.com/docker-library

1.3 制作一个base镜像案例

  • 第一步:创建一个c语言程序
cat >hello.c<<EOF
#include<stdio.h> int main() { printf("hello docker\n"); }
EOF
  • 第二步:安装c语言编译环境
yum -y install gcc glibc-static
  • 第三步:将C语言程序生成可执行文件
#生成文件
gcc
-static hello.c -o hello

#运行检查
./hello
  • 第四步:编写dockerfile
FROM scratch
ADD hello /
CMD ["/hello"]
  • 第五步:build一个镜像
docker build -t hello-docker .
  • 第六步:通过镜像运行容器
docker run hello-docker

1.4 镜像的管理

  • 列出镜像

通过docker images命令列出docker主机上可用的镜像:

docker image ls
docker images
  • 查找镜像

通过docker search命令来查找所有Docker Hub上公共的可用镜像:

docker search centos
  • 拉取镜像

通过docker pull *** 从Docker Hub 拉取镜像:

docker pull [image_id]
  • 删除镜像

通过docker rmi 命令删除docker主机上的镜像:

docker image rm image_id
docker rmi image_id
  • 查看镜像构建历史

通过docker history命令查看镜像的构建历史:

docker history {image_id]

1.5 构建镜像

构建Docker镜像有以下两种方法:

  • 使用docker commit命令。
  • 使用Dockerfile 文件。

不推荐使用docker commit来构建镜像,而应该使用更灵活、更强大的Dockerfile来构建Docker镜像。

1.5.1 docker commit

从一个改变过的容器中创建出一个镜像!不提倡使用这种方式创建镜像。

创建过程示例:

  • 第一步:交互式运行一个centos容器 
docker run -it centos
  • 第二步:在container里面安装一个vim
[root@e06e38343df1 /]# yum -y install vim
  • 第三步:退出容器,得到一个退出后的容器
[root@e06e38343df1 /]# exit
exit
[root@docker01 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
e06e38343df1        centos              "/bin/bash"         3 minutes ago       Exited (0) 6 seconds ago                       zen_einstein
  • 第四步:通过commit命令,将容器封装成镜像
[root@docker01 ~]# docker commit e06e38343df1 centos-vim
sha256:5296e3e165f88a30951abdc7f99ffcef6b4f4015b811c3ad248dfdc9e4f1bee9

#其中,
e06e38343df1是容器的id编号,centos-vim是需要生成的image名,并默认tag为latest
  • 第五步:查看生成结果
[root@docker01 ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos-vim          latest              5296e3e165f8        36 seconds ago      340MB
hello-docker        latest              dded1e846e79        7 minutes ago       861kB
centos              latest              9f38484d220f        2 weeks ago         202MB
  • 第六步:对比两个容器的创建过程

对比发现,两个镜像的imaeg层基本一致,只是centos-vim比centos多了一层而已。

[root@docker01 ~]# docker history centos
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
9f38484d220f        2 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           2 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           2 weeks ago         /bin/sh -c #(nop) ADD file:074f2c974463ab38c…   202MB               
[root@docker01 ~]# docker history centos-vim
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
5296e3e165f8        About a minute ago   /bin/bash                                       139MB               
9f38484d220f        2 weeks ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           2 weeks ago          /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           2 weeks ago          /bin/sh -c #(nop) ADD file:074f2c974463ab38c…   202MB        

1.5.2 docker build

通过Dockerfile来创建一个容器!推荐使用这种方式。

首先删除刚才生成的镜像

[root@docker01 ~]# docker image rm centos-vim
Untagged: centos-vim:latest
Deleted: sha256:5296e3e165f88a30951abdc7f99ffcef6b4f4015b811c3ad248dfdc9e4f1bee9
Deleted: sha256:cb2194f0da66c3b2e7a6c5d5731dc3446f29875f4d47af87e2dd0d95c0ec6a09
  • 第一步:创建一个docker-file目录,并进入该目录
[root@docker01 ~]# mkdir docker-file
[root@docker01 ~]# cd docker-file/
  • 第二步:编写Dockerfile
[root@docker01 docker-file]# vim Dockerfile
[root@docker01 docker-file]# cat Dockerfile 
FROM centos
RUN yum -y install vim
  • 第三步:运行docker build命令创建镜像
[root@docker01 docker-file]# docker build -t centos-vim-new .
  • 第四步:查看创建结果
[root@docker01 docker-file]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos-vim-new      latest              7bc0867a884a        49 seconds ago      340MB
hello-docker        latest              dded1e846e79        20 minutes ago      861kB
centos              latest              9f38484d220f        2 weeks ago         202MB

1.6 docker file语法

1.6.1 FROM

用于docker file最开头的语法,指定base image

FROM scratch    #从头制作一个base image
FROM centos    #使用base image

最佳实践:尽量使用官方的image作为base image!

1.6.2 LABEL

定义了image的metadata,例如作者、版本、描述等,类似于代码里面的注释

LABEL maintainer="xxx"
LABEL version="1.0"
LABEL description="this is description"

最佳实践:Metadata不可少!

1.6.3 RUN

执行运行命令,每执行一次RUN,都会生成新的image layer

RUN yum -y install vim
RUN yum update && yum -y install vim\
python-dev

最佳实践:为了美观,复杂的RUN用反斜线换行!为了避免无用分层,合并多条命令成一行!

1.6.4 WORKDIR

设定当前的工作目录,类似于linux中的cd命令来改变目录

WORKDIR /test  #如果没有会自动创建test目录
WORKDIR demo
RUN PWD      #输出结果因该是/test/demo

最佳实践:用WORKDIR,不要用RUN cd!尽量使用绝对目录!

1.6.5 ADD 和 COPY

将本地的文件添加到image里面。

ADD hello /
ADD test.tar.gz /  #添加到根目录并解压

最佳实践:

  • 大部分情况,COPY优于ADD!
  • ADD除了COPY还有额外的解压功能!
  • 添加远程文件/目录请使用curl或者wget!

1.6.6 ENV

设定一个环境变量或者常量。

ENV MYSQL_VERSION 5.6    #设置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \    #引用常量
&& rm -rf /var/lib/apt/lists/*

最佳实践:尽量使用ENV增加可维护性!

1.6.7 CMD

  • 设置容器启动后默认执行的命令和参数。
  • 如果docker run制定了其他命令,则CMD命令被忽略。
  • 如果定义了多个CMD,只有最后一个会执行。
FROM centos
ENV name Docker
CMD echo "hello $name"

#执行命令后的输出结果?
docker run [image]输出?
docker run -it [image] /bin/bash输出?

执行命令的两种格式:

  • shell格式:
#运行命令

RUN apt-get install -y vim CMD echo "hello docker" ENTRYPOINT echo "hello docker"
#Dockerfile

FROM centos
ENV name Docker
ENTRYPOING echo "hello $name"
  • exec格式:
RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]
#Dockerfile

FROM centos
ENV name Docker
ENTRYPOING ["/bin/echo","hello $name"]

1.6.8 ENTRYPOINT

  • 设置容器启动时运行的命令,让容器以应用程序或服务的形式运行
  • 不会被忽略,一定会执行!

最佳实践:写一个shell脚本作为entrypoint

COPY docker-entrypoint.sh /usr/local/bin
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 27017
CMD ["mongod"]

1.6.9 VOLUME

1.6.10 EXPOSE

1.6.11 一个docker file实战

  • 第一步:准备一个代码文件app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
    return "hello docker"
if __name__ == '__main__':
    app.run()
  • 第二步:运行测试该文件
pip install Flask
python app.py
  • 第三步:验证启动结果
[root@docker01 ~]# curl http://127.0.0.1:5000
hello docker
  • 第四步:创建Dockerfile,并打包成镜像
#dockerfile 内容
FROM python:2.7 LABEL maintainer="test message" RUN pip install Flask COPY app.py /app/ WORKDIR /app EXPOSE 5000 CMD ["python","app.py"]

#docker build镜像
docker build -t flask-hello-docker .
  • 第五步:运行容器
docker run -d flask-hello-docker

二、Docker Container

2.1 什么是container

  • 通过Image创建
  • 在Image layer上创建一个container layer(可读写)
  • 类比面向对象:类和实例
  • Imange负责app的存储和分发,Container负责运行ap

2.2 container常用命令

#查看正在运行的容器
docker container ls
docker ps
#查看正在运行和已经停止的容器 docker container ls -a docker ps -a #运行一个容器 docker run [image_id]

#运行容器,并指定容器名
docker run --name=demo [image_id]

#进入一个运行的容器
docker exec -it [container_id] /bin/bash    #新开一个终端
docker attach [container_id]           #进入同一个终端,一般不用

#停止容器
docker stop [container_id]
#交互式运行一个容器 docker run
-it centos #删除一个容器 docker container rm container_id docker rm container_id #删除所有容器 docker rm `docker ps -aq` #删除所有已经停止的容器 docker rm `docker ps -q -f "status=exited"`

#查看一个容器的详细信息
docker inspect [container_id]

#查看容器的日志
docker logs [container_id]

#查看容器的ip地址
docker exec -it [container_id] ip a

 

posted @ 2019-03-31 12:08  流光给给  阅读(304)  评论(0编辑  收藏  举报