本文主要涉及Docker镜像、容器相关知识

Docker架构和底层技术

Docker提供了一个开发、打包、运行应用的平台
Docker Engine将应用和infrastructure分离开

Docker Engine

Docker Engine由后台进程(dockerd)、REST API Server、CLI接口(docker)组成

#查看Client、Server、Engine版本
docker version
#查看docker进程
ps -ef | grep docker

底层技术支持

(1)Namespaces:做隔离pid,net,ipc,mnt,uts
(2)Control groups:做资源限制
(3)Union file systems:Container和image的分层

Docker Image

Image里面是一层层的文件系统,即UnionFS(联合文件系统)。每一层文件系统我们都叫一层layer,Image本身是read-only的。构建镜像的时候,每个构建操作都是对一层修改,增加一层文件系统,当你使用Image的时候,你看到的是一个整体,不知道Image到底含有多少文件系统。

#查看image
docker images
#删除镜像
docker rmi 镜像名称
#使用Dockerfile创建镜像,其中“.”表示指向当前目录下的dockerdile,也可以使用“-f 文件目录”
docker build -t 镜像名称 .

获取Image方式

(1)Dockerfile
(2)Pull from Registry

Docker Container

Container概念

(1)通过Image创建的
(2)在Image layer之上建立一个可读写的Container
(3)Image和Container的关系好比类和实例的关系
(4)Image负责application的存储和分发,Container负责运行application

#运行容器
docker run 镜像名称
#交互式运行容器
docker run -it 镜像名称
#查看正在运行容器
docker ps
#查看已经停止的容器
docker ps -a
#删除容器
docker rm 容器名称
#批量删除停止的容器
docker rm $(docker ps -aq)
#批量删除status是exited的容器
docker rm $(docker ps -f "status=exited" -q)
#运行停止的容器/停止运行的容器
docker start 容器名称 / docker stop 容器名称
#进入容器
docker exec -it 容器ID bash
#从容器中创建新的镜像
docker commit 容器名称 镜像名称

Dockerfile

FROM

尽量使用官方的base image

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

LABEL

定义一个image的Metadata,帮助信息。

LABEL maintainer=“1335402049@qq.com”
LABEL version="1.0"
LABEL description="This is a dscription"

RUN

为了美观、负杂的RUN,使用反斜线换行;避免无用分层,合成多条命令成一行

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

WORKDIR

使用WORKDIR,不要使用RUN cd,尽量使用绝对目录

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

ADD和COPY

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

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

ENV

尽量使用ENV

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

RUN CMD ENTRYPOINT

RUN:执行命令并创建新的Image Layer
CMD:设置容器启动后默认执行的命令和参数
ENTRYPOINT:设置容器启动时运行的命令

CMD与ENTRYPOINT区别?
(1)CMD
容器启动时默认执行的命令;
如果docker run指定了其他命令,CMD命令会被忽略;
如果定义了多个CMD,只有最后一个会执行
(2)ENTRYPOINT
让容器以应用程序或者服务的形式运行;
不会被忽略,一定会执行

资源限制

#内存限制
docker run --memory=200M 镜像名称
#cpu限制(相对)
docker run --cpu-shares=10 镜像名称