Docker入门必看

1,077 阅读8分钟

名词概念:镜像、容器、仓库

   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。

一、编写第一个Dockerfile

       举一个栗子:假如现在有一个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
  • -p是端口映射,-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-registry-demo文件夹下面创建logs, $PWD表示当前路径


二、docker-compose的使用

       我们已经学会怎么构建一个简单的镜像文件,以及怎么启动容器。但是你会发现,当我们每次启动容器的时候都需要写一长串命令,像这种: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-registry

       在结束上面一些关于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 
  • ‐d:表示在后台运行该容器 
  • ‐p 5000:5000:私有镜像仓库容器内部默认暴露的5000端口映射到宿主机的5000端口 
  • ‐‐restart=always:表示容器启动后自动启动本地私有镜像仓库 
  • ‐‐name registry:表示为生成的容器命名为registry 
  • ‐v /usr/docker/registry:/var/lib/registry:表示将容器内的默认存储置/var/lib/registry中的数据挂载到宿主机的/usr/docker/registry目录下,这样当容器销毁后,在容器中/var/lib/registry目录下的数据会自动备份到宿主机指定目录 

小提示: 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 
  •  ‐x509:x509是一个自签发证书的格式 
  • ‐days 3650:表示证书有效期 
  • 192.168.158.129:5000:表示具体部署Docker Registry本地镜像仓库的地址和端口 
  • domain.key和domain.crt:就是生成的证书文件
  • rsa:2048:是证书算法长度 

 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

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阶段上传