搭建一個高可用的鏡像倉庫,這是我見過最詳細、最簡單的教程

2022-01-09 我的小碗湯


大家好,我是小碗湯,今天分享一篇搭建一個高可用鏡像倉庫的教程。詳細中夾雜著簡單~。篇幅較長,兄弟們不妨耐心看完~

Harbor 部署架構圖harbor 使用 helm 部署在 k8s 集群中,通過 ingress-nginx 代理。pgsql 採用 Pgpool-II 代理,做主從切換、通過同步流式複製進行數據複製,客戶端請求通過 Pgpool-II 路由。

這裡假設示例主機信息如下

版本信息

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/bash

set -o errexit

node=$1
if [[ -z "${node}" ]]; then
        echo "Error: need node argument, example: pg-0"
        exit -1
fi


existUp=$(docker ps -f name=${node} -q)

if [[ -n "${existUp}" ]]; then
        # nothing
        echo "node: ${node} is Up"
        exit 0
fi

existNotUp=$(docker ps -a -f name=${node} -q)

if [[ -n "${existNotUp}" ]]; then
        # start
        echo "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: pgpool
    app.kubernetes.io/instance: pgsql
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: postgresql-ha-doc
    helm.sh/chart: postgresql-ha-8.0.2
  name: pgpool-for-docker-dp-pgsql
  namespace: harbor
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/component: pgpool
      app.kubernetes.io/instance: pgsql
      app.kubernetes.io/name: postgresql-ha-doc
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/component: pgpool
        app.kubernetes.io/instance: pgsql
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/name: postgresql-ha-doc
        helm.sh/chart: postgresql-ha-8.0.2
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - topologyKey: kubernetes.io/hostname
            labelSelector:
              matchLabels:
                app.kubernetes.io/component: pgpool
                app.kubernetes.io/instance: pgsql
      containers:
      - env:
        - name: BITNAMI_DEBUG
          value: "false"
        - name: PGPOOL_BACKEND_NODES
          value: 0:172.0.0.1:5432,1:172.0.0.2:5432,
        - name: PGPOOL_SR_CHECK_USER
          value: repmgrharbor
        - name: PGPOOL_SR_CHECK_PASSWORD
          value: repmgrpwd
        - name: PGPOOL_SR_CHECK_DATABASE
          value: postgres
        - name: PGPOOL_ENABLE_LDAP
          value: "no"
        - name: PGPOOL_POSTGRES_USERNAME
          value: pgharbor
        - name: PGPOOL_POSTGRES_PASSWORD
          value: pgpwd
        - name: PGPOOL_ADMIN_USERNAME
          value: pgpooladmin
        - name: PGPOOL_ADMIN_PASSWORD
          value: pgpoolpwd
        - name: PGPOOL_ENABLE_LOAD_BALANCING
          value: "yes"
        - name: PGPOOL_DISABLE_LOAD_BALANCE_ON_WRITE
          value: transaction
        - name: PGPOOL_ENABLE_LOG_CONNECTIONS
          value: "no"
        - name: PGPOOL_ENABLE_LOG_HOSTNAME
          value: "yes"
        - name: PGPOOL_ENABLE_LOG_PER_NODE_STATEMENT
          value: "no"
        - name: PGPOOL_CHILD_LIFE_TIME
        - name: PGPOOL_ENABLE_TLS
          value: "no"
        image: docker.io/bitnami/pgpool:4.2.6-debian-10-r7
        imagePullPolicy: IfNotPresent
        livenessProbe:
          exec:
            command:
            - /opt/bitnami/scripts/pgpool/healthcheck.sh
          failureThreshold: 5
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        name: pgpool
        ports:
        - containerPort: 5432
          name: postgresql
          protocol: TCP
        readinessProbe:
          exec:
            command:
            - bash
            - -ec
            - PGPASSWORD=${PGPOOL_POSTGRES_PASSWORD} psql -U "pgharbor" -d "pgharbor"
              -h /opt/bitnami/pgpool/tmp -tA -c "SELECT 1" >/dev/null
          failureThreshold: 5
          initialDelaySeconds: 5
          periodSeconds: 5
          successThreshold: 1
          timeoutSeconds: 5
        resources: {}
        securityContext:
          runAsUser: 1001
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 1001
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: pgpool
    app.kubernetes.io/instance: pgsql
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: postgresql-ha-doc
    helm.sh/chart: postgresql-ha-8.0.2
  name: pgpool-for-docker-dp-pgsql
  namespace: harbor
