个人亲自录制全套DevOps系列实战教程 :手把手教你玩转DevOps全栈技术
Harbor私服搭建
讲完Nexus3再来看下harbor,其实大同小异,只不过harbor的管理要比Nexus3更专业、功能更完善,大家按需选择即可,Nexus的优势是他能和Maven仓库复用同一个服务器。
官网:https://goharbor.io/docs/2.6.0/install-config/installation-prereqs/
其实Harbor更适合拿一台虚拟机或物理机来安装,当然也可以集成到k8s,但如果是单台docker服务下安装,就有些不太合适了,
不合适的原因是Harbor需要docker-engine、docker-compose、openssl
的支持,即要在装有这些工具包机器上安装Harbor。
有3种安装方案:
- 直接安装在宿主机[复用docker环境][演示https方式]
- 将harbor安装到容器:手动构建镜像,镜像中安装harbor需要的环境(docker环境等)[演示http方式]
- 将harbor安装到容器:类似jenkins那样,将需要的环境从宿主机映射到容器(该方式我们不再演示)
下边我们先来演示容器中单独部署Harbor仓库
Docker容器部署[http协议版]
下载安装包:从官方(https://github.com/goharbor/harbor/releases)下载harbor稳定版,
离线安装包:harbor-offline-installer-v2.6.2.tgz,大约有769M,如果大家无法访问可以找我索取。
目录:我们依然按照老规矩,将文件拷贝到/docker/harbor目录,目录结构如下,所有资料下文都有。1.将离线安装包拷贝到目标目录:
/docker/harbor/harbor-offline-installer-v2.6.2.tgz
2.事先准备一个harbor的配置文件:harbor.yml
值得关注的属性如下,其他忽略【此处只需要修改hostname和注释掉https,其他默认即可】
3.准备一个docker的配置文件:/etc/docker/daemon.json
主要是把镜像加速和信任列表创建好,否则最好映射到宿主,因为毕竟是容器,删除后容易丢失。
4.创建Dockerfile镜像文件:/docker/harbor/Dockerfile
此处使用阿里云的yum源安装docker,也可以用官方:https://download.docker.com/linux/centos/docker-ce.repo
大坑:
注意我们是基于centos7的镜像构建的,而我们容器内安装有docker-engine,那么肯定要通过systemctl启动服务,而systemctl是需要root权限的,虽然我们Dockerfile指定了USER root,但这只是容器的root,他对于宿主机来说仍然是普通用户,而我们需要启动容器时指定privileged: true
,这样容器内的root才真正具备root权限,但是正式因为当前基于centos7,而centos7的privileged: true设置是不起作用的,这在官方也提供了解决方法,但是太麻烦,我们采用另一种方式,就是容器启动前先执行/usr/sbin/init
脚本,即可解决。具体大家可以到官网查询,我这里就不多说了。
官方安装:https://hub.docker.com/_/centos -> 正文部分在解决Systemd的位置,可以自行选择。
第二个坑:
容器中我们安装了docker服务,那么肯定是要通过systemctl start docker来启动,但是要想让systemctl能执行就需要开启init进程,init进程必须在系统启动的时候开启,作为第一个进程,init无法在脚本中启动,因此只能是将容器的启动命令设置成/usr/sbin/init,然后将启动服务的命令写成脚本,再把执行脚本的命令写入/etc/rc.local中,这样就可以在centos7容器中使用systemctl启动服务了。
第三个坑:
按照上述操作其实还有个坑,就是发现放到rc.local的代码并没有执行,这是因为centos7开始/etc/rc.d/rc.local的权限变成了644,并没有执行权限,而我们修改的是/etc/rc.local,他是软连接到/etc/rc.d/rc.local,所以我们还需要给/etc/rc.d/rc.local授权 chmod +x /etc/rc.d/rc.local,并且我们要先检查一下rc.local服务是否启动,如果没启动还需要让他也向docker一样随机启动(systemctl status rc-local.service/systemctl enable rc-local.service)
5.容器启动脚本vi /docker/harbor/start.sh
6.创建docker-compose.yml编排脚本:vi /docker/harbor/docker-compose.yml
注意:
harbor的配置文件端口我们从80改成了9090,保持了和宿主机映射的端口一致,为什么呢?
经过我的实践,如果容器中使用80,宿主机使用9090,这样映射访问harbor的web页面是没问题的,但是通过docker login 10.10.1.199:9090时就会访问不到。7.构建部署镜像
宿主机执行部署:./docker/harbor/docker-compose up -d --build
看到这样的日志表示启动完成,而容器内部其实是启动了多个容器:
8.验证:浏览器中输入10.10.1.199:9090
输入默认用户admin,密码Harbor12345
9.客户端登录试试:
宿主机中执行docker login 10.10.1.199:9090,结果却报错了
我们不是已经加入到信任列表了吗?==>注意我们是把harbor服务地址加入到了自身容器中,而没有加入到宿主机,而此时是使用宿主机访问,所以要加入到宿主机
加入后重启宿主机docker服务再试,就没问题了。
宿主机部署Harbor[https协议版]
1.数字证书
这里我们使用openssl工具来生成证书,其实我们会经常遇到ssh-keygen、openssl、keytool,甚至有时候会用到puttygen,这里简单说明下他们的关系:
- ssh-keygen:是openssh提供的管理密钥证书的工具,即通过他生成的一般是符合ssh使用的证书格式;http://www.openssh.com/
- openssl:我们知道ssl/tls协议,那openssl顾名思义,是一个开源的用于加密和安全通讯的工具包,包括生成证书等功能;https://github.com/openssl/openssl
- keytool:他是JDK提供的一个密钥管理工具,也可以生成证书等;https://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html
- puttygen:他是putty这个软件提供的密钥管理工具https://puttygen.tech/index.php <br>
完全参考官方文档安装:https://goharbor.io/docs/2.6.0/install-config/configure-https/
2.生成CA根证书
生产中我们需要到CA机构申请证书,而此时我们自己生成CA证书,自己给自己签发证书
3.生成自签名证书:即服务端(harbor)要使用的证书
4.将证书配置给Harbor和Docker(harbor所在机器的Docker服务)
5.启动harbor:将harbor.yml的https节点打开
出错了:
提示我们目录或文件不存在:No such file or directory: '/hostfs/docker/harbor/harbor/data/cert/omv.local.key'
但是这个目录/hostfs哪来的?
我们知道了harbor是在docker容器中运行,那么prepare脚本应该也是去创建容器了,打开这个脚本,我们发现以下代码:
再次执行ok!
# 进行启动 ./install.sh
问题:
该问题是启动harbor相关的nginx容器时遇到宿主机80端口被占用的情况,我是因为omv主机服务的端口用了80
有两种修改方法:
- 修改omv更换成其他端口
- 修改harbor的nginx容器成其他端口:很简单,打开harbor目录,此时因为运行了install.sh,已经生成了docker-compose.yml,我们打开找到位置修改端口即可
- 再启动
6.验证浏览器使用:
输入https://10.10.1.199,注意此时使用的是https,所以默认不输入端口默认使用443,而上边我们看到80和443都已放开,只不过没使用80端口
那没使用上边为什么报错呢?因为即便没使用但是我们做了映射啊,所以上边还有第3种方法,就是不映射80端口,只映射443端口即可,但是默认harbor各容器内部通信是使用http协议的,并且各容器并未配置link连接(由docker-compose.yml可知)
,所以关闭80映射是影响内部通信大家可以测试一下。如果想把内部通信方式改为https其实和harbor对外https修改方式大同小异,可参看官方文档,这里就不演示了。
内部通信https配置官方文档:https://goharbor.io/docs/2.6.0/install-config/configure-internal-tls/因为我们使用的自签名证书,所以浏览器从服务端拿到证书后是无法通过已知的CA认证机构校验的,所以需要我们自己将证书加入到浏览器的信任列表,我们此处选择继续访问即可。
和docker容器方式一样可以正常访问,此处不截图了,避免重复。7.验证Docker推送和拉取
docker的使用,这里和Nexus有些区别,harbor同nexus一样,都是需要我们自己创建仓库的,只不过nexus每个仓库我们可以单独指定端口,而harbor则不可以,
所以为了区分拉取/推送哪个仓库,我们需要打标签时加上namespace(即仓库名),而nexus则可以通过端口来区分。
我们先来创建一个仓库:从页面可知也可以创建代理仓库,此处我们选择公开,即允许匿名拉取。进入仓库,可以看到有很多配置功能,这也是他比nexus强大的地方之一,比如webhooks可以对接harbor仓库的10几个事件通知,方便我们做监控。
进入"镜像仓库"选项卡,我们可以看到镜像列表,右侧有推送命令,大家可以自行查看
显然我们并不存在这样的镜像。
疑惑1:
其实通过界面对比Nexus我们会有些疑惑,Nexus有group仓库,可以汇总所有仓库内容,方便拉取,那么harbor有吗?
为此harbor提供了机器人账号,可以通过创建机器人账号关联多个仓库,这样我们使用机器人账号就可以使用多个仓库的镜像。
疑惑2:
Nexus有proxy仓库,可以作为镜像代理仓库,harbor有吗?
harbor是从v2.1.1版本开始增加了这个功能,通过新建"目标"指定外网仓库,然后新建工程指定为代理,以此实现
注意:
拉取时我们除了要加项目名到url中还需要增加一个library名称空间,来表名使用代理仓库
如:docker pull omv.local/hub/library/busybox ,这样才可以
具体可见官方文档:https://goharbor.io/docs/2.6.0/administration/configure-proxy-cache/
8.Nexus和Harbor对比:
各有长处,大家自行选择即可,下边演示我使用的nexus。
- Nexus使用更加方便
- Harbor对镜像的管理更加强大