防伪码:梅须逊雪三分白,雪却输梅一段香

                    docker技术剖析--dockerfile and registry(构建容器和私有仓库)

一、根据Dockerfile构建出一个容器

1、Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。2、Docker程序将读取Dockerfile,根据指令生成定制的p_w_picpath。相比p_w_picpath这种黑盒子,Dockerfile这种显而易见的脚本更容易被使用者接受,它明确的表明p_w_picpath是怎么产生的。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成p_w_picpath即可,省去了敲命令的麻烦。

3、Dockerfile由一行行命令语句组成,并且支持以  #  开头的注释行。

4、Dockerfile的指令是忽略大小写的,建议使用大写,每一行只支持一条指令,每条指令可以携带多个参数。
5、Dockerfile的指令根据作用可以分为两种,构建指令和设置指令。构建指令用于构建p_w_picpath,其指定的操作不会在运行p_w_picpath的容器上执行;设置指令用于设置p_w_picpath的属性,其指定的操作将在运行p_w_picpath的容器中执行。

一般的,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

# Thisdockerfile uses the ubuntu p_w_picpath

# VERSION 2 - EDITION 1

# Author: docker_user

# Command format: Instruction [arguments / command] ..

# Base p_w_picpath to use, this must be set as the first line

FROM ubuntu

# Maintainer: docker_user (@docker_user)

MAINTAINER docker_user [email protected]

# Commands to update the p_w_picpath

RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list

RUN apt-get update && apt-get install -y nginx

RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# Commands when creating a new container

CMD /usr/sbin/nginx

其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。

后面则是镜像操作指令,例如  RUN  指令, RUN  指令将对镜像执行跟随的命令。每运行一条  RUN  指令,镜像添加新的一层,并提交。

最后是  CMD  指令,来指定运行容器时的操作命令。

dockerfile指令

指令的一般格式为  INSTRUCTION arguments  ,指令包括  FROM  、 MAINTAINER  、 RUN  等。

(1)FROM(指定基础p_w_picpath)

构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的p_w_picpath。FROM指令指定的基础p_w_picpath可以是官方远程仓库中的,也可以位于本地仓库。
该指令有两种格式:

FROM   

指定基础p_w_picpath为该p_w_picpath的最后修改的版本。

或者:

FROM :  

指定基础p_w_picpath为该p_w_picpath的一个tag版本。

(2)MAINTAINER(用来指定镜像创建者信息)

构建指令,用于将p_w_picpath的制作者相关的信息写入到p_w_picpath中。当我们对该p_w_picpath执行docker inspect命令时,输出中有相应的字段记录该信息。
格式:

MAINTAINER   

(3)RUN(安装软件用)

构建指令,RUN可以运行任何被基础p_w_picpath支持的命令。如基础p_w_picpath选择了ubuntu,那么软件管理部分只能使用ubuntu的命令。
该指令有两种格式:

RUN  (the command is run in a shell - `/bin/sh -c`)  

RUN ["executable", "param1", "param2" ... ]  (exec form)  

前者将在 shell 终端中运行命令,即  /bin/sh -c  ;后者则使用  exec  执行。

指定使用其它终端可以通过第二种方式实现,例如  RUN ["/bin/bash", "-c", "echo hello"]  。

每条  RUN  指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用  \  来换行。

(4)CMD(设置container启动时执行的操作)

该指令有三种格式:

设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。

CMD ["executable","param1","param2"]  使用  exec  执行,推荐方式;

CMD command param1 param2  在  /bin/sh中执行,提供给需要交互的应用;

当Dockerfile指定了ENTRYPOINT,那么使用下面的格式:

CMD ["param1","param2"]  提供给  ENTRYPOINT  的默认参数;

ENTRYPOINT指定的是一个可执行的脚本或者程序的路径,该指定的脚本或者程序将会以param1和param2作为参数执行。所以如果CMD指令使用上面的形式,那么Dockerfile中必须要有配套的ENTRYPOINT。

指定启动容器时执行的命令,每个Dockerfile只能有一条  CMD  命令。如果指定了多条命令,只有最后一条会被执行。

如果用户启动容器时候指定了运行的命令,则会覆盖掉  CMD  指定的命令。

