搭建一个高可用的镜像仓库,这是我见过最详细、最简单的教程
作者 | 小碗湯
來源 |?我的小碗湯
今天分享一篇搭建一個高可用鏡像倉庫的教程。詳細中夾雜著簡單~。
Harbor 部署架構圖
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 為哨兵模式,架構圖如下:
Redis 實例拓撲分布:
至于 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 一主一從集群部署,架構圖實例如下:
PGPool、Pgsql 實例拓撲分布:
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往期推薦
性能提升一個數量級,大殺器來了!
k8s集群居然可以圖形化安裝了?
用了HTTPS,沒想到還是被監控了
快速搭建實驗環境:使用 Terraform 部署 Proxmox 虛擬機
點分享
點收藏
點點贊
點在看
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的搭建一个高可用的镜像仓库,这是我见过最详细、最简单的教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汽车电气化竞争:获胜的途径
- 下一篇: 解码2017双11:全球狂欢新记录背后的