部署准备 环境准备

  • 确认操作系统版本

[root@linuxfdc ~]# cat /etc/redhat-release CentOS Linux release 7.8.2003 (Core)

  • 禁用防火墙和Selinux

禁用防火墙、更新SElinux。

  • 确保cfssl工具已经安装

  • 安装证书管理工具cfssl。

安装Docker、Docker Compose

安装Docker、Docker Compose。

准备安装包 下载最新稳定版:https://github.com/goharbor/harbor/releases/download/v2.1.0/harbor-offline-installer-v2.1.0.tgz

准备自签名根证书 X.509证书包含三个文件:key,csr,crt:

  • csr

Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,用于提交给证书颁发机构(CA)对证书进行签名的;其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保管好。

  • key

是服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密。

  • crt

是由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息。

创建证书存放目录


mkdir -pv /root/harbor/cert

cd /root/harbor/cert

生成自签名根证书配置文件 根据自己的需要自定义ca-config.json,修改为如下配置:

[kevin@linuxfdc cert]$ cat > ca-config.json << EOF
{
    "signing": {
      "default": {
        "expiry": "8760h"
      },
      "profiles": {
        "harbor": {
          "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
          ],
          "expiry": "8760h"
        }
      }
    }
}
EOF

这个策略,有一个default默认的配置,和一个profiles,profiles可以设置多个profile,这里的profile是harbor。

  • default

默认策略,指定了证书的默认有效期是一年(8760h);

  • harbor

表示该配置(profile)的用途是为harbor生成证书及相关的校验工作;

  • signing

表示该证书可用于签名其它证书;生成的ca.pem证书中CA=TRUE;

  • server auth

表示可以用该CA对server提供的证书进行验证;

  • client auth

表示可以用该CA对client提供的证书进行验证;

  • expiry

也表示过期时间,如果不写以default中的为准。

生成自签名根证书请求文件


[root@K8S-HARBOR cert]# cat > ca-csr.json << EOF
{
	"CN": "harbor.cluster.local",	
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [{
		"C": "CN",
		"ST": "Shaanxi",
		"L": "Xi'an",
		"O": "Harbor",
		"OU": "Harbor Security"
	}]
}
EOF

参数介绍:

  • CN

Common Name,浏览器使用该字段验证网站是否合法,一般写的是域名。

  • key

生成证书的算法;

  • hosts

表示哪些主机名(域名)或者IP可以使用此csr申请的证书,为空或者""表示所有的都可以使用;

  • names

一些其它的属性:

  • C: Country,国家
  • ST: State,州或者是省份
  • L: Locality Name,地区,城市
  • O: Organization Name,组织名称,公司名称(在K8S中常用于指定* Group,进行RBAC绑定)
  • OU: Organization Unit Name,组织单位名称,公司部门 生成自签名根证书
[root@K8S-HARBOR cert]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca  
2020/09/08 16:38:48 [INFO] generating a new CA key and certificate from CSR
2020/09/08 16:38:48 [INFO] generate received request
2020/09/08 16:38:48 [INFO] received CSR
2020/09/08 16:38:48 [INFO] generating key: rsa-2048
2020/09/08 16:38:49 [INFO] encoded CSR
2020/09/08 16:38:49 [INFO] signed certificate with serial number 262743830065161790985636603005551175222856124160

[root@K8S-HARBOR cert]# ll
total 24
-rw-r--r-- 1 10000 kevin  310 Sep  8 16:30 ca-config.json
-rw-r--r-- 1 root  root  1029 Sep 18 15:18 ca.csr
-rw-r--r-- 1 10000 kevin  246 Sep 18 15:15 ca-csr.json
-rw------- 1 root  root  1679 Sep 18 15:18 ca-key.pem
-rw-r--r-- 1 root  root  1411 Sep 18 15:18 ca.pem

该命令会生成运行CA所必需的文件ca-key.pem(私钥)和ca.pem(证书),还会生成ca.csr(证书签名请求),用于交叉签名或重新签名。 ** 转换成CRT格式** 将ca.pem转换为ca.crt。格式区别:

  • .crt:是用于存放证书,它是2进制形式存放的,不含私钥。
  • .pem:跟crt的区别是它以ASCII来表示的,可查看。


[root@K8S-HARBOR cert]# openssl x509 -outform der -in ca.pem -out ca.crt

基于这种方式生成的CRT文件在使用openssl命令校验时将失败,可通过修改后缀的方式生成CRT文件,如:


[root@K8S-HARBOR cert]# cp ca.pem ca.crt

校验证书信息

  • 查看cert(证书信息)
# 输出信息JSON格式
[root@K8S-HARBOR cert]# cfssl certinfo -cert ca.pem

# 输出信息被格式化
[root@K8S-HARBOR cert]# openssl x509 -noout -text -in ca.pem