spec:
  ports:
  - name: postgresql
    port: 5432
    protocol: TCP
    targetPort: postgresql
  selector:
    app.kubernetes.io/component: pgpool
    app.kubernetes.io/instance: pgsql
    app.kubernetes.io/name: postgresql-ha-doc
  sessionAffinity: None
  type: 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: ingress
  tls:
    enabled: true
    certSource: secret
    secret:
      # The name of secret which contains keys named:
      # "tls.crt" - the certificate
      # "tls.key" - the private key
      secretName: "harbor-ingress"
  ingress:
    hosts:
      core: harbor-pro.kubeinfo.cn
    controller: default
    annotations:
      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: true
  resourcePolicy: "keep"
  persistentVolumeClaim:
    registry:
      storageClass: "cephfs"
      accessMode: ReadWriteMany
      size: 200Gi
notary:
  enabled: false
database:
  # if external database is used, set "type" to "external"
  # and fill the connection informations in "external" section
  type: external
  external:
    host: "pgpool-for-docker-dp-pgsql.harbor.svc.cluster.local"
    port: "5432"
    username: "pgharbor"
    password: "pgpwd"
  maxOpenConns: 1000

redis:
  # if external Redis is used, set "type" to "external"
  # and fill the connection informations in "external" section
  type: external
  external:
    # 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+sentinel
    sentinelMasterSet: "mymaster-EC4Fy7DJ"
    password: "harborpwd"

values.yaml 中的域名修改為自己的域名,這裡用到的是 harbor-pro.kubeinfo.cnexpose.tls.certSource 可以為 auto,即 chart 包會自動生成證書,我們這裡用 secret域名對應的證書 secret 名,這裡為 harbor-ingress,即上面創建的外部 pgsql 信息,這裡連接到集群內 pgpool 的域名storageClass 這裡用 Rook 部署的 ceph 集群的文件存儲,修改為 cephfs安裝 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

原文

本文首發於微信公眾號【我的小碗湯】,歡迎掃文末二維碼關注~

參考資料[1]

Cymbal 項目: https://github.com/dangdangdotcom/cymbal

[2]

harbor-helm 倉庫: https://github.com/goharbor/harbor-helm

[3]

harbor 域名: https://harbor-pro.kubeinfo.cn


推薦閱讀

真快!10秒內將k8s集群運行起來

這款工具,幫你輕鬆用手機管理 K8S 集群

6個工具助你在Windows上輕鬆運行Kubernetes

當年加入相互「保」,現在相互「寶」涼了!交的錢都白交了?

5 個必備的命令行工具,效率飛起

極簡工具 | MacOS上運行容器和k8s | 支持M1

目前MacOS上,管理容器和k8s可選擇的產品有哪些?

一款k8s實時錯誤監控工具,值得用起來

Docker容器如何優雅使用NVIDIA GPU

頂級工具 | Popeye幫你發現k8s集群潛在問題

Web自動化神器,批量下載小姐姐美圖,可直接導入使用



點讚👍   星標✨  在看 👁 讓我看見你們!!

本公眾號主要分享linux、Golang、網絡、雲原生相關技術,實用工具,歡迎掃碼關注!

