1. 程式人生 > 實用技巧 >CentOS離線安裝docker

CentOS離線安裝docker

一、簡介

在Kubernetes系統中,Pod的管理物件RC、Deployment、DaemonSet和Job都面向無狀態的服務。但是有很多服務是有狀態的,特別是一些複雜的中介軟體叢集,例如MySQL叢集、MongoDB叢集、Kafka叢集、zookeeper叢集等,這些應用叢集有4個共同點:

  • 每個節點都有固定的身份ID,通過這個ID,叢集中的成員可以相互發現並通訊

  • 叢集的規模是比較固定的,叢集規模不能隨意變動

  • 叢集中的每個節點都是有狀態的,通常會持久化資料到永久儲存中

  • 如果磁碟損壞,則叢集裡的某個節點無法正常執行,叢集功能受損

StatefulSet旨在與有狀態的應用及分散式系統一起使用,它有如下特性:

  • StatefulSet裡每個Pod都有穩定、唯一的網路標識,可以用來發現叢集內的其他成員。假設StatefulSet的名稱為Kafka,那麼第一個Pod叫Kafka-0,第二個叫Kafka-1,以此類推

  • StatefulSet控制的Pod副本啟停順序是受控的,操作第n個Pod時,前n-1個Pod已經是執行且準備好的狀態

  • StatefulSet的Pod採用穩定的持久化儲存卷,通過PV或者PVC來實現,刪除Pod時預設不會刪除與StatefulSet相關的儲存卷

StatefulSet除了要與PV卷捆綁使用以儲存Pod的狀態資料,還要與Headless Service配合使用,即在每個StatefulSet定義中都要宣告它屬於哪個Headless Service。Headless Service於普通Service的關鍵區別在於,它沒有Cluster IP,如果解析Headless Service的DNS域名,則返回的是該Service對應的全部Pod的Endpoint列表。StatefulSet在Headless Service的基礎上又為StatefulSet控制的每個Pod例項建立了一個DNS域名,這個域名格式為: $(podname).$(headless service name)

二、使用StatefulSet搭建MongoDB叢集

為了完成MongoDB叢集的搭建,需要建立如下三個資源物件

  • 一個StorageClass,用於StatefulSet自動為各個應用Pod申請PVC

  • 一個Headless Service,用於維護MongoDB的叢集狀態

  • 一個StatefulSet

2.1建立一個StorageClass物件

storageclass-fast.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io
/glusterfs parameters: restful: http://192.168.10.106:18080

執行kubectl create建立該storage class

# kubectl create -f storageclass-fast.yaml 
storageclass.storage.k8s.io/fast created

2.2 授權ServiceAccount

在2.4步驟需要使用mongo-sidecar的pod來配置管理mongo pod。

由於預設的service account僅僅只能獲取當前Pod自身的相關屬性,無法觀察到其他名稱空間Pod的相關屬性資訊。如果想要擴充套件Pod,或者一個Pod需要用於管理其他Pod或者是其他資源物件,是無法通過自身的名稱空間的serviceaccount進行獲取其他Pod的相關屬性資訊的,因此需要進行手動建立一個serviceaccount,並在建立Pod時進行定義。或者直接將預設的serviceaccount進行授權。

defaultaccount.yaml

kind: ClusterRoleBinding
metadata:
  name: default-view
subjects:
  - kind: ServiceAccount
    name: default
    namespace: default
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io

2.3 建立Headless Service

mongodb-sidecar作為MongoDB叢集的管理者,將使用此Headless Service來維護各個MongoDB例項之間的叢集關係,以及叢集規模變化時的自動更新

mongodb-headless-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: mongo
  labels:
    name: mongo
spec:
  ports:
  - port: 27017
    targetPort: 27017
  clusterIP: None
  selector:
    role: mongo

執行kubectl create命令建立該Headless Service

# kubectl create -f mongodb-headless-service.yaml 
service/mongo created

2.4 MongoDB StatefulSet

