docker 入门

logo

简介

docker是基于LXC的容器技术,它利用Linux内核中namespace隔离进程环境,cgroup限制进程使用物理设备资源,同时创新性的将只读镜像分层,当需要在容器中运行镜像时,只需要在镜像的最外面添加一层可写层。你可以简单的将docker容器理解为进程以及运行进程所需要的轻量级环境。

logo
如上图所示,左边是VM,右边是docker的工作层次,可以看出容器是在操作系统层面上实现的虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现的管理器。docker的优势在于比VM更轻,无需整个系统的资源环境,直接在容器中运行应用,而且支持Build once, run anywhere。缺点就是所有的容器都是运行在Linux内核上的进程,安全性值得考量,尤其是docker用在大量租户的云计算环境中。

镜像

docker的镜像是一个只读的模版。对于镜像,你既可以从docker hub中pull下来,也可以自己利用本地文件系统创建上传到docker hub上,当然首先你需要到docker hub上注册一个账号。

显示本地镜像

1
docker images

pull镜像

1
docker pull ubuntu:14.04

push镜像

首先需要将镜像打个标签,然后上传(af8表示镜像的ID,mainboy代表docker上注册的用户名)

1
2
docker tag af8 mainboy/ubuntu:14.04
docker push mainboy/ubuntu

利用Dockerfile来创建镜像

利用Dockerfile创建镜像方便管理,便于上传给团队其他人分享。
1) 首先创建Dockerfile如下操作:

1
2
3
mkdir test
cd test
vim Dockerfile

2) 然后在Dockerfile中加入如下指令,注意每条指令都会新建镜像的一层,层数不要超过127层:

1
2
3
4
5
6
#This is a comment
FROM ubuntu:14.04
MAINTAINER mainboy <wowyk@qq.com>
RUN apt-get -qq update
RUN apt-get -qqy install ruby ruby-dev
RUN gem install sinatra

Dockerfile的基本语法:

使用#注释
FROM指令告诉docker使用那个镜像作为基础
MAINTAINER是维护者的信息
RUN开头的指令会在创建中运行,比如上述的安装一些软件包

3) 创建镜像:

1
docker build -t mainboy/test test/

-t 表示给镜像添加标签名
test/ 表示Dockerfile所在目录
创建成功后会在docker images中看到名为mainboy/test的镜像

容器

容器是从镜像创建运行的实例。启动容器有两种方式,一种是基于镜像新建一个容器启动,另一种是将在终止状态的容器重新启动。
运行hello world:

1
docker run ubuntu:14.04 /bin/echo "hello world"

启动一个bash终端:

1
docker run -it ubuntu:14.04 /bin/bash

-t 表示给docker分配一个伪终端
-i 表示让容器的接受输入

查看运行中的容器:

1
docker ps

终止一个运行中的容器:

1
docker stop imageID(表示镜像的ID)

清理容器,镜像的快捷方式:
1) 在~/.bash_aliases中加入下面快捷键

1
2
3
4
5
6
7
8
9
10
11
# kill all running docker
alias dockerkill='docker kill $(docker ps -a -q)'

# remove all stop docker
alias dockercleanc='docker rm $(docker ps -a -q)'

# remove no tag images
alias dockercleani='docker rmi $(docker images -q -f dangling=true)'

# remove all stop docker and no tag images
alias dockerclean='dockercleanc||true&&dockercleani'

2) 应用~/.bash_aliases

1
source ~/.bash_aliases

3) 如上所示
dockercleanc直接清理掉所有停止的容器

容器的导入导出,镜像的存出载入:
1) 镜像的存出载入:
存出:

1
docker save -o ubuntu_14.04.tar ubuntu:14.04

载入:

1
docker load --input ubuntu_14.04.tar

或者

1
docker load < ubuntu_14.04.tar

2) 容器的导出导入:
导出:

1
docker export ContainerID > ubuntu.tar

导入:

1
cat ubuntu.tar | sudo docker import - mainboy/ubuntu:14:04

或者通过指定URL或者某个目录来导入

1
docker import http://example.com/exampleimage.gz example/imagerepo

3) 两者的区别:
容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),所以从容器快照文件导入时可以重新指定标签等元数据信息,而镜像存储文件将保存完整记录,体积也要大一些。

仓库

仓库是存放镜像文件的场所。仓库又分为公开仓库和私有仓库,一般情况公开仓库指的是docker hub,类似于github。私有仓库指的是本地网络下搭建的私有仓库。
如何向docker hub上传镜像之前已经说过,如果你想让其他人和你一起修改你的镜像,可以在docker hub的Collaborators中添加那个人,这和github是类似的,下面简单介绍一下如何在本地建立自己的私有仓库来管理镜像。
1) 运行docker-registry镜像,这是官方提供的用于构建私有镜像的仓库

1
docker run -d -p 5000:5000 -v /home/de66/registry:/tmp/registry registry

默认情况下,仓库会被创建在容器的/tmp/registry下,如果是按照上面的方式运行registry,如果你在本地上传的镜像会存储在/home/de66/registry/repositories/library/
2) 上传镜像方式和上传到docker hub上的方式相同

1
docker tag imageID 仓库IP:5000/test

3) push镜像

1
docker push 仓库IP:5000/test

4) pull镜像

1
docker pull 仓库IP:5000/test

上传失败解决方案:
ubuntu系统

1
2
3
4
# 修改*/etc/default/docker*添加DOCKER_OPTS
DOCKER_OPTS="--insecure-registry 仓库IP:5000"
# 重启Docker
service docker restart

centOS系统

1
2
3
4
5
6
7
8
9
# 修改*/etc/sysconfig/docker*添加DOCKER_OPTS
DOCKER_OPTS=="--selinux-enabled=true --insecure-registry 仓库IP:5000"
# 在*/lib/systemd/system/docker.service* [service]下添加
EnvironmentFile=/etc/sysconfig/docker
# 在ExecStart后面加入$DOCKER_OPTS如下
ExecStart=/usr/bin/docker daemon $DOCKER_OPTS -H fd://
# 重启Docker服务
systemctl daemon-reload
service docker restart