(5)ENTRYPOINT(设置container启动时执行的操作)

设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。
两种格式:

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command param1 param2  (shell中执行)。

配置容器启动后执行的命令,并且不可被  docker run  提供的参数覆盖。

每个 Dockerfile 中只能有一个  ENTRYPOINT  ,当指定多个时,只有最后一个起效。


该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。

当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效。

例如:CMD指令将不会被执行,只有ENTRYPOINT指令被执行  

CMD echo “Hello, World!”  

ENTRYPOINT ls -l  

另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。

例如

FROM ubuntu  

CMD ["-l"]  

ENTRYPOINT ["/usr/bin/ls"]  

(6)USER(设置container容器的用户,默认是root用户

格式为  USER daemon

指定运行容器时的用户名或 UID,后续的  RUN  也会使用指定用户。

当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例

如: RUN groupadd -r postgres&&useradd -r -g postgrespostgres

例如: 指定memcached的运行用户  

ENTRYPOINT ["memcached"]  

USER daemon  

或  

ENTRYPOINT ["memcached", "-u", "daemon"]  

(7)EXPOSE(指定容器需要映射到宿主机器的端口)

格式为  EXPOSE [...]

设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。

要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口,然后在运行容器的时候指定-p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用-p选项。

例如: 映射一个端口  

EXPOSE port1  

# 相应的运行容器使用的命令  

docker run -p port1 p_w_picpath  

 

例如: 映射多个端口  

EXPOSE port1 port2 port3  

# 相应的运行容器使用的命令  

docker run -p port1 -p port2 -p port3 p_w_picpath  

# 还可以指定需要映射到宿主机器上的某个端口号  

docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 p_w_picpath  

端口映射是docker比较重要的一个功能,原因在于我们每次运行容器的时候容器的IP地址不能指定而是在桥接网卡的地址范围内随机生成的。宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次访问容器中的某个服务时都要查看容器的IP的地址。

对于一个运行的容器,可以使用docker port加上容器中需要映射的端口和容器的ID来查看该端口号在宿主机器上的映射端口

(8)ENV(用于设置环境变量)

构建指令,指定一个环境变量,会被后续  RUN  指令使用,并在容器运行时保持。

格式:

ENV    

设置了后,后续的RUN命令都可以使用,container启动后,可以通过docker inspect查看这个环境变量,也可以通过在docker run --env key=value时设置或修改环境变量。
假如你安装了JAVA程序,需要设置JAVA_HOME,那么可以在Dockerfile中这样写:ENV JAVA_HOME /path/to/java/dirent
再例如:

ENV PG_MAJOR 9.3

ENV PG_VERSION 9.3.4

RUN curl http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress

ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

(9)ADD(从src复制文件到container的dest路径)

构建指令,所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0;

如果是一个目录,那么会将该目录下的所有文件添加到container中,不包括目录;

如果文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式);

如果是文件且中不使用斜杠结束,则会将视为文件,的内容会写入

如果是文件且中使用斜杠结束,则会文件拷贝到目录下。

格式:

ADD    

该命令将复制指定的到容器中的

其中可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)
是container中的绝对路径(10)COPY

格式为 COPY

复制本地主机的(为Dockerfile所在目录的相对路径)到容器中的

(11)VOLUME(指定挂载点)

设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。

格式:

VOLUME [""]

例如:FROM base  

VOLUME ["/tmp/data"]  

运行通过该Dockerfile生成p_w_picpath的容器,/tmp/data目录中的数据在容器关闭后,里面的数据还存在。例如另一个容器也有持久化数据的需求,且想使用上面容器共享的/tmp/data目录,那么可以运行下面的命令启动一个容器:

docker run -t -i -rm -volumes-from container1 p_w_picpath2 bash  

container1为第一个容器的ID,p_w_picpath2为第二个容器运行p_w_picpath的名字。

(12)WORKDIR(切换目录)

设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。为后续的  RUN、CMD、ENTRYPOINT  指令配置工作目录。

格式:

WORKDIR /path/to/workdir  

例如: 在 /p1/p2 下执行 vim a.txt  

