自动化部署实践(三)- docker镜像管理

582 阅读4分钟

我正在参加「掘金·启航计划」

前言

由于采用docker部署,我们会将应用打包成镜像,而为了更好地管理我们生成的镜像,需要搭建一个私有的镜像库来管理。这样既安全,又能方便镜像的管理。

私有镜像库

对于私有镜像库,可以理解为存放镜像的文件服务。镜像库也被称为制品库,我们打包好的镜像就是制品,然后放到制品库里做中转和版本管理

常用的制品库工具有: NexusHarborJfrog Artifactory等。 我们这里选用sonatype的Nexus,因为它免费,基本可以满足大部分基础业务场景。

安装 Nexus 服务

下载安装包

wget https://dependency-fe.oss-cn-beijing.aliyuncs.com/nexus-3.29.0-02-unix.tar.gz

解压安装包

tar -zxvf ./nexus-3.29.0-02-unix.tar.gz

启动服务

解压后会有两个目录,分别是主程序文件夹nexus-3.29.0-02 和 数据文件sonatype-work

我们进入 nexus-3.29.0-02 下面的 bin 目录,然后启动nexus,命令如下:

cd nexus-3.29.0-02/bin
./nexus start

然后打开浏览器,访问 localhost:8081 。因为启动时间比较长,短时间会打不开,等一会就好了。在 nexus 启动后,会进入这个欢迎页面: image.png

配置Nexus

修改登录密码 先获取初始密码,通过如下命令可以获取初始密码:

sudo cat sonatype-work/nexus3/admin.password

点击右上角的登录,登录名为admin,密码为上一步获取的密码。 按提示修改登录密码,为了方便学习和测试,这里需要打开匿名访问(即允许未登录情况下从制品库拉取或推送制品到制品库)。

新建一个Docker私服

登录之后,按如图所示的步骤新建一个 dockerhosted 类型的服务。

这里可以看到docker有三种类型,分别是proxyhostedgroup

  • proxy: 只下载,不允许用户推送。可以理解为缓存外网制品的制品库,起到 内网缓存 的作用。
  • hosted:和 proxy 相反,原则上 只允许用户推送,不允许缓存
  • group:此类型制品库可以将以上两种类型的制品库组合起来。 image.png 填写制品库的基础信息,大致包含如下四项:
    • name 制品库的唯一标识
    • HTTP端口 向外提供的制品库服务端口 这里配置8082
    • 是否匿名拉取镜像
    • 是否兼容docker v1 api

image.png

配置镜像库的访问权限

左侧菜单找到Security -> Realms,将Docker Bearer Token Realm 添加到右侧的Active框中,选中后点击中间的➡️右箭头。如图: image.png

推送镜像到私有仓库

1. 登录配置

因为我们使用的是http的服务,需要单独做一下配置,否则会访问不通。(https服务的话不用配)

sudo vi /etc/docker/daemon.json

将我们制品库的地址写入insecure-registries,值为数组。如下:

{ "insecure-registries" : [ "10.0.2.15:8082" ], }

2. 登录Dokcer

// ip换成自己虚拟机的ip
sudo docker login ip:8082

输入用户名和密码,如图所示代表登录成功。 image.png

3. 推送本地镜像到docker私服

  1. 先下载一个镜像到本地
  • 可以直接执行docker pull 镜像名称:tagDocker Hub上下载一个镜像到本地
  • 或者启动一个容器docker run 镜像名:tag,如果本地没有这个镜像会自动去Docker Hub上去下载。没tag时默认下载的latest版本
sudo docker run -d httpd

如图,以httpd镜像启动一个容器,-d代表容器的运行模式,默认在后台运行,即启动后不进入容器。可以看到镜像的下载过程。 image.png 2. 将下载的镜像重新打个tag 我们给httpd这个镜像打个test的tag

sudo docker tag httpd httpd:test

然后通过sudo docker images查看我们刚刚的打的tag image.png 3. 推送到Docker私服 为了推送到我们自己的服务地址,这里需要在镜像前面加上私服的地址,如图: image.png 这时候提示我们没有10.0.2.15:8082/httpd 这个tag,所以我们在打tag的时候就需要将ip和port加在tag的开头

我们重新打一下,如图: image.png

重新推送镜像,push成功则如图所示 image.png

4. 接入jenkins

为了测试docker镜像是否可以推送成功,我们将测试项目的shell脚本修改如下:

image.png

错误解决

最终运行失败,提示是我们操作权限不够,所以我们在每个docker命令前加个sudo,然后又出现如下提示:

image.png 这是因为Jenkins服务器在执行sudo命令时的上下文有误,导致这个命令执行的异常。

解决方案:

  1. 在虚拟机上运行如下命令
    $ sudo visudo

  2. 在文件的末尾加上一行 (需要进入insert模式 按i进入)

    jenkins ALL=(ALL) NOPASSWD: ALL

  3. 保存并退出 :wq!

  4. 重启Jenkins服务

    sudo /etc/init.d/jenkins restart

  5. 重新执行项目的Build Now即可

添加Jenkins的凭据

我们的shell脚本直接暴露docker的登录名和密码是很不安全的,可以将用户名密码添加到jenkins的凭据里,然后在shell中通过变量的形式引用。

  1. 添加环境变量,选择Use secret text(s) or file(s),添加Username and password(separated) image.png

  2. 分别填入用户名和密码的变量名(后面使用),如图: image.png

  3. 添加docker登录用户的基本信息,然后Add。如图: image.png

  4. 修改shell脚本如下:

echo 'docker push'
sudo docker login -u $DOCKER_LOGIN_USERNAME -p $DOCKER_LOGIN_PASSWORD 10.0.2.15:8082 
sudo docker tag httpd 10.0.2.15:8082/httpd:jenkins
sudo docker push 10.0.2.15:8082/httpd:jenkins
  1. 重新执行Build Now

至此,jenkins的docker镜像管理就打通了,环境配置相关的就基本结束了,下一篇开始正式接入项目😄。