准备证书
下载安装cfssl工具
下载下来的工具是可以直接执行的
root@harbor:~# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 root@harbor:~# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 root@harbor:~# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
下载完成之后可以重命名一下直接使用
root@harbor:~# mv cfssl_linux-amd64 /opt/bin/cfssl root@harbor:~# mv cfssljson_linux-amd64 /opt/bin/cfssljson root@harbor:~# mv cfssl-certinfo_linux-amd64 /opt/bin/cfssl-certinfo root@harbor:~# chmod +x /opt/bin/* root@harbor:/opt/pki# export PATH=$PATH:/opt/bin #如果想用起来方便点也可以将cfssl工具加到PATH环境变量中
cfssl命令介绍
cfssl常用命令如下:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca ## 初始化ca cfssl gencert -initca -ca-key key.pem ca-csr.json | cfssljson -bare ca ## 使用现有私钥, 重新生成 cfssl certinfo -cert ca.pem #查看cert(证书信息) cfssl certinfo -csr ca.csr #查看CSR(证书签名请求)信息
cfssl工具,子命令介绍:
bundle: 创建包含客户端证书的证书包
genkey: 生成一个key(私钥)和CSR(证书签名请求)
scan: 扫描主机问题
revoke: 吊销证书
certinfo: 输出给定证书的证书信息, 跟cfssl-certinfo 工具作用一样
gencrl: 生成新的证书吊销列表
selfsign: 生成一个新的自签名密钥和 签名证书
print-defaults: 打印默认配置,这个默认配置可以用作模板
config:生成ca配置模板文件
csr:生成证书请求模板文件
serve: 启动一个HTTP API服务
gencert: 生成新的key(密钥)和签名证书
-initca:初始化一个新ca
-ca:指明ca的证书
-ca-key:指明ca的私钥文件
-config:指明请求证书的json文件
-profile:与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息
ocspdump
ocspsign
info: 获取有关远程签名者的信息
sign: 签名一个客户端证书,通过给定的CA和CA密钥,和主机名
ocsprefresh
ocspserve
创建根证书
cfssl工具利用json格式创建证书比较方便,先自己创建一个json的根证书
root@harbor:/opt/pki # cat > ca-config.json <<EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "harbor": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "876000h" } } } } 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@harbor:/opt/pki # cat > ca-csr.json <<EOF { "CN": "harbor", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "HuBei", "L": "WuHan", "O": "harbor", "OU": "org" } ], "ca": { "expiry": "876000h" } } EOF
CN: Common Name,浏览器使用该字段验证网站是否合法,一般写的是域名。非常重要。浏览器使用该字段验证网站是否合法
key:生成证书的算法
hosts:表示哪些主机名(域名)或者IP可以使用此csr申请的证书,为空或者""表示所有的都可以使用(本例中没有hosts字段)
names:一些其它的属性
C: Country, 国家
ST: State,州或者是省份
L: Locality Name,地区,城市
O: Organization Name,组织名称,公司名称(在k8s中常用于指定Group,进行RBAC绑定)
OU: Organization Unit Name,组织单位名称,公司部门
初始化生成CA证书和密钥
root@harbor:/opt/pki # cfssl gencert -initca ca-csr.json | cfssljson -bare ca # 该命令会生成运行CA所必需的文件ca-key.pem(私钥)和ca.pem(证书),还会生成ca.csr(证书签名请求),用于交叉签名或重新签名。
cfssl certinfo -cert ca.pem #查看cert(证书信息) cfssl certinfo -csr ca.csr #查看CSR(证书签名请求)信息
创建harobr服务器证书
创建harbor证书请求文件
root@harbor:/opt/pki # cat > harbor-csr.json <<EOF { "CN": "harbor", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "HuBei", "L": "WuHan", "O": "harbor", "OU": "org" } ] } EOF
使用请求文件根据CA配置颁发证书
root@harbor:/opt/pki# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=harbor harbor-csr.json |cfssljson -bare harbor
- -config :指定CA证书机构的配置文件
- -profile:指定CA配置文件中的哪个模块
root@harbor:/opt/pki# ll -rst total 44 4 drwxr-xr-x 4 root root 4096 Oct 14 05:52 ../ 4 -rw-r--r-- 1 root root 289 Oct 14 06:02 ca-config.json 4 -rw-r--r-- 1 root root 238 Oct 14 06:02 ca-csr.json 4 -rw-r--r-- 1 root root 1338 Oct 14 06:04 ca.pem 4 -rw-r--r-- 1 root root 989 Oct 14 06:04 ca.csr 4 -rw------- 1 root root 1679 Oct 14 06:04 ca-key.pem 4 -rw-r--r-- 1 root root 215 Oct 14 06:47 harbor-csr.json 4 -rw-r--r-- 1 root root 1375 Oct 14 06:47 harbor.pem 4 -rw-r--r-- 1 root root 989 Oct 14 06:47 harbor.csr 4 -rw------- 1 root root 1679 Oct 14 06:47 harbor-key.pem 4 drwxr-xr-x 2 root root 4096 Oct 14 06:47 ./ # 此时已经生成了harbor的证书(harbor.pem)和harbor的私钥(harbor-key.pem)
安装docker和docker-compose
安装docker
root@harbor:~# apt-get purge docker-ce docker-ce-cli containerd.io && rm -rf /var/lib/docker #卸载老版本docker(如果有的话)
当执行apt-get install时,apt软件包管理工具会先检查要安装的软件的状态,向我这种情况下,手动删除了软件配置后,并不会引起dpkg中记录的状态的改变,即仍为 config-files 状态,所以安装过程会直接跳过创建配置文件这一过程。于是当软件重新安装后想要启动进程的时候,才发现找不到文件。所以当你想彻底地删除软件包的时候,用 apt-get purge 吧
root@harbor:~# apt update #更换apt源之后需要操作 root@harbor:~# apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common #安装docker依赖 root@harbor:~# root@harbor:~# curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - #添加GPG证书 root@harbor:~# add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" #写入软件源信息 root@harbor:~# apt-get update && apt-get -y install docker-ce #安装最新版docker-ce root@harbor:/etc/apt# cat > /etc/docker/daemon.json <<EOF { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com", "https://reg-mirror.qiniu.com", "https://registry.docker-cn.com" ], "insecure-registries":["IP:443"], "exec-opts": ["native.cgroupdriver=systemd"] } EOF # 配置docker镜像仓库,设置cgroupdriver为systemd root@harbor:/etc/apt# cat > /etc/sysctl.conf << EOF net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF root@harbor:/etc/apt# sysctl -p net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 # 配置内核参数开启路由转发 root@harbor:/etc/apt# systemctl daemon-reload && systemctl enable --now docker root@harbor:/etc/apt# systemctl is-active docker active
安装docker-compose
root@harbor:~# wget https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-x86_64 root@harbor:~# mv docker-compose-darwin-x86_64 /usr/local/bin/docker-compose root@harbor:~# chmod +x /usr/local/bin/docker-compose root@harbor:/opt/harbor# docker-compose -v Docker Compose version v2.11.2
安装harbor
root@harbor:/opt# wget https://github.com/goharbor/harbor/releases/download/v2.6.1/harbor-offline-installer-v2.6.1.tgz root@harbor:/opt# tar -xf harbor-offline-installer-v2.6.1.tgz root@harbor:/opt# cd harbor/ root@harbor:/opt/harbor# ls LICENSE common.sh harbor.v2.6.1.tar.gz harbor.yml input install.sh prepare # 如果是harbor.yml.tmpl可以mv重命名为harbor.yml root@harbor:/opt/harbor# vim harbor.yml # 修改hostname,注释http相关配置,修改https证书路径
示例如下:
root@harbor:/opt/harbor# ./prepare #运行harbor脚本启用https root@harbor:/opt/harbor# ./install.sh # 执行harbor自带脚本安装harbor # ✔ ----Harbor has been installed and started successfully.---- # 有以上打印表示安装成功
查看容器状态
root@harbor:/opt/harbor# docker-compose ps NAME COMMAND SERVICE STATUS PORTS harbor-core "/harbor/entrypoint.…" core running (healthy) harbor-db "/docker-entrypoint.…" postgresql running (healthy) harbor-jobservice "/harbor/entrypoint.…" jobservice running (healthy) harbor-log "/bin/sh -c /usr/loc…" log running (healthy) 127.0.0.1:1514->10514/tcp harbor-portal "nginx -g 'daemon of…" portal running (healthy) nginx "nginx -g 'daemon of…" proxy running (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp redis "redis-server /etc/r…" redis running (healthy) registry "/home/harbor/entryp…" registry running (healthy) registryctl "/home/harbor/start.…" registryctl running (healthy #需要在harbor部署目录执行
harbor启停命令如下
docker-compose down -v docker-compose up -d
登录harbor
浏览器输入访问地址:
https模式:https://IP:443
http 模式: http://IP:80
用户:admin
密码:harbor.yml文件中harbor_admin_password的值,默认是Harbor12345
。
配置docker使用harbor仓库
登录harbor仓库
root@harbor:/opt/harbor# docker login -u admin -p Harbor12345 harbor.org # 这里用了https就别再加443,否则容易出错,harbor.org可以在/etc/hosts中配置解析 WARNING! Using --password via the CLI is insecure. Use --password-stdin. 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
退出的话docker logout
https://<你自己的IP>:443
即可
另外,harbor使用域名的情况下,需要将harbor证书传到docker节点,否则会报错x509证书错误,具体做法可以参考官网
root@master1:~# ls /etc/docker/certs.d/harbor.org/ ca.crt harbor.org.crt harbor.org.key
仅仅这样还不够,还需要编辑 /etc/docker/daemon.json
root@master1:~# cat /etc/docker/daemon.json { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com", "https://reg-mirror.qiniu.com", "https://registry.docker-cn.com" ], "insecure-registries":["https://harbor.org:443"], #这里和实际域名需要匹配 "exec-opts": ["native.cgroupdriver=systemd"] }
和原来一样,改完之后重启docker服务
小提示:我这边使用admin登录结果出现可以登录成功,但是无法push镜像的情况,建议在harbor上新建其他用户进行使用
如果想要快速将本地容器镜像都改名并上传至harbor,可以使用我这个脚本(会删除原有镜像,如果不想删除记得注释后半截)
#!/bin/bash source_images=$(docker images |awk 'NR!=1{print $1":"$2}') for i in $source_images;do j=$(echo ${i##*/}) # j=$(echo $i|awk -F '/' '{print $NF}') #取j的时候上面两种取法都可以,第一种轻量一些 harbor_k8s=harbor.hu.org/kubernetes/$j docker tag "$i" "$harbor_k8s" docker push "$harbor_k8s" done #下面开始删除远来的镜像,如果不想删就将下面的都注释掉 untag_images=$(docker images |awk 'NR!=1{print $1":"$2}') for m in $untag_images;do docker rmi $m done
如果想直接对其他k8s节点也进行这个操作,可以利用ansible的script模块
root@harbor:~# ansible k8s_node -m script -a rename_image.sh
小提示
1 使用proxy访问harbor
如果需要使用proxy访问harbor,需要注意修改external_url
且如果proxy的端口和harbor端口不匹配的时候一定要取消external_url注释且端口需要写proxy的端口
2 shell从最左或者最右删除字符
root@harbor:~# image=aaa/bbb/ccc/ddd:v1 root@harbor:~# echo ${#image} #打印变量长度 18 root@harbor:~# echo ${image} #标准查看变量 aaa/bbb/ccc/ddd:v1 #从左边开始删除使用#,*在需要匹配的字符左边 #删除匹配到的第一个 root@harbor:~# echo ${image#*/} bbb/ccc/ddd:v1 #删除匹配到的最后一个 root@harbor:~# echo ${image##*/} ddd:v1 #从右边开始删除使用%,*在需要匹配的字符右边 #删除匹配到的第一个 root@harbor:~# echo ${image%/*} aaa/bbb/ccc #删除匹配到的最后一个 root@harbor:~# echo ${image%%/*} aaa