WORKDIR /p1 

WORKDIR p2 

RUN vim a.txt  

可以使用多个  WORKDIR  指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。

例如

WORKDIR /a

WORKDIR b

WORKDIR c

RUN pwd

则最终路径为  /a/b/c  。

(13)ONBUILD(在子镜像中执行)

ONBUILD   

ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行。

格式为  ONBUILD [INSTRUCTION]  。

配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。

例如,Dockerfile使用如下的内容创建了镜像  p_w_picpath-A  。

[...]

ONBUILD ADD . /app/src

ONBUILD RUN /usr/local/bin/python-build --dir /app/src

[...]

如果基于 p_w_picpath-A 创建新的镜像时,新的Dockerfile中使用  FROM p_w_picpath-A  指定基础镜像时,会自动执行ONBUILD  指令内容。

等价于在后面添加了两条指令。

FROM p_w_picpath-A

#Automatically run the following

ADD . /app/src

RUN /usr/local/bin/python-build --dir /app/src

使用  ONBUILD  指令的镜像,推荐在标签中注明,例如  ruby:1.9-onbuild  。

 

编写完成Dockerfile之后,可以通过docker build  命令来创建镜像。

基本的格式为docker build [选项] 路径,该命令将读取指定路径下的Dockerfile,并将该路径下所有内容发送给 Docker 服务端,由服务端来创建镜像。因此一般建议放置Dockerfile的目录为空目录。

要指定镜像的标签信息,可以通过  -t  选项,例如

$ sudodocker build –tmyrepo/myapp/tmp/test1/

1) 创建一个sshd_dockerfile工作目录

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第1张图片

编辑run.sh文件

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第2张图片

在主机上生成ssh秘钥对,并创建authorized_keys文件

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第3张图片

2) 编写Dockerfile

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第4张图片

FROM docker.io/centos:centos6

MAINTAINER from [email protected]

RUN yum install -q -y httpd openssh-server sudo

RUN useradd admin

RUN echo "admin:admin" | chpasswd

RUN echo "admin  ALL=(ALL)  ALL" >> /etc/sudoers

RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key

RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

RUN mkdir -p /var/run/sshd

RUN mkdir -p /home/admin/.ssh

RUN sed -ri 's/#ServerName www.example.com:80/ServerName www.benet.com/g' /etc/httpd/conf/httpd.conf

ADD authorized_keys /home/admin/.ssh/authorized_keys

ADD run.sh /run.sh

RUN chmod 775 /run.sh

EXPOSE 22 80

CMD ["/run.sh"]

以上选项的含义解释:

FROM centos:centos6选择一个已有的os镜像作为基础

MAINTAINER 镜像的作者

RUN yum install -y openssh-server sudo安装openssh-server和sudo软件包

添加测试用户admin,密码admin,并且将此用户添加到sudoers里

RUN useradd admin

RUN echo "admin:admin" | chpasswd

RUN echo "admin   ALL=(ALL)       ALL" >> /etc/sudoers

下面这两句比较特殊,在centos6上必须要有,否则创建出来的容器sshd不能登录

RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key

RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

注意:centos7上必须要有,否则创建出来的容器sshd不能登录

RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key

RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key

RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key

将公钥信息上传到远程连接用户的宿主目录的.ssh下

ADD  authorized_keys /home/admin/.ssh/authorized_keys

启动sshd服务并且暴露22端口

RUN mkdir /var/run/sshd 

EXPOSE 22 80

CMD ["/run.sh"]   也可以写成这种方式CMD ["/usr/sbin/sshd", "-D"] 

 

在sshd_dockerfile目录下,使用docker  build命令来创建镜像,注意:在最后还有一个”.”,表示使用当前目录中的dockerfile

[root@localhost sshd_dockerfile]# docker build --no-cache -t "centos:httpdv1" .

Sending build context to Docker daemon 4.608 kB

Step 1 : FROM docker.io/centos:centos6

 ---> cf2c3ece5e41

Step 2 : MAINTAINER from [email protected]

 ---> Running in 02bd0437a4b1

 ---> 5c8b8cf12528

Removing intermediate container 02bd0437a4b1