statefulset-mongo.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo
spec:
  serviceName: mongo  # 宣告它屬於哪個Headless Service
  replicas: 3
  selector:         # has to match .sepc.template.metadata.labels
    matchLabels:
      role: mongo
      environment: test
  template:
    metadata:
      labels:      # has to match .spec.selector.matchLabels
        role: mongo
        environment: test
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mongo
        image: mongo:3.4
        command:
        - mongod
        - "--replSet"
        - rs0
        - "--bind_ip"
        - 0.0.0.0
        - "--smallfiles"
        - "--noprealloc"
        ports:
        - containerPort: 27017
        volumeMounts:
        - name: mongo-persistent-storage
          mountPath: /data/db
      - name: mongo-sidecar
        image: cvallance/mongo-k8s-sidecar
        env:
        - name: MONGO_SIDECAR_POD_LABELS
          value: "role=mongo,environment=test"
        - name: KUBERNETES_MONGO_SERVICE_NAME
          value: "mongo"
  volumeClaimTemplates:
  - metadata:
      name: mongo-persistent-storage
      annotations:
        volume.beta.kubernetes.io/storage-class: "fast"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 2Gi

其中主要配置說明如下:

(1)在該statefulset定義中包含連個容器:mongo和mongo-sidecar。mongo是主服務程式,mongo-sidecar是將多個mongo例項進行叢集設定的工具。mongo-sidecar中的環境變數如下:

  • MONGO_SIDECAR_POD_LABELS:設定為mongo容器的標籤,用於sidecar查詢它所要管理的MongoDB叢集例項

  • KUBERNETES_MONGO_SERVICE_NAME: 它的值為mongo,表示sidecar將使用mongo這個服務名來完成MongoDB叢集的設定

    (2)replicas=3 表示MongoDB叢集由3個mongo例項組成

    (3)volumeClaimTemplates是 StatefulSet最重要的儲存設定。在annotations段設定volume.beta.kubernetes.io/storage-class="fast" 表示使用名為fast的StorageClass自動為每個mongo Pod例項分配後端儲存

    (4)resources.requests.storage=2Gi 表示為每個mongo例項都分配2G的磁碟空間

2.5 驗證MongoDB叢集

最終可以看到StatefulSet依次建立並啟動了3個mongo Pod例項,它們的名字依次為mongo-0、mongo-1、mongo-2:

# kubectl get pods -l role=mongo
NAME      READY   STATUS    RESTARTS   AGE
mongo-0   2/2     Running   0          72m
mongo-1   2/2     Running   0          71m
mongo-2   2/2     Running   0          64m

StatefulSet會用volumeClaimTemplates中定義為每個Pod副本都建立一個PVC例項,每個PVC的名稱由StatefulSet定義中volumeClaimTemplates的名稱和Pod副本的名稱組合而成:

# kubectl get pvc -l role=mongo
NAME                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mongo-persistent-storage-mongo-0   Bound    pvc-63b576fc-1324-46db-b708-0c40f5896103   2Gi        RWO            fast           86m
mongo-persistent-storage-mongo-1   Bound    pvc-6b2dfbc3-f57e-4e05-9cd7-dfabb3c5b00e   2Gi        RWO            fast           75m
mongo-persistent-storage-mongo-2   Bound    pvc-24ed1a31-b9a8-4214-a189-137cf9eccc12   2Gi        RWO            fast           67m

下面是mongo-0這個Pod中volume設定,可以看到系統自動為其掛載了對應的PVC:

# kubectl get pod mongo-0 -o yaml | grep -A 3 volumes
  volumes:
  - name: mongo-persistent-storage
    persistentVolumeClaim:
      claimName: mongo-persistent-storage-mongo-0

登入任意一個mongo Pod,在mongo命令列介面使用rs.status()命令檢視MongoDB叢集狀態,該mongodb叢集已由sidecar完成了建立。在叢集中包含3個節點的名稱都是StatefulSet設定的DNS域名格式的網路標識名稱:

mongo-0.mongo.default.svc.cluster.local
mongo-1.mongo.default.svc.cluster.local
mongo-2.mongo.default.svc.cluster.local

同時,可以檢視每個mongodb例項的各自角色(PRIMARY或SECONDARY)

rs.status()
...
...
...
"members" : [
        {
            "_id" : 0,
            "name" : "mongo-0.mongo.default.svc.cluster.local:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 100,
            "optime" : {
                "ts" : Timestamp(1592286258, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-06-16T05:44:18Z"),
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1592286196, 2),
            "electionDate" : ISODate("2020-06-16T05:43:16Z"),
            "configVersion" : 5,
            "self" : true,
            "lastHeartbeatMessage" : ""
        },
        {
            "_id" : 1,
            "name" : "mongo-1.mongo.default.svc.cluster.local:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 45,
            "optime" : {
...
...