1.基于角色控制: 用户和仓库都是基于项目进行组织的,而用户在项目中可以拥有不同的权限
2.基于镜像的复制策略: 镜像可以在多个Harbor实例之间进行复制(同步)
3.支持LDAP/AD: Harbor 可以集成企业内部有的AD/LDAP (类似数据库的一-张表),用于对已经存在的用户认证和管理
4.镜像删除和垃圾回收: 镜像可以被删除,也可以回收镜像占用的空间
5.图形化用户界面: 用户可以通过浏览器来浏览,搜索镜像仓库以及对项目进行管理
6.审计管理: 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理
7.支持RESTful API: RESTful API提供给管理员对于Harbor 更多的操控,使得与其它管理软件集成变得更容易
8.Harbor 和docker registry的 关系: Harbor实质 上是对docker registry做 了封装,扩展了自己的业务模板
Harbor在架构上主要有Proxy、 Registry、 Core services、 Database (Harbor-db) 、Log collector ( Harbor-log)、Job services六个组件
● Proxy: Harbor 的Registry、 UI、Token 服务等组件,都处在nginx 反向代理后边。该代理将来自浏览器、docker clients的请求转发到后端不同的服务上
● Registry:负责储存Docker 镜像,并处理Docker push/pull命令。由于要对用户进行访问控制,即不同用户对Docker 镜像有不同的读写权限,Registry 会指向一个Token 服务,强制用户的每次Docker pull/push 请求都要携带一个合法的Token,Registry会通过公钥对Token进行解密验证
● Core services: Harbor的核心功能,主要提供以下3个服务:
UI (harbor-ui) :提供图形化界面,帮助用户管理Registry. 上的镜像( image),并对用户进行授权
WebHook: 为了及时获取Registry.上image 状态变化的情况,在Registry. 上配置 Webhook,把状态变化传递给UI模块
Token 服务:负责根据用户权限给每个Docker push/pull 命令签发Token。 Docker 客户端向Registry服务发起的请求,
如果不包含Token,会被重定向到Token服务,获得Token后再重新向Registry 进行请求
● Database (harbor-db) :为core services提供数据库服务,负责储存用户权限、审计日志、Docker 镜像分组信息等数据
● Job services: 主要用于镜像复制,本地镜像可以被同步到远程Harbor 实例上
● Log collector (harbor-log) :负责收集其他组件的日志到一个地方
Harbor 的每个组件都是以 Docker 容器的形式构建的,因此,使用 Docker Compose 来对它进行部署。
总共分为7个容器运行,通过在 docker- compose.yml 所在目录中执行 docker-compose ps命令来查看, 名称分别为:nginx、 harbor-jobservice、 harbor-ui、 harbor-db、 harbor-adminserver、registry、 harbor-log。
其中 harbor-adminserver 主要是作为一个后端的配置数据管理,并没有太多的其他功能。harbor-ui 所要操作的所有数据都通过 harbor-adminserver 这样一个数据配置管理中心来完成。

Harbor服务器:192.168.10.10 docker-ce、docker-compose、harbor-offline-v1.2.2
client服务器:192.168.10.20 docker-ce
下载或者上传 Docker-Compose
curl -L https://github.com/docker/compose/releases/download/1.21.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose #下载安装包,我这里直接传入下载的安装包
chmod +x /usr/local/bin/docker-compose
docker-compose -v

(1)下载或上传 Harbor 安装程序
wget http://harbor.orientsoft.cn/harbor-1.2.2/harbor-offline-installer-v1.2.2.tgz #下载安装包,我这里是之前已经传入下载的安装包
tar zxvf harbor-offline-installer-v1.2.2.tgz -C /usr/local/


(2)修改harbor安装的配置文件
vim /usr/local/harbor/harbor.cfg
--5行--修改,设置为Harbor服务器的IP地址或者域名
hostname = 192.168.10.10
--59行--指定管理员的初始密码,默认的用户名/密码是admin/Harbor12345
harbor_admin_password = Harbor12345