Step 3 : RUN yum install -q -y httpd openssh-server sudo

 ---> Running in cac5c0661e31

install-info: No such file or directory for /usr/share/info/ipc.info

 ---> 8217526950c1

Removing intermediate container cac5c0661e31

Step 4 : RUN useradd admin

 ---> Running in 9f067575fcc5

 ---> 434a46a9d9b7

Removing intermediate container 9f067575fcc5

Step 5 : RUN echo "admin:admin" | chpasswd

 ---> Running in 4fc098b1944f

 ---> 9b30d92cc2f8

Removing intermediate container 4fc098b1944f

Step 6 : RUN echo "admin  ALL=(ALL)  ALL" >> /etc/sudoers

 ---> Running in cf449db4e8b0

 ---> 958c58e8cf3e

Removing intermediate container cf449db4e8b0

Step 7 : RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key

 ---> Running in c07dfc40de6a

ing public/private dsa key pair.

Your identification has been saved in /etc/ssh/ssh_host_dsa_key.

Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub.

The key fingerprint is:

65:2e:34:e9:28:2e:05:cc:e3:cd:b9:56:f1:74:0a:78 root@68a1f3cfce80

The key's randomart p_w_picpath is:

+--[ DSA 1024]----+

|                 |

| o   .   .       |

|  = . E = +      |

| . = o O B       |

|  . * o S .      |

|   o +   .       |

|  . +            |

|   o             |

|                 |

+-----------------+

 ---> c71b15053329

Removing intermediate container c07dfc40de6a

Step 8 : RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

 ---> Running in 22f89e60e3cb

Enter passphrase (empty for no passphrase): Enter same passphrase again: Generating public/private rsa key pair.

Your identification has been saved in /etc/ssh/ssh_host_rsa_key.

Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub.

The key fingerprint is:

d2:e2:db:8a:8c:f1:31:97:c9:0a:f3:27:0d:75:b4:5b root@68a1f3cfce80

The key's randomart p_w_picpath is:

+--[ RSA 2048]----+

|                 |

|        .        |

|       . .       |

|      ..o E      |

|     .o.So       |

|    .o =.        |

|  + oo*          |

|   O.*oo         |

|  . *oo..        |

+-----------------+

 ---> 85934eb336c0

Removing intermediate container 22f89e60e3cb

Step 9 : RUN mkdir -p /var/run/sshd

 ---> Running in 4283e5fd0df5

 ---> aa73493a7bd3

Removing intermediate container 4283e5fd0df5

Step 10 : RUN mkdir -p /home/admin/.ssh

 ---> Running in a93eaa720d85

 ---> 60d9caed6257

Removing intermediate container a93eaa720d85

Step 11 : RUN sed -ri 's/#ServerName www.example.com:80/ServerName www.benet.com/g' /etc/httpd/conf/httpd.conf

 ---> Running in bb990d411b95

 ---> 5dd27b1ecc3a

Removing intermediate container bb990d411b95

Step 12 : ADD authorized_keys /home/admin/.ssh/authorized_keys

 ---> 44331f21246d

Removing intermediate container b49ac6ccebc6

Step 13 : ADD run.sh /run.sh

 ---> fbac25942581

Removing intermediate container 8a199cee60e9

Step 14 : RUN chmod 775 /run.sh

 ---> Running in c16e98e92af0

 ---> bc7b3a62bbf6

Removing intermediate container c16e98e92af0

Step 15 : EXPOSE 22 80

 ---> Running in 02a15849100c

 ---> 9687385e5a06

Removing intermediate container 02a15849100c

Step 16 : CMD /run.sh

 ---> Running in eb5f59e85ed9

 ---> d95ea0e3fb37

Removing intermediate container eb5f59e85ed9

Successfully built d95ea0e3fb37

执行docker p_w_picpaths查看新生成的镜像

[root@localhost ~]# docker p_w_picpaths

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第5张图片

使用刚才建好的镜像运行一个容器,将容器的端口映射到主机的10122

[root@localhost ~]# docker run -dit --name webserver1 -p 10122:22 -p 80:80 --restart=always centos:httpdv1

[root@localhost ~]# docker ps

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第6张图片

