搭建一个高可用的镜像仓库,这是我见过最详细、最简单的教程
作者 | 小碗湯
來源 |?我的小碗湯
今天分享一篇搭建一個(gè)高可用鏡像倉庫的教程。詳細(xì)中夾雜著簡單~。
Harbor 部署架構(gòu)圖
harbor 使用 helm 部署在 k8s 集群中,通過 ingress-nginx 代理。
pgsql 采用 Pgpool-II 代理,做主從切換、通過同步流式復(fù)制進(jìn)行數(shù)據(jù)復(fù)制,客戶端請(qǐng)求通過 Pgpool-II 路由。
pgpool 無狀態(tài)部署在 k8s 集群中。
pgsql 主從實(shí)例部署在集群外虛擬機(jī)上。
redis 哨兵模式部署在集群外虛擬機(jī)上。
這里假設(shè)示例主機(jī)信息如下
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 為哨兵模式,架構(gòu)圖如下:
Redis 實(shí)例拓?fù)浞植?#xff1a;
至于 Redis 集群在虛擬機(jī)上的部署,我使用的是Cymbal 項(xiàng)目[1]
Cymbal 秉承開箱即用的原則,整個(gè)部署過程十分簡單,最小化版本只需要一個(gè) runnable jar 及 mysql 服務(wù)的支持即可。
Cymbal 是當(dāng)當(dāng)網(wǎng)架構(gòu)部孵化并開源的 Redis PaaS 平臺(tái),基于 Spring Boot2 開發(fā)。目標(biāo)是幫助技術(shù)團(tuán)隊(duì)以簡單,低成本的方式管理大規(guī)模 Redis 集群。目前當(dāng)當(dāng)網(wǎng)內(nèi)部使用 Cymbal 管理的 Redis 實(shí)例數(shù)量達(dá)到 1000+。
Cymbal 采用 DevOps 的設(shè)計(jì)思想,以多租戶的方式,最大程度上賦予開發(fā)人員運(yùn)維權(quán)限,從而加快團(tuán)隊(duì)運(yùn)轉(zhuǎn)。同時(shí),Cymbal 上面集成了豐富的運(yùn)維功能:從監(jiān)控、報(bào)警到在線擴(kuò)縮容等,力求最大程度上消除運(yùn)維門檻。
假設(shè)用 Cymbal 部署之后 redis 哨兵信息如下:172.0.0.1:9381,172.0.0.2:9381,172.0.0.3:9381
哨兵 Master 為: mymaster-EC4Fy7DJ
密碼為: harborpwd
下面會(huì)用到這些信息。
Pgsql
基于 PGpool 中間件實(shí)現(xiàn) postgresql 一主一從集群部署,架構(gòu)圖實(shí)例如下:
PGPool、Pgsql 實(shí)例拓?fù)浞植?#xff1a;
Pgpool 在 k8s 集群中多實(shí)例部署,Pgsql 主從實(shí)例在虛擬機(jī)中用 docker 容器啟動(dòng)。
docker 部署 pgsql
在虛擬機(jī)上直接部署 pgsql 集群在時(shí)間成本上,還是不太容易的。我們這里使用 docker 去管理,會(huì)輕松一點(diǎn)。
創(chuàng)建 volume,由于復(fù)制管理器映像的 PostgreSQL 是非 root 用戶,因此您還需要為主機(jī)中的掛載目錄設(shè)置適當(dāng)?shù)臋?quán)限:
#?主實(shí)例 #?docker?volume?create?pg-0 #?chgrp?-R?root?/var/lib/docker/volumes/pg-0 #?chmod?-R?g+rwX?/var/lib/docker/volumes/pg-0 #?從實(shí)例 #?docker?volume?create?pg-1 #?chgrp?-R?root?/var/lib/docker/volumes/pg-1 #?chmod?-R?g+rwX?/var/lib/docker/volumes/pg-1我們這里將主從部署在不同的主機(jī)上,所以兩組命令應(yīng)該在兩臺(tái)主機(jī)上執(zhí)行。從而保證不同時(shí)掛掉。
啟動(dòng) pgsql 實(shí)例的腳本:
#!/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啟動(dòng)時(shí),用:
#?start-pg.sh?{容器名}容器名為 pg-0(主)或者 pg-1(從)。
pgsql 掛掉自啟動(dòng)
docker 容器掛掉后,用 crontab 保證容器可以重新啟動(dòng),30s 為間隔去執(zhí)行 start-pg.sh 腳本。
執(zhí)行 crontab -e 在最后新增以下內(nèi)容,然后: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?)創(chuàng)建 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 手動(dòng)創(chuàng)庫
harbor 對(duì)接外部 pgsql 時(shí),需要提前創(chuàng)建庫,所以手動(dòng)創(chuàng)建以下四個(gè) database(一般 DBA 來做這件事), 可以直接連接 pgsql 主實(shí)例,也可以通過 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#?創(chuàng)建ns kubectl?create?ns?harbor創(chuàng)建域名證書 Secret,這里需要用到你的域名證書。
kubectl??create?secret?tls?harbor-ingress?-n?harbor?--cert=./product.cn.pem?--key=./product.cn.key如果沒有域名證書,也可以使用自動(dòng)生成證書,下面會(huì)講到。
修改 values.yaml 中以下內(nèi)容:
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 包會(huì)自動(dòng)生成證書,我們這里用 secret
域名對(duì)應(yīng)的證書 secret 名,這里為 harbor-ingress,即上面創(chuàng)建的
外部 redis 信息
外部 pgsql 信息,這里連接到集群內(nèi) pgpool 的域名
storageClass 這里用 Rook 部署的 ceph 集群的文件存儲(chǔ),修改為 cephfs
harbor 密碼自定義
安裝 harbor
helm?install?pro?-n?harbor?-f?values.yaml?.正常情況,一段時(shí)間后,harbor 會(huì)啟動(dòng)成功,我們?cè)L問harbor 域名[3]即可看到 harbor 的界面。
升級(jí)
如果修改了 values.yaml 后,執(zhí)行升級(jí):
helm?upgrade?pro?-n?harbor?-f?values.yaml?.卸載
helm?uninstall?pro?-n?harbor往期推薦
性能提升一個(gè)數(shù)量級(jí),大殺器來了!
k8s集群居然可以圖形化安裝了?
用了HTTPS,沒想到還是被監(jiān)控了
快速搭建實(shí)驗(yàn)環(huán)境:使用 Terraform 部署 Proxmox 虛擬機(jī)
點(diǎn)分享
點(diǎn)收藏
點(diǎn)點(diǎn)贊
點(diǎn)在看
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的搭建一个高可用的镜像仓库,这是我见过最详细、最简单的教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汽车电气化竞争:获胜的途径
- 下一篇: 解码2017双11:全球狂欢新记录背后的