一、在Linux中搭建harborV2.x的私有仓库

安装docker,docker-compose的步骤请参考上期文章,唯一不同的是就是需要修改一下harbor和docker-compose的版本,强调一点,harbor2.x的版本需要的docker-compose的版本最低是1.18.0

安装docker

参考上期文章

安装docker-compose

[root@node2 ~]#curl -L "https://get.daocloud.io/docker/compose/releases/download/1.18.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
[root@node2 ~]# chmod +x /usr/local/bin/docker-compose #添加权限
[root@node2 ~]# docker-compose version #查看版本信息
docker-compose version 1.18.0, build 8dd22a9
docker-py version: 2.6.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

安装Harbor

root@localhost ~]# mkdir -p /opt/harbor
[root@localhost ~]# cd /opt/harbor/
[root@localhost harbor]# yum -y install wget
[root@localhost harbor]# wget https://github.com/vmware/harbor/releases/download/v2.3.1/harbor-online-installer-v2.3.1.tgz
[root@localhost harbor]# ls
harbor-online-installer-v1.1.2.tgz
[root@localhost harbor]# tar -zxf harbor-online-installer-v2.3.1.tgz 
[root@localhost harbor]# ll 
total 32
-rw-r--r-- 1 root root  3361 Jul 19 18:48 common.sh
-rw-r--r-- 1 root root  7835 Sep 24 13:45 harbor.yml.tmpl
-rwxr-xr-x 1 root root  2500 Jul 19 18:48 install.sh
-rw-r--r-- 1 root root 11347 Jul 19 18:48 LICENSE
-rwxr-xr-x 1 root root  1881 Jul 19 18:48 prepare

解压完成之后的文件目录如上面所示。

[root@localhost harbor]# cp harbor.yml.tmpl harbor.yml
[root@localhost harbor]# vim  harbor.yml
hostname: 192.168.192.131

# 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: /data/cert
#  private_key: /data/cert
...
#此处省略
prepare.shinstall.sh
[root@localhost harbor]# ./prepare
[root@localhost harbor]# ./install.sh 启动harbor
  • 访问测试,出现以下的界面说明就完成了

使用https登陆,生成ssl证书

默认情况下,Harbor不附带证书。可以在没有安全性的情况下部署Harbor,以便您可以通过HTTP连接到它。但是,只有在没有外部网络连接的测试或开发环境中,才可以使用HTTP。在外网暴露环境中使用HTTP会使您遭受中间人攻击。在生产环境中,请始终使用HTTPS。如果启用Content Trust with Notary来正确签名所有镜像,则必须使用HTTPS。