在宿主主机打开一个终端,连接刚才新建的容器

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第7张图片

注:admin用户是容器中的用户,192.168.152.142是宿主机的地址。

测试sudo执行授权命令:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第8张图片

用docker  inspect查看容器的ip地址,在宿主机上直接ssh连接容器

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第9张图片

二、Docker仓库

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

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

 

Docker Hub 官方仓库

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

 

注册&登录

可以通过命令行执行docker login 命令来输入用户名、密码和邮箱来完成注册和登录。注册成功后,本地用户目录的 .docker/config.json中将保存用户的认证信息。

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第10张图片

基本操作

用户无需登录即可通过docker search 命令来查找官方仓库中的镜像,并利用docker pull 命令来将它下载到本地。

例如以 centos 为关键词进行搜索:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第11张图片

可以看到返回了很多包含关键字的镜像,其中包括镜像名字、描述、星级(表示该镜像的受欢迎程度)、是否官方创建、是否自动创建。官方的镜像说明是官方项目组创建和维护的,automated 资源允许用户验证镜像的来源和内容。

根据是否是官方提供,可将镜像资源分为两类。一种是类似 centos 这样的基础镜像,被称为基础或根镜像。这些基础镜像是由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。还有一种类型,比如tianon/centos 镜像,它是由 Docker 的用户创建并维护的,往往带有用户名称前缀。可以通过前缀user_name/ 来指定使用某个用户提供的镜像,比如tianon用户。另外,在查找的时候通过 -s N 参数可以指定仅显示评价为 N 星以上的镜像。

 

创建自己的仓库----镜像仓库

拓扑:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第12张图片

说明:

docker.benet.com 这是docker registry服务器的主机名称,ip是192.168.1.107;因为https的SSL证书要用到主机名,所以要设置主机名。

dockerregistry 服务器作为处理docker镜像的最终上传和下载,用的是官方的镜像registry。

nginx 1.6.x 是一个用nginx作为反向代理服务器

注:关闭selinux

1)私有仓库https支持:

A)安装依赖软件包:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第13张图片

在Nginx编译需要PCRE,因为Nginx的Rewrite模块和HTTP核心模块会使用到PCRE正则表达式。需要安装pcre和pcre-devel用yum就能安装。

Zlib库提供了开发人员的压缩算法,在nginx的模块中需要使用gzip压缩。

需要安装zlib和zlib-devel用yum就可以安装

在Nginx中如果需要为服务器提供安全则需要用到OpenSSL库。

需要安装的是openssl和openssl-devel。用yum就可以安装。

 B)配置SSL

(1) 编辑/etc/hosts,把docker.benet.com的ip地址添加进来,例如:

主机名、ip地址:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第14张图片

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第15张图片

/etc/hosts文件内容:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第16张图片

(2) 生成根密钥(使用xshell完成操作)

先把

/etc/pki/CA/cacert.pem 
/etc/pki/CA/index.txt 
/etc/pki/CA/index.txt.attr 
/etc/pki/CA/index.txt.old 
/etc/pki/CA/serial 
/etc/pki/CA/serial.old

删除掉!

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第17张图片

(3) 生成根证书

执行

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第18张图片

输出如下信息

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第19张图片

会提示输入一些内容,因为是私有的,所以可以随便输入,最好记住能与后面保持一致,特别是"Common Name”。必须要和hostname显示的一致。

上面的自签证书cacert.pem应该生成在/etc/pki/CA下。

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第20张图片

(4) 为nginx web服务器生成ssl密钥

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第21张图片

注:因为CA中心与要申请证书的nginx服务器是同一个所以就在本机上执行为nginx服务器生成ssl密钥了,否则应该是在另一台需要用到证书的服务器上生成。

查看nginx服务器的密钥

wKioL1hMHLmDx-a6AAAHOiZ5Dq8747.png-wh_50

(5) 为nginx生成证书签署请求

执行

openssl req -new -key nginx.key -out nginx.csr

输出如下信息

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第22张图片

同样会提示输入一些内容,Commone Name一定要是你要授予证书的服务器域名或主机名,challenge password不填。

(6) 私有CA根据请求来签发证书

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第23张图片

