一. 初始Docker 仓库
在之前几篇文章中,使用过很多镜像创建实例,但是大家有没有发现以下几个问题
● 拉取的镜像只在当前服务器,只能本地使用
● 多个服务器部署同一个应用时,会拉取多次镜像
● 应用集群节点数过多,同一时间去拉取会消耗很大的网络出口带宽
● 命名规范性,一台服务器上部署多个应用模块,则命名需要很强的规范性
● 不便管理,一台服务器上部署多个项目模块时,无法对每个项目的模块进行区分
Yum仓库,当本地需要去拉取依赖包时只需要进行认证、配置就可以直接下载。而Docker 仓库,就是与Yum起到相同功能的角色,一个是解决系统环境依赖包问题,一个是解决镜像管理、拉取问题
二. Docker 仓库软件介绍
● 第三方远程仓库
Docker Hub、阿里云、网易云仓库,镜像存储在第三方云上
● Docker Repository
Docker自身提供的一款私有仓库,没有Web Ui管理页面
● 开源技术实现
Harbor,提供丰富的Api操作接口以及完善的Web UI功能
本文着重介绍"Harbor"仓库的实现
三. Harbor仓库的部署与使用
3.1 Harbor官网地址
https://github.com/goharbor/harbor/releases
3.2 Harbor系统要求说明
docker 17.06.0-ce +和docker-compose 1.18.0+
3.3 本文使用版本说明
[root@bjtn-app183-214 Harbor]# docker info | grep -i "server version" Server Version: 18.06.3-ce -rwxr-x--- 1 root root 643358224 May 2 14:32 harbor-offline-installer-v1.10.2.tgz [root@bjtn-app183-214 Harbor]# pwd /opt/app/Harbor [root@bjtn-app183-214 Harbor]# ll total 628280 -rwxr-x--- 1 root root 643358224 May 2 14:32 harbor-offline-installer-v1.10.2.tgz
3.4 安装docker compose
[root@bjtn-app183-214 Harbor]# curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 423 100 423 0 0 337 0 0:00:01 0:00:01 --:--:-- 337 100 16.2M 100 16.2M 0 0 647k 0 0:00:25 0:00:25 --:--:-- 702k [root@bjtn-app183-214 Harbor]# chmod +x /usr/local/bin/docker-compose && sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose [root@bjtn-app183-214 Harbor]# docker-compose -v docker-compose version 1.25.1, build a82fef07
3.5 Harbor仓库支持https
docker、maven对接Harbor默认是https
[root@bjtn-app183-214 cert]# pwd /opt/app/Harbor/cert [root@bjtn-app183-214 cert]# openssl genrsa -out docker-repo.key 4096 Generating RSA private key, 4096 bit long modulus .............................................................................................................................................................................................................................++ ....................................................................++ e is 65537 (0x10001) [root@bjtn-app183-214 cert]# openssl req -x509 -new -nodes -sha512 -days 36500 \ > -subj "/C=TW/ST=Taipei/L=Taipei/O=example/OU=Personal/CN=docker-repo.com" \ > -key docker-repo.key \ > -out docker-repo.crt [root@bjtn-app183-214 cert]# ll total 8 -rw-r----- 1 root root 2033 May 2 14:44 docker-repo.crt -rw-r----- 1 root root 3243 May 2 14:43 docker-repo.key
3.6 部署Harbor
解压tar包 [root@bjtn-app183-214 Harbor]# pwd /opt/app/Harbor [root@bjtn-app183-214 Harbor]# tar -xf harbor-offline-installer-v1.10.2.tgz [root@bjtn-app183-214 Harbor]# mv harbor/* ./ [root@bjtn-app183-214 Harbor]# rm -rf harbor 修改配置 hostname: 本地主机IP https: https端口以及证书文件 port: certificate: 指明crt秘钥文件 private_key: 指明key秘钥文件 data_volume: 数据存储路径 harbor_admin_password: 登录Harbor Web UI密码 进行初始化,会拉取镜像文件 [root@bjtn-app183-214 Harbor]# ./prepare prepare base dir is set to /opt/app/Harbor Unable to find image 'goharbor/prepare:v1.10.2' locally v1.10.2: Pulling from goharbor/prepare ae8395e171fb: Pull complete ca35e8aaa3ab: Pull complete 40fe63fa9717: Pull complete b716a0e0062b: Pull complete 611e775dac46: Pull complete 456ee3045669: Pull complete 3dfaed1ae811: Pull complete 进行安装 ./install.sh
3.7 尝试访问主页
四. Docker客户端 与 Harbor之间交互
4.1 Docker 认证 Harbor
修改docker启动配置,新添Harbor仓库地址 --insecure-registry harbor的主机IP,笔者认为每一台docker客户端都需要配置
ExecStart=/usr/bin/dockerd --graph /opt/app/Docker --insecure-registry https://10.10.183.214
重启Docker Daemon
systemctl daemon-reload systemctl restart docker
进行登录认证
[root@bjtn-app183-214 Harbor]# docker login 10.10.183.214 Username: admin Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
4.2 Harbor 创建临时项目
4.3 为镜像打标签
命令格式:docker tag [SOURCE_IMAGE][:TAG] [HarborIp]/[Repository]/IMAGE[:TAG]
这里以rancher-server为例
[root@bjtn-app183-214 ~]# docker images | grep rancher rancher/server v1.6.12 f61683a6ad09 3 years ago 968MB [root@bjtn-app183-214 ~]# docker tag rancher/server:v1.6.12 10.10.183.214/docker-harbor-test1/docker-rancher-server:version1 [root@bjtn-app183-214 ~]# docker images | grep rancher 10.10.183.214/docker-harbor-test1/docker-rancher-server version1 f61683a6ad09 3 years ago 968MB rancher/server
4.4 Docker客户端 上传镜像
命令格式:docker push [HarborIp]/[Repository]/[Image]:[Tag]
[root@bjtn-app183-214 ~]# docker push 10.10.183.214/docker-harbor-test1/docker-rancher-server:version1 The push refers to repository [10.10.183.214/docker-harbor-test1/docker-rancher-server] b05601ba6e00: Pushed 753ee21c6bb5: Pushed .... version1: digest: sha256:627047da2ec626d3ce9f090834c8e29274c0899df962abbeee8a06ee0617e8c5 size: 4302
4.5 验证Harbor仓库下载
下载命令格式:docker pull [HarborIp]/[Repository]/[Image]:[Tag]
删除本地与"rancher"相关的镜像
[root@bjtn-app183-214 ~]# docker rmi `docker images | grep -i "rancher" | awk '{print $3}' | xargs` --force Untagged: 10.10.183.214/docker-harbor-test1/docker-rancher-server:version1 Untagged: 10.10.183.214/docker-harbor-test1/docker-rancher-server@sha256:627047da2ec626d3ce9f090834c8e29274c0899df962abbeee8a06ee0617e8c5 Untagged: rancher/server:v1.6.12 Untagged: rancher/server@sha256:19df74c0a542f3c105648436a806cc78a6db89c96f5421d0eaecfb5dd5947bce Deleted: sha256:f61683a6ad0906c80b9e2c698842ba8c55f971f68aa03ad6cc8712358fd74de1
docker客户端下载"rancher"镜像
[root@bjtn-app183-214 ~]# docker pull 10.10.183.214/docker-harbor-test1/docker-rancher-server:version1 version1: Pulling from docker-harbor-test1/docker-rancher-server c314617ce3f1: Already exists 2389af727e43: Already exists ... Digest: sha256:627047da2ec626d3ce9f090834c8e29274c0899df962abbeee8a06ee0617e8c5 Status: Downloaded newer image for 10.10.183.214/docker-harbor-test1/docker-rancher-server:version1 [root@bjtn-app183-214 ~]# docker images | grep -i "rancher" 10.10.183.214/docker-harbor-test1/docker-rancher-server version1 f61683a6ad09 3 years ago 968MB
说明: Harbor仓库显示的镜像大小只有"334.86MB",但是下载到Docker客户端本地后大小有"968MB",个人理解是Harbor仓库只展示了最外层镜像的大小,没有展示内部封装或者里依赖镜像大小
五. Harbor Api接口使用
● 以下脚本实现了调用Harbor Api定时清理所有项目所有仓库的历史镜像信息,只保留每个仓库近10次镜像
● 仓库中镜像的tag已[server]:[time](服务名称:时间戳)规范命名
● 笔者在项目中部署时未使用"latest"版本,部署总是有问题(未解决),在部署中以最新时间戳的tag进行部署,后续可根据业务需求进行更改
● mvn编译+上传镜像到Harbor是在代码层实现,笔者只是实现了拉取+部署,后续可以调研下"jenkins docker cloud"插件使用
● 关于其他Api接口使用方法可以自行研究下
#!/bin/bash # Created on Wed Mar 3 17:25:18 CST 2021 # author:wtc # haror 认证信息 harbor_host="$ip" harbor_user="$user" harbor_pass="$pass" # 获取所有项目信息 get_all_project_id() { project_id_data=`curl -s -u "$harbor_user:$harbor_pass" -X GET --insecure --header 'Accept: application/json' "https://$harbor_host/api/search" | jq ".project" | jq ".[].project_id" | xargs` echo "$project_id_data" } # 获取所有仓库信息 get_all_repo_name() { for project_id in $project_id_data;do repo_name_data=`curl -s -u "$harbor_user:$harbor_pass" -X GET --insecure --header 'Accept: application/json' "https://$harbor_host/api/repositories?project_id=$project_id" | jq .[].name | xargs` echo "$repo_name_data" done } repo_name_data=`get_all_repo_name` # 保留近10个最新镜像文件,包含latest get_all_image_tag() { for repo_name in $repo_name_data;do tag_data=`curl -s -u "$harbor_user:$harbor_pass" -X GET --insecure --header 'Accept: application/json' "https://$harbor_host/api/repositories/$repo_name/tags" | jq ".[].name" | xargs` array_tag=(`echo $tag_data`) # 控制保留历史版本个数 if [ ${#array_tag[@]} -le 10 ];then echo "$repo_name 仓库的镜像数未超过10个,不做处理!" continue else for ((tag_index=0;tag_index<=`expr ${#array_tag[@]} - 10`;tag_index++));do tag_name=${array_tag[$tag_index]} if [ "$tag_name" == "latest" ];then continue else curl -s -u "$harbor_user:$harbor_pass" -X DELETE --insecure --header 'Accept: application/json' "https://$harbor_host/api/repositories/$repo_name/tags/$tag_name" if [ $? -eq 0 ];then echo "$repo_name 仓库的镜像${array_tag[$tag_index]}删除成功!" else echo "$repo_name 仓库的镜像${array_tag[$tag_index]}删除失败!" fi fi done fi done } # 删除|部署 if [ "$#" -ne 6 ];then # 开启是否删除镜像 get_all_image_tag else # 项目名称在代码中写死,通过Jenkins传参 ${project}、${mould}、${PortMapping}、${YamlPath}、${YamlName}、${LogPath} echo "$@" # 部署由jenkins 个性化传参,这里不做展示 fi