第二章 Docker的镜像和容器

一、Docker 架构和底层技术简介

1.1 Docker Platfrom

  • Docker 提供了一个开发、打包、运行app的平台
  • 把APP和底层 infrastructure 隔离开来
Docker 平台

1.2 Docker Engine

Docker 核心组件
Docker Engine 由三部分组成

  • 后台进程(dockerd)
    守护进程,也就是Server端。
[root@iZ2zecjyzb15bzhr9xrg5oZ ~]# ps -ef | grep docker
root     10842     1  0 10:37 ?        00:00:04 /usr/bin/dockerd -H fd://
root     10860 10842  0 10:37 ?        00:00:09 containerd --config /var/run/docker/containerd/containerd.toml --log-level info
root     11181 11153  0 11:32 pts/0    00:00:00 grep --color=auto docker
  • REST API Server
    Server端与客户端(Docker Client)是通过Rest API进行通信。
  • CLI 接口 (docker)
    image、container、网络等等
Docker Engine

1.3 Docker 组织架构

Docker 组织架构

1.4 Docker 底层技术支持

  • Namespaces:做隔离 pid,net, ipc, mnt , uts
  • Control groups:做资源限制,内存等
  • Union file systems: Container 和 image分层

二、Docker Image

2.1 image 概述

image:文件和 meta data 的集合,rootfs(root filesystem)
Base Image 只包含rootfs,不包含bootfs,这么做可以共享主机内核空间
Linux 内核空间 bootfs、用户空间 rootfs