关于 Harbor.cfg 配置文件中有两类参数:所需参数和可选参数
1、所需参数:这些参数需要在配置文件 Harbor.cfg 中设置。如果用户更新它们并运行 install.sh 脚本重新安装 Harbour, 参数将生效。具体参数如下:
2、可选参数:这些参数对于更新是可选的,即用户可以将其保留为默认值,并在启动 Harbor 后在 Web UI 上进行更新。如果进入 Harbor.cfg,只会在第一次启动 Harbor 时生效,随后对这些参数的更新,Harbor.cfg 将被忽略。
注意:如果选择通过 UI 设置这些参数,请确保在启动 Harbor 后立即执行此操作。具体来说,必须在注册或在 Harbor 中创建任何新用户之前设置所需的 auth_mode。当系统中有用户时(除了默认的 admin 用户), auth_mode 不能被修改。 具体参数如下:
另外,默认情况下,Harbour 将镜像存储在本地文件系统上。在生产环境中,可以考虑 使用其他存储后端而不是本地文件系统,如 S3、Openstack Swif、Ceph 等对象存储。但需要更新 common/templates/registry/config.yml 文件。
cd /usr/local/bin/harbor/
./prepare
./install.sh


cd /usr/local/bin/harbor/
docker-compose ps



(1)登录 Harbor
docker login [-u admin -p Harbor12345] http://127.0.0.1

(2)下载镜像进行测试
docker pull nginx

(3)将镜像打标签
格式:docker tag 镜像:标签 仓库IP/项目名称/镜像名:标签
docker tag nginx:latest 127.0.0.1/fzr/nginx:v1

(4)上传镜像到 Harbor
docker push 127.0.0.1/fzr/nginx:v1

(5)在 Harbor 界面 FZR 目录下可看见此镜像及相关信息

以上操作都是在 Harbor 服务器本地操作。如果其他客户端登录到 Harbor,就会报如下错误。出现这问题的原因为Docker Registry 交互默认使用的是 HTTPS,但是搭建私有镜像默认使用的是 HTTP 服务,所以与私有镜像交互时出现以下错误。(192.168.10.20)
docker login -u admin -p Harbor12345 http://192.168.10.10
解决办法是:在 Docker server 启动的时候,增加启动参数,默认使用 HTTP 访问。
解决办法是:
第一种:在Docker server启动的时候,增加启动参数,默认使用 HTTP 访问。
vim /usr/lib/systemd/system/docker.service
--13行--修改
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 192.168.10.10 --containerd=/run/containerd/containerd.sock
或
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.10.10
第二种:vim /etc/ docker/daemon.json
{
"insecure-registries": ["192.168.10.10"],
#添加,注意用逗号结尾
"registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"]
}


(1)重启 Docker,再次登录
systemctl daemon-reload
systemctl restart docker
docker login -u admin -p Harbor12345 http://192.168.10.10

将自动保存凭据到/root/.docker/config.json,下次登录时可直接使用凭据登录 Harbor
(2)下载镜像进行测试
docker pull 192.168.10.10/fzr/nginx:v1

(3)上传镜像进行测试
docker pull cirros
docker tag cirros:latest 192.168.10.10/fzr/cirros:v2
docker push 192.168.10.10/fzr/cirros:v2


在 Harbor 仓库中,任何镜像在被 push 到 regsitry 之前都必须有一个自己所属的项目。
单击“+项目”,填写项目名称,项目级别若设置为"私有",则不勾选。如果设置为公共仓库,则所有人对此项目下的镜像拥有读权限,命令行中不需要执行"Docker login"即可下载镜像,镜像操作与 Docker Hub 一致。





(1)创建用户并分配权限
在 Web 管理界面中单击系统管理 -> 用户管理 -> +用户,
填写用户名为“feizirui”,邮箱为“feizirui@qq.com”,全名为“feizirui”,密码为“Feizirui12345”,注释为“管理员”(可省略)。
附:用户创建成功后,单击左侧“...”按钮可将上述创建的用户设置为管理员角色或进行删除操作,本例不作任何设置。


(2)添加项目成员
单击项目 ->fzr-> 成员 -> + 成员,填写上述创建的用户zhangsan并分配角色为“开发人员”。
附:此时单击左侧“...”按钮仍然可对成员角色进行变更或者删除操作


(3)在客户端上使用普通账户操作镜像
删除上述打标签的本地镜像
docker rmi 192.168.10.10/fzr/cirros:v2

先退出当前用户,然后使用上述创建的账户feizirui 登录