注意目录名称一致
[root@VM-4-10-centos ssl]# mkdir -p /etc/cert
[root@VM-4-10-centos ssl]# cd /etc/cert
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt
[root@VM-4-10-centos cert]# openssl req  -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt
Generating a 4096 bit RSA private key
........................................++
....................++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BJ
Locality Name (eg, city) [Default City]:BJ
Organization Name (eg, company) [Default Company Ltd]:WH
Organizational Unit Name (eg, section) []:WH
Common Name (eg, your name or your server's hostname) []:xx.xx.xx.xx
Email Address []:2820524218@qq.com
server.keyserver.csropenssl req -newkey rsa:4096 -nodes -sha256 -keyout server.key -out server.csr
[root@VM-4-10-centos cert]# openssl req  -newkey rsa:4096 -nodes -sha256 -keyout server.key -out server.csr
Generating a 4096 bit RSA private key
.....................................................++
....++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BJ
Locality Name (eg, city) [Default City]:BJ
Organization Name (eg, company) [Default Company Ltd]:WH
Organizational Unit Name (eg, section) []:WH
Common Name (eg, your name or your server's hostname) []:xx.xx.xx.xx
Email Address []:2820524218@qq.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
  • 生成一个x509 v3扩展文件,给文件是必须创建的
[root@VM-4-10-centos cert]# echo subjectAltName = IP:xx.xx.xx.xx > extfile.cnf
//导出自签名证书,注意证书文件名称,同样推荐设置为 server.crt
[root@VM-4-10-centos cert]# openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out server.crt
Signature ok
subject=/C=CN/ST=BJ/L=BJ/O=WH/OU=WH/CN=xx.xx.xx.xx/emailAddress=2820524218@qq.com
Getting CA Private Key
#完成以上的工作之后发现一共是7个文件
[root@VM-4-10-centos cert]# tree
.
|-- ca.crt
|-- ca.key
|-- ca.srl
|-- extfile.cnf
|-- server.crt
|-- server.csr
`-- server.key

0 directories, 7 files
  • 将其中自签名证书(server.crt) 拷贝到docker 客户端指定目录下
    其中【域名】为后面harbor.yml中hostname,不存在的目录需要自己逐层创建。
#创建对应的目录
[root@VM-4-10-centos cert]# mkdir -p  /etc/docker/certs.d/xx.xx.xx.xx/
#将server.crt拷贝到我们创建的目录下面
[root@VM-4-10-centos cert]# cp ca.crt /etc/docker/certs.d/xx.xx.xx.xx/
#重新启动docker
[root@VM-4-10-centos cert]# systemctl restart docker 
[root@VM-4-10-centos cert]# systemctl daemon-reload 
harbor.yaml
# 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: xx.xx.xx.xx

# 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: /etc/cert/server.crt
  private_key: /etc/cert/server.key

# # Uncomment following will enable tls communication between all harbor components
# internal_tls:
#   # set enabled to true means internal tls is enabled
#   enabled: true
#   # put your cert and key files on dir
#   dir: /etc/harbor/tls/internal
...
#此处省略

主要将修改配置文件的hostname为我们刚刚输入的和https存放证书的位置,改成我们创建存放证书目录的位置。

  • 启动harbor
./prepare      //预处理生成配置文件已经docker-compose.yml
./install		//装载并启动harbor各个容器
vim vim common/config/nginx/nginx.conf
  }
...
  include /etc/nginx/conf.d/*.server.conf;

  server {
    listen 8443 ssl;
#    server_name harbordomain.com;
    server_tokens off;
    # SSL
    ssl_certificate /etc/cert/server.crt;
    ssl_certificate_key /etc/cert/server.key;

    # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
    ssl_protocols TLSv1.2;
    ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    # disable any limits to avoid HTTP 413 for large image uploads
    client_max_body_size 0;

    # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
    chunked_transfer_encoding on;
...
/prepare
  • 登录到该harbor仓库中
[root@VM-4-10-centos harbor]# docker login https://xx.xx.xx.xx
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

遇到的问题

  • ① 提示登录的时候拒绝连接
[root@ecs-431f-0001 cmd]# docker login http://81.68.93.33 -u admin
Password: 
Error response from daemon: Get https://81.68.93.33/v2/: dial tcp 81.68.93.33:443: connect: connection refused

cat /etc/docker/daemon.json
[root@ecs-431f-0002 nginxvolume]# cat /etc/docker/daemon.json 

{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
  "insecure-registries": ["https://81.68.93.33"]

}

登录成功

二、golang使用调用harbor的api
curl
go-harborgoharbor-clien

go-harbor的使用方法

package main

import (
	
	"fmt"
	
	"github.com/TimeBye/go-harbor"
	"github.com/TimeBye/go-harbor/pkg/model"
	// legacymodel "github.com/mittwald/goharbor-client/v4/apiv2/model/legacy"
)

func main() {
// user:用户名
// pwd:密码
// url:harbor地址。或者是域名
// repo:仓库名称
// images:镜像名称
// tag:版本号
	url := "http://81.68.93.33" 
	user := "admin"
	pwd := "Harbor12345"
	repo := "anan"
	images := "busybox"
	tag := "1.0"
	Harborv2(user, pwd, url, repo, images, tag)

}

func Harborv2(user, pwd, url, repo, images, tag string) {
	// harbor:2.0
		harborClient, err := harbor.NewClientSet(url, user, pwd)
	if err != nil {
		panic(err)
	}
	query := model.Query{}

	//用户
	fmt.Println(harborClient.User.Get("1"))
	fmt.Println(harborClient.User.List(&query))
	// fmt.Println(harborClient.User.Delete("6"))

	//仓库
	// fmt.Println(harborClient.V2.Repositories("anan").Get("mysql"))
	// fmt.Println(harborClient.V2.Repositories("anan").List(&query))
	// fmt.Println(harborClient.V2.Repositories("anan").Delete("mysql"))

	//项目
	// fmt.Println(harborClient.V2.Get("15"))
	// fmt.Println(harborClient.V2.List(&query))
	// fmt.Println(harborClient.V2.Delete("11"))

	
	//制品fmt.Println(harborClient.V2.Repositories("anan").Artifacts("mysql").List(&query))
	fmt.Println(harborClient.V2.Repositories("anan").Artifacts("mysql").Get("5.7"))
	// fmt.Println(harborClient.V2.Repositories("anan").Artifacts("busybox").Delete("1.0"))
}

goharbor-client使用方法

其实goharbor-client完全可以按照harbor的swagger接口测试的方法去写,因为github中提供的内容不是很多,但是他的方法都是见名知意,很好理解。

package main

import (
	

	"fmt"
	"github.com/mittwald/goharbor-client/v4/apiv2"
	legacymodel "github.com/mittwald/goharbor-client/v4/apiv2/model/legacy"
)

func main() {
	// harbor2.0
	// url := "http://81.68.93.33"
	// user := "admin"
	// pwd := "Harbor12345"
	// repo := "anan"
	// images := "busybox"
	// tag := "1.0"
	// Harborv2(user, pwd, url, repo, images, tag)

	// harbor1.0
	// s, _ := Harborv1("admin", "12345", "http://39.106.254.42", "anan", "busybox", "1.0")
	// fmt.Println(s)

	// goharbor-client
	goharborClient()
}



func goharborClient() {
	client, err := apiv2.NewRESTClientForHost("http://81.68.93.33/api", "admin", "Harbor12345")
	if err != nil {
		panic(err)
	}
	// legacyModel := legacymodel.RegistryCredential{
	// 	AccessKey:    "",
	// 	AccessSecret: "",
	// 	Type:         "",
	// }
	// query := model.Query{}

	//用户

	//新建用户(输入密码的时候需要一个大写,一个小写,一个字母,不少于8个字符)
	// result, err := client.NewUser(context.TODO(), "anzhijie", "anzhijie@qq.com", "anzhijie", "Anzhijie123", "test")
	// if err != nil {
	// 	log.Println("创建用户错误", err)
	// }
	// fmt.Println(result)
	//    获取用户
	// fmt.Println(client.GetUser(context.Background(), "anzhijie"))
	// 获取到用户的Id
	u, _ := client.GetUser(context.TODO(), "anzhijie")
	UserId:=u.UserID
	fmt.Println(UserId)
	// 修改用户
	user := legacymodel.User{
		UserID: UserId,
		Email: "Anzj1997@163.com",
		Realname: "anzhijie",
		Comment: "第二次修改",
	}
	fmt.Println(client.UpdateUser(context.Background(), &user))
	// project
	// fmt.Println(client.GetProject(context.TODO(), "anan"))
	// fmt.Println(client.ListProjects(context.TODO(), ""))

}

其他的操作暂且写不测试 ,其实只要模仿这swagger测试即可


参考文章:https://www.freesion.com/article/16241153409/ 参考文章:https://juejin.cn/post/6997575528102232078#heading-6