在上一篇文章中,Jenkins在项目构建完成之后,将最终生成的docker镜像推送到阿里云上,但在有些情况下,比如公司政策或出于安全的考虑,并不希望将镜像交由外部的网络,只允许在公司内网中访问,那这时可以使用Harbor来解决这个问题。本文将通过部署Harbor来存储Jenkins最终生成的docker镜像。
1、Harbor简介
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有Registry中, 确保数据和知识产权在公司内部网络中管控。另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。其拥有如下的特点:
- 基于角色的访问控制:用户与Docker镜像仓库通过“项目”进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
- 镜像复制:镜像可以在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
- 图形化用户界面:用户可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间。
- AD/LDAP支持:Harbor可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。
- 审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
- 国际化:已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言会添加进来。
- RESTful API RESTful API:提供给管理员对于Harbor更多的操控, 使得与其它管理软件集成变得更容易。
- 部署简单:docker-compose和离线安装。
2、安装
Harbor的安装支持离线和在线安装,同时也可以通过helm在k8s集群中进行安装,这里采用在线安装的方式。
2.1 准备
- 硬件
新建一台虚拟机,CPU 2核 内存 4G 硬盘20+100(挂载到/data
目录)G - 软件
docker:19.03.2
docker-compose:1.24.1
openssl:用于生成harbor的证书和key - 网络端口
由于是在内网中所以可以考虑关闭防火墙,但至少必须保证以下端口是开放的:
443:harbor门户和核心api使用的接口,使用https协议
4443:连接到Harbor的Docker内容信任服务
80:harbor门户和核心api使用的接口,使用http协议 - 域名和hosts文件
最终将新建的虚拟机的域名设置为:harbor.tlh.com
-
添加域名映射(需要访问harbor的都需要配置)
echo "192.168.241.145 harbor.tlh.com" >> /etc/hosts
2.2 生成证书
-
创建文件夹,存放所有的生成文件
mkdir ssl cd ssl
-
获取证书授权
openssl genrsa -out ca.key 4096 # 设置证书的信息 openssl req -x509 -new -nodes -sha512 -days 3650 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.tlh.com" \ -key ca.key \ -out ca.crt
-
创建私钥key
openssl genrsa -out harbor.tlh.com.key 4096
-
生成证书前面请求
openssl req -sha512 -new \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.tlh.com" \ -key harbor.tlh.com.key \ -out harbor.tlh.com.csr
-
生成证书
cat > v3.ext <<-EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1=harbor.tlh.com DNS.2=harbor.tlh DNS.3=harbor EOF # 生成证书 openssl x509 -req -sha512 -days 3650 \ -extfile v3.ext \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -in harbor.tlh.com.csr \ -out harbor.tlh.com.crt
2.3 部署安装
-
配置Harbor的证书和key
mkdir /data/cert cp harbor.tlh.com.crt /data/cert/ cp harbor.tlh.com.key /data/cert/
-
配置docker的证书、key和CA
Docker进程解析.crt文件作为CA证书,将.cert文件作为客户端证书。-
生成CA
openssl x509 -inform PEM -in harbor.tlh.com.crt -out harbor.tlh.com.cert
-
复制文件:每个需要链接到Harbor的都需要进行如下操作
mkdir -p /etc/docker/certs.d/harbor.tlh.com # 复制文件 cp harbor.tlh.com.cert /etc/docker/certs.d/harbor.tlh.com/ cp harbor.tlh.com.key /etc/docker/certs.d/harbor.tlh.com/ cp ca.crt /etc/docker/certs.d/harbor.tlh.com/
-
-
配置Harbor
下载在线安装文件
通过这个链接https://github.com/goharbor/harbor/releases,下载需要安装的在线安装包,这里选择:v1.9.3-
解压
tar xvf harbor-online-installer-version.tgz
-
修改配置文件
在解压之后的文件夹中,修改harbor.yml文件,该文件中所有必填的数据都是没有被注释的,这里主要修改hostname和https的配置:hostname: harbor.tlh.com # https related config https: # https port for harbor, default is 443 port: 443 # The path of cert and key files for nginx,配置证书和私钥的路径 certificate: /data/cert/harbor.tlh.com.crt private_key: /data/cert/harbor.tlh.com.key # The default data volume,设置数据存储的路径 data_volume: /data
-
安装
-
执行准备安装脚本
./prepare
-
执行安装
./install.sh
-
可选插件
Notary:内容信任,对push到仓库的数据进行签名
Clair:镜像(appc和docker)缺陷静态扫描工具
-
Chart仓库
# 携带安装notary、Clair和chart ./install.sh --with-notary --with-clair --with-chartmuseum
-
3. 使用
-
浏览器访问:https://harbor.tlh.com/,用户名:admin 密码:Harbor12345
创建用户
进入主界面之后,在用户管理中新建一个用户名为:jenkins 密码为:Jenkins!23的用户,作为docker客户端登陆harbor使用的账户。-
创建项目
在项目管理界面创建项目名为:tlhhup的项目,容量设置为不限制。
添加用户
将2中添加的用户添加到该项目的成员中。-
推送镜像
docker login reg.yourdomain.com docker push reg.yourdomain.com/myproject/myrepo:mytag
4. Jenkins中使用
新建一个id为harbor的凭证,具体方式查看上一篇文章的配置
-
修改tlhhup项目的配置,将docker仓库的地址修改为harbor的地址
stage('Build Docker Image'){ container('docker'){ sh ''' mkdir context cp target/tlhhup-1.0-SNAPSHOT.jar context cp doc/Dockerfile context ''' sh 'docker build -t harbor.tlh.com/tlhhup/jks:${BUILD_NUMBER} context' } } stage('Push Docker Image'){ container('docker'){ sh 'echo Push Docker Image' withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) { sh ''' docker login harbor.tlh.com -u ${dockerHubUser} -p ${dockerHubPassword} docker push harbor.tlh.com/tlhhup/jks:${BUILD_NUMBER} ''' } } }
-
构建
-
Jenkins结果
-
harbor结果
-