什么是镜像
Docker镜像是由文件系统叠加而成。最底端是一个引导文件系统,即bootfs。当一个容器启动后,它将会被移动到内存中,而引导文件系统则会被卸载,以留出更多的内存供initrd磁盘镜像使用。
Docker镜像的第二层是root文件系统rootfs,它可以是一种或多种操作系统(如Debian或者Ubuntu文件系统)。
Docker里,root文件系统永远只能是只读状态,并且Docker利用联合加载技术又会在root文件系统层上加载更多的只读文件系统。联合加载的意思是一次加载多个文件系统,但在外面看起来只能看到一个。联合加载会将各层文件系统叠加到一起,这样最终的文件系统会包含所有底层的文件和目录。
一个镜像可以放到另一个镜像的顶部。位于下方的镜像成为父镜像,最底部的为基础镜像。最后,当从一个镜像启动容器时,Docker会在该镜像的最顶层加载一个读写文件系统。Docker中运行的程序就是在这个读写层中执行的。
Docker相关指令
- 执行docker容器(拉取镜像、运行)
sudo docker run -i -t --name next_container ubuntu /bin/bash
-i 保证容器中STDIN是开启的,即可交互命令行的形式
-t 为要创建的容器分配一个伪tty终端
–name 设置容器的名称
- 重启已经停止的容器
1.通过名称重启
sudo docker start next_container
2.通过ID重启
sudo docker start aa3f365f0f4e
也可以使用docker restart命令来重新启动一个容器。
- 查看已经存在的容器
1.查看正在运行的容器
sudo docker ps
2.查看所有容器信息
sudo docker ps -a
- 附着到正在运行的容器上
Docker重新启动时,会沿用docker run命令时指定的参数来运行。此外,也可以用docker attach命令重新附着到该容器的会话上。
1.通过名称附着
sudo docker start next_container
2.通过ID附着
sudo docker start aa3f365f0f4e
- 创建守护式容器
sudo docker run --name daemon_dave -d ubuntu /bin/sh -c “while true; do echo hello world; sleep 1; done”
docker run命令使用-d参数后,容器会在后台运行。
- 获取日志
1.获取日志
sudo docker logs daemon_dave
2.跟踪日志
sudo docker logs -f daemon_dave
3.跟踪守护式容器的最新日志
sudo docker logs -ft daemon_dave
在Docker容器启动时,我们可以通过–log-driver选项来配置日志驱动。默认的json-file。
- 查看容器内的进程
docker top
- Docker统计信息
docker stats daemon_dave daemin_kate daemon_clare
- 在容器内部运行进程
1. 在容器中运行后台任务
sudo docker exec -d daemon_dave touch /etc/new_config_file
2. 在容器内运行交互命令
sudo docker exec -t -i daemon_dave /bin/bash
- 自动重启容器
docker run --restart=always --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
–restart标志被设置为always,无论容器退出的代码是什么,都会重新启动。还可以设置为on-failure,在容器退出代码非零时重启,其接受一个可选的重启次数参数。
- 查看容器
sudo docker inspect --format='{{ .State.Running }}' daemon_dave
–format标志来选定查看结果
- 删除容器
docker rm 80430f122399
//删除所有容器
sudo docker rm 'sudo docker ps -a -q'
- 列出Docker镜像
1. 查看所有镜像
sudo docker images
2. 查看fedora镜像
sudo docker images fedora
- 拉取镜像
sodu docker pull ubuntu:12.04
- 查找镜像
查找所有Docker Hub上公共的可用镜像
sudo docker search puppet
- 构建镜像
基于Dockerfile构建新镜像
创建一个示例仓库
mkdir static_web
cd static_web
touch Dockerfile
创建一个名为static_web的目录保存Dockerfile,这个目录就是构建环境,Docker称此为环境上下文或者构建上下文。Docker会在构建镜像时将构建上下文和该上下文中的文件和目录上传到Docker守护进程。这样Docker守护进程既要能直接访问用户想在镜像中存储的任何代码、文件或者其他数据。
# Version: 0.0.1
From ubuntu:14.04
MAINTAINER James Turnbull "james@example.com"
RUN apt-get update && apt-get install -y nginx
RUN echo 'Hi. I am in your container' \
>/usr/share/nginx/html/index.html
EXPOSE 80
Dockerfile由一系列指令和参数组成,每条指令,如FROM,都必须为大写字母,并且要跟随参数。大致流程执行如下
- Docker从基础镜像运行一个容器。
- 执行一条指令,对容器做出修改。
- 执行类似docker commit的操作,提交一个新的镜像层。
- Docker再基于新提交的镜像运行一个新容器。
- 执行下一条指令,知道所有指令都执行完毕。
默认情况下,RUN指令会在shell里使用命令包装器/bin/sh -c 来执行。如果是在一个不支持shell的平台上运行,可以使用exec格式的RUN指令。
RUN [ "apt-get", " install", "-y", "nginx" ]
执行docker build
cd static_web
docker build -t="jamtur01/static_web:v1"
-t设置新镜像的仓库,名称及标签。
从Git仓库构建Docker镜像
docker build docker build -t="jamtur01/static_web:v1" git@github.com:jamtur01/docker-static_web
- 从新镜像启动容器
sudo docker run -d -p 80 --name static_web jamtur01/static_web nginx -g "daemon off"
-p 用来控制Docker在运行时应该公开那些网络端口给外部(宿主机)。
查看Docker端口映射情况
docker ps -l
//查看某个容器ID/容器名称映射端口号
docker port 419238bc03 80
绑定端口
//绑定不同的端口
sudo docker run -d -p 8080:80 --name static_web jamtur01/static_web nginx -g "daemon off"
//绑定到特定的网络接口
sudo docker run -d -p 127.0.0.1:80:80 --name static_web jamtur01/static_web nginx -g "daemon off"
- Dockerfile指令
CMD
会被docker run命令的覆盖掉,而且只有最后一行CMD命令生效
CMD [ "/bin/bash"]
覆盖本地命令
docker run -i -t jamtur01/test /bin/ps
ENTRYPOINT
ENTRYPOINT不容易在启动容器时被覆盖,可以通过–entrypoint标志覆盖ENTRYPOINT指令。
1.指定ENTRYPOINT指令
ENTRYPOINT ["/usr/sbin/nginx"]
2.指定ENTRYPOINT指令参数
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
WORKDIR
WORKDIR指令用来在从镜像创建一个新容器时,在容器内部设置一个工作目录。ENTRYPOINT和/或CMD指定程序会在这个目录下执行。
WORKDIR /opt/webapp/db
RUN bundle install
WORKDIR /opt/webapp
ENTRYPOINT [ "rackup" ]
- ENV
ENV指令用来在镜像构建过程中设置环境变量
ENV RVM_PATH /home/rvm
这个新环境变量可以在后续的任何RUN指令中使用,如同在前面指定了环境变量前缀
RUN gem install unicorn
//等同于
RVM_PARH=/home/rvm gem install unicorn
ENV TARGET_DIR /opt/app
WORKDIR $TARGET_DIR
- ADD
ADD指令用来构建环境下的文件和目录复制到镜像中。
ADD software.lic /opt/application/software.lic
ADD第一个参数为源文件地址,也可以是以url形式,第二个参数为目的地址。在处理本地归档文件(gzip,bzip2,xz)指定为源文件,Docker会自动将归档文件解压。
- COPY
COPY指令跟ADD指令一致,但不会处理解压文件,只执行copy操作。
COPY conf.d/ /etc/apache2/
- LABEL
LABEL指令用于为Docker镜像添加元数据。元数据以键值对的形式展现,LABEL指令以label="value"的形式出现。
LABEL version="1.0"
LABEL location="New York" type="Data Center" role="Web Server"
- ARG
ARG指令用来定义可以在docker build命令运行时传递给构建运行时的变量,我们只需要在构建时使用–build-arg标志即可。
ARG build
ARG webapp_user=user
在docker build中使用这些参数
docker build --build-arg build=1234 -t jamtur01/webapp .
这里构建jamtur01/webapp镜像时,build变量将会设置成1234,而webapp_user变量则会集成设置的默认值user。
- 将镜像推到Docker Hub
socker push jamtur01/static_web
- 删除镜像
docker rmi
docker rmi jamtur01/static_web
- 构建自己的Docker Registry
从Docker 1.3.1开始,需要在启动Docker守护进程的命令中添加-insecure-registry localhost:5000标志,并重启守护进程,才能使用本地Registry。
1.从容器运行Registry
docker run -p 5000:5000 registry:2
2.查看需要上传的本地docker image ID
docker images jamtur01/static_web
3.使用新的Registry给该镜像打上标签,为了指定新Registry目的地址,需要在镜像名前面加上主机名和端口前缀。
docker tag 22d47c8cb6e5 docker.example.com:5000/jamtur
4.docker push到新的Registry
docker push docker.example.com:5000/jamtur01/static_web
5.从本地Registry构建新的容器
docker run -t -i docker.example.com:5000/jamtur01/static_web /bin/bash