引言
在之前的学习中, 我知道了 docker 的三大组件分别是 ---- 镜像, 容器, 仓库. 了解了这三个组件也就初步理解了 docker. 所以我学习了这三个组件, 并记录下来.
镜像
docker 在运行一个容器时需要本地存在相对应的镜像, 执行流程大致是这样的:
准备容器
查看容器所需要的镜像是否存在于本地
如果存在, 运行容器
如果不存在, 检索远程镜像仓库, 找到并下载
运行容器
获取镜像
通过 docker pull 来从镜像仓库获取镜像:
- ubuntu@VM-68-11-ubuntu:~$ docker pull ubuntu:latest
- latest: Pulling from library/ubuntu
- Digest: sha256:3f119dc0737f57f704ebecac8a6d8477b0f6ca1ca0332c7ee1395ed2c6a82be7
- Status: Downloaded newer image for ubuntu:latest
在下载的过程中, 会出现镜像的每一层信息.
如果官方仓库注册服务器下载速度太慢, 我们可以从其他仓库下载, 这个时候因为不是从默认的注册仓库下载, 所以我们需要显式的声明下载仓库地址:
- $ sudo docker pull dl.dockerpool.com:5000/ubuntu:latest
- Pulling dl.dockerpool.com:5000/ubuntu
- ab8e2728644c: Pulling dependent layers
- 511136ea3c5a: Download complete
- 5f0ffaa9455e: Download complete
- a300658979be: Download complete
- 904483ae0c30: Download complete
显示镜像
docker images
通过上面命令可以查看本地已经下载的镜像文件
从上面的信息中, 我们可以获得:
来自那个仓库(REPOSITORY)
镜像标记(TAG)
ID 号唯一标识(IMAGE ID)
创建时间(CREATED)
镜像大小(SIZE)
TAG: 用来标记来自同一仓库的不同镜像, 比如 Ubuntu 仓库中中有多个镜像, 通过 TAG 来区分版本. 如果不记得具体的版本了, 默认用 latest 标记信息
修改镜像
使用下载的镜像启动容器
- $ sudo docker run -t -i training/sinatra /bin/bash
- root@0b2616b0e5a8:/#
在容器中增加 json 和 gem 应用
root@0b2616b0e5a8:/# gem install json
结束后通过 exit 退出容器, 现在容器中有我们刚刚添加的应用, 容器已经被我们改变了. 通过 docker commit 来提交更新后的副本
- $ sudo docker commit -m "Added json gem" -a "Docker Newbee" 0b2616b0e5a8 ouruser/sinatra:v2
- 4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
-m 来指定提交的说明信息, 跟我们使用的版本控制工具一样;
-a 可以指定更新的用户信息; 之后是用来创建镜像的容器的 ID;
最后指定目标镜像的仓库名和 tag 信息.
创建成功后会返回这个镜像的 ID 信息.
我们可以使用 docker images 查看新创建的镜像.
Dockerfile
当在一个团队中分享新创建的镜像时, 我们可以使用 Dockerfile 来解决这个团队分享问题.
Dockerfile 包含一些怎样创建镜像的指令.
新建一个目录和一个 Dockerfile:
- $ mkdir sinatra
- $ cd sinatra
- $ touch Dockerfile
Dockerfile 的每一条指令都创建镜像的一层:
- # This is a comment
- FROM ubuntu:14.04
- MAINTAINER Docker Newbee <newbee@docker.com>
- RUN apt-get -qq update
- RUN apt-get -qqy install ruby ruby-dev
- RUN gem install sinatra
基本语法:
通过 #来进行注释
FROM 指令告诉 Docker 使用哪个镜像来作为基础镜像
接着是维护者的信息
RUN 开头的指令会在创建中运行. 比如安装一个软件包
另外, ADD 命令是复制本地文件到镜像; EXPOSE 命令来向外部开放端口; CMD 命令来描述容器启动后运行的程序等.
编写完 Dockerfile 后通过 docker build 来创建生成镜像.
sudo docker build -t="ouruser/sinatra:v2" .
-t 标记来添加 tag, 指定新的镜像的用户信息. 注意:"." 不能删除, 它指的是 Dockerfile 所在路径(当前的目录), 如果 Dockerfile 在其他位置, 可以将 "." 替换成一个具体的 Dockerfile 路径.
build 进程在执行操作. 它要做的第一件事情就是上传这个 Dockerfile 内容, 因为所有的操作都要依据 Dockerfile 来进行. Docker 指令被按条执行, 每一步创建一个新的容器, 在容器中执行指令并提交修改, 当所有指令执行完成后, 返回最终 id.
我们可以通过 docker tag 来修改镜像的标签. 通过 docker push 将创建的镜像上传到仓库中进行分享.
导出和导入镜像
将镜像导出到本地, 可以使用 docker save 命令
$sudo docker save -o ubuntu_14.04.tar ubuntu:14.04
可以使用 docker load 从导出的本地文件中再导入本地的镜像库
$ sudo docker load --input ubuntu_14.04.tar
或
$ sudo docker load <ubuntu_14.04.tar
删除本地的镜像
使用 docker rmi 命令删除本地的镜像
注意:
docker rm 命令是用来删除容器的, 两个删除命令的操作对象是不同的.
在删除一个镜像时首先要删除依赖于这个镜像的所有容器, 否则可能会出现错误.
容器
容器是独立运行的一套或者一组应用以及他们的运行态环境. 虚拟机可以理解为模拟运行的一整套操作系统 (提供运行态环境和其他系统环境) 和运行在上面的应用. 所以容器相较于虚拟机来说, 显得非常轻量级, 启动速度也是以秒级计算的.
启动
容器启动有两种形式:
一种是基于镜像创建一个新的容器并启动
另一种是将在终止状态的容器重新启动
启动容器命令用 docker run 来实现, 如下面的例子:
- $ sudo docker run ubuntu:16.04 /bin/echo 'Hello world'
- Hello world
启动一个 bash 终端, 允许用户交互:
- $ sudo docker run -t -i ubuntu:16.04 /bin/bash
- root@af8bae53bdd3:/#
-t 选项让 Docker 分配一个伪终端 (pseudo-tty) 并绑定到容器的标准输入上;-i 则让容器的标准输入保持打开.
当在执行 docker run 来创建一个容器时, docker 的流程是:
检查本地是否有指定的镜像, 如果没有从共有仓库下载
利用指定的基础镜像创建一个容器
分配一个文件系统, 并且在只读的镜像层外面挂载一层读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器
从地址池中配置一个 IP 地址给容器
执行用户指定的应用程序
关闭容器
那么怎么启动一个之前已经终止的容器呢? 我们可以利用 docker start 命令来将一个终止的容器重新启动起来.
容器的核心为所执行的应用程序, 所需要的资源都是应用程序运行所必需的. 在与容器交互的伪终端中我们可以通过 ps 或者 top 命令进行查看容器中进程的信息.
守护态运行
我们想要让一个容器在后台以守护态形式运行. 可以在执行 docker run 命令时增加 - d 参数.
- $ sudo docker run -d ubuntu:16.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
- 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
以守护态运行容器后会返回容器的 id, 我们可以通过 docker ps 查看容器信息.
- $ sudo docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 1e5535038e28 ubuntu:14.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage
注意: 想要查看所有没有删除的容器需要加上 - a 参数.
想要查看守护态容器在后台输出的信息, 可是使用 docker logs 进行查看:
- $ docker logs insane_babbage
- hello world
- hello world
. . .
进入容器内
当加上 - d 运行容器时, 容器以守护态形式进行在后台执行, 但有时候我们想要进入到容器中进行工作, 应该怎么实现呢??
1. 我们可以使用 docker 自带的指令 docker attach
- $ sudo docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 243c32535da7 ubuntu:latest "/bin/bash" 18 seconds ago Up 17 seconds nostalgic_hypatia
- $sudo docker attach nostalgic_hypatia
- root@243c32535da7:/#
但是多个窗口同时进入到一个容器中呢? 这个时候所有窗口都会同步显示, 并且一个窗口如果出现堵塞, 其他窗口也会无法运行, 所以 attach 非常不方便.
2. nsenter 命令
我们可以通过 nsenter 命令进入容器, 而是用 nsenter 命令需要安装 nsenter 工具, 安装步骤如下:
- $ cd /tmp;
- $ curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-;
- $ cd util-linux-2.24;
- $ ./configure --without-ncurses
- $ make nsenter && sudo cp nsenter /usr/local/bin
注意: nsenter 工具在 util-linux 包 2.23 版本后包含, 如果你的电脑中有 util-linux 包, 首先要看版本是否过低. Ubuntu14.04 使用的是 util-linux 包的 2.20 版本.
为了连接到容器, 我们需要知道容器的第一个进程的 PID, 通过下面方法获得:
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
通过这个 PID 进行连接容器:
nsenter --target $PID --mount --uts --ipc --net --pid
终止容器
当我们需要停止一个正在执行的容器时, 使用 docker stop 指令.
如果该容器中指定的应用终止时, 容器也会自动终止. 比如上面我们让容器运行一个伪终端与用户进行交互, 当通过 exit 退出伪终端时, 这个容器也自动终止了.
如果想让一个运行态的容器终止后重新启动, 我们可以使用 docker restart 指令.
导出和导入
导出
docker 中想要对容器进行备份导出也是非常简单的, 可以通过 docker export
$ sudo docker export 7691a814370e> ubuntu.tar
在导出时我们需要知道该容器的 ID.
导入
可以使用 docker import 指令将容器快照导入为镜像.
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
我们也可以通过指定 URL 获得目录路径来进行导入:
$sudo docker import http://example.com/exampleimage.tgz example/imagerepo
load 和 import 的区别
docker load 是用来导入镜像存储文件到本地镜像库; docker import 是导入一个容器快照到本地镜像库. 区别在于容器快照文件将会丢弃所有历史记录和元数据信息(即容器当时的快照状态), 而镜像文件将保存完整记录, 体积更大.
删除容器
当我们想要删除一个容器时, 可以使用 docker rm 指令来删除一个终止状态的容器. 如果我们想要删除一个正在运行的状态, 可以加上 - f 参数.
仓库
仓库就是存放镜像的地方.
目前 Docker 官方维护了一个公共仓库 Docker Hub (https://hub.docker.com/) , 其中已经包括了超过 15000 的镜像. 大部分需求, 都可以通过在 Docker Hub 中直接下载镜像来实现.
登录
通过 docker login 指令来输入用户名, 密码和邮箱后完成注册和登录. 用户的认证信息保存在本地的. dockercfg.
检索
我们想要查找官方仓库中有哪些我们需要的镜像, 可以通过 docker search 指令实现, 并通过 docker pull 下载到本地镜像仓库中.
- ubuntu@VM-68-11-ubuntu:~$ docker search ubuntu
- NAME DESCRIPTION STARS OFFICIAL AUTOMATED
- ubuntu Ubuntu is a Debian-based Linux operating sys... 8174 [OK]
- dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC 208 [OK]
- rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi... 167 [OK]
- consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session... 125 [OK]
- ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 94 [OK]
- ubuntu-upstart Upstart is an event-based replacement for th... 87 [OK]
- neurodebian NeuroDebian provides neuroscience research s... 52 [OK]
- 1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 43 [OK]
- ubuntu-debootstrap debootstrap --variant=minbase --components=m... 39 [OK]
- nuagebec/ubuntu Simple always updated Ubuntu docker images w... 23 [OK]
- tutum/ubuntu Simple Ubuntu docker images with SSH access 18
- i386/ubuntu Ubuntu is a Debian-based Linux operating sys... 13
以上~~
来源: https://www.cnblogs.com/lishanlei/p/9489202.html