下载和上传镜像进行测试
docker pull 192.168.10.10/fzr/cirros:v2
docker tag cirros:latest 192.168.10.10/fzr/cirros:v3
docker push 192.168.10.10/fzr/cirros:v3

Web 界面日志,操作日志按时间顺序记录用户相关操作

要更改 Harbour的配置文件中的可选参数时,请先停止现有的 Harbor实例并更新 Harbor.cfg;然后运行 prepare 脚本来填充配置; 最后重新创建并启动 Harbour 的实例。
使用 docker-compose 管理 Harbor 时,必须在与 docker-compose.yml 相同的目录中运行。
cd /usr/local/harbor
docker-compose down -v
vim harbor.cfg #只能修改可选参数
./prepare
docker-compose up -d
//如果有以下报错,需要开启防火墙 firewalld 服务解决
Creating network "harbor_harbor" with the default driver
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-b53c314f45e8 -j RETURN: iptables: No chain/target/match by that name.
(exit status 1))
systemctl restart firewalld.service
docker-compose up -d



在Harbor服务器上操作
(1)移除 Harbor 服务容器
cd /usr/local/harbor
docker-compose down -v

(2)把项目中的镜像数据进行打包
持久数据,如镜像,数据库等在宿主机的/data/目录下,日志在宿主机的/var/log/harbor/目录下
ls /data/registry/docker/registry/v2/repositories/ly
cd /data/registry/docker/registry/v2/repositories/ly
tar zcvf ly.tar.gz ./*



cd /usr/local/harbor
docker-compose down -v
rm -r /data/database
rm -r /data/registry




再次关闭服务并开启服务,然后在查看web界面


类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案
我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是
来自Java,我正在尝试在Ruby中实现LinkedList。我在Java中实现它的通常方法是有一个名为LinkedList的类和一个名为Node的私有(private)内部类,其中LinkedList的每个对象都作为Node对象。classLinkedListprivateclassNodeattr_accessor:val,:nextendend我不想将Node类暴露给外部世界。然而,通过Ruby中的这个设置,我可以使用这个访问LinkedList类之外的私有(private)Node类对象-node=LinkedList::Node.new我知道,在Ruby1.9中,我们可以使用
您好,我正在尝试创建一个帮助程序,用于将ruby方法大量定义为私有(private)类方法。通常,可以通过使用private_class_method键工作将方法定义为私有(private)类方法。但我想创建一个以下样式的助手:classPersondefine_private_class_methodsdodefmethod_oneenddefmethod_twoendendend我计划通过以下方式动态定义它,但根本不起作用:classObjectdefself.define_private_class_methods&blockinstance_evaldoprivate&bl
在另一个对象中注册该对象后,我需要将一些实例方法设为私有(private)。我不想卡住对象,因为它必须保持可编辑状态,只是功能较少。而且我不想取消定义这些方法,因为它们是在内部使用的。我需要的是这样的:classMyClassdefmy_methodputs"Hello"endenda=MyClass.newb=MyClass.newa.my_method#=>"Hello"a.private_instance_method(:my_method)a.my_method#=>NoMethodErrorb.my_method#=>"Hello"有什么想法吗?
最好用一个例子来解释:文件1.rb:deffooputs123end文件2.rb:classArequire'file1'endA.new.foo将给出错误“':调用了私有(private)方法'foo'”。我可以通过执行A.new.send("foo")来解决这个问题,但是有没有办法公开导入的方法?编辑:澄清一下,我没有混淆include和require。另外,我不能使用正常包含的原因(正如许多人正确指出的那样)是因为这是元编程设置的一部分。我需要允许用户在运行时添加功能;例如,他可以说“run-this-app--includefile1.rb”,应用程序的行为将根据他在file1
我正在尝试使用docker运行一个Rails应用程序。通过github的sshurl安装的gem很少,如下所示:Gemfilegem'swagger-docs',:git=>'git@github.com:xyz/swagger-docs.git',:branch=>'my_branch'我在docker中添加了keys,它能够克隆所需的repo并从git安装gem。DockerfileRUNmkdir-p/root/.sshCOPY./id_rsa/root/.ssh/id_rsaRUNchmod700/root/.ssh/id_rsaRUNssh-keygen-f/root/.ss