名词概念:镜像、容器、仓库
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository):仓库可看着一个代码控制中心,用来保存镜像。
关于docker的一些优点和使用场景可以去docker官网查看,这里不一一列出,上述简单介绍一下几个关键名词,下面开始学习怎么使用docker。
举一个栗子:假如现在有一个web项目,我们需要部署到服务器上面去,并且启动可以访问。我们的思路肯定是把这个项目的war包拷贝到服务器的tomcat的webapps下面,然后将这个tomcat启动。这是没学docker之前的思路,那么现在怎么用docker容器来把这个项目跑起来呢?
我们知道学了docker以后,我们的思维发生了变化,各个应用都可以尝试用容器部署,例如tomcat、mysql、Redis等都可以用容器启动,所以我们自己的项目也是这样。容器可以理解为是镜像的一个实例化对象,所以首先需要有镜像文件,才能启动容器,那么这个镜像文件就是通过Dockfile来定制的,Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明, 简单来说就是用来定制镜像的一个规则文件。
首先用idea建了一个web项目,且打成war包后上传到服务器的某个文件夹下面,这里是放在了docker-registry-demo文件夹下面, 同时在同级目录建了一个Dockerfile文件,下图所示:
Dockerfile内容如下:
from tomcat:latest copy ./docker-registry-demo.war /usr/local/tomcat/webapps/复制代码
本次dockerfile的内容特别简单,就两句话,第一句是依赖基础镜像tomcat,因为我们的项目是要在tomcat中运行的,第二句是将当前路径的war拷贝到tomcat容器的webapps下面。之后我们使用构建镜像的,命令直接构建就行了。
使用命令:docker build -t docker-registry-demo .复制代码
注意这里的.指的是上下文路径,上下文路径是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。我们看到构建步骤一就是在发送这个上下文环境到镜像文件中,第三步的copy也是在上下文环境中找到这个war。
我们的项目已经构建成一个镜像文件了,通过docker images命令可以查看所有的镜像文件,接下来就是运行这个文件,即容器启动。
使用命令:docker run -p 8083:8080 -d docker-registry-demo复制代码
一句简单命令就把项目启动了,我们在浏览器输入访问地址:
现在我们已经成功将自己的项目通过docker容器部署起来了,但是我们有时候会遇到需要在服务器查看日志情况,这里有两种方式:一种是进入到这个容器里面,或者是将日志数据映射到服务器某个位置。
方式一:
使用docker ps命令查看当前活跃的容器,再通过命令docker exec -it 容器ID /bin/bash
进入容器以后,就是我们熟悉的目录了,在这可以查看日志
方式二:
在容器启动的时候指定数据的映射,即数据卷设置
docker run -p 8080:8080 --name tomcat -v $PWD/logs:/usr/local/tomcat/logs 4e7840b49fad复制代码
-v
参数为容器添加数据卷。-v
参数参数可以多次使用,以添加多个数据卷。我们已经学会怎么构建一个简单的镜像文件,以及怎么启动容器。但是你会发现,当我们每次启动容器的时候都需要写一长串命令,像这种:docker run -p 8080:8080 --name tomcat -v $PWD/logs:/usr/local/tomcat/logs 4e7840b49fad , 虽然可以复制,但是还是觉得很麻烦,所以docker为我们提供了docker-compose的使用,就是用来简化启动配置的。
docker-compose是一个yml文件,在这个文件里面我们可以将一些启动配置写在里面,例如数据卷的设置,容器名称,端口映射等。首先我们要进行compose的下载安装,这里不介绍。安装完成以后,使用命令docker-compose --version查看是否安装成功
安装好docker-compose以后,接下来就是编写文件,同样在docker-registry-demo文件夹下面创建docker-compose-yaml文件,内容是:
version: "2.2" services: docker-registry-demo: volumes: - ./logs:/usr/local/tomcat/logs image: docker-registry-demo-image build: . ports: - 8002:8080 复制代码
这是一个yml文件,所以格式也是yml格式, volumes就是数据卷设置,ports是端口映射,build是帮我们构建镜像,image是镜像名称。
使用命令:docker-compose up -d复制代码
上述命令是以compose方式启动容器,不需要带很多参数,变得方便很多。
停止容器可以使用docker stop 容器id, 也可以使用命令:docker-compose down.
说明:用docker-compose down停止容器是可以同时删除停止后的容器,不用再手动删除了,而且可以同时停止所有在docker-compose文件里面定义的容器。
在结束上面一些关于docker基础知识铺垫后,进入今天的学习正题,怎么搭建docker私仓。
我们都知道maven私服,就是在服务器上有一块jar包共享区域,大家可以在共享仓库里面进行pull或者push。docker的私服差不多也是这个概念,只不过这块共享区域放的不是jar, 而是镜像文件,这样就能实现不同服务器都可以从这块共享区域上传或者拉取镜像,十分方便。我们知道的docker仓库有DockerHub, 还有aliyun提供的镜像服务,今天就来学习怎么搭建自己的私仓,这也是常用的情况。
docker私服是用docker-registry技术实现的,所以先要下载docker-registry镜像并启动registry容器。
使用命令:$ docker run ‐d ‐p 5000:5000 ‐‐restart=always ‐‐name registry ‐v /usr/docker/registry:/var/lib/registry registry:2 复制代码
小提示: Docker Registry目前有v1和v2两个版本,v2版本并不是v1版本的简单升级,而是在很多 功能上都有了改进和优化。v1版本使用的是Python开发的,而v2版本是用go语言开发的; v1版本本地镜像仓库容器中数据默认挂载点是/tmp/registry,而v2版本的本地镜像仓库容 器中数据默认挂载点是/var/lib/registry 。
启动好registry容器,我们就将上面构建的docker-registry-demo镜像推送到仓库,首先需要给镜像重命名。由于推送到本地私有镜像仓库的镜像名必须符合“仓库IP:端口 号/repository”的形式,所以可以使用下面命令命名:
docker tag docker-registry-demo localhost:5000/docker-registry-demo2复制代码
接下来通过push命令推送镜像到仓库
docker push localhost:5000/docker-registry-demo2复制代码
推送结束,我们可以到仓库地址/usr/docker/registry/docker/registry/v2/repositories查看所有的镜像文件。
上面的步骤很简单,当然也是不安全的,所以需要配置私有仓库认证,这样在进行镜像文件推送或者拉取时,必须要登陆,这样安全性得到了保障。怎么配置私有仓库认证?
1、查看Docker Registry私有仓库搭建所在服务器地址:ifconfig 例如:服务器地址为:192.168.158.129
2、生成自签名证书
要确保Docker Registry本地镜像仓库的安全性,还需要一个安全认证证书,来保证其他 Docker机器不能随意访问该机器上的Docker Registry本地镜像仓库,所以需要在搭建 Docker Registry本地镜像仓库的Docker主机上先生成自签名证书(如果已购买证书就无需生成),具体操作指令如下。
$ mkdir registry $ cd registry $ mkdir certs $ cd certs $ openssl req ‐x509 ‐days 3650 ‐subj '/CN=192.168.158.129:5000/' ‐nodes ‐newkey rsa:2048 ‐keyout domain.key ‐out domain.crt 复制代码
3、生成用户名和密码
在Docker Registry本地镜像仓库所在的Docker主机上生成自签名证书后,为了确保 Docker机器与该Docker Registry本地镜像仓库的交互,还需要生成一个连接认证的用户名和密码,使其他Docker用户只有通过用户名和密码登录后才允许连接到Docker Registry本地镜像仓库
$ cd .. $ mkdir auth $ docker run ‐‐entrypoint htpasswd registry:2 ‐Bbn admin 123456 > auth/htpasswd 复制代码
4、启动Docker Registry本地镜像仓库服务(将之前创建的容器删除)
docker run -p 5000:5000 --restart=always --name registry -v /usr/docker/registry:/var/lib/registry -v /registry/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v /registry/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key -d 708bc6af7e5e复制代码
5、配置Docker Registry访问接口
完成Docker Registry本地镜像仓库服务启动后,还需要在搭建了Docker Registry本地镜像仓库所在的Docker主机上配置供其他Docker机器访问的接口,具体指令如下:
$ mkdir ‐p /etc/docker/certs.d/192.168.158.129:5000 $ cp certs/domain.crt /etc/docker/certs.d/192.168.158.129:5000 复制代码
6、Docker Registry私有仓库使用登记 在Docker机器终端使用
vi /etc/docker/daemon.json命令编辑daemon.json文 件,在该文件中添加如下内容 {"insecure‐registries":["192.168.158.129:5000"]}
7、重启并加载docker配置文件
$ /etc/init.d/docker restart 复制代码
自此,我们的仓库认证已经做完,下面我们再试一下push镜像。首先是重命名。
docker tag docker-registry-demo 192.168.158.129:5000/docker-registry-demo3复制代码
docker push 192.168.158.129:5000/docker-registry-demo3 复制代码
发现此时权限受限制,我们可以先登陆
docker login 192.168.158.129:5000复制代码
登陆成功后,在push镜像到仓库成功
push 成功后,我们可以在另外一台服务器pull该镜像,当然前提也是需要先登陆,再使用pull命令。体现了一次构建,到处运行的优势。
docker-maven-plugin插件让我们在idea中可以直接构建docker镜像文件,然后推送到远程私仓,使用起来非常方便,具体使用如下:
首先修改docker.service文件 开启2375端口,供其他客户端上传
vim /usr/lib/systemd/system/docker.service 复制代码
修改ExecStart这一行为以下内容
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock \复制代码
重新启动docker
// 1,加载docker守护线程 systemctl daemon-reload // 2,重启docker systemctl restart docker复制代码
在idea项目的pom.xml中加入以下内容
<plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.1.0</version> <executions> <execution> <id>build-image</id> <phase>install</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <serverId>my-docker-registry</serverId> <imageName>192.168.158.129:5000/docker-registry-demo</imageName> <dockerHost>http://192.168.158.129:2375</dockerHost> <baseImage>tomcat</baseImage> <pushImage>true</pushImage> <resources> <resource> <targetPath>/usr/local/tomcat/webapps/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.war</include> </resource> </resources> </configuration> </plugin> </plugins>复制代码
这里需要注意的一点是,因为我们已经配了仓库安全认证,所以需要登录,这里的登录是通过settings.xml中配置:
<server> <id>my-docker-registry</id> <username>admin</username> <password>123456</password> </server> 复制代码
然后在pom.xml中指定
<serverId>my-docker-registry</serverId>复制代码
使用命令:mvn clean install 进行打镜像包同时push到远程私仓,注意只有配置了<pushImage>true</pushImage>
才会在install阶段上传,否则只能在deploy阶段上传