相關焦點

  • 雲計算核心技術Docker教程:使用registry搭建私有鏡像倉庫
    來源:TechWeb.com.cn在之前的教程中我們使用docker拉取的鏡像都是docker hub上的使用的是公共倉庫,當我們在企業項目中開發時不可能把鏡像放到公共倉庫進行管理,所以為了更好的管理鏡像,我們需要搭建私有鏡像倉庫,今天我們介紹使用Docker官方提供的鏡像registry
  • npm本地倉庫搭建教程
    為了讓大家第一時間看到優質內容,請點擊藍色【三維網格3D】關注我們▽看完你將能收穫:搭建自己本地的個人或者公司私有的npm倉庫。唔~~~阿里、京東、騰訊、百度、網易只要是你在中國認識的網際網路企業,基本都在用,而他們npm包都是從npm官網下載來的,而npm官網是外國網站,那麼就問題來了,咱們直接訪問npm外網下載包的時候,會有一股神秘的力量把你保護起來,導致下載包的速度很慢,因此中國優秀的前端團隊——來自阿里的淘寶團隊,就鏡像了一個國內的npm網站。
  • 雲計算核心技術Docker教程:使用harbor搭建私有鏡像倉庫
    之前介紹的docker搭建私有鏡像倉庫是使用的官方提供的私有倉庫registry,安裝使用雖然簡單,但在管理的功能上存在不足。Harbor是一個用於存儲和分發Docker鏡像的企業級Registry伺服器,作為一個企業級私有Registry伺服器,Harbor提供了更好的性能和安全。
  • Mac版最詳細的Flutter開發環境搭建
    ,官網的搭建教程只是按步驟讓你進行操作,中間出現的問題完全沒有提及,對我這種沒搞過原生開發的小白來說超級不友好。而網上很多相關博客教程,感覺不夠詳細,許多環境搭建過程中的坑確實是提到了,但解決的辦法寫的比較籠統,在此我將本次環境搭建鎖遇到的各種奇奇怪怪的問題一一匯總,爭取結合各路大神的博客加上自己實際遇到的問題整理出一篇超級實用且詳細的教程,讓童鞋們在學習flutter的路上少走彎路,讓你的起跑順暢起來,大神們請指正或忽略。系統環境要求Flutter是相對新出的框架,對系統有一定的要求。
  • RabbitMQ 集群高可用部署詳細介紹
    無奈工作使然,理想使然,我回到啦公司,敲起啦鍵盤,擼起啦代碼,程序狗的世界一片黯然,一片黯然,願天下所有努力的程序狗都夢想成真吧!!回到正題,為什麼搭建rabbitmq集群?rabbitmq集群有那些模式?如何搭建Rabbitmq集群?rabbitmq鏡像高可用策略有那些?
  • 雲計算核心技術Docker教程:Docker鏡像使用
    當運行容器時,使用的鏡像如果在本地中不存在,docker 就會自動從 docker 鏡像倉庫中下載,默認是從 Docker Hub 公共鏡像源下載。我們可以使用 docker images 來列出本地主機上的鏡像。
  • 最簡單的Openstack搭建方式
    詳細的安裝鏡像說明詳見「openstack 之 kolla安裝鏡像」    其實我就是這樣過來的,從剛開始的聽說過Openstack被吸引,然後想實際生產系統嘗試使用,上官網看資料,根據官網的資料一步步的做實驗,遇到無數個坑,發現社區裡面其實很多資料多多少少都有些問題,如果不是自己親自做實驗去驗證,真的沒辦法放心。
  • 【AngularJS教程】快速入門篇之搭建環境
    該web應用是一個Android設備清單的目錄列表,您可以篩選列表以便查看您感興趣的設備,然後查看設備的詳細信息。本教程將向您展示AngularJS怎樣使得web應用更智能更靈活,而且不需要各種擴展程序或插件。 通過本教程的學習,您將:閱讀示例學習怎樣使用AngularJS的客戶端數據綁定和依賴注入功能來建立可立即響應用戶操作的動態數據視圖。
  • 小白站長網站搭建教程
    今天阿呆給大家講一下如何搭建自己的個人網站適合小白站長的個人網站搭建在搭建網站之前需要準備的材料:1.一個備案過的域名【可以自己購買一個域名並備案一下,也可以上百度上百度免費二級域名在平臺上註冊一個免費的二級域名
  • 桃花源記手遊寵物倉庫在哪 位置教程詳細介紹
    桃花源記手遊寵物倉庫在哪 位置教程詳細介紹時間:2017-07-01 09:24   來源:3454遊戲   責任編輯:玲玲 川北在線核心提示:原標題:桃花源記手遊寵物倉庫在哪 位置教程詳細介紹 桃花源記手遊寵物倉庫在哪,寶寶倉庫存放位置在哪呢?
  • cad怎麼鏡像?CAD鏡像功能的使用教程
    cad怎麼鏡像?在使用CAD進行繪圖時,我們需要掌握鏡像功能,這樣可以加速我們繪圖的過程。一個人繪圖水平的高低,很大程度上取決於繪圖的速度,下面分享CAD鏡像功能的使用教程,需要的朋友可以參考下在使用CAD進行繪圖時,我們需要掌握鏡像功能,這樣可以加速我們繪圖的過程。
  • 用Docker 搭建Web服務環境
    開發環境只需要安裝配置一次,之後搭建相同的開發環境很簡單,只需要一條命令即可完成!這就是本文的目的,介紹 Docker 下安裝配置 Web 的服務環境,實現一次安裝配置,多次重用、跨平臺重用的功能。容器都是基於鏡像而創建的,基於一個鏡像可以創建若干個名字不同但功能相同的容器。鏡像是靜態的,容器是動態的。除了鏡像和容器之外,還有兩個概念需要了解一下的,那就是倉庫和 docker-compose。Docker 倉庫是存放鏡像的地方,我們可以從 Docker 倉庫中拉取鏡像到本地,然後再基於鏡像創建容器。
  • 這可能是我見過的,關於INDEX+MATCH使用的最簡明教程了!
    一番解釋之後,是不是覺得INDEX+MATCH的使用原理很簡單呢。2、MATCH函數,INDEX函數的基本使用在了解了基本原理之後,要想熟練的使用INDEX+MATCH,就必須先分別能夠熟練地使用MATCH函數、INDEX函數。讓我們來看看他們是怎麼使用的。
  • Docker系列教程01-使用Docker鏡像
    前言學習Docker,我們需要掌握它的三大核心概念:鏡像、容器和倉庫。今天先帶大家學習Docker鏡像相關的基礎知識。如果讀者之前是VM管理員,則可以把Docker鏡像理解為VM模板,如果您是一名研發人員,可以將鏡像理解為類(class)。簡單說,Docker鏡像是一個不包含系統內核而又精簡的作業系統。
  • 最詳細的 Hadoop 入門教程
    第二部分:Hadoop本地模式安裝Hadoop 本地模式只是用於本地開發調試,或者快速安裝體驗 Hadoop,這部分做簡單的介紹。第三部分:Hadoop偽分布式模式安裝學習 Hadoop 一般是在偽分布式模式下進行。
  • 這是我見過最棒的廚房裝修教程,5大布局方式+收納技巧!圖文並茂
    這是我見過最棒的廚房裝修教程,5大布局方式+收納技巧!圖文並茂今天已經立春了,春天氣溫舒適對於裝修來說是個好季節。大家都知道家裝是個系統工程,不僅要考慮造價、美觀,還得保證空間利用率,這幾天就有不少粉絲問我,像現在樓房裡,廚房比較小只有幾平米,應該如何布局才能更實用?今天我們就專門針對廚房裝修出了一份實用教程,囊括了5種主流布局方式和廚房收納技巧,大家跟著教程做相信肯定可以做出滿意的廚房!
  • 新手入門靶機BEE-BOX教程—環境搭建(一)
    想到之前我剛進入安全的時候,大佬告訴我有手就行,我把這四字真言分享到群裡,表哥們一邊感謝一邊將我圍在牆角,一頓揍。本著有手就行,網上搜索一波就完事,發現網上比較殘差不齊,所以本篇打算做一個Bee-box通關教程再此。作為一個本人思路整理及給入門同學一個參考,大神勿噴。
  • 輕鬆理解Docker倉庫、Docker鏡像和Docker容器的含義及關係
    Docker是使用Go語言編寫的,Docker很輕量,使用起來特別容易,不僅可以在各大平臺上移植,還可以實現虛擬化,還有跟語言也無關,這無疑讓各國的開發者歡呼雀躍呀,這東西太好了,開發者編寫好的東西,放到Docker裡面,隨便扔,都能運行,不需要進行額外的一大堆的配置。
  • 阿里巴巴SpringCloud開源教程、文檔合集,趕緊收藏
    錯過了這一篇,你可能再也學不會 Spring Cloud 了!Spring Boot作為下一代 web 框架,Spring Cloud 作為最新最火的微服務的翹楚,你還有什麼理由拒絕。趕快上船吧,老船長帶你飛。終章不是最後一篇,它是一個匯總,未來還會寫很多篇。不要問我為什麼?
  • 乾貨 | 重裝 Windows 系統最簡單的教程
    這個時候如果找不到具體原因,無法有效解決,最簡單有效的辦法就是重裝系統。學習重裝系統的成本極低,看了本文,我相信你會發現重裝系統並沒有你想像中那麼高大上,「Just So Easy」學會了重裝系統,如有神技加身,不僅可以為己所用,還可以在關鍵時刻大顯身手,給 親友,同事,領導,重裝系統,解決電腦問題,頓時令他人對你刮目相看,提升自我價值,為自己的形象加分。