搭建一个高可用的镜像仓库,这是我见过最详细、最简单的教程

22b9686373616396c121a53fcc425216.gif

作者 | 小碗汤

来源 | 我的小碗汤

今天分享一篇搭建一个高可用镜像仓库的教程。详细中夹杂着简单~。

Harbor 部署架构图

821f3c89f662478f1e2f10c216116d1d.png

  • harbor 使用 helm 部署在 k8s 集群中,通过 ingress-nginx 代理。

  • pgsql 采用 Pgpool-II 代理,做主从切换、通过同步流式复制进行数据复制,客户端请求通过 Pgpool-II 路由。

  • pgpool 无状态部署在 k8s 集群中。

  • pgsql 主从实例部署在集群外虚拟机上。

  • redis 哨兵模式部署在集群外虚拟机上。

这里假设示例主机信息如下

  • VM1:172.0.0.1

  • VM2:172.0.0.2

  • VM3:172.0.0.3

版本信息

  • harbor-helm 1.5.0

  • harbor 2.1.0

  • redis 4.0.12

  • Pgsql 9.6.16

  • Pgpool 4.2.6

harbor-helm 1.5.0 chart 包自带的 harbor 版本为 2.1.0

Redis

Redis 为哨兵模式,架构图如下:

42855897ff4fccbf7b8ad945bdd2d642.png

Redis 实例拓扑分布:

f9aac5e72a79bf184c5292cc04679888.png

至于 Redis 集群在虚拟机上的部署,我使用的是Cymbal 项目[1]

Cymbal 秉承开箱即用的原则,整个部署过程十分简单,最小化版本只需要一个 runnable jar 及 mysql 服务的支持即可。

Cymbal 是当当网架构部孵化并开源的 Redis PaaS 平台,基于 Spring Boot2 开发。目标是帮助技术团队以简单,低成本的方式管理大规模 Redis 集群。目前当当网内部使用 Cymbal 管理的 Redis 实例数量达到 1000+。

Cymbal 采用 DevOps 的设计思想,以多租户的方式,最大程度上赋予开发人员运维权限,从而加快团队运转。同时,Cymbal 上面集成了丰富的运维功能:从监控、报警到在线扩缩容等,力求最大程度上消除运维门槛。

假设用 Cymbal 部署之后 redis 哨兵信息如下:172.0.0.1:9381,172.0.0.2:9381,172.0.0.3:9381

哨兵 Master 为: mymaster-EC4Fy7DJ

密码为: harborpwd

下面会用到这些信息。

Pgsql

基于 PGpool 中间件实现 postgresql 一主一从集群部署,架构图实例如下:

8aae085f6023893bfd848f4d841820b2.png

PGPool、Pgsql 实例拓扑分布:

55802989b387d2937494efd387a51247.png

Pgpool 在 k8s 集群中多实例部署,Pgsql 主从实例在虚拟机中用 docker 容器启动。

docker 部署 pgsql

在虚拟机上直接部署 pgsql 集群在时间成本上,还是不太容易的。我们这里使用 docker 去管理,会轻松一点。

创建 volume,由于复制管理器映像的 PostgreSQL 是非 root 用户,因此您还需要为主机中的挂载目录设置适当的权限:

# 主实例
# docker volume create pg-0
# chgrp -R root /var/lib/docker/volumes/pg-0
# chmod -R g+rwX /var/lib/docker/volumes/pg-0
# 从实例
# docker volume create pg-1
# chgrp -R root /var/lib/docker/volumes/pg-1
# chmod -R g+rwX /var/lib/docker/volumes/pg-1

我们这里将主从部署在不同的主机上,所以两组命令应该在两台主机上执行。从而保证不同时挂掉。

启动 pgsql 实例的脚本:

#!/bin/bashset -o errexitnode=$1
if [[ -z "${node}" ]]; thenecho "Error: need node argument, example: pg-0"exit -1
fiexistUp=$(docker ps -f name=${node} -q)if [[ -n "${existUp}" ]]; then# nothingecho "node: ${node} is Up"exit 0
fiexistNotUp=$(docker ps -a -f name=${node} -q)if [[ -n "${existNotUp}" ]]; then# startecho "node: ${node} is not Up, will start it"docker start ${existNotUp}exit 0
fi# create
docker run --detach --name ${node} \
--network host \
--env REPMGR_PARTNER_NODES=pg-0,pg-1 \
--env REPMGR_NODE_NAME=${node} \
--env REPMGR_NODE_NETWORK_NAME=${node} \
--env REPMGR_PRIMARY_HOST=${node} \
--env REPMGR_USERNAME=repmgrharbor \
--env REPMGR_PASSWORD=repmgrpwd \
--env POSTGRESQL_POSTGRES_PASSWORD=pgpwd \
--env POSTGRESQL_USERNAME=pgharbor \
--env POSTGRESQL_PASSWORD=pgpwd \
--env POSTGRESQL_DATABASE=pgharbor \
--env BITNAMI_DEBUG=true \
--env TZ=Asia/Shanghai \
-v ${node}:/bitnami/postgresql \
-v /neworiental/pgsql/custom-conf/:/bitnami/repmgr/conf/ \
bitnami/postgresql-repmgr:9.6.16

启动时,用:

# start-pg.sh {容器名}

容器名为 pg-0(主)或者 pg-1(从)。

pgsql 挂掉自启动

docker 容器挂掉后,用 crontab 保证容器可以重新启动,30s 为间隔去执行 start-pg.sh 脚本。

执行 crontab -e 在最后新增以下内容,然后:wq 保存退出即可:

# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * *              /pgsql/start-pg.sh pg-1
* * * * * ( sleep 30 ; /pgsql/start-pg.sh pg-1 )

创建 Pgpool

apiVersion: apps/v1
kind: Deployment
metadata:labels:app.kubernetes.io/component: pgpoolapp.kubernetes.io/instance: pgsqlapp.kubernetes.io/managed-by: Helmapp.kubernetes.io/name: postgresql-ha-dochelm.sh/chart: postgresql-ha-8.0.2name: pgpool-for-docker-dp-pgsqlnamespace: harbor
spec:progressDeadlineSeconds: 600replicas: 2revisionHistoryLimit: 10selector:matchLabels:app.kubernetes.io/component: pgpoolapp.kubernetes.io/instance: pgsqlapp.kubernetes.io/name: postgresql-ha-docstrategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatetemplate:metadata:creationTimestamp: nulllabels:app.kubernetes.io/component: pgpoolapp.kubernetes.io/instance: pgsqlapp.kubernetes.io/managed-by: Helmapp.kubernetes.io/name: postgresql-ha-dochelm.sh/chart: postgresql-ha-8.0.2spec:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- topologyKey: kubernetes.io/hostnamelabelSelector:matchLabels:app.kubernetes.io/component: pgpoolapp.kubernetes.io/instance: pgsqlcontainers:- env:- name: BITNAMI_DEBUGvalue: "false"- name: PGPOOL_BACKEND_NODESvalue: 0:172.0.0.1:5432,1:172.0.0.2:5432,- name: PGPOOL_SR_CHECK_USERvalue: repmgrharbor- name: PGPOOL_SR_CHECK_PASSWORDvalue: repmgrpwd- name: PGPOOL_SR_CHECK_DATABASEvalue: postgres- name: PGPOOL_ENABLE_LDAPvalue: "no"- name: PGPOOL_POSTGRES_USERNAMEvalue: pgharbor- name: PGPOOL_POSTGRES_PASSWORDvalue: pgpwd- name: PGPOOL_ADMIN_USERNAMEvalue: pgpooladmin- name: PGPOOL_ADMIN_PASSWORDvalue: pgpoolpwd- name: PGPOOL_ENABLE_LOAD_BALANCINGvalue: "yes"- name: PGPOOL_DISABLE_LOAD_BALANCE_ON_WRITEvalue: transaction- name: PGPOOL_ENABLE_LOG_CONNECTIONSvalue: "no"- name: PGPOOL_ENABLE_LOG_HOSTNAMEvalue: "yes"- name: PGPOOL_ENABLE_LOG_PER_NODE_STATEMENTvalue: "no"- name: PGPOOL_CHILD_LIFE_TIME- name: PGPOOL_ENABLE_TLSvalue: "no"image: docker.io/bitnami/pgpool:4.2.6-debian-10-r7imagePullPolicy: IfNotPresentlivenessProbe:exec:command:- /opt/bitnami/scripts/pgpool/healthcheck.shfailureThreshold: 5initialDelaySeconds: 30periodSeconds: 10successThreshold: 1timeoutSeconds: 5name: pgpoolports:- containerPort: 5432name: postgresqlprotocol: TCPreadinessProbe:exec:command:- bash- -ec- PGPASSWORD=${PGPOOL_POSTGRES_PASSWORD} psql -U "pgharbor" -d "pgharbor"-h /opt/bitnami/pgpool/tmp -tA -c "SELECT 1" >/dev/nullfailureThreshold: 5initialDelaySeconds: 5periodSeconds: 5successThreshold: 1timeoutSeconds: 5resources: {}securityContext:runAsUser: 1001terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext:fsGroup: 1001terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: pgpoolapp.kubernetes.io/instance: pgsqlapp.kubernetes.io/managed-by: Helmapp.kubernetes.io/name: postgresql-ha-dochelm.sh/chart: postgresql-ha-8.0.2name: pgpool-for-docker-dp-pgsqlnamespace: harbor
spec:ports:- name: postgresqlport: 5432protocol: TCPtargetPort: postgresqlselector:app.kubernetes.io/component: pgpoolapp.kubernetes.io/instance: pgsqlapp.kubernetes.io/name: postgresql-ha-docsessionAffinity: Nonetype: ClusterIP

直接kubectl apply以上 yaml 即可。


连接 pgsql 手动创库

harbor 对接外部 pgsql 时,需要提前创建库,所以手动创建以下四个 database(一般 DBA 来做这件事), 可以直接连接 pgsql 主实例,也可以通过 Pgpool 连接:

# PGPASSWORD=pgpwd psql -h localhost -p 5432 -U pgharbor -d pgharbor
pgharbor=> CREATE DATABASE registry ENCODING 'UTF8';
pgharbor=> CREATE DATABASE notary_signer ENCODING 'UTF8';
pgharbor=> CREATE DATABASE notary_server ENCODING 'UTF8';
pgharbor=> CREATE DATABASE clair ENCODING 'UTF8';

harbor 物料

harbor-helm 仓库[2]

部署 harbor

下载 harbor-helm 包:

# wget https://github.com/goharbor/harbor-helm/archive/refs/tags/v1.5.0.tar.gz
# tar -zxf v1.5.0.tar.gz
# cd harbor-helm-1.5.0# 创建ns
kubectl create ns harbor

创建域名证书 Secret,这里需要用到你的域名证书。

kubectl  create secret tls harbor-ingress -n harbor --cert=./product.cn.pem --key=./product.cn.key

如果没有域名证书,也可以使用自动生成证书,下面会讲到。

修改 values.yaml 中以下内容:

expose:type: ingresstls:enabled: truecertSource: secretsecret:# The name of secret which contains keys named:# "tls.crt" - the certificate# "tls.key" - the private keysecretName: "harbor-ingress"ingress:hosts:core: harbor-pro.kubeinfo.cncontroller: defaultannotations:ingress.kubernetes.io/ssl-redirect: "true"ingress.kubernetes.io/proxy-body-size: "0"nginx.ingress.kubernetes.io/ssl-redirect: "true"nginx.ingress.kubernetes.io/proxy-body-size: "0"
# If Harbor is deployed behind the proxy, set it as the URL of proxy
externalURL: https://harbor-pro.kubeinfo.cn
# The initial password of Harbor admin. Change it from portal after launching Harbor
harborAdminPassword: "Harbor678901"persistence:enabled: trueresourcePolicy: "keep"persistentVolumeClaim:registry:storageClass: "cephfs"accessMode: ReadWriteManysize: 200Gi
notary:enabled: false
database:# if external database is used, set "type" to "external"# and fill the connection informations in "external" sectiontype: externalexternal:host: "pgpool-for-docker-dp-pgsql.harbor.svc.cluster.local"port: "5432"username: "pgharbor"password: "pgpwd"maxOpenConns: 1000redis:# if external Redis is used, set "type" to "external"# and fill the connection informations in "external" sectiontype: externalexternal:# support redis, redis+sentinel# addr for redis: <host_redis>:<port_redis># addr for redis+sentinel: <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3>addr: "172.0.0.1:9381,172.0.0.2:9381,172.0.0.3:9381"# The name of the set of Redis instances to monitor, it must be set to support redis+sentinelsentinelMasterSet: "mymaster-EC4Fy7DJ"password: "harborpwd"
  • values.yaml 中的域名修改为自己的域名,这里用到的是 harbor-pro.kubeinfo.cn

  • expose.tls.certSource 可以为 auto,即 chart 包会自动生成证书,我们这里用 secret

  • 域名对应的证书 secret 名,这里为 harbor-ingress,即上面创建的

  • 外部 redis 信息

  • 外部 pgsql 信息,这里连接到集群内 pgpool 的域名

  • storageClass 这里用 Rook 部署的 ceph 集群的文件存储,修改为 cephfs

  • harbor 密码自定义

安装 harbor

helm install pro -n harbor -f values.yaml .

正常情况,一段时间后,harbor 会启动成功,我们访问harbor 域名[3]即可看到 harbor 的界面。

升级

如果修改了 values.yaml 后,执行升级:

helm upgrade pro -n harbor -f values.yaml .

卸载

helm uninstall pro -n harbor

4f33b8b1e0bf4592effad4fdf8135035.gif

29087bde02d00abe45d44d1d318c2d2b.png

往期推荐

性能提升一个数量级,大杀器来了!

k8s集群居然可以图形化安装了?

用了HTTPS,没想到还是被监控了

快速搭建实验环境:使用 Terraform 部署 Proxmox 虚拟机

93aa8fd44b81b637f4f7f8cab266e322.gif

点分享

35624886ec90e42a56b3924b263c0c80.gif

点收藏

f6992ad1fa09b9c1f91a480d42658f17.gif

点点赞

809ccda0fdc85a271f95e128b76e68cf.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512511.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

onclick 源码_精读:手写React框架 解析Hooks源码

写在开头:去年发表过一篇手写React&#xff0c;带diff算法&#xff0c;异步setState队列的文章&#xff0c;有一位阿里的朋友在下面评论&#xff0c;让我可以用hooks实现一次&#xff0c;也很简单&#xff0c;我当时觉得&#xff0c;这人有病&#xff0c;现在回过头来看&#x…

EMR on ACK 全新发布,助力企业高效构建大数据平台

简介&#xff1a; 阿里云 EMR on ACK 为用户提供了全新的构建大数据平台的方式&#xff0c;用户可以将开源大数据服务部署在阿里云容器服务&#xff08;ACK&#xff09;上。利用 ACK 在服务部署和对高性能可伸缩的容器应用管理的能力优势&#xff0c;用户只需要专注在大数据作业…

华为120hz鸿蒙系统,华为亮剑,120Hz+鸿蒙系统+5500mAh,竟然如此销魂

原标题&#xff1a;华为亮剑&#xff0c;120Hz鸿蒙系统5500mAh&#xff0c;竟然如此销魂随着制造工艺的不断成熟&#xff0c;智能手机也迎来了前所未有的发展&#xff0c;同时这也导致了手机厂商们之间的竞争变得愈发的激烈了。众所周知&#xff0c;华为手机是一个深受普通老百…

云上应用系统数据存储架构演进

简介&#xff1a; 回顾过去二十年的技术发展&#xff0c;整个应用形态和技术架构发生了很大的升级换代&#xff0c;而任何技术的发展都与几个重要的变量相关。本文将会给大家分享应用系统数据架构的演进以及云上的架构最佳实践。 作者 | 木洛 来源 | 阿里技术公众号 一 前言 …

深入解析 Dubbo 3.0 服务端暴露全流程

简介&#xff1a; 随着云原生时代的到来&#xff0c;Dubbo 3.0 的一个很重要的目标就是全面拥抱云原生。正因如此&#xff0c;Dubbo 3.0 为了能够更好的适配云原生&#xff0c;将原来的接口级服务发现机制演进为应用级服务发现机制。 作者介绍 熊聘&#xff0c;Github账号pin…

jquery将html转换word,HTML代码转word!亲测!可用!!!

现在项目中遇到一个需求&#xff0c;就是一个富文本编辑区中&#xff0c;有echars表格。用户点击保存按钮&#xff0c;需要导出为word文档。因为现在接手的项目&#xff0c;是基于上一个项目的框架。两个项目功能点差不多。但是在导出word这块&#xff0c;是后台java做的。也就…

智能搜索推荐一体化营收增长解决方案

简介&#xff1a; 图数据库GDB提供智能搜索推荐一站式服务&#xff0c;基于达摩院的智能搜索推荐算法和知识图谱技术&#xff0c;助力企业快速过渡冷启动过程&#xff0c;面向业务场景定制化方案&#xff0c;以提升核心业务指标&#xff0c;实现业务营收增长。 方案架构 方案特…

Redis 使用 List 实现消息队列的利与弊

作者 | 码哥字节 来源 | 码哥字节 分布式系统中必备的一个中间件就是消息队列&#xff0c;通过消息队列我们能对服务间进行异步解耦、流量消峰、实现最终一致性。 目前市面上已经有 RabbitMQ、RochetMQ、ActiveMQ、Kafka等&#xff0c;有人会问&#xff1a;“Redis 适合做消息队…

阿里云表格存储全面升级,打造一站式物联网存储新方案

简介&#xff1a; 阿里云表格存储全面升级&#xff0c;打造一站式物联网存储新方案 2021年9月1日&#xff0c;阿里云表格存储Tablestore重磅发布新能力&#xff1a;一站式物联网存储IoTstore。该新能力是阿里云表格存储Tablestore面向物联网深度垂直场景进行的一次技术升级&am…

手把手一起 图形化安装 k8s 集群

作者 | 小碗汤来源 | 我的小碗汤今天接着上一节&#xff0c;使用 KuboardSpray 图形化安装kubernetes集群[1]&#xff0c;记录了安装时可能遇到的问题。对此项目感兴趣的同学&#xff0c;不妨亲手实践一下~以下记录了安装单节点&#xff08;单master的集群&#xff09;&#xf…

Jaeger插件开发及背后的思考

简介&#xff1a; 本文主要介绍Jaeger最新的插件化后端的接口以及开发方法&#xff0c;让大家能够一步步的根据文章完成一个Jaeger插件的开发。此外SLS也推出了对于Jaeger的支持&#xff0c;欢迎大家试用。 随着云原生 微服务的推广和落地&#xff0c;服务监控也变得越来越重…

基于 MySQL + Tablestore 分层存储架构的大规模订单系统实践-架构篇

简介&#xff1a; 本文简要介绍了基于 MySQL 结合 Tablestore 的大规模订单系统方案。这种方案支持大数据存储、高性能数据检索、SQL搜索、实时与全量数据分析&#xff0c;且部署简单、运维成本低。 作者 | 弘楠 来源 | 阿里技术公众号 一 背景 订单系统存在于各行各业&#…

ajax返回来总是html,ajax返回类型

基于arcgis的webgis开发中目前是否还直接用ajax技本人是arcgis刚接触者&#xff0c;以前有听说过ajax这个技术&#xff0c;用于浏览器和web服务ajax技术现在依然是客户端浏览器和服务器交互的重要手段。 如果你用arcgis api for js技术&#xff0c;同样会使用ajax技术。这是良好…

三分钟教你用 Scarlet 写一个 WebSocket App

作者 | Eason来源 | 程序员巴士在移动应用程序中&#xff0c;数据层是屏幕上显示内容的真实来源。然而&#xff0c;在今年早些时候在 Tinder 中集成了 WebSocket API 时&#xff0c;维护它成为了一个令人头疼的问题。为了在 Android 上更轻松地集成 WebSocket&#xff0c;Scarl…

重磅发布|新一代云原生数据仓库AnalyticDB「SQL智能诊断」功能详解

简介&#xff1a; AnalyticDB For MySQL为用户提供了高效、实时、功能丰富并且智能化的「SQL智能诊断」和「SQL智能调优」功能&#xff0c;提供用户SQL性能调优的思路、方向和具体的方法&#xff0c;降低用户使用成本&#xff0c;提高用户使用ADB的效率 SQL是一种简单易用的业…

技术干货|基于Apache Hudi 的CDC数据入湖「内附干货PPT下载渠道」

简介&#xff1a; 阿里云技术专家李少锋(风泽)在Apache Hudi 与 Apache Pulsar 联合 Meetup 杭州站上的演讲整理稿件&#xff0c;本议题将介绍典型 CDC 入湖场景&#xff0c;以及如何使用 Pulsar/Hudi 来构建数据湖&#xff0c;同时将会分享 Hudi 内核设计、新愿景以及社区最新…

探究 Java 应用的启动速度优化

简介&#xff1a; 在高性能的背后&#xff0c;Java 的启动性能差也令人印象深刻&#xff0c;大家印象中的 Java 笨重缓慢的印象也大多来源于此。高性能和快启动速度似乎有一些相悖&#xff0c;本文将和大家一起探究两者是否可以兼得。 作者 | 梁希 高性能和快启动速度&#x…

阿里云刘伟光:金融核心系统将步入分布式智能化的时代

1月18日&#xff0c;阿里云在京发布金融核心系统转型“红宝书”&#xff0c;并推出“金融级云原生工场”&#xff0c;通过新的建设理念和相应的全链路平台技术&#xff0c;以及先进的部署体系&#xff0c;支撑金融机构建设面向未来的新一代分布式智能化核心系统。 阿里云智能新…

5分钟搞定Loki告警多渠道接入

简介&#xff1a; Loki是受Prometheus启发的水平可扩展、高可用、多租户日志聚合系统。用户既可以将Loki告警直接接入SLS开放告警&#xff0c;也可以先将Loki接入Grafana或Alert Manager&#xff0c;再借助Grafana或Alert Manager实现Loki间接接入SLS开放告警。 直接接入 您可…

当微服务遇上 Serverless | 微服务容器化最短路径,微服务 on Serverless 最佳实践

简介&#xff1a; 阿里云Serverless应用引擎&#xff08;SAE&#xff09;初衷是让客户不改任何代码&#xff0c;不改变应用部署方式&#xff0c;就可以享受到微服务K8sServerless的完整体验&#xff0c;开箱即用免运维。 前言 微服务作为一种更灵活、可靠、开放的架构&#x…