执行

openssl ca -in nginx.csr -out nginx.crt

输出内容:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第24张图片

同样会提示输入一些内容,选择y就可以了!

查看nginx的证书

wKioL1hMHW7QVsYJAAAH5arbXI4929.png-wh_50

C)安装,配置,运行nginx

(1) 添加组和用户

wKiom1hMHYmBcUjPAAAIbm6HDJM219.png-wh_50

(2) 下载nginx源文件:

wget http://nginx.org/download/nginx-1.11.2.tar.gz

(3) 编译,安装nginx:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第25张图片

上述选项的解释:

--user=USER 设定程序运行的用户环境(www)
--group=GROUP 设定程序运行的组环境(www)

--prefix=PATH 设定安装目录

--with-pcre启用pcre库,Nginx的Rewrite模块和HTTP核心模块会使用到PCRE正则表达式

--with-http_stub_status_module 是为了启用 nginx 的 NginxStatus 功能,用来监控 Nginx 的当前状态

--with-http_ssl_module                     开启SSL模块,支持使用HTTPS协议的网页

--with-http_realip_module                开启Real IP的支持,该模块用于从客户请求的头数据中读取Real Ip地址

--with-http_addition_module           开启Addtion模块,该模块允许你追加或前置数据到相应的主体部分

--with-http_flv_module模块ngx_http_flv_module 为Flash Video(FLV)文件提供服务端伪流媒体支持


make && make install

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第26张图片

(4) 编辑/opt/nginx/conf/nginx.conf文件

    

wKioL1hMHnezrFwSAAAHbgROJOM350.png


user  www;


worker_processes  4;

 

events {


worker_connections  4096;


 http {


include  mime.types;


default_type  application/octet-stream;


sendfile        on;


keepalive_timeout  65;


upstream registry {


server  192.168.1.107:5000;

    }

 

server {


listen       443 ssl;


server_name  docker.benet.com;


ssl_certificate  /etc/pki/CA/ssl/nginx.crt;


ssl_certificate_key  /etc/pki/CA/ssl/nginx.key;


ssl_session_cache    shared:SSL:1m;


ssl_session_timeout  5m;


ssl_ciphers  HIGH:!aNULL:!MD5;


ssl_prefer_server_ciphers  on;


location  /  {


proxy_pass  http://registry;


client_max_body_size    3000m;


proxy_set_header  Host  $host;


proxy_set_header  X-Forward-For  $remote_addr;

}

}

}

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第27张图片

相关选项含义:

ssl_session_cache会话缓存用于保存SSL会话,这些缓存在工作进程间共享,可以使用ssl_session_cache指令进行配置。1M缓存可以存放大约4000个会话。

ssl_session_timeout缓存超时,默认的缓存超时是5分钟。

ssl_ciphers  HIGH:!aNULL:!MD5使用高强度的加密算法

ssl_prefer_server_ciphers  on依赖SSLv3和TLSv1协议的服务器密码将优先于客户端密码。即:在SSLv3或这是TLSv1握手时选择一个密码,通常是使用客户端的偏好。如果这个指令是启用的,那么服务器反而是使用服务器的偏好。

client_max_body_size即允许上传文件大小的最大值

proxy_set_header Host $host和proxy_set_header X-Forward-For $remote_addr的作用描述:

nginx为了实现反向代理的需求而增加了一个ngx_http_proxy_module模块。其中proxy_set_header指令就是该模块需要读取的配置文件。在这里,所有设置的值的含义和http请求同中的含义完全相同,除了Host外还有X-Forward-For。
      Host的含义是表明请求的主机名,因为nginx作为反向代理使用,而如果后端真实的服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败【默认反向代理服务器会向后端真实服务器发送请求,并且请求头中的host字段应为proxy_pass指令设置的服务器】。
同理,X_Forward_For字段表示该条http请求是有谁发起的?如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来自反向代理服务器,如果后端有防***策略的话,那么机器就被封掉了。因此,在配置用作反向代理的nginx中一般会增加两条配置,修改http的请求头:
proxy_set_header Host $host;
proxy_set_header X-Forward-For $remote_addr;
这里的$host和$remote_addr都是nginx的导出变量,可以再配置文件中直接使用。

(5) 验证配置

/opt/nginx/sbin/nginx -t

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第28张图片

(6) 启动nginx:

执行/opt/nginx/sbin/nginx

(7) 验证nginx是否启动:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第29张图片

2、配置,运行Docker

(1) 停止docker服务

(2)编辑/etc/sysconfig/docker文件,加上如下一行

DOCKER_OPTS="--insecure-registry docker.benet.com --tlsverify --tlscacert /etc/pki/CA/cacert.pem"

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第30张图片

(3) 把根证书复制到/etc/docker/certs.d/docker.yy.com/目录下

mkdir -p /etc/docker/certs.d/docker.benet.com

cp /etc/pki/CA/cacert.pem /etc/docker/certs.d/docker.benet.com/ca-certificates.crt

 

wKioL1hMH9TCd_QsAAAK-513uk0210.png


(4) 启动docker

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第31张图片

3、运行私有仓库容器

通过获取官方 registry 镜像来运行

docker search registry

docker pull registry

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第32张图片

使用官方的 registry 镜像来启动本地的私有仓库。用户可以通过指定参数来配置私有仓库位置。

例如将目录/opt/data/registry作为私有仓库的位置

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第33张图片

运行私有仓库容器

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第34张图片

可以通过 -v 参数来将镜像文件存放在本地的指定路径。例如上面的例子将上传的镜像放到 /opt/data/registry 目录。

-p(小写的)用于将容器的5000端口映射宿主机的5000端口。

4)验证registry:

