文章目录
- 一、docker-compose
- 1. 下载 Docker Compose:
- 2.添加执行权限:
- 3.验证安装
- 二、安装harbor 2.0
- 1.下载harbor离线包
- 2. 根据需求配置 Harbor
- 3.给harbor创建SSL证书
- 4.预编译harbor
- 5. 安装并启动 Harbor (必须到你安装的目录)
- 三、登录harbor的web页面
- 四、harbor的启动和停止
- 五、harbor的使用
- 六、 探索工厂模式:如何优化Harbor项目管理与API集成
- 步骤1:创建Harbor服务和工厂类
- Harbor服务类 HarborService.java
- Harbor应用工厂类 HarborApplicationFactory.java
- 步骤2:Harbor客户端工厂和API请求类
- Harbor客户端工厂类 HarborClientFactory.java
- Harbor 2.0.x版本客户端工厂类 HarborClientFactory20X.java
- 步骤3:HarBorControlle
一、docker-compose
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它通过一个配置文件(通常是 docker-compose.yml)来定义应用的服务、网络和卷,并使这些服务能够在单个命令中启动和停止 。
在实际生产环境中,一个应用往往由许多服务构成,而 docker 的最佳实践是一个容器只运行一个进程,因此运行多个微服务就要运行多个容器。多个容器协同工作需要一个有效的工具来管理他们,定义这些容器如何相互关联。compose 应运而生。compose 是用来定义和运行一个或多个容器(通常都是多个)运行和应用的工具。使用 compose 可以简化容器镜像的构建以及容器的运行。compose 使用 YAML 文件来定义多容器之间的关系。一个 docker-compose up 就可以把完整的应用跑起来。 本质上, compose 把 YAML 文件解析成 docker 命令的参数,然后调用相应的 docker 命令行接口,从而将应用以容器化的方式管理起来。它通过解析容器间的依赖关系顺序地启动容器。而容器间的依赖关系由 YAML 文件中的 links 标记指定。
1. 下载 Docker Compose:
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
这条命令会将 Docker Compose 下载并保存到 /usr/local/bin/docker-compose。
2.添加执行权限:
sudo chmod +x /usr/local/bin/docker-compose
3.验证安装
docker-compose --version
docker-compose version 1.29.2, build 5becea4c
二、安装harbor 2.0
Harbor是一个开源的企业级Docker Registry,用于存储和分发Docker镜像。它提供了一些额外的安全、身份验证和管理功能,使得在企业环境中更容易管理Docker镜像。您可以通过Harbor来管理镜像的存储、访问控制、安全扫描和复制等功能。
1.下载harbor离线包
可以去https://github.com/goharbor/harbor/releases找到合适的版本下载,或者直接使用这个地址https://github.com/goharbor/harbor/releases/download/v2.0.0/harbor-offline-installer-v2.0.0.tgz 点击它下载下来再传到centos上。
或者直接在centos上使用命令下
wget -P /usr/local/src/ https://github.com/goharbor/harbor/releases/download/v2.0.0/harbor-offline-installer-v2.0.0.tgz
下载完成后将包上传到服务器的/root/app目录。(你想下载到哪里就放在哪个目录下)
[root@localhost app]# tar -zxvf harbor-offline-installer-v2.0.0.tgz
harbor/harbor.v2.0.0.tar.gz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl
[root@localhost app]# ll
总用量 488972
drwxr-xr-x. 2 root root 122 7月 2 11:28 harbor
-rw-r--r--. 1 root root 500705880 6月 24 09:51 harbor-offline-installer-v2.0.0.tgz
2. 根据需求配置 Harbor
解压成功之后进入到harbor目录:
[root@localhost app]# cd harbor
[root@localhost harbor]# cp harbor.yml.tmpl harbor.yml
[root@localhost harbor]# vim harbor.yml
注释:
● hostname写上你要访问的harbor的地址当主机名。
● certificate和private_key是支持HTTPS访问的证书的路径,文件名最好和主机名对应,便于记忆。
● harbor_admin_password是默认的harbor登录的密码
● database-password我猜是默认的harbor数据库密码,默认的是root123,建议改掉。
● data_volume 是数据默认存放目录,即harbor的docker持久化目录默认放在了/data下
或者创建一个
cat > /root/app/harbor/harbor.yml <<EOF
hostname: 192.168.235.130
http:
port: 80
https:
port: 443
certificate: /root/app/harbor/certs/192.168.235.130.crt
private_key: /root/app/harbor/certs/192.168.235.130.key
harbor_admin_password: Harbor12345
database:
password: harbor123db
max_idle_conns: 50
max_open_conns: 100
data_volume: /data
clair:
updaters_interval: 12
trivy:
ignore_unfixed: false
skip_update: false
insecure: false
jobservice:
max_job_workers: 10
notification:
webhook_job_max_retry: 10
chart:
absolute_url: disabled
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
_version: 2.0.0
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- clair
- trivy
EOF
3.给harbor创建SSL证书
没有创建证书的话会502错误
- 安装openssl证书工具
yum install -y openssl
- 创建证书存放文件夹
[root@localhost harbor]# mkdir certs
[root@localhost harbor]# cd certs/
- 生成无加密的根证书私钥(注意一定要进到证书目录)
[root@localhost certs]# openssl genrsa -out ca.key 4096
Generating RSA private key, 4096 bit long modulus
..................................................................++
.......................................++
e is 65537 (0x10001)
使用刚才生成的私钥制作自签名证书(将这里的192.168.235.130替换成你的域名即可)
[root@localhost certs]# openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=192.168.235.130/OU=192.168.235.130/CN=192.168.235.130" -key ca.key -out ca.crt
[root@localhost certs]# ls
ca.crt ca.key
生成服务器端自己域名的key(将这里的192.168.235.130替换成你的域名即可)
[root@localhost certs]# openssl genrsa -out 192.168.235.130.key 4096
Generating RSA private key, 4096 bit long modulus
.................................................................................................................................................................................................................++
...............................................................++
e is 65537 (0x10001)
生成服务器端自己域名的CSR签名请求(将这里的192.168.235.130替换成你的域名即可)
openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=harbor.hiibm.com/OU=192.168.235.130/CN=192.168.235.130" -key 192.168.235.130.key -out 192.168.235.130.csr
生成一个 openssl 命令需要的外部配置文件 xexternalfile.ext(将这里的192.168.235.130替换成你的域名即可)
cat > xexternalfile.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=192.168.235.130
EOF
通过外部配置文件 xexternalfile.ext和 csr 生成 crt(将这里的192.168.235.130替换成你的域名即可)
openssl x509 -req -sha512 -days 3650 -extfile xexternalfile.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in 192.168.235.130.csr -out 192.168.235.130.crt
将服务端的 crt 转换成客户端用的 cert(将这里的192.168.235.130替换成你的域名即可)
openssl x509 -inform PEM -in 192.168.235.130.crt -out 192.168.235.130.cert
4.预编译harbor
cd /root/app/harbor
./prepare
5. 安装并启动 Harbor (必须到你安装的目录)
cd /root/app/harbor
./install.sh
直到看到[✔ ----Harbor has been installed and started successfully.----]才说明harbor安装成功了。
6.查看docker进程,看harbor是否安装成功
docker ps
看到一堆包含harbor的docker ps进程
-至此,harbor2.0就安装完成了。
三、登录harbor的web页面
**1. 打开浏览器,访问 http://,使用配置文件中设置的管理员账户(默认用户名为 admin,密码为 Harbor12345)登录到 Harbor 的 Web 界面。 **
至此,harbor就彻底安装完成了。
四、harbor的启动和停止
cd /root/app/harbor
#停止harbor
docker-compose -f docker-compose.yml down
#启动harbor
docker-compose -f docker-compose.yml up -d
五、harbor的使用
- 登录Harbor管理界面后,您可以创建项目(Project),用于组织和管理Docker镜像。
- 设置项目的访问权限和成员,可以控制谁可以查看、上传和管理镜像
# 登录 用户名密码 admin/Harbor12345
docker login -u admin -p Harbor12345 192.168.235.130
# 给本地镜像打tag,命令格式如下
docker tag [ImageId] [harbor域名]/[项目名]/[REPOSITORY]:[TAG]
# 上传镜像
docker push [harbor域名]/[项目名]/[REPOSITORY]:[TAG]
eg: docker push 192.168.235.130/wise2c/wisebuild-frontend:harbor-db-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:clair-adapter-photon-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:clair-photon-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:notary-server-photon-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:notary-signer-photon-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:harbor-registryctl-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:registry-photon-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:nginx-photon-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:harbor-log-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:harbor-jobservice-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:harbor-core-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:harbor-portal-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:harbor-db-v2.0.0
docker push 192.168.235.130/wise2c/wisebuild-frontend:prepare-v2.0.0
查看一下 推送成功
点击复制图标 复制拉取命令
docker pull 192.168.235.130/wise2c/wisebuild-frontend@sha256:485c21b2cfb96d0213ff1f9a99fe751179078290c6709d247a6e4abf0781fd93
用户管理:
LDAP集成和OIDC支持:可以集成LDAP或OIDC,管理和认证用户身份。
角色和权限管理:管理用户的角色和权限,以控制其对Harbor功能和资源的访问权限。
仓库管理:
项目和命名空间:创建和管理项目,将镜像组织到命名空间中,便于管理和访问控制。
镜像版本管理:管理镜像的不同版本和标签,支持版本控制和历史记录。
镜像复制:
复制策略:配置镜像复制策略,将镜像同步复制到多个Harbor实例或外部Registry,以提高可用性和冗余性。
标签管理:
标签策略:定义标签策略,管理和限制镜像标签的使用,以维护镜像的一致性和安全性。
项目定额:
资源配额:为每个项目设置资源配额,限制项目可以使用的存储空间和计算资源,以控制资源的分配和使用。
审查服务:
安全扫描服务:集成安全扫描工具,对上传的镜像进行漏洞扫描,并提供漏洞报告和建议修复措施。
垃圾清理:
镜像清理策略:配置镜像保留策略和垃圾清理任务,定期清理过期和未使用的镜像,以节省存储空间并优化性能。
配置管理:
系统配置:管理Harbor的全局设置,包括网络配置、存储后端、SSL证书、日志配置等,以定制化和优化Harbor的运行环境。
六、 探索工厂模式:如何优化Harbor项目管理与API集成
在这个教程中,我们将演示如何使用Java编写代码来访问Harbor的API,并获取特定项目的详细信息。我们将使用Harbor的REST API和Java的HttpClient库进行示例代码编写。
准备工作
- 环境要求:
Java开发环境(JDK 8或更高版本)
Maven或Gradle(用于管理依赖)
- Harbor实例:
确保您有一个运行中的Harbor实例,并已知道其地址、用户名和密码。
- harbor数据库设计
工厂模式概述
工厂模式是一种常见的创建型设计模式,旨在封装对象的创建过程,使得客户端无需关心具体对象的实例化细节。通过工厂模式,我们可以集中管理对象的创建逻辑,并通过统一的接口或方法提供对象实例。
实例分析:Harbor项目管理与API集成
在我们的实例中,我们使用了工厂模式来优化Harbor项目的管理和API集成。具体实现如下:
步骤1:创建Harbor服务和工厂类
首先,我们需要创建一些Java类来管理与Harbor的交互。
Harbor服务类 HarborService.java
import java.util.Optional;
public class HarborService {
// 根据ID获取Harbor实例
public Optional<Harbor> harbor(long id) {
return repository.findById(id); // 假设repository已定义并实现了findById方法
}
// 根据Harbor实例ID和项目ID获取项目详细信息
public Optional<HarborProject> project(long id, int projectId) {
Optional<Harbor> harbor = harbor(id);
if (harbor.isPresent()) {
HarborClientFactory clientFactory = HarborApplicationFactory.getHarborClientFactory(harbor.get());
return Optional.ofNullable(clientFactory.project(projectId));
}
return Optional.empty();
}
}
Harbor应用工厂类 HarborApplicationFactory.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HarborApplicationFactory {
private static final Logger logger = LoggerFactory.getLogger(HarborApplicationFactory.class);
// 根据Harbor版本返回对应的HarborClientFactory实例
public static HarborClientFactory getHarborClientFactory(Harbor harbor) {
if (harbor.getVersion().contains("v1.7") || harbor.getVersion().contains("v1.10")) {
return new HarborClientFactory10X(harbor.getAddress(), harbor.getUsername(), harbor.getPassword());
}
if (harbor.getVersion().contains("v2.0") || harbor.getVersion().contains("v2.10")) {
return new HarborClientFactory20X(harbor.getAddress(), harbor.getUsername(), harbor.getPassword());
}
throw new BizRuntimeException(String.format("当前Harbor版本[%s]不支持", harbor.getVersion()));
}
}
步骤2:Harbor客户端工厂和API请求类
接下来,我们将创建Harbor客户端工厂和API请求类,用于实际调用Harbor的REST API。
Harbor客户端工厂类 HarborClientFactory.java
public abstract class HarborClientFactory {
protected final String address;
protected final String username;
protected final String password;
public HarborClientFactory(String address, String username, String password) {
this.address = address;
this.username = username;
this.password = password;
}
// 定义获取项目详情的抽象方法
public abstract HarborProject project(long proID);
}
Harbor 2.0.x版本客户端工厂类 HarborClientFactory20X.java
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HarborClientFactory20X extends HarborClientFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(HarborClientFactory20X.class);
private static final String PROJECT_PATH_DEFAULT = "/api/v2.0/projects";
public HarborClientFactory20X(String address, String username, String password) {
super(address, username, password);
}
@Override
public HarborProject project(long proID) {
TrustSslUtil.initDefaultSsl(); // 忽略SSL验证,仅用于本地测试环境
HarborProject project = new HarborProject();
String url = address + PROJECT_PATH_DEFAULT + "/" + proID;
ResponseEntity<Project> response;
try {
RestTemplate restTemplate = new RestTemplate();
response = restTemplate.getForEntity(url, Project.class);
} catch (HttpClientErrorException e) {
if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
throw new BizRuntimeException(String.format("未找到项目[%d]", proID));
}
throw new BizRuntimeException(String.format("获取项目[%d]失败: %s", proID, e.getMessage()));
}
// 将API响应映射到HarborProject对象
Project projectResponse = response.getBody();
if (projectResponse != null) {
BeanUtils.copyProperties(projectResponse, project);
project.setDeleted(projectResponse.getDeleted() != null && projectResponse.getDeleted());
project.setBublic(projectResponse.getMetadata().isPublicX());
}
return project;
}
}
应用工厂模式的好处包括但不限于:
- 封装对象创建逻辑:将具体的对象实例化过程封装在工厂类中,客户端无需了解具体的实现细节。
- 简化对象的创建和管理:通过统一的接口或方法,简化了对象的创建和管理过程,提高了代码的灵活性和可维护性。
- 支持多版本和扩展性:通过工厂模式,可以根据不同的需求或版本,选择合适的对象实例化方式,支持系统的扩展和升级。
public class HarborProject implements Serializable {
@JsonProperty("project_id")
private int projectId;
@JsonProperty("owner_id")
private int ownerId;
@JsonProperty("name")
private String name;
@JsonProperty("creation_time")
private Date creationTime;
@JsonProperty("update_time")
private Date updateTime;
@JsonProperty("deleted")
private int deleted;
@JsonProperty("owner_name")
private String ownerName;
@JsonProperty("public")
private int bublic;
@JsonProperty("current_user_role_id")
private int currentUserRoleId;
@JsonProperty("repo_count")
private int repoCount;
@JsonProperty("metadata")
private HarborAuthority metadata;
private Long tenantId;
private String tenantName;
}
步骤3:HarBorControlle
@RestController
@RequestMapping("/api/harbors")
public class HarborController {
private static final Logger logger = LoggerFactory.getLogger(HarborController.class);
private final HarborService harborService;
@Autowired
public HarborController(HarborService harborService) {
this.harborService = harborService;
}
@GetMapping("/{id}/projects/{projectId}")
@ApiOperation(value = "查询Harbor实例下的项目", tags = "Harbor")
public Serializable getHarborProject(@PathVariable("id") long id, @PathVariable("projectId") int projectId) {
Optional<HarborProject> project = harborService.project(id, projectId);
if (!project.isPresent()) {
return BizErrorType.RESOURCE_NOT_FOUND;
}
return project.get();
}
}
BizErrorType 错误类型定义
public enum BizErrorType {
RESOURCE_NOT_FOUND("12000001", "请求资源未找到"),
}
TrustSslUtil 忽略ssl工具类
package com.wise2c.biz.util;
import javax.net.ssl.*;
import java.net.Socket;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
/**
* 忽略证书验证
*/
public class TrustSslUtil {
public static void initDefaultSsl() {
try {
SSLContext sc = SSLContext.getInstance("SSL");
HostnameVerifier hv = (urlHostName, session) -> true;
TrustManager[] trustAllCerts = new TrustManager[]{
new X509ExtendedTrustManager() {
@Override
public void checkClientTrusted(X509Certificate[]
x509Certificates, String s) {
}
@Override
public void checkServerTrusted(X509Certificate[]
x509Certificates, String s) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[]
x509Certificates, String s, Socket socket) {
}
@Override
public void checkServerTrusted(X509Certificate[]
x509Certificates, String s, Socket socket) {
}
@Override
public void checkClientTrusted(X509Certificate[]
x509Certificates, String s, SSLEngine sslEngine) {
}
@Override
public void checkServerTrusted(X509Certificate[]
x509Certificates, String s, SSLEngine sslEngine) {
}
}};
sc.init(null, trustAllCerts, new SecureRandom());
SSLContext.setDefault(sc);
HttpsURLConnection.setDefaultHostnameVerifier(hv);
} catch (Exception e) {
e.printStackTrace();
}
}
}