针对输出信息,说明:

  • 确认 Issuer 字段的内容和 ca-csr.json 一致;
  • 确认 Subject 字段的内容和客户端请求文件如下面的 ca-csr.json 一致。
  • 查看CSR(证书签名请求)信息

[root@K8S-HARBOR cert]# cfssl certinfo -csr ca.csr 示例:使用自签名证书签署请求 生成harbor.cluster.local证书请求文件


[root@K8S-HARBOR cert]# cat > harbor-csr.json << EOF
{
	"CN": "harbor.cluster.local",
	"hosts": [
	  "local",
      "cluster.local",
      "harbor.cluster.local"
    ],
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [{
		"C": "CN",
		"ST": "Shaanxi",
		"L": "Xi'an",
		"O": "Harbor",
		"OU": "Harbor Security"
	}]
}
EOF

生成harbor.cluster.local证书


[root@K8S-HARBOR cert]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=harbor harbor-csr.json | cfssljson -bare harbor
2020/09/18 15:38:18 [INFO] generate received request
2020/09/18 15:38:18 [INFO] received CSR
2020/09/18 15:38:18 [INFO] generating key: rsa-2048
2020/09/18 15:38:19 [INFO] encoded CSR
2020/09/18 15:38:19 [INFO] signed certificate with serial number 160381788685832694502009193205750931266964565823
2020/09/18 15:38:19 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").

[root@K8S-HARBOR cert]# ll
total 40
-rw-r--r-- 1 10000 kevin  310 Sep  8 16:30 ca-config.json
-rw-r--r-- 1 root  root  1002 Sep 18 15:21 ca.crt
-rw-r--r-- 1 root  root  1029 Sep 18 15:18 ca.csr
-rw-r--r-- 1 10000 kevin  246 Sep 18 15:15 ca-csr.json
-rw------- 1 root  root  1679 Sep 18 15:18 ca-key.pem
-rw-r--r-- 1 root  root  1411 Sep 18 15:18 ca.pem
-rw-r--r-- 1 root  root  1127 Sep 18 15:38 harbor.csr
-rw-r--r-- 1 10000 kevin  341 Sep 18 15:15 harbor-csr.json
-rw------- 1 root  root  1679 Sep 18 15:38 harbor-key.pem
-rw-r--r-- 1 root  root  1525 Sep 18 15:38 harbor.pem

参考 如何创建自签名证书? 部署Harbor 不建议在Harbor上启用https,而是在将Harbor放置到一个LB的后边,配置LB的SSL访问,并在LB上做SSL termination。

解压安装包


[root@K8S-HARBOR ~]# tar -vxf harbor-offline-installer-v2.1.0.tgz -C /root/

修改配置文件


[root@K8S-HARBOR harbor]# cp harbor.yml.tmpl harbor.yml

HTTP方式访问 HTTP方式与Harbor交互时不需要准备自签名证书,修改harbor.yml里hostname、data_volume等参数,禁用https:

[root@K8S-HARBOR harbor]# vi harbor.yml
# Configuration file of Harbor

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: harbor.cluster.local #修改主机名

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80

# https related config
#https: #禁用https
  # https port for harbor, default is 443
  #port: 443
  # The path of cert and key files for nginx
  #certificate: /root/harbor/cert/harbor.pem  
  #private_key: /root/harbor/cert/harbor-key.pem
...

# The default data volume
data_volume: /data/apps/harbor #修改数据存放目录
...

HTTPS方式访问 HTTPS方式与Harbor交互时需要准备自签名证书(参考部署准备中的自签名证书部分),修改harbor.yml里hostname、certificate、private_key、data_volume等参数:

[root@K8S-HARBOR harbor]# vi harbor.yml
# Configuration file of Harbor

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: harbor.cluster.local #修改主机名

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80

# https related config
https:
  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  certificate: /root/harbor/cert/harbor.pem      #修改证书地址
  private_key: /root/harbor/cert/harbor-key.pem  #修改证书地址
...

# The default data volume
data_volume: /data/apps/harbor  #修改数据存放目录
...

部署Harbor 加载镜像


[root@K8S-HARBOR harbor]# docker load -i harbor.v2.1.0.tar.gz

生成部署文件 生成docker-compose.yml配文件,增加其他功能:


[root@K8S-HARBOR harbor]# ./prepare --with-clair --with-notary --with-trivy --with-chartmuseum
#--with-clair  镜像安全扫描插件
#--with_notary 内容信任(镜像签名)插件 
#--with-trivy  镜像漏洞检测插件
#--with-chartmuseum Chart仓库服务
  
#HTTP模式下无法启用--with-notary

部署Harbor组件


docker-compose up -d

查看日志 Harbor采用的是Log Driver是syslog,所以产生的日志目录为:


/var/log/harbor/  

测试Harbor 下面操作需要在访问harbor.cluster.local的节点上执行,以K8S-PROD-M1节点为例展示。

配置证书 因为我们配置使用的是自签名的证书,因此需要将前面生成的CA证书拷贝到需要访问Harbor仓库的每个Docker主机的/etc/docker/certs.d/{registry-hostname}/下。

  • 创建证书存放目录