image 概述
[root@iZ2zecjyzb15bzhr9xrg5oZ ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
xiaopeng163/redis   latest              ca77520764aa        5 minutes ago       205MB
ubuntu              14.04               5dbc3f318ea5        4 weeks ago         188MB
hello-world         latest              fce289e99eb9        7 weeks ago         1.84kB

2.2 获取Image(1)

Build from Dockerfile 从Dockerfile文件创建

[root@iZ2zecjyzb15bzhr9xrg5oZ ~]# cat Dockerfile
FROM ubuntu:14.04
LABEL maintainer="Peng Xiao "
RUN apt-get update && apt-get install -y redis-server
EXPOSE 6379
ENTRYPOINT [ "/usr/bin/redis-server" ]
[root@iZ2zecjyzb15bzhr9xrg5oZ ~]# docker build -t xiaopeng163/redis:latest .
Sending build context to Docker daemon  88.21MB
Step 1/5 : FROM ubuntu:14.04
14.04: Pulling from library/ubuntu
e53f134edff2: Pull complete
efbbd466a715: Pull complete
e11368b8e0c7: Pull complete
7dab2de7692b: Pull complete
Digest: sha256:cac55e5d97fad634d954d00a5c2a56d80576a08dcc01036011f26b88263f1578
Status: Downloaded newer image for ubuntu:14.04
 ---> 5dbc3f318ea5
Step 2/5 : LABEL maintainer="Peng Xiao "
 ---> Running in 5810a86127c3
Removing intermediate container 5810a86127c3
 ---> e727304e9f12
Step 3/5 : RUN apt-get update && apt-get install -y redis-server
 ---> Running in 7ee9055b1d9f
Get:1 http://security.ubuntu.com trusty-security InRelease [65.9 kB]
Get:2 http://security.ubuntu.com trusty-security/main amd64 Packages [1000 kB]
Get:3 http://security.ubuntu.com trusty-security/restricted amd64 Packages [18.1 kB]
.........
Get:21 http://archive.ubuntu.com trusty/multiverse amd64 Packages [169 kB]
Fetched 13.4 MB in 12s (1042 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
  libjemalloc1 redis-tools
The following NEW packages will be installed:
  libjemalloc1 redis-server redis-tools
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 412 kB of archives.
After this operation, 1272 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ trusty/universe libjemalloc1 amd64 3.5.1-2 [76.8 kB]
Get:2 http://archive.ubuntu.com/ubuntu/ trusty-updates/universe redis-tools amd64 2:2.8.4-2ubuntu0.2 [66.8 kB]
Get:3 http://archive.ubuntu.com/ubuntu/ trusty-updates/universe redis-server amd64 2:2.8.4-2ubuntu0.2 [269 kB]
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin:
Fetched 412 kB in 2s (139 kB/s)
Selecting previously unselected package libjemalloc1.
(Reading database ... 11582 files and directories currently installed.)
Preparing to unpack .../libjemalloc1_3.5.1-2_amd64.deb ...
Unpacking libjemalloc1 (3.5.1-2) ...
Selecting previously unselected package redis-tools.
Preparing to unpack .../redis-tools_2%3a2.8.4-2ubuntu0.2_amd64.deb ...
Unpacking redis-tools (2:2.8.4-2ubuntu0.2) ...
Selecting previously unselected package redis-server.
Preparing to unpack .../redis-server_2%3a2.8.4-2ubuntu0.2_amd64.deb ...
Unpacking redis-server (2:2.8.4-2ubuntu0.2) ...
Processing triggers for ureadahead (0.100.0-16) ...
Setting up libjemalloc1 (3.5.1-2) ...
Setting up redis-tools (2:2.8.4-2ubuntu0.2) ...
Setting up redis-server (2:2.8.4-2ubuntu0.2) ...
invoke-rc.d: policy-rc.d denied execution of start.
Processing triggers for libc-bin (2.19-0ubuntu6.14) ...
Processing triggers for ureadahead (0.100.0-16) ...
Removing intermediate container 7ee9055b1d9f
 ---> c1ad31df9c88
Step 4/5 : EXPOSE 6379
 ---> Running in c8ecb56d9c5c
Removing intermediate container c8ecb56d9c5c
 ---> d4d06822c9ef
Step 5/5 : ENTRYPOINT [ "/usr/bin/redis-server" ]
 ---> Running in cf99fb384f45
Removing intermediate container cf99fb384f45
 ---> ca77520764aa
Successfully built ca77520764aa
Successfully tagged xiaopeng163/redis:latest

2.4 获取Image(2)

Pull from Registry 从仓库获取

[root@iZ2zecjyzb15bzhr9xrg5oZ ~]# docker pull ubuntu:14.04
14.04: Pulling from library/ubuntu
Digest: sha256:cac55e5d97fad634d954d00a5c2a56d80576a08dcc01036011f26b88263f1578
Status: Image is up to date for ubuntu:14.04

2.5 DIY一个Base Image

步骤:先写脚本、然后编译、然后构建镜像,然后运行
先写一个脚本 hello.c,然后编译成二进制文件,需要用到gcc

#include

int main()
{
    printf("hello docker\n");
}

安装Gcc

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# yum install gcc glibc-static -y
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# gcc -static hello.c -o hello
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# ls
hello  hello.c
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# ./hello
hello docker

新建一个Dockerfile

FROM scratch
ADD hello /
CMD ["/hello"]

执行build

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker build -t along/hello-world .
Sending build context to Docker daemon  860.7kB
Step 1/3 : FROM scratch
 --->
Step 2/3 : ADD hello /
 ---> 611f300ea44e
Step 3/3 : CMD ["/hello"]
 ---> Running in 51d182042590
Removing intermediate container 51d182042590
 ---> 2ff83cfd58bd
Successfully built 2ff83cfd58bd
Successfully tagged along/hello-world:latest

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
along/hello-world   latest              2ff83cfd58bd        56 seconds ago      857kB
xiaopeng163/redis   latest              ca77520764aa        23 minutes ago      205MB
ubuntu              14.04               5dbc3f318ea5        4 weeks ago         188MB
hello-world         latest              fce289e99eb9        7 weeks ago         1.84kB

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker history 2ff83cfd58bd
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
2ff83cfd58bd        2 minutes ago       /bin/sh -c #(nop)  CMD ["/hello"]               0B
611f300ea44e        2 minutes ago       /bin/sh -c #(nop) ADD file:68a0159a95ced5415…   857kB


[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker run along/hello-world
hello docker

三、初识 Container

由Image创建,必须先有image,才会有container

Container
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
b252634ce3e0        along/hello-world   "/hello"            6 minutes ago       Exited (13) 6 minutes ago                       dreamy_minsky
82852bceb956        hello-world         "/hello"            2 hours ago         Exited (0) 2 hours ago                          gifted_mclaren

-q : 显示容器id
常用命令:

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker run along/hello-world

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
579bd229f967        along/hello-world   "/hello"            7 seconds ago       Exited (13) 6 seconds ago                        thirsty_northcutt
094af6e6bdb0        along/hello-world   "/hello"            9 seconds ago       Exited (13) 8 seconds ago                        cocky_chatelet
26cd7496e6ed        along/hello-world   "/hello"            10 seconds ago      Exited (13) 9 seconds ago                        pensive_wilson
1a359bc2f398        along/hello-world   "/hello"            11 seconds ago      Exited (13) 10 seconds ago                       tender_lovelace
87c7d6a041aa        along/hello-world   "/hello"            13 seconds ago      Exited (13) 12 seconds ago                       keen_perlman
82852bceb956        hello-world         "/hello"            3 hours ago         Exited (0) 3 hours ago                           gifted_mclaren
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container ls -aq
579bd229f967
094af6e6bdb0
26cd7496e6ed
1a359bc2f398
87c7d6a041aa
82852bceb956
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker rm $(docker container ls -aq)
579bd229f967
094af6e6bdb0
26cd7496e6ed
1a359bc2f398
87c7d6a041aa
82852bceb956
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container ls -aq
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container ls -f "status=exited"
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                           PORTS               NAMES
7a761a9b15ee        along/hello-world   "/hello"            About a minute ago   Exited (13) About a minute ago                       kind_goldstine
72291dc5dcc7        along/hello-world   "/hello"            About a minute ago   Exited (13) About a minute ago                       keen_pare
6cbc836fb8de        along/hello-world   "/hello"            About a minute ago   Exited (13) About a minute ago                       goofy_dubinsky
8dacd30bbfb1        along/hello-world   "/hello"            About a minute ago   Exited (13) About a minute ago                       stoic_archimedes
81ac045f35a2        along/hello-world   "/hello"            2 minutes ago        Exited (13) 2 minutes ago                            youthful_williams
d1ccd8b7a215        along/hello-world   "/hello"            2 minutes ago        Exited (13) 2 minutes ago                            recursing_greider
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container ls -f "status=exited" -q
7a761a9b15ee
72291dc5dcc7
6cbc836fb8de
8dacd30bbfb1
81ac045f35a2
d1ccd8b7a215
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker rm $(docker container ls -f "status=exited" -q)
7a761a9b15ee
72291dc5dcc7
6cbc836fb8de
8dacd30bbfb1
81ac045f35a2
d1ccd8b7a215
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

交互式运行
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker  run -it centos

四、构建自己的 Docker 镜像

4.1 docker container commit

简写: docker commit

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker container commit
"docker container commit" requires at least 1 and at most 2 arguments.
See 'docker container commit --help'.

Usage:  docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

4.2 docker image build

简写: docker build

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker image build
"docker image build" requires exactly 1 argument.
See 'docker image build --help'.

Usage:  docker image build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

4.3 构建镜像

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker commit recursing_ganguly along/centos-vim
sha256:3e0b78a186a0c4ae1977e3a28d8dd9d3d78c20b0fae436975a65da1daa109da5
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
along/centos-vim    latest              3e0b78a186a0        10 seconds ago      335MB
along/hello-world   latest              2ff83cfd58bd        About an hour ago   857kB
xiaopeng163/redis   latest              ca77520764aa        2 hours ago         205MB
ubuntu              14.04               5dbc3f318ea5        4 weeks ago         188MB
hello-world         latest              fce289e99eb9        7 weeks ago         1.84kB
centos              latest              1e1148e4cc2c        2 months ago        202MB
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker history 1e1148e4cc2c
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
1e1148e4cc2c        2 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
           2 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
           2 months ago        /bin/sh -c #(nop) ADD file:6f877549795f4798a…   202MB
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker history 3e0b78a186a0
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
3e0b78a186a0        About a minute ago   /bin/bash                                       133MB
1e1148e4cc2c        2 months ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
           2 months ago         /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
           2 months ago         /bin/sh -c #(nop) ADD file:6f877549795f4798a…   202MB
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]#

以Dockerfile文件构建镜像

FROM centos
RUN yum install -y vim
[root@iZ2zecjyzb15bzhr9xrg5oZ docker-centos-vim]# docker build -t along/centos-vim-new .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 1e1148e4cc2c
Step 2/2 : RUN yum install -y vim
 ---> Running in eab1d210d253
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirrors.huaweicloud.com
 * extras: mirrors.huaweicloud.com
 * updates: mirrors.njupt.edu.cn

........
........

Complete!
Removing intermediate container eab1d210d253
 ---> 776e135d7bcf
Successfully built 776e135d7bcf
Successfully tagged along/centos-vim-new:latest
[root@iZ2zecjyzb15bzhr9xrg5oZ docker-centos-vim]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
along/centos-vim-new   latest              776e135d7bcf        16 seconds ago      335MB
along/hello-world      latest              2ff83cfd58bd        About an hour ago   857kB
ubuntu                 14.04               5dbc3f318ea5        4 weeks ago         188MB
centos                 latest              1e1148e4cc2c        2 months ago        202MB

五、Dockerfile 语法梳理及最佳实践

5.1 关键字 FROM

FROM scratch  # 制作base image
FROM centos  # 使用 base image
FROM ubuntu:14.04
……

尽量使用官方的image作为base image ! 为了安全

5.2 关键字 LABEL

LABEL maintainer="[email protected]"
LABEL version="1.0"
LABEL description="This is description"

Metadata 不可少! 必须要有的信息,相当于代码里面的注释

5.3 关键字 RUN

执行命令并创建新的 Image Layer

RUN yum update && yum install -y vim \
python-dev #反斜线换行
  • Shell 格式
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
  • Exec 格式
RUN [ "apt-get","install","-y","vim" ]
FROM centos 
ENV name Docker
ENTRYPOINT [ "/bin/bash","-c", "hello $name" ]

5.4 关键字 WORKDIR

设定工作目录

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

用WORKDIR ,不要使用 RUN cd!,尽量使用绝对路径!

5.5 关键字 ADD COPY

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

WORKDIR /root
ADD  hello test/   #/root/test/hello 结合使用

WORKDIR /root
COPY  hello test/   

** ADD 和 COPY 大部分情况,COPY优先于 ADD,ADD处理COPY还有额外功能(解压)添加远程文件/目录请使用curl 或者 wget! **

5.6 关键字ENV

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

** 尽量使用ENV增加可维护性 **

5.7 关键字 VOLUME EXPOSE

存储和网络

5.8 CMD ENTRYPOINT

CMD: 设置容器启动后默认执行的命令和参数

特点 :

  • 容器启动时默认执行的命令
  • 如果 docker run 指定了其他命令,CMD命令被忽略
  • 如果定义了多个CMD,只有最后一个会执行

5.9 标准Dockerfile mysql

https://github.com/docker-library/mysql/blob/master/5.5/Dockerfile

ENTRYPOINT: 设置容器启动时运行的命令
特点:

  • 让容器以应用程序或者服务的形式运行
  • 不会被忽略,一定会执行
  • 最佳实践:写一个shell脚本作为entrypoint
COPY docker-entrypoint.sh /usr/local/bin
ENTRYPOINT ["docker-entryporin.sh']

EXPOSE 27017
CMD ["mongod"]

5.9 Mysql 5.6 Dockerfile

FROM debian:stretch-slim

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql

RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*

# add gosu for easy step-down from root
ENV GOSU_VERSION 1.7
RUN set -x \
    && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
    && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
    && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
    && export GNUPGHOME="$(mktemp -d)" \
    && gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
    && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
    && gpgconf --kill all \
    && rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \
    && chmod +x /usr/local/bin/gosu \
    && gosu nobody true \
    && apt-get purge -y --auto-remove ca-certificates wget

RUN mkdir /docker-entrypoint-initdb.d

RUN apt-get update && apt-get install -y --no-install-recommends \
# for MYSQL_RANDOM_ROOT_PASSWORD
        pwgen \
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
        perl \
# mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
        libaio1 \
# mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
        libncurses5 \
    && rm -rf /var/lib/apt/lists/*

ENV MYSQL_MAJOR 5.5
ENV MYSQL_VERSION 5.5.62

RUN apt-get update && apt-get install -y ca-certificates wget --no-install-recommends && rm -rf /var/lib/apt/lists/* \
    && wget "https://cdn.mysql.com/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.12-x86_64.tar.gz" -O mysql.tar.gz \
    && wget "https://cdn.mysql.com/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.12-x86_64.tar.gz.asc" -O mysql.tar.gz.asc \
    && apt-get purge -y --auto-remove ca-certificates wget \
    && export GNUPGHOME="$(mktemp -d)" \
# gpg: key 5072E1F5: public key "MySQL Release Engineering " imported
    && gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5 \
    && gpg --batch --verify mysql.tar.gz.asc mysql.tar.gz \
    && gpgconf --kill all \
    && rm -rf "$GNUPGHOME" mysql.tar.gz.asc \
    && mkdir /usr/local/mysql \
    && tar -xzf mysql.tar.gz -C /usr/local/mysql --strip-components=1 \
    && rm mysql.tar.gz \
    && rm -rf /usr/local/mysql/mysql-test /usr/local/mysql/sql-bench \
    && rm -rf /usr/local/mysql/bin/*-debug /usr/local/mysql/bin/*_embedded \
    && find /usr/local/mysql -type f -name "*.a" -delete \
    && apt-get update && apt-get install -y binutils && rm -rf /var/lib/apt/lists/* \
    && { find /usr/local/mysql -type f -executable -exec strip --strip-all '{}' + || true; } \
    && apt-get purge -y --auto-remove binutils
ENV PATH $PATH:/usr/local/mysql/bin:/usr/local/mysql/scripts

# replicate some of the way the APT package configuration works
# this is only for 5.5 since it doesn't have an APT repo, and will go away when 5.5 does
RUN mkdir -p /etc/mysql/conf.d \
    && { \
        echo '[mysqld]'; \
        echo 'skip-host-cache'; \
        echo 'skip-name-resolve'; \
        echo 'datadir = /var/lib/mysql'; \
        echo '!includedir /etc/mysql/conf.d/'; \
    } > /etc/mysql/my.cnf

RUN mkdir -p /var/lib/mysql /var/run/mysqld \
    && chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
    && chmod 777 /var/run/mysqld

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306
CMD ["mysqld"]

关于Dockerfile 官网有更详细的文档:https://docs.docker.com/engine/reference/builder/

六、镜像的发布/实战

6.1 发布

先在Docker官网注册 hub.docker.com
要注意,镜像的名称,斜线前面得是Docker注册的用户名,不一致会导致提交失败

[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
along/centos-vim-new    latest              776e135d7bcf        3 hours ago         335MB
along0505/hello-world   latest              2ff83cfd58bd        4 hours ago         857kB
along/hello-world       latest              2ff83cfd58bd        4 hours ago         857kB
ubuntu                  14.04               5dbc3f318ea5        4 weeks ago         188MB
centos                  latest              1e1148e4cc2c        2 months ago        202MB
[root@iZ2zecjyzb15bzhr9xrg5oZ hello]# docker push along0505/hello-world:latest
The push refers to repository [docker.io/along0505/hello-world]
87b869f39f56: Pushed
latest: digest: sha256:1742813c5d94e3fff816db40b8fd0dbc12e89187c7895a656b1d56dc60451126 size: 527

6.2 实战

app.py

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
    return "hello docker"
if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000)

Dockerfile

FROM python:2.7
LABEL maintainer="Along0505"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD ["python","app.py"]
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker build -t along0505/flask-hello-1828 .
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
along0505/flask-hello-1828   latest              5a686aeca955        16 seconds ago      917MB
along0505/flask-hello-ls     latest              3b3523ee6228        32 minutes ago      917MB
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker run along0505/flask-hello-1828
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker run -d along0505/flask-hello-1828
4e399b778291a07792e448c5b3b51d792b633a3b0f7108065223580dbc8612bc
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
4e399b778291        along0505/flask-hello-1828   "python app.py"     17 seconds ago      Up 16 seconds       5000/tcp            ecstatic_elion

七、容器的操作

7.1 容器操作命令

[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
4e399b778291        along0505/flask-hello-1828   "python app.py"     About an hour ago   Up About an hour    5000/tcp            ecstatic_elion
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker exec -it 4e399b778291 bash
root@4e399b778291:/app# pwd
/app
root@4e399b778291:/app# ps -ef | grep python
root         1     0  0 10:32 ?        00:00:00 python app.py
root        20    14  0 11:43 pts/0    00:00:00 grep python
root@4e399b778291:/app# exit
exit
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker exec -it 4e399b778291 python
Python 2.7.15 (default, Feb  6 2019, 12:35:55)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker exec -it 4e399b778291 ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
60: eth0@if61:  mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker ps -a
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS                         PORTS               NAMES
4e399b778291        along0505/flask-hello-1828   "python app.py"     About an hour ago   Up About an hour               5000/tcp            ecstatic_elion
9ac0aa94474b        along0505/flask-hello-1828   "python app.py"     About an hour ago   Exited (0) About an hour ago                       vigilant_fermi
fbc4030dd352        b93e078729a8                 "/bin/bash"         2 hours ago         Exited (0) 2 hours ago                             quizzical_pike
fef55c06c492        b93e078729a8                 "/bash"             2 hours ago         Created                                            lucid_lalande
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker rm $(docker ps -aq)
9ac0aa94474b
fbc4030dd352
fef55c06c492
Error response from daemon: You cannot remove a running container 4e399b778291a07792e448c5b3b51d792b633a3b0f7108065223580dbc8612bc. Stop the container before attempting removal or force remove
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker container ls -a
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
4e399b778291        along0505/flask-hello-1828   "python app.py"     About an hour ago   Up About an hour    5000/tcp            ecstatic_elion
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker ps -a
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
4e399b778291        along0505/flask-hello-1828   "python app.py"     About an hour ago   Up About an hour    5000/tcp            ecstatic_elion
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
along0505/flask-hello-1828   latest              5a686aeca955        About an hour ago   917MB
along0505/flask-hello-ls     latest              3b3523ee6228        2 hours ago         917MB
                                     d303fc94272b        2 hours ago         917MB
                                     b93e078729a8        2 hours ago         917MB
along/centos-vim-new         latest              776e135d7bcf        6 hours ago         335MB
along/hello-world            latest              2ff83cfd58bd        7 hours ago         857kB
python                       2.7                 0313c3892dbc        8 days ago          912MB
ubuntu                       14.04               5dbc3f318ea5        4 weeks ago         188MB
centos                       latest              1e1148e4cc2c        2 months ago        202MB
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker run -d --name=demo along0505/flask-hello-1828
509c3b1a217e1668077035f58040d9a1190a79147b46b3de51c1a3fb08d3db97
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
509c3b1a217e        along0505/flask-hello-1828   "python app.py"     3 seconds ago       Up 2 seconds        5000/tcp            demo
4e399b778291        along0505/flask-hello-1828   "python app.py"     About an hour ago   Up About an hour    5000/tcp            ecstatic_elion
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker stop demo
demo
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
4e399b778291        along0505/flask-hello-1828   "python app.py"     About an hour ago   Up About an hour    5000/tcp            ecstatic_elion
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker start demo
demo
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
509c3b1a217e        along0505/flask-hello-1828   "python app.py"     35 seconds ago      Up 2 seconds        5000/tcp            demo
4e399b778291        along0505/flask-hello-1828   "python app.py"     About an hour ago   Up About an hour    5000/tcp            ecstatic_elion
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker inspect 509c3b1a217e
[
    {
        "Id": "509c3b1a217e1668077035f58040d9a1190a79147b46b3de51c1a3fb08d3db97",
        "Created": "2019-02-21T11:47:55.578771862Z",
        "Path": "python",
        "Args": [
            "app.py"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 16555,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2019-02-21T11:48:27.610815032Z",
            "FinishedAt": "2019-02-21T11:48:20.915206503Z"
        },
        "Image": "sha256:5a686aeca955121f2fc3b8c09e45f79721f516bde598bdf31700f264a601aefb",
        "ResolvConfPath": "/var/lib/docker/containers/509c3b1a217e1668077035f58040d9a1190a79147b46b3de51c1a3fb08d3db97/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/509c3b1a217e1668077035f58040d9a1190a79147b46b3de51c1a3fb08d3db97/hostname",
        "HostsPath": "/var/lib/docker/containers/509c3b1a217e1668077035f58040d9a1190a79147b46b3de51c1a3fb08d3db97/hosts",
        "LogPath": "/var/lib/docker/containers/509c3b1a217e1668077035f58040d9a1190a79147b46b3de51c1a3fb08d3db97/509c3b1a217e1668077035f58040d9a1190a79147b46b3de51c1a3fb08d3db97-json.log",
        "Name": "/demo",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "shareable",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/f8dba522ae54f0bc8dcb61c57adc9e2a35b9d29035d6d139eb030361fe18109d-init/diff:/var/lib/docker/overlay2/46f9e28a1ce0877e415111413b4e1942c5d1f6a8131f6926e3effd9e4f592885/diff:/var/lib/docker/overlay2/b242b2c2e881a27ec6b6452cdc2ea367b5238892809d046712c3e586335baee4/diff:/var/lib/docker/overlay2/bca0e06bd5dbb5cde447b887e9a0294183c38a804f15ace551a344268f2b813f/diff:/var/lib/docker/overlay2/631591eebd09c6b8f31b595d8b5732c37a32fc0eef288dc824268ec0c0313f81/diff:/var/lib/docker/overlay2/16b8fe9c78ae30c59171b2e96cd031bc49ceef6b46c2f1815a8d0d880a5e090c/diff:/var/lib/docker/overlay2/cc1ee6372148736be3e3797f11666c5b40308fdc643234deff76ceeaec2baf73/diff:/var/lib/docker/overlay2/47b31931155b15937e06b6963d0360a3765e24786fa216f7a0f132be39c5e572/diff:/var/lib/docker/overlay2/3ed47f83761b5e70783c4cf65c27296aa757cb2f9f97062a5cf53ba3033a7814/diff:/var/lib/docker/overlay2/22444f3b0bd7de4ec4ef3af1118a098ac6678df4bbafb7a4a0e4a128c2a71e11/diff:/var/lib/docker/overlay2/b39d249ba57433ca5ac5e0c224dcf2c8073f8112b0e40d1d350b2a23c0cd2c22/diff:/var/lib/docker/overlay2/3bded4af801aae1b75af476e6c54fdf81cf4d270ad9ffb26ba48c7fd6cbc1347/diff",
                "MergedDir": "/var/lib/docker/overlay2/f8dba522ae54f0bc8dcb61c57adc9e2a35b9d29035d6d139eb030361fe18109d/merged",
                "UpperDir": "/var/lib/docker/overlay2/f8dba522ae54f0bc8dcb61c57adc9e2a35b9d29035d6d139eb030361fe18109d/diff",
                "WorkDir": "/var/lib/docker/overlay2/f8dba522ae54f0bc8dcb61c57adc9e2a35b9d29035d6d139eb030361fe18109d/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "509c3b1a217e",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "5000/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "LANG=C.UTF-8",
                "PYTHONIOENCODING=UTF-8",
                "GPG_KEY=C01E1CAD5EA2C4F0B8E3571504C367C218ADD4FF",
                "PYTHON_VERSION=2.7.15",
                "PYTHON_PIP_VERSION=19.0.2"
            ],
            "Cmd": [
                "python",
                "app.py"
            ],
            "ArgsEscaped": true,
            "Image": "along0505/flask-hello-1828",
            "Volumes": null,
            "WorkingDir": "/app",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "maintainer": "Along0505<[email protected]>"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "9338e276986a1b56c0ae20717798b71ba8d7ca5b3feb73fa9af9e60cab60409c",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "5000/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/9338e276986a",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "0f2af52df2ed7cdfec8989d138a833d47ce2c2e9a3386a4b1fb2cc2c2ab65898",
            "Gateway": "172.18.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.18.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:12:00:03",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "2f98fd4d1460da600e7a8208a2dea6cae5726b8d1e31cbc41e86c7295a443130",
                    "EndpointID": "0f2af52df2ed7cdfec8989d138a833d47ce2c2e9a3386a4b1fb2cc2c2ab65898",
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:12:00:03",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@iZ2zecjyzb15bzhr9xrg5oZ flask]# docker logs 509c3b1a217e
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

你可能感兴趣的:(第二章 Docker的镜像和容器)