引言

在之前的学习中,我知道了docker的三大组件分别是----镜像,容器,仓库。了解了这三个组件也就初步理解了docker。所以我学习了这三个组件,并记录下来。

镜像

docker在运行一个容器时需要本地存在相对应的镜像,执行流程大致是这样的:

  1. 准备容器
  2. 查看容器所需要的镜像是否存在于本地
  3. 如果存在,运行容器
  4. 如果不存在,检索远程镜像仓库,找到并下载
  5. 运行容器

获取镜像

通过docker pull来从镜像仓库获取镜像:

ubuntu@VM---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:/ubuntu:latest
Pulling dl.dockerpool.com:/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..tar ubuntu:14.04

可以使用docker load从导出的本地文件中再导入本地的镜像库

$ sudo docker load --input ubuntu_14..tar

$ sudo docker load < ubuntu_14..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的流程是:

  1. 检查本地是否有指定的镜像,如果没有从共有仓库下载
  2. 利用指定的基础镜像创建一个容器
  3. 分配一个文件系统,并且在只读的镜像层外面挂载一层读写层
  4. 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器
  5. 从地址池中配置一个IP地址给容器
  6. 执行用户指定的应用程序
  7. 关闭容器

那么怎么启动一个之前已经终止的容器呢?我们可以利用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" seconds ago Up 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.

我们也可以通过指定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---ubuntu:~$ docker search ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating sys… [OK]
dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC [OK]
rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… [OK]
consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… [OK]
ansible/ubuntu14.-ansible Ubuntu 14.04 LTS with ansible [OK]
ubuntu-upstart Upstart is an event-based replacement for th… [OK]
neurodebian NeuroDebian provides neuroscience research s… [OK]
1and1internet/ubuntu--nginx-php-phpmyadmin-mysql- ubuntu--nginx-php-phpmyadmin-mysql- [OK]
ubuntu-debootstrap debootstrap --variant=minbase --components=m… [OK]
nuagebec/ubuntu Simple always updated Ubuntu docker images w… [OK]
tutum/ubuntu Simple Ubuntu docker images with SSH access
i386/ubuntu Ubuntu is a Debian-based Linux operating sys…

以上~~

docker学习篇(二)---- 基础篇的更多相关文章

  1. Python学习笔记之基础篇(-)python介绍与安装

    Python学习笔记之基础篇(-)初识python Python的理念:崇尚优美.清晰.简单,是一个优秀并广泛使用的语言. python的历史: 1989年,为了打发圣诞节假期,作者Guido开始写P ...

  2. Django学习笔记(基础篇)

    Django学习笔记(基础篇):http://www.cnblogs.com/wupeiqi/articles/5237704.html

  3. Spark学习体系整理(基础篇、中级篇、高级篇所涉及内容)

    新手刚开始学习比较迷茫,参考下面,然后找相关资料学习 1 Spark基础篇      1.1 Spark生态和安装部署          在安装过程中,理解其基本操作步骤.          安装部署 ...

  4. Docker学习笔记二(linux下安装Docker)

    Docker学习笔记二(linux下安装Docker) 1.在线安装linux Docker 这种方式首先要保证linux 环境下可以上网,当然,小编是在自己的电脑上安装了虚拟机,在虚拟机上安装了,l ...

  5. Docker学习(二): 镜像的使用与构建

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

  6. docker学习笔记二:常用命令

    docker学习笔记二:常用命令 查看docker常用命令 docker --help 返回结果如下: 其中常用的命令如下: 1.image相关操作 展示所有的image: 删除image: rmi ...

  7. Python学习总结之一 -- 基础篇

    Python学习第一篇 一:写在前面 啊,最近我的新博客一直都没有更新学习内容了,只是最近一直都在忙着寻找实习机会(或许这只是一个借口,真实原因是我太懒惰了,改改改!).终于今天又投递了几个新的实习职 ...

  8. 与你一起学习MS Project——基础篇:Project基础应用

    为了更清晰容易地熟悉掌握Project的基础应用,我们在基础篇中一起来学习掌握在Project中如何做进度计划.资源计划.成本计划以及跟踪项目的执行情况并生成所需的项目报表. 一.进度计划 这里,首先 ...

  9. Linux虚拟网络:Docker网络知识之基础篇

    我们在工作中应用了docker容器化技术,服务的部署.维护和扩展都方便了很多.然而,近期在私有化部署过程中,由于不同服务器环境的复杂多变,常常遇到网络方面的问题,现象为容器服务运行正常,但宿主机.容器 ...

  10. mysql学习笔记之基础篇

    数据库学习之基础篇 ① 开放数据库互连(Open Database Connectivity,ODBC ② 结构化查询语言(Structured Query Language) ③ 进入mysql:M ...

随机推荐

  1. FortiGate端口聚合配置

    1.端口聚合(LACP)应用场景 该功能高端设备上支持,FortiGate60D.FortiGate90D和FortiGate240D等低端型号不支持. 1.在带宽比较紧张的情况下,通过逻辑聚合可以扩 ...

  2. URL重写中的中文参数问题

    在做搜索功能时,需要输入关键字,如果搜索出来的结果很多,又需要分页.这里用URL重写技术(即href="?keyword=关键字&page=分页数"),就涉及到了传递中文关 ...

  3. 关于弹性布局的 flex-grow的用法和flex-shrink的用法

    1.首先 flex-grow设置在子项目上 2.flex-grow默认值为0,如果为值1的时候就会撑满 3.flex-grow还可以给其中的一个子元素单独设置,设置为2,其它的则为1或者2都可以,具体 ...

  4. Django formset

    一 什么是formset Form组件或ModelForm用于做一个表单验证而formset是用于做多个表单的验证组件,用于做批量操作 二 formset的使用方法 1 设置form信息 class ...

  5. redis在游戏服务器中的使用初探(一) 环境搭建

    这里我们尝试在游戏服务器中的数据处理中使用redis 通过该系列文章能够学习 redis的基本操作 源码编译 客户端开源库的编译和使用 以及在游戏服务器中的缓存使用 作为初次摸索 尽量使得环境简单  ...

  6. window 安装mysql

    常见错误:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 密码输入错误:无法远程 ...

  7. 使用Maven搭建SpringMVC

    1.创建Maven Project 注意选择webapp 2.添加Maven依赖 <project xmlns="http://maven.apache.org/POM/4.0.0&q ...

  8. 解决win10系统无法安装.NET Framework 3.5

    方法1:“我的电脑”,单击右键选择“管理” 在打开的“计算机管理”窗口中依路径“服务和应用程序—服务”打开,在列表中找到“Windows Update”并双击打开. 启动类型:自动. 服务状态下面点击 ...

  9. [C#.net]未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序

    C#操作Execl文件常用的2种方式是NPOI和Microsoft.Jet.OleDb,前者需要引用dll,后者需要安装Office客户端 今天发现别人电脑使用Microsoft.Jet.OleDb能 ...

  10. jquery如何在元素后面添加一个元素

    jQuery添加插入元素技巧: jquery添加分为在指定元素的里面添加和外面添加两种: 里面添加使用(append 和prepend) 里面添加又分为在里面的前面添加和后面添加 里面的前面添加使用 ...