[root@K8S-PROD-M1 ~]# mkdir -p /etc/docker/certs.d/harbor.cluster.local

  • 获取自签证书

[root@K8S-PROD-M1 ~]# scp root@192.168.122.90:/root/harbor/cert/ca.pem /etc/docker/certs.d/harbor.cluster.local/
[root@K8S-PROD-M1 ~]# scp root@192.168.122.90:/root/harbor/cert/harbor.pem /etc/docker/certs.d/harbor.cluster.local/
[root@K8S-PROD-M1 ~]# scp root@192.168.122.90:/root/harbor/cert/harbor-key.pem /etc/docker/certs.d/harbor.cluster.local/

# 最终/etc/docker目录下文件
[root@K8S-HARBOR docker]# tree
.
├── certs.d
│   └── harbor.cluster.local
│       ├── ca.pem           <-- Certificate authority that signed the registry certificate
│       ├── harbor-key.pem   <-- Server key signed by CA
│       └── harbor.pem       <-- Server certificate signed by CA
├── daemon.json
└── key.json

更新系统CA


[root@K8S-HARBOR ~]# cp /root/harbor/cert/ca.crt /etc/pki/ca-trust/source/anchors/ca.crt
[root@K8S-HARBOR ~]# update-ca-trust extract

配置域名解析


[root@K8S-PROD-M1 ~]# vi /etc/hosts
...

# 添加Harbor域名解析
192.168.122.90    harbor.cluster.local
更新Docker配置
vi /etc/docker/daemon.json 
{
    "insecure-registries": ["harbor.cluster.local"]
}
[root@K8S-PROD-M1 ~]# systemctl reload docker && systemctl status docker

Docker Client访问 默认管理员账户:admin/Harbor12345.


[kevin@linuxfdc ~]$ docker login harbor.cluster.local
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /home/kevin/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Harbor UI测试访问

  • NAT配置

iptables -t nat -A PREROUTING -m tcp -p tcp -d 192.168.191.32 --dport 8080 -j DNAT --to-destination 192.168.122.90:80 iptables -t nat -A PREROUTING -m tcp -p tcp -d 192.168.191.32 --dport 8443 -j DNAT --to-destination 192.168.122.90:443

  • 访问Harbor UI

默认管理员账户:admin/Harbor12345.

https://harbor.cluster.local 测试Chart 确保启用了Chart功能 即在生成docker-compose.yml配置文件时,启用了--with-chartmuseum功能。

更新Helm Repo信息 HTTP方式

# 域名方式
[root@K8S-PROD-M1 ~]# helm repo add local http://harbor.cluster.local/chartrepo/library

# IP地址方式
[root@K8S-PROD-M1 ~]# helm repo add local http://192.168.122.90/chartrepo/library


HTTPS方式 需要自签名证书、用户名和密码:


[root@K8S-PROD-M1 ~]# helm repo add --username=admin --password=Harbor12345 --ca-file /root/harbor/cert/ca.pem \
--cert-file /root/harbor/cert/harbor.pem --key-file /root/harbor/cert/harbor-key.pem \
local https://harbor.cluster.local/chartrepo/library
"local" has been added to your repositories

[root@K8S-PROD-M1 ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "local" chart repository
...

安装helm push Plugin


[root@K8S-PROD-M1 ~]# helm plugin install https://github.com/chartmuseum/helm-push

推送Chart至local Repo HTTP方式


[root@K8S-PROD-M1 workspace]# helm push /root/workspace/ingress-nginx-3.12.0.tgz local
Pushing ingress-nginx-3.12.0.tgz to local...
Done.

HTTPS方式 需要同时加上自签名证书、用户名和密码:

# 推送Chart目录,/root/workspace/ingress-nginx是Chart应用目录
[root@K8S-PROD-M1 ~]# helm push --username=admin --password=Harbor12345 --ca-file /root/harbor/cert/ca.pem \
--cert-file /root/harbor/cert/harbor.pem --key-file /root/harbor/cert/harbor-key.pem \
/root/workspace/ingress-nginx local
Pushing ingress-nginx-3.12.0.tgz to local...
Done.

# 推送tgz文件,ingress-nginx-3.15.2.tgz是Chart应用文件
[root@K8S-PROD-M1 ~]# helm push --username=admin --password=Harbor12345 --ca-file /root/harbor/cert/ca.pem \
--cert-file /root/harbor/cert/harbor.pem --key-file /root/harbor/cert/harbor-key.pem \
/root/workspace/ingress-nginx-3.12.0.tgz local

** 获取Chart至本地**

# 获取最新版本
[root@K8S-PROD-M1 workspace]# helm pull ingress-nginx/ingress-nginx

# 获取指定版本
[root@K8S-PROD-M1 workspace]# helm pull ingress-nginx/ingress-nginx --version 3.12.0