用浏览器输入: https://docker.benet.com

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第35张图片

或者:curl -i -k https://docker.benet.com

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第36张图片

curl是通过url语法在命令行下上传或下载文件的工具软件,它支持http,https,ftp,ftps,telnet等多种协议,常被用来抓取网页和监控Web服务器状态

 

服务端的配置就到此完成!

注意:注意防火墙

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第37张图片

5)Docker客户端配置

(1)编辑/etc/hosts,把docker.benet.com的ip地址添加进来,例如:

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第38张图片

(2)把docker registry服务器端的根证书追加到ca-certificates.crt文件里

先从docker registry服务器端把文件/etc/pki/CA/cacert.pem拷贝到本机,然后执行命令:

cat ./cacert.pem>> /etc/pki/tls/certs/ca-certificates.crt

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第39张图片

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第40张图片

(3) 验证docker.yy.com下的registry:

用浏览器输入: https://docker.benet.com

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第41张图片

或者:curl -i -k https://docker.benet.com

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第42张图片

(4) 使用私有registry步骤:

        登录: docker login -u testuser -p pwd123 -e "[email protected]" https://docker.benet.com

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第43张图片

        从Docker HUB 上拉取一个镜像测试,为基础镜像打个标签:

docker tag centos:centos6 docker.benet.com/centos:centos6

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第44张图片

        发布:上传镜像到本地私有仓库

docker push docker.benet.com/centos:centos6

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第45张图片

查看私有仓库是否有对应的镜像

# curl 192.168.0.167:5000/v1/search

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第46张图片

查看镜像的存储目录和文件(在镜像服务器)

tree /opt/data/registry/repositories

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第47张图片

从私有仓库pull下来p_w_picpath,查看p_w_picpath

首先删除所有镜像

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第48张图片

然后下载

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第49张图片

 查看私有仓库是否有对应的镜像

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第50张图片

浏览器访问仓库

docker技术剖析--dockerfile and registry(构建容器和私有仓库)_第51张图片

弊端:

server端可以login到官方的Docker Hub,可以pull,push官方和私有仓库! 
client端只能操作搭设好的私有仓库! 
私有仓库不能search!

优点:

所有的build,pull,push操作只能在私有仓库的server端操作,降低企业风险!

注意:当client端docker login到官方的https://index.docker.io/v1/网站,出现x509: certificate signed by unknown authority错误时

重命名根证书mv /etc/pki/tls/certs/ca-certificates.crt /etc/pki/tls/certs/ca-certificates.crt.bak 
重启docker服务!systemctl restart docker


谢谢观看,真心的希望能帮到您!