Harbor高可用方案设计

1. 系统架构

本文档参照Harbor官方高可用方案说明,并且在Kubernetes集群通过helm来部署Harbor

Harbor的大部分组件都是无状态的应用,针对该种应用比如portal、core、nginx等只需要增加其相应的副本数量即可;在存储数据层面,需要提供高可用的Postgresql、redis集群,另外针对镜像和chart服务也需要提供可持久的存储(PVCs)。鉴于以上理论,也就有了下面的Harbor高可用方案设计架构图(摘自Harbor官网):

既然有了上图的系统架构设计,下面开始着手具体部署实现。

另外本文只针对Harbor高可用的设置,其它部署可参照Harbor NFS部署Harbor CEPH部署

2. 部署准备

2.1 Chart下载

首先下载Harbor Chart,参照如下操作即可:

# 添加helm harbor repo
helm repo add harbor https://helm.goharbor.io

# 下载chart
helm fetch harbor/harbor

# 解压缩
tar xvf harbor-xxx.tgz
cd harbor-xxx/

2.2 Harbor参数配置

跟常规部署一样,需要修改values.yaml文件:

  • 修改Harbor对外暴露方式:上面提到的两篇博文都是采用NodePort的暴露方式,此处建议采用Ingress,于是需要修改expose.ingress.hosts.coreexpose.ingress.hosts.notary这两个字段;
  • 修改externalURL:修改成expose.ingress.hosts.core字段的值,但是前面加上协议名称;
  • 修改PostgreSQL配置:首先修改database.type --> external,然后填入database.external区域的信息比如访问数据库的host、端口、用户名、密码等信息,另外注意:这一块需要提前手动创建四个空数据库:harbor Core、Clair、Notary Server、Notary Signer,然后把数据库的名称填入database.external区域,至于PostgreSQL高可用部署下文会进一步说明;
  • 修改Redis配置:首先修改redis.type --> external,然后填入redis.external区域信息,高可用方案下如果采用Redis Sentinal方案,因为Harbor上游项目代码的Redis客户端不支持Sentinal,所以可以考虑使用HAProxy
  • 持久化存储配置:这一块配置跟上面所提两篇博文一致,预先安装对应存储的驱动插件,然后依据StorageClass创建PVC进而提供PV方式;
  • 修改其他组件的副本数量:修改 portal.replicas , core.replicas , jobservice.replicas , registry.replicas , chartmuseum.replicas , clair.replicas , notary.server.replicas and notary.signer.replicas to n(n>=2,这里是3)

配置完之后,我们需要在环境中搭建高可用的数据库:PostgreSQL和Redis

3. PostgreSQL高可用部署

这里采用stolon来部署PostgreSQL的高可用,具体部署步骤可参考Stolon Inside Kubernetes

一点说明:尽管helm hub上已经有stolon的chart,但是不建议使用,本人曾经尝试安装过几次,不过最后都没安装成功,原因未知。

3.1 下载源码和镜像

按如下操作即可:

# 源码下载
git clone https://github.com/sorintlab/stolon.git

# stolon镜像下载
docker pull sorintlab/stolon:v0.13.0-pg10  # 网上随便找的一个镜像,实际使用时可根据需求修改stolon/examples/kubernetes/image/docker/Dockerfile实现订制

# 进入kubernetes部署目录
cd stolon/examples/kubernetes/

3.2 初始化Stolon集群

# stolon集群初始化
kubectl run -i -t stolonctl --image=sorintlab/stolon:v0.13.0-pg10 --restart=Never --rm -- /usr/local/bin/stolonctl --cluster-name=kube-stolon --store-backend=kubernetes --kube-resource-kind=configmap init

3.3 参数配置

进入stolon kubernetes安装目录后,可以看到:

需要修改出不多:

  • 镜像信息:此处均修改成sorintlab/stolon:v0.13.0-pg10

  • postgres数据库用户名称:默认stolon,可通过修改stolon-keeper.yaml文件配置项完成设置;

  • postgres数据库访问密码:默认password1,在secret.yaml中存储,如需更改先base64转码后存入;

  • 后端存储配置:HA方案采用共享存储,这里提前预先安装ceph驱动插件只需在stolon-keeper.yaml文件做如下图示修改即可,至于容量大小按需填入;

  • 副本数量:按需填入,这里默认都是2

3.4 组件安装

下面开始stolon各个组件的部署,依次执行如下命令即可:

 kubectl create -f stolon-sentinel.yaml
 kubectl create -f secret.yaml
 kubectl create -f stolon-keeper.yaml
 kubectl create -f stolon-proxy.yaml 
 kubectl create -f stolon-proxy-service.yaml

# RBAC相关
kubectl create -f role.yaml
kubectl create -f role-binding.yaml

如果出现如下结果说明安装基本上是ok了:

并且我们还可以通过kubectl logs命令发现两个keeper一个是master,而另一个则是standby

3.5 Harbor高可用准备及相关参数调整

3.5.1 Harbor参数调整

更新values.yaml文件:

  • database.external.host --> stolon-proxy-service即stolon-proxy的service名称;
  • database.external.username --> stolon
  • database.external.password --> password1

3.5.2 Postgres初始化

如上面所说,需要预先在Postgres集群中创建几个空数据库,可借助kubernetes Job来完成。因为Postgres客户端命令行工具支持以文件传入SQL命令的方式,所以只需把创建数据库的命令放入几个文件里,然后通过一个脚本调用它们即可:

  • 几个sql命令文件:
  • 初始化脚本程序

#!/bin/bash
# postgresql.sh

host="stolon-proxy-service"
user="stolon"
db="postgres"
export PGPASSWORD="password1"

args=(
        # force postgres to not use the local unix socket (test "external" connectibility)
        --host "$host"
        --username "$user"
        --dbname "$db"
        --quiet --no-align --tuples-only
)

if select="$(echo 'SELECT 1' | psql "${args[@]}")" && [ "$select" = '1' ]; then
   psql -h stolon-proxy-service -p 5432 postgres -U stolon -f "/docker-entrypoint-initdb.d/notary_server.sql"
   psql -h stolon-proxy-service -p 5432 postgres -U stolon -f "/docker-entrypoint-initdb.d/notary_signer.sql"
   psql -h stolon-proxy-service -p 5432 postgres -U stolon -f "/docker-entrypoint-initdb.d/registry.sql"
   psql -h stolon-proxy-service -p 5432 postgres -U stolon -f "/docker-entrypoint-initdb.d/clair.sql"   
   exit 0
fi
exit 1
  • Job yaml文件
apiVersion: batch/v1
kind: Job
metadata:
  name: stolon-init-database-job
spec:
  template:
    spec:
      containers:
      - name: stolon-proxy
        image: sorintlab/stolon:master-pg10
        command:
          - "/bin/bash"
          - "/docker-entrypoint-initdb.d/postgresql.sh"
        volumeMounts:
        - mountPath: /docker-entrypoint-initdb.d
          name: database
      restartPolicy: OnFailure     #失败重启
      volumes:
        - name: database
          hostPath:
            path: /postgres_init  # 把之前准备的sql和脚本文件放置这个目录下,总共5个文件
  activeDeadlineSeconds: 600   #10分钟没有complete,不再重启并移除Pod

把之前准备好的sql和脚本文件拷贝到各个worker节点/postgres_init目录,然后再master执行批处理任务即可完成数据库的初始化工作,另外如果新建的数据库名称跟Harbor配置不一致注意更新,自此Postgresql高可用部署完成。

4. Redis高可用部署

4.1 Redis哨兵集群部署

直接采用helm部署即可,操作步骤可参考如下:

helm repo add stable `https://kubernetes-charts.storage.googleapis.com` 
helm fetch stable/redis-ha
tar xvf redis-ha-xxx.tgz
cd redis-ha

