1 docker概念

Docker是通过内核虚拟化技术来提供容器的资源隔离与安全保障等,由于docker通过操作系统层的虚拟化实现隔离,所以docker容器在运行时,不需要类似虚拟机额外的操作系统开销,提高资源利用率。

Docker 扩展了 Linux 容器(Linux Containers),或着说 LXC,通过一个高层次的 API 为进程单独提供了一个轻量级的虚拟环境。Docker 利用了 LXCcgroups Linux 自己的内核。和传统的虚拟机不同的是,一个 Docker 容器并不包含一个单独的操作系统,而是基于已有的基础设施中操作系统提供的功能来运行的。

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的cgroupnamespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的libcontainer,从 1.11 开始,则进一步演进为使用 runC containerd

2 docker版本

较老版本的Docker被称为dockerdocker-engine2017年的31号之后,Docker的版本命名开始发生变化,同时将CE版本和EE版本进行分开。

Docker Engine改为Docker CE(社区版)

Docker Data Center改为Docker EE(企业版) 

3 docker三个基本概念

镜像(Image

操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。

docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

容器(Container

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。

docker容器可以理解为在沙盒中运行的进程。这个沙盒包含了该进程运行所必须的资源,包括文件系统、系统类库、shell 环境等等。但这个沙盒默认是不会运行任何程序的。你需要在沙盒中运行一个进程来启动某一个容器。这个进程是该容器的唯一进程,所以当该进程结束的时候,容器也会完全的停止。

仓库(Repository

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
    一个 Docker Registry中可以包含多个仓库(Repository );每个仓库可以包含多个标签(Tag)每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

仓库名经常以两段式路径形式出现,比如 jwilder/nginx-proxy ,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务

4 docker与传统虚拟机区别

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

5 docker与传统虚拟机比较

特性

容器

虚拟机

启动

秒级

分钟级

硬盘使用

一般为MB

一般为GB

性能

接近原生

弱于原生

系统支持量

单机支持上千个容器

一般几十个

6 安装docker

   基本环境

主机名

系统版本

IP地址

docker

CentOS 7.2

10.0.0.12

 

# yum -y install yum-utils device-mapper-persistent-data lvm2   #安装依赖包

# yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo #安装docker yum

# yum makecache fast      #更新yum软件源缓存

# yum -y install docker-ce   #安装CE社区版的docker

# systemctl start docker

# systemctl enable docker

7 更改默认register

    默认的docker官方register连接不上,所以改为Docker官方提供的中国registry mirror,就是所谓的镜像加速器

# cat /etc/docker/daemon.json    #如果没有该文件,则自己创建

{

  "registry-mirrors": [

    "https://registry.docker-cn.com"

  ]

}

# systemctl daemon-reload

# systemctl restart docker

# docker pull hello-world    #下载个hello-world镜像测试是否成功

# docker images           #查看本地仓库里的镜像

REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE

docker.io/hello-world   latest              f2a91732366c        3 weeks ago         1.848 kB

8 docker文件说明

8.1 默认配置文件

/etc/docker/daemon.json

8.2 默认存储位置

/var/lib/docker

9 操作镜像

docker运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,docker会从镜像仓库下载该镜像。

9.1 获取镜像

docker镜像仓库获取镜像的命令是docker pull,其命令格式为:

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。
Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub
仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名> 。对于 Docker
Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。

[root@docker ~]# docker pull centos    #下载centos镜像,不指定版本号,默认下载最新的latest

Using default tag: latest

latest: Pulling from library/centos

85432449fd0f: Pull complete

Digest: sha256:3b1a65e9a05f0a77b5e8a698d3359459904c2a354dc3b25ae2e2f5c95f0b3667

Status: Downloaded newer image for centos:latest

[root@docker ~]# docker image ls      #查看下载好的镜像

REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE

centos                 latest              3fa822599e10        2 weeks ago         204MB

[root@docker ~]# docker search centos    #搜索所有的centos镜像

[root@docker ~]# docker search centos

NAME                   DESCRIPTION                           STARS        OFFICIAL      AUTOMATED

centos                   The official build of CentOS.                3893         [OK]                ansible/centos7-ansible     Ansible on Centos7                        103         [OK]

jdeathe/centos-ssh         CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8...   90         [OK]

consol/centos-xfce-vnc      Centos container with "headless" VNC sessi...    37         [OK]

imagine10255/centos6-lnmp-php56   centos6-lnmp-php56                 35         [OK]

……省略

[root@docker ~]# docker search -s 90 centos    #搜索被收藏90次及以上centos镜像

[root@docker ~]# docker search centos

NAME                   DESCRIPTION                           STARS        OFFICIAL      AUTOMATED

centos                   The official build of CentOS.                3893         [OK]                ansible/centos7-ansible     Ansible on Centos7                        103         [OK]

jdeathe/centos-ssh         CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8...   90         [OK]

9.2 列出镜像

# docker image ls或者# docker images

REPOSITORY     TAG         IMAGE ID         CREATED             SIZE

ubuntu         16.04       00fd29ccc6f1      2 days ago          111MB

centos          latest       fa822599e10      2 weeks ago         204MB

hello-world      latest       f2a91732366c     3 weeks ago         1.85kB                       

镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签

 

# docker image ls centos    #列出centos镜像

REPOSITORY      TAG           IMAGE ID          CREATED          SIZE

centos           latest         3fa822599e10      2 weeks ago        204MB

# docker image ls ubuntu:16.04   #列出特定镜像,指出仓库名和标签

REPOSITORY     TAG        IMAGE ID       CREATED         SIZE

ubuntu         16.04       00fd29ccc6f1    2 days ago  

docker image ls -f since=centos   #列出在centos之后下载的镜像

REPOSITORY    TAG           IMAGE ID        CREATED          SIZE

ubuntu        16.04          00fd29ccc6f1     2 days ago        111MB

docker system df        #查看镜像、容器、数据卷所占用的空间

TYPE               TOTAL       ACTIVE        SIZE           RECLAIMABLE

Images              2              2        203.5MB         0B (0%)

Containers          2               0        46B                 46B (100%)

Local Volumes       0               0        0B                  0B

Build Cache                                  0B                  0B

# docker image ls -q     #列出所有镜像的id

00fd29ccc6f1

3fa822599e10

f2a91732366c

# docker image ls --format "{{.ID}}: {{.Repository}}"  #列出镜像ID和仓库名

00fd29ccc6f1: ubuntu

3fa822599e10: centos

f2a91732366c: hello-world

9.3 定制镜像

9.3.1 启动一个容器

# docker run --name webserver -d -p 80:80 nginx  #第一个80是操作系统的端口,第二个是容器里的端口

Unable to find image 'nginx:latest' locally

latest: Pulling from library/nginx

e7bb522d92ff: Pull complete

0f4d7753723e: Pull complete

91470a14d63f: Pull complete

Digest: sha256:2ffc60a51c9d658594b63ef5acfac9d92f4e1550f633a3a16d898925c4e7f5a7

Status: Downloaded newer image for nginx:latest

1237c47dade0837e82f6cf28f232c2a6aabe4eb36370a806a4c9b5d8d095210d

nginx镜像启动了一个容器(如果本地仓库里没用nginx镜像会自动下载),命名为webserver,并且映射了80端口,这样就可以用浏览器去访问这个nginx服务器了。访问地址为:10.0.0.12

# docker exec -it webserver bash    #以交互式终端方式进入webserver容器并执行bash命令

修改nginxindex.html文件内容

[root@1237c47dade0:/]# echo '

Hello ,Docker!

' >/usr/share/nginx/html/index.html

[root@1237c47dade0:/]# exit

[root@docker ~]#

9.3.2 commit定制镜像

当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。而Docker提供了一个docker commit命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。

docker commit 的语法格式为:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

[root@docker ~]# docker commit --author "wangning <[email protected]>" --message "修改了默认网页" webserver nginx:v2

--author是指定修改的作者

--message是记录本次修改的内容,这点和git版本控制相似,这里这些信息可以省略留空

webserver是启动的容器名称

nginx:v2是自定义的版本号

[root@docker ~]# docker image ls nginx  #查看新定制镜像,×××的是新定制的镜像

REPOSITORY     TAG       IMAGE ID           CREATED             SIZE

nginx           v2        811c1f4cfdeb        8 minutes ago       108MB

nginx           latest      f895b3fb9e30        4 days ago          108MB

用新定制的镜像启动一个容器webserver2,浏览器里输入http://10.0.0.12:81就可以访问了

[root@docker ~]# docker run --name webserver2 -d -p 81:80 nginx:v2

9.3.2.1  commit小结

使用docker commit命令可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。使用docker commit意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。

9.3.3 Dockerfile定制镜像

镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile

9.3.3.1  创建Dockerfile文件

[root@docker ~]# mkdir /opt/nginx

[root@docker ~]# touch /opt/nginx/Dockerfile

[root@docker ~]# cat /opt/nginx/Dockerfile 

FROM nginx

RUN  echo '

Hello,Docker is a container!

' >/usr/share/nginx/html/index.html

FROM 指定基础镜像

RUN用来执行shell命令,shell命令要尽量写成一行,这样可以避免镜像臃肿

9.3.3.2  构建镜像

[root@docker ~]# cd /opt/nginx/

[root@docker nginx]# docker build -t nginx:v3 .   #一定要在Dockerfile所在目录执行,注意后面有个点

Sending build context to Docker daemon  2.048kB

Step 1/2 : FROM nginx

 ---> f895b3fb9e30

Step 2/2 : RUN echo '

Hello,Docker is a container!

' >/usr/share/nginx/html/index.html

 ---> Running in e9a34a37ab7a

Hello,Docker is a container!

/usr/share/nginx/html/index.html

 ---> ad0e0e8cb74f

Removing intermediate container e9a34a37ab7a

Successfully built ad0e0e8cb74f

Successfully tagged nginx:v3

[root@docker nginx]# docker image ls nginx   #此时已经构建好了镜像

REPOSITORY    TAG           MAGE ID       CREATED          SIZE

nginx          v3            ad0e0e8cb74f   2 minutes ago      108MB

nginx          v2            811c1f4cfdeb    3 hours ago        108MB

nginx          latest          f895b3fb9e30   5 days ago         108MB

# docker run --name webserver3 -d -p 82:80 nginx:v3   #用镜像nginx:v3启动一个容器webserver3

浏览器里输入http://10.0.0.12:82即可访问

9.3.3.3  Dockerfile常用命令

这些命令不区分大小写

FROM 后加基础镜像

MAINTAINER 后加维护者信息

RUN 后加shell命令

ADD Dockerfile所在目录里的指定的文件放入相应的目录

WORKDIR 相当于cd的意思

VOLUME 目录挂载

EXPOSE 后加指定服务启用的端口号

CMD后加要启动的服务

 

下面以centos:2镜像为基础镜像,安装一个nginx服务,并启动它。

Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样去启动后台服务,容器内没有后台服务的概念。

[root@docker nginx]# cat /opt/nginx/Dockerfile

#This docker file

#Version 4

#Author: wangning

 

FROM centos:2

MAINTAINER wangning [email protected]

# daemon off;表示以前台方式启动

RUN yum install -y nginx && echo "daemon off;" >>/etc/nginx/nginx.conf

ADD index.html /usr/share/nginx/html/index.html

EXPOSE 80

CMD ["nginx"]

[root@docker nginx]# cat /opt/nginx/index.html

the docker is a good container!

[root@docker nginx]# tree

.

├── Dockerfile

└── index.html

0 directories, 2 files

[root@docker nginx]# docker build -t nginx:v4 .    #构建镜像nginx:v4

Sending build context to Docker daemon  3.072kB

Step 1/6 : FROM centos:2

 ---> 2377ded06842

Step 2/6 : MAINTAINER wangning [email protected]

 ---> Running in 058ad0745355

 ---> c5b43803658b

Removing intermediate container 058ad0745355

Step 3/6 : RUN yum install -y nginx && echo "daemon off;" >>/etc/nginx/nginx.conf

 ---> Running in 6a28e9f696ca

Loaded plugins: fastestmirror, ovl

……

# docker run --name webserver4 -d -p 83:80 nginx:v4       #用镜像nginx:v4启动一个容器webserver4

9.4 导入导出镜像

[root@docker ~]# docker image ls   #列出镜像

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

nginx               v4                  cc79e9595141        About an hour ago   395MB

centos              2                   2377ded06842        3 hours ago         290MB

nginx               v3                  dc8d7882a686        6 hours ago         108MB

nginx               v2                  811c1f4cfdeb        10 hours ago        108MB

ubuntu              16.04               00fd29ccc6f1        2 days ago          111MB

nginx               latest              f895b3fb9e30        5 days ago          108MB

centos              latest              3fa822599e10        2 weeks ago         204MB

[root@docker ~]# docker save nginx:v4 >/opt/nginx_v4.tar         #导出镜像

[root@docker ~]# # docker load 导入镜像

9.5 删除镜像

镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete 行为就不会发生。所以并非所有的 docker rm 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。

镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变动非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。

除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。容器是以镜像为基础,再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。

 

用镜像名(仓库名加tag标签)的方式删除

[root@docker ~]# docker image rm nginx:v4

用镜像id方式删除

[root@docker ~]# docker image rm cc79e9595141

10 操作容器

简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。

10.1 查看容器

[root@docker ~]# docker container ls    #查看运行中的容器

CONTAINER ID     IMAGE       COMMAND      CREATED      STATUS          PORTS        NAMES

e994d092dff1   nginx:v2   "nginx -g 'daemon ..."  12 hours ago  Up 38 seconds  0.0.0.0:81->80/tcp  webserver2

1237c47dade0   nginx   "nginx -g 'daemon ..."    15 hours ago  Up 5 minutes  0.0.0.0:80->80/tcp   webserver

 

[root@docker ~]# docker container ls -a  [root@docker ~]# docker ps -a  #查看所有容器,包括停止状态的容器

CONTAINER ID    IMAGE      COMMAND        CREATED         STATUS        PORTS         NAMES

ed23f12df3ba  nginx:v3    "nginx -g 'daemon ..."   8 hours ago   Exited (0) 5 minutes ago           webserver3

e994d092dff1  nginx:v2    "nginx -g 'daemon ..."   12 hours ago  Up 6 minutes   0.0.0.0:81->80/tcp   webserver2

1237c47dade0  nginx    "nginx -g 'daemon ..."   15 hours ago   Up 11 minutes   0.0.0.0:80->80/tcp   webserver

[root@docker ~]# docker inspect nginx      #查看nginx容器的详细信息

10.2 进入容器

进入容器命令 docker exec

进入webserver容器里,可以执行shell命令进行操作,-i交互式 -t伪终端

[root@docker nginx]# docker exec -it webserver bash

root@1237c47dade0:/# cat /etc/issue

Debian GNU/Linux 9 \n \l             #从公有仓库下载的nginx镜像,用的操作系统是Debian

root@1237c47dade0:/# ls

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

root@1237c47dade0:/# exit     退出容器

exit

[root@docker nginx]#

10.3 启动和停止容器

启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。

10.3.1 新建并启动容器

# docker run --name webserver4 -d -p 83:80 nginx:v4   #第一个83是操作系统的端口,第二个80是容器里的端口

nginx:v4镜像启动了一个容器,命名为webserver4,并且映射了83端口,-d表示后台运行

这样就可以用浏览器去访问这个nginx服务器了。访问地址为:http://10.0.0.12:83

小结:

当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从公有仓库下载
1.利用镜像创建并启动一个容器
2.分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
3.从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
4.从地址池配置一个 ip 地址给容器
5.执行用户指定的应用程序
6.执行完毕后容器被终止

10.3.2 启动已终止的容器

[root@docker ~]# docker container start webserver3   #启动webserver3容器

10.3.3 停止容器

[root@docker ~]# docker container stop webserver3   #停止webserver3容器

[root@docker ~]# docker kill $(docker ps -q)          #停止所有正在运行的容器

10.4 删除容器

删除终止的容器

[root@docker ~]# docker container rm  webserver4

删除运行中的容器

[root@docker ~]# docker container rm -f webserver3

删除所有停止状态的容器

root@docker ~]# docker container prune

WARNING! This will remove all stopped containers.

Are you sure you want to continue? [y/N] y

Deleted Containers:

e994d092dff1501bc62ed26f43a7ecbb478014f21cc0949236b8a73fc6f62577

1237c47dade0837e82f6cf28f232c2a6aabe4eb36370a806a4c9b5d8d095210d

11 访问仓库

仓库(Repository)是集中存放镜像的地方。

一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 dl.dockerpool.com/ubuntu 来说,dl.dockerpool.com 是注册服务器地址,ubuntu 是仓库名。

11.1 公共仓库

目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 15,000 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。

注册

你可以在 https://cloud.docker.com 免费注册一个 Docker 账号。

登录

可以通过执行 docker login 命令交互式的输入用户名及密码来完成在命令行界面登录Docker Hub

你可以通过 docker logout 退出登录。

拉取镜像

你可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。

 

[root@docker ~]# docker login

Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.

Username: 1198143315

Password: *******

Login Succeeded

[root@docker ~]# docker search centos

NAME    DESCRIPTION                    STARS               OFFICIAL            AUTOMATED

centos   The official build of CentOS.          3886                [OK]               

ansible/centos7-ansible   Ansible on Centos7    103                                       [OK]

jdeathe/centos-ssh      CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8...  90                     [OK]

consol/centos-xfce-vnc Centos     container with "headless" VNC sessi...  37                    [OK]

tutum/centos                  Simple CentOS docker image with SSH access      34          

……省略

根据是否是官方提供,可将镜像资源分为两类。

一种是类似 centos 这样的镜像,被称为基础镜像或根镜像。这些基础镜像由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。

还有一种类型,比如 tutum/centos 镜像,它是由 Docker 的用户创建并维护的,往往带有用户名称前缀。可以通过前缀 username/ 来指定使用某个用户提供的镜像,比如 tutum用户。

小结

官方的公共仓库网速很慢,经常登录不上,可改用docker在中国的镜像站,详见7更改默认register

11.2 私有仓库

有时候使用Docker Hub这样的公共仓库不方便,用户可以创建一个本地仓库供私人使用,个人感觉类似于centos的本地yum源。

11.2.1 安装运行docker-registry

可以选择用yum方式安装docker-registry包,也可以通过获取官方registry镜像来运行,这里选择第二种方式。

[root@docker ~]# docker pull registry    #下载registry镜像

[root@docker ~]# docker run --name registry -d -p 5000:5000 --restart=always -v /opt/registry:/var/lib/registry registry

registry镜像创建一个容器,命名为registry,默认情况下,仓库会被创建在容器的/var/lib/registry目录下,此处的选项-v表示将容器里的/var/lib/registry挂载到本地的/opt/registry目录下,类似于Linuxmount命令。

[root@docker ~]# docker container ls      #查看registry容器是否正常运行

CONTAINER ID  IMAGE     COMMAND      CREATED         STATUS          PORTS               NAMES

8a7d1d95dc54  registry   "/entrypoint.sh /e..."   3 minutes ago  Up 3 minutes   0.0.0.0:5000->5000/tcp   registry

11.2.2 上传镜像

[root@docker ~]# docker image ls       #先查看本地有哪些镜像

[root@docker system]# docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

nginx               latest              f895b3fb9e30        6 days ago          108MB

registry            latest              177391bcf802        2 weeks ago         33.3MB

使用docker tag nginx:latest这个镜像标记为10.0.0.12:5000/nginx:latest

格式为 docker tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]

root@docker ~]# docker tag nginx:latest 10.0.0.12:5000/nginx:latest

[root@docker ~]# docker image ls    查看标记好的镜像

[root@docker ~]# docker image ls

REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE

nginx                  latest              f895b3fb9e30        6 days ago          108MB

10.0.0.12:5000/nginx   latest              f895b3fb9e30        6 days ago          108MB

registry               latest              177391bcf802        2 weeks ago         33.3MB

[root@docker ~]# docker push 10.0.0.12:5000/nginx:v4       #开始向私有仓库上传镜像

The push refers to a repository [10.0.0.12:5000/nginx]

Get https://10.0.0.12:5000/v2/: http: server gave HTTP response to HTTPS client

此时上面红色报错是https问题,因为Docker1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动docker server时增加启动参数为默认使用http访问。

修改etc/docker/daemon.json这个文件,×××部分为添加的内容

[root@docker ~]# cat /etc/docker/daemon.json

{

  "registry-mirrors": [

    "https://registry.docker-cn.com"

  ],

  "insecure-registry": [

    "10.0.0.12:5000"

  ]

}

再次上传镜像

[root@docker ~]# docker push 10.0.0.12:5000/nginx:latest

The push refers to a repository [10.0.0.12:5000/nginx]

995f02eaa054: Pushed

938981ec0340: Pushed

2ec5c0a4cb57: Pushed

latest: digest: sha256:3eff18554e47c4177a09cea5d460526cbb4d3aff9fd1917d7b1372da1539694a size: 948

curl查看私有仓库中的镜像

[root@docker ~]# curl 10.0.0.12:5000/v2/_catalog

{"repositories":["nginx"]}

11.2.3 下载镜像

先从本地删除这个镜像

[root@docker ~]# docker image rm 10.0.0.12:5000/nginx:latest 

[root@docker ~]# docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

nginx               latest              f895b3fb9e30        6 days ago          108MB

registry            latest              177391bcf802        2 weeks ago         33.3MB

然后再从私有仓库中下载这个镜像

[root@docker ~]# docker pull 10.0.0.12:5000/nginx:latest

latest: Pulling from nginx

Digest: sha256:3eff18554e47c4177a09cea5d460526cbb4d3aff9fd1917d7b1372da1539694a

Status: Downloaded newer image for 10.0.0.12:5000/nginx:latest

[root@docker ~]# docker image ls

REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE

10.0.0.12:5000/nginx   latest              f895b3fb9e30        6 days ago          108MB

nginx                  latest              f895b3fb9e30        6 days ago          108MB

registry               latest              177391bcf802        2 weeks ago         33.3MB

12 数据管理

在容器中管理数据主要有两种方式:

数据卷(Volumes

挂载主机目录(Bind mounts

12.1 数据卷特性:

1.       可以在容器之间共享和重用

2.       对数据卷的修改会立马生效

3.       对数据的更新,不会影响镜像

4.       数据卷默认会一直存在,即使容器被删除

12.2 操作数据卷

[root@docker ~]# docker volume create my-vol    #创建数据卷

[root@docker ~]# docker volume ls      #查看所有数据卷

DRIVER              VOLUME NAME

local               my-vol

[root@docker ~]# docker volume inspect my-vol    #查看指定数据卷的信息

[

    {

        "CreatedAt": "2017-12-18T20:21:13-05:00",

        "Driver": "local",

        "Labels": {},

        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",

        "Name": "my-vol",

        "Options": {},

        "Scope": "local"

    }

]

[root@docker ~]# docker run --name nginx -d -p 80:80 -v my-vol:/nginx_data nginx

nginx镜像创建一个容器nginx,将数据卷my-vol挂载到容器nginx里的nginx_data(如果容器里没有此目录,则会自动创建)目录下,当nginx_data有数据写入时,本地的卷my-vol里也会相应的写入数据,当容器nginx被删除时,卷my-vol里的数据不会被删除。

[root@docker ~]# docker inspect nginx       #查看nginx容器有关卷的详细信息

……省略

"Mounts": [

            {

                "Type": "volume",

                "Name": "my-vol",

                "Source": "/var/lib/docker/volumes/my-vol/_data",

                "Destination": "/nginx_data",

                "Driver": "local",

                "Mode": "z",

                "RW": true,

                "Propagation": ""

…..省略

[root@docker ~]# docker volume rm my-vol    #删除数据卷my-vol,如果该卷正在被容器使用,则会报错无法删除

[root@docker ~]# docker volume prune    #删除所有没有被使用的数据卷,即无主的数据卷

12.3 小结

数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷 ,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用docker rm -v这个命令。

13 docker网络

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P -p 参数来指定端口映射。

当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。

当使用-p标记时,可以自己指定映射端口

[root@docker ~]# docker run --name nginx -d -P nginx

[root@docker ~]# docker container ls

CONTAINER ID   IMAGE        COMMAND         CREATED      STATUS        PORTS           NAMES

a8d681612934  nginx   "nginx -g 'daemon ..."   9 seconds ago    Up 9 seconds   0.0.0.0:32768->80/tcp  nginx

当使用-P时,系统随机分配了一个端口32768对应容器nginx里的80端口