修改values.yaml配置,修改的地方不多绝大部分默认配置即可,其中有两处额外注意一下:

  • redis访问密码设置:需提前创建一个包含redis密码信息的secret对象,比如下面这样:

然后通过kubectl create -f redis-secret.yaml创建,之后根据secret修改values.yaml对应认证信息即可:

(secret中密码都是base64转码之后的结果,此处redis密码: password1 )
注意:如果如本文redis集群最终要对接Harbor且采用haproxy tcp-check来侦测redis master,此处auth--> false

  • 持久化存储设置:因为数据库后端采用共享存储,设置好PVC对应的storageclass和容量即可:

然后开始部署:

# 可以先检查下配置
helm install --name vienfu-redis-cluster . --debug --dry-run
# 正式安装
helm install --name vienfu-redis-cluster .

等待一会而便会发现部署完成了:


下面做个简单测试:


4.2 Harbor高可用准备及参数调整

一般情况下只需访问redis-sentinal集群服务便可对redis master进行读写,但是由于Harbor内置的redis客户端不支持sentinal,所以直接访问redis sentinal服务是不行的。那么直接访问redis-server的服务可以吗?答案也是不可以的,因为这有可能后端最终访问到redis slave节点,而slave节点却是只读的,所以需要其他一种方式能够从redis server节点中找出redis master,根据官方文档提示采用HAProxy,仔细查阅下HAProxy配置官方文档,可以通过haproxy tcp-check功能来锁定redis master,如下是可参照的haproxy配置:

# cat /etc/haproxy/conf.d/redis-ha.conf

frontend ft_redis
 bind 10.0.2.15:6379 name redis
 default_backend bk_redis

backend bk_redis
 option tcp-check
 tcp-check connect
 tcp-check send PING\r\n
 tcp-check expect string +PONG
 tcp-check send info\ replication\r\n
 tcp-check expect string role:master
 tcp-check send QUIT\r\n
 tcp-check expect string +OK
 server R1 vienfu-redis-cluster-redis-ha-server-0.vienfu-redis-cluster-redis-ha.default.svc.cluster.local:6379 check inter 1s
 server R2 vienfu-redis-cluster-redis-ha-server-1.vienfu-redis-cluster-redis-ha.default.svc.cluster.local:6379 check inter 1s
 server R3 vienfu-redis-cluster-redis-ha-server-2.vienfu-redis-cluster-redis-ha.default.svc.cluster.local:6379 check inter 1s

然后设置开机启动及重启haproxy服务即可。

注意此处也要对应调整Harbor参数配置:redis.external.host --> 上面haproxy配置的VIP:10.0.2.15

4.2.1 其它说明

此外如你所见,此处haproxy后端server的配置采用的是对应server的域名,直接使用POD IP也可以,不过考虑到该IP可能会变,所以建议使用域名来配置haproxy后端server,那么节点如何解析kubernetesservice域名呢?对,通过CoreDNS

首先,需要获取CoreDNS对应的nameserver,很简单执行如下命令即可:

kubectl get svc -n kube-system

把结果dns服务对应的CLUSTER-IP作为新增的nameserver配置到节点的域名配置文件中(一般默认/etc/resolve.conf),不过高版本的linux一般都是通过systemd来控制域名解析服务,如果直接修改该文件重启域名服务是不生效的,在此提供一个简单方法直接关掉systemd-resolved并且禁用开机启动,这样直接修改/etc/resolve.conf就立刻生效了,其他方法可参照Ubuntu 18.04修改DNS

之后,重启haproxy服务的过程中可能会碰到如下问题:提示后端server的域名无法解析,但是执行nslookup命令却能解析域名,发现也ping不通,最终参照网上nslookup works but can not ping问题最终得以解决。

5. Harbor HA安装

按照如下命令执行完成最终部署:

# 可先检查下Harbor配置
helm install --name harbor-ha . --debug --dry-run

# 正式部署
helm install --name harbor-ha . 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容