首頁>技術>

前言

在前一篇文章中簡單地介紹了《5分鐘透過docker快速部署並使用apollo配置中心》,使用者可以快速地瞭解到配置中心apollo的基本使用,如需要看上文的可以看如下連結:https://www.toutiao.com/i6914234898681299464/

但是在生產環境中我們往往需要高可用的部署配置中心,這樣我們就得有k8s來進行部署。在apollo的官方文件中有關於k8s部署的文章(https://github.com/ctripcorp/apollo/tree/master/scripts/apollo-on-kubernetes),但是在執行的過程中是會遇到一定的坑的。包括實際部署中遇到的,映象的製作、portal服務的多例項支援、ingress的建立都沒有說到,本人在部署的過程中已經全部解決以上問題,希望可以幫到沒有部署過的使用者。

部署成功頁面

下面是部署完成後,訪問apollo的登入頁面

登入頁面

輸入使用者名稱密碼:apollo/admin,部署環境完成portal頁面圖

部署完成apollo後頁面

k8s的dashboard部署頁面,本文部署了dev, fat, pro三個環境。

部署環境完成k8s後dashboard圖

部署過程

本文在部署的時候使用了當前最新的apollo版本為:1.7.1,所以下面的所有構建也是基於當前版本的。

一、構建映象

首先從git上下載原始碼,可以從github下載:https://github.com/ctripcorp/apollo;也可以從gitee下載:https://gitee.com/nobodyiam/apollo,國內的會快一點。然後進入到目錄

/scripts/apollo-on-kubernetes

去構建映象。

1、 直接使用編譯的的包進行安裝,獲取 apollo 壓縮包

可以直接從官網下載,因為github實在是太慢了。建議直接從我的百度雲下載。

A、下載比較慢,直接用我百度雲

連結:https://pan.baidu.com/s/1eLL2ocYE1uzXcvzO2Y3dNg

提取碼:nfvm

B、從 https://github.com/ctripcorp/apollo/releases 下載預先打好的 java 包

(1)進入scripts/apollo-on-kubernetes/執行 wget https://github.com/ctripcorp/apollo/releases/download/v1.7.1/apollo-portal-1.7.1-github.zip(2)進入scripts/apollo-on-kubernetes/執行 wget https://github.com/ctripcorp/apollo/releases/download/v1.7.1/apollo-adminservice-1.7.1-github.zip(3)進入scripts/apollo-on-kubernetes/執行 wget https://github.com/ctripcorp/apollo/releases/download/v1.7.1/apollo-configservice-1.7.1-github.zip

2、解壓壓縮包, 獲取程式 jar 包

不要忘記重新命名,把版本號去掉。

解壓 apollo-portal-1.7.1-github.zip獲取 apollo-portal-1.7.1.jar, 重新命名為 apollo-portal.jar, 放到 scripts/apollo-on-kubernetes/apollo-portal-server解壓 apollo-adminservice-1.7.1-github.zip獲取 apollo-adminservice-1.7.1.jar, 重新命名為 apollo-adminservice.jar, 放到 scripts/apollo-on-kubernetes/apollo-admin-server解壓 apollo-configservice-1.7.1-github.zip獲取 apollo-configservice-1.7.1.jar, 重新命名為 apollo-configservice.jar, 放到 scripts/apollo-on-kubernetes/apollo-config-server

3、構建映象

注意:因為許多地方都要同時改,在構建的時候要確定名稱空間,我使用zizai。

要構建如下的映象:alpine-bash-3.8-image,apollo-config-server,apollo-admin-server和apollo-portal-server,對應的映象檔案,在對應的目錄下:

構建映象要去到對應的Dockerfile同級目錄下去執行。

例如,去到scripts/apollo-on-kubernetes/apollo-config-server下執行:

docker build -t apollo-config-server:v1.7.1 .

注意,總共要構建4個映象。整體的思路是:先構建映象,然後打tag,再推到倉庫裡去。

在對應目錄下,總結整體指令碼如下:

alpine-bash-3.8-image的映象:docker build -t alpine-bash:3.8 .docker tag alpine-bash:3.8  hub.thinkinpower.net/zizai/alpine-bash:3.8docker push hub.thinkinpower.net/zizai/alpine-bash:3.8apollo對應的映象:docker build -t apollo-config-server:v1.7.1 .docker tag apollo-config-server:v1.7.1  hub.xx.net/zizai/apollo-config-server:v1.7.1docker push hub.xx.net/zizai/apollo-config-server:v1.7.1docker build -t apollo-admin-server:v1.7.1 .docker tag apollo-admin-server:v1.7.1  hub.xx.net/zizai/apollo-admin-server:v1.7.1docker push hub.xx.net/zizai/apollo-admin-server:v1.7.1docker build -t apollo-portal-server:v1.7.1 .docker tag apollo-portal-server:v1.7.1  hub.thinkinpower.net/zizai/apollo-portal-server:v1.7.1docker push hub.thinkinpower.net/zizai/apollo-portal-server:v1.7.1
二、部署apollo到kubernetes

1、建立資料庫指令碼

說明一下:

在實際的生產環境使用中,透過分散式儲存來實現的磁碟在mysql這種IO密集性應用中,效能問題會顯得非常突出。所以在實際應用中,一般不會把mysql這種應用直接放入kubernetes中管理,而是使用專用的伺服器來獨立部署。而像web這種無狀態應用依然會執行在kubernetes當中,這個時候web伺服器要連線kubernetes管理之外的資料庫,有兩種方式:一是直接連線資料庫所在物理伺服器IP,另一種方式就是藉助kubernetes的Endpoints直接將外部伺服器對映為kubernetes內部的一個服務。

我們使用外面的mysql作為資料庫,不會將mysql部署到k8s裡。

執行目錄scripts/apollo-on-kubernetes/db下的指令碼。Apollo服務端共需要兩個資料庫:ApolloPortalDB和ApolloConfigDB。每一個配置的config一個數據庫指令碼,portal一個數據庫指令碼。資料庫指令碼見:https://github.com/ctripcorp/apollo/tree/master/scripts/apollo-on-kubernetes/db,在git裡已經有。如果apollo 開啟了 4 個環境, 即 dev、test-alpha、test-beta、prod, 在MySQL 中匯入 scripts/apollo-on-kubernetes/db 下的檔案。

2、部署k8s的yaml檔案

官網的yaml可以下載修改就可以了,因為我用自己的倉庫的映象,並且多次測試,我主要有如下的修改:

securityContext:

privileged: true

(2)新增倉庫的金鑰:

imagePullSecrets:

- name: registry-harbor

(3)下面修改為每次都拉映象:Always

imagePullPolicy: Always

(4)新增mysql的配置資訊

我只用3個環境,需要修改的檔案如圖:

因為修改得比較多,我將在下面列出每一個檔案。我只拿開發環境apollo-env-dev的作為一個示例,其它的只是對應修改就可以了。在執行的時候,建議大家從下面的(3)、(2)、(1)的順序執行下面的檔案。

(1)、service-apollo-admin-server-dev.yaml

---# configmap for apollo-admin-server-devkind: ConfigMapapiVersion: v1metadata:  namespace: zizai  name: configmap-apollo-admin-server-devdata:  application-github.properties: |    spring.datasource.url = jdbc:mysql://service-mysql-for-apollo-dev-env.zizai:3306/DevApolloConfigDB?characterEncoding=utf8    spring.datasource.username = admin    spring.datasource.password = mysql-admin    eureka.service.url = http://statefulset-apollo-config-server-dev-0.service-apollo-meta-server-dev:8080/eureka/,http://statefulset-apollo-config-server-dev-1.service-apollo-meta-server-dev:8080/eureka/,http://statefulset-apollo-config-server-dev-2.service-apollo-meta-server-dev:8080/eureka/---kind: ServiceapiVersion: v1metadata:  namespace: zizai  name: service-apollo-admin-server-dev  labels:    app: service-apollo-admin-server-devspec:  ports:    - protocol: TCP      port: 8090      targetPort: 8090  selector:    app: pod-apollo-admin-server-dev  type: ClusterIP  sessionAffinity: ClientIP---kind: DeploymentapiVersion: apps/v1metadata:  namespace: zizai  name: deployment-apollo-admin-server-dev  labels:    app: deployment-apollo-admin-server-devspec:  replicas: 3  selector:    matchLabels:      app: pod-apollo-admin-server-dev  strategy:    rollingUpdate:      maxSurge: 1      maxUnavailable: 1    type: RollingUpdate  template:    metadata:      labels:        app: pod-apollo-admin-server-dev    spec:      imagePullSecrets:           # dokcer倉庫密碼,不需要的可以去掉        - name: registry-harbor      affinity:        podAntiAffinity:          preferredDuringSchedulingIgnoredDuringExecution:          - weight: 100            podAffinityTerm:              labelSelector:                matchExpressions:                - key: app                  operator: In                  values:                  - pod-apollo-admin-server-dev              topologyKey: kubernetes.io/hostname            volumes:        - name: volume-configmap-apollo-admin-server-dev          configMap:            name: configmap-apollo-admin-server-dev            items:              - key: application-github.properties                path: application-github.properties            initContainers:        - image: hub.thinkinpower.net/zizai/alpine-bash:3.8          imagePullPolicy: Always          name: check-service-apollo-config-server-dev          command: ['bash', '-c', "curl --connect-timeout 2 --max-time 5 --retry 60 --retry-delay 1 --retry-max-time 120 service-apollo-config-server-dev.zizai:8080"]            containers:        - image: hub.thinkinpower.net/zizai/apollo-admin-server:v1.7.1          imagePullPolicy: Always          name: container-apollo-admin-server-dev          ports:            - protocol: TCP              containerPort: 8090          volumeMounts:            - name: volume-configmap-apollo-admin-server-dev              mountPath: /apollo-admin-server/config/application-github.properties              subPath: application-github.properties                    env:            - name: APOLLO_ADMIN_SERVICE_NAME              value: "service-apollo-admin-server-dev.zizai"                    readinessProbe:            tcpSocket:              port: 8090            initialDelaySeconds: 10            periodSeconds: 5                    livenessProbe:            tcpSocket:              port: 8090            initialDelaySeconds: 120            periodSeconds: 10                dnsPolicy: ClusterFirst      restartPolicy: Always

(2)、service-apollo-config-server-dev.yaml

---# configmap for apollo-config-server-devkind: ConfigMapapiVersion: v1metadata:  namespace: zizai  name: configmap-apollo-config-server-devdata:  application-github.properties: |    spring.datasource.url = jdbc:mysql://service-mysql-for-apollo-dev-env.zizai:3306/DevApolloConfigDB?characterEncoding=utf8    spring.datasource.username = admin    spring.datasource.password = mysql-admin    eureka.service.url = http://statefulset-apollo-config-server-dev-0.service-apollo-meta-server-dev:8080/eureka/,http://statefulset-apollo-config-server-dev-1.service-apollo-meta-server-dev:8080/eureka/,http://statefulset-apollo-config-server-dev-2.service-apollo-meta-server-dev:8080/eureka/---kind: ServiceapiVersion: v1metadata:  namespace: zizai  name: service-apollo-meta-server-dev  labels:    app: service-apollo-meta-server-devspec:  ports:    - protocol: TCP      port: 8080      targetPort: 8080  selector:    app: pod-apollo-config-server-dev  type: ClusterIP  clusterIP: None  sessionAffinity: ClientIP---kind: ServiceapiVersion: v1metadata:  namespace: zizai  name: service-apollo-config-server-dev  labels:    app: service-apollo-config-server-devspec:  ports:    - protocol: TCP      port: 8080      targetPort: 8080      nodePort: 30002  selector:    app: pod-apollo-config-server-dev   type: NodePort  sessionAffinity: ClientIP---kind: StatefulSetapiVersion: apps/v1metadata:  namespace: zizai  name: statefulset-apollo-config-server-dev  labels:    app: statefulset-apollo-config-server-devspec:  serviceName: service-apollo-meta-server-dev  replicas: 3  selector:    matchLabels:      app: pod-apollo-config-server-dev  updateStrategy:    type: RollingUpdate  template:    metadata:      labels:        app: pod-apollo-config-server-dev    spec:      imagePullSecrets:           # dokcer倉庫密碼,不需要的可以去掉        - name: registry-harbor      affinity:        podAntiAffinity:          preferredDuringSchedulingIgnoredDuringExecution:          - weight: 100            podAffinityTerm:              labelSelector:                matchExpressions:                - key: app                  operator: In                  values:                  - pod-apollo-config-server-dev              topologyKey: kubernetes.io/hostname      volumes:        - name: volume-configmap-apollo-config-server-dev          configMap:            name: configmap-apollo-config-server-dev            items:              - key: application-github.properties                path: application-github.properties            containers:        - image: hub.thinkinpower.net/zizai/apollo-config-server:v1.7.1          imagePullPolicy: Always          name: container-apollo-config-server-dev          ports:            - protocol: TCP              containerPort: 8080          volumeMounts:            - name: volume-configmap-apollo-config-server-dev              mountPath: /apollo-config-server/config/application-github.properties              subPath: application-github.properties                    env:            - name: APOLLO_CONFIG_SERVICE_NAME              value: "service-apollo-config-server-dev.zizai"                    readinessProbe:            tcpSocket:              port: 8080            initialDelaySeconds: 10            periodSeconds: 5                    livenessProbe:            tcpSocket:              port: 8080            initialDelaySeconds:  120            periodSeconds: 10                dnsPolicy: ClusterFirst      restartPolicy: Always

(3)、service-mysql-for-apollo-dev-env.yaml

---# 為外部 mysql 服務設定 servicekind: ServiceapiVersion: v1metadata:  namespace: zizai  name: service-mysql-for-apollo-dev-env  labels:    app: service-mysql-for-apollo-dev-envspec:  ports:    - protocol: TCP      port: 3306      targetPort: 3306  type: ClusterIP  sessionAffinity: None---kind: EndpointsapiVersion: v1metadata:  namespace: zizai  name: service-mysql-for-apollo-dev-envsubsets:  - addresses:      - ip: 10.29.254.48    ports:      - protocol: TCP        port: 3306

3、新增Ingress

官網給的示例是用k8s的NodePort來訪問,但是在實際中,我們用會用Ingress來訪問Portal。

注意:因為我們在部署portal的時候是多例項的,所以Ingress要新增保持會話,要不頁面會登入不了,進入不了portal頁面。具體為:

metadata:  annotations:    nginx.ingress.kubernetes.io/affinity: "cookie"  # 解決會話保持    nginx.ingress.kubernetes.io/session-cookie-name: "route"    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"

ingress的程式碼示例為如下:

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: zizai-apollo-portal  namespace: zizai  annotations:    nginx.ingress.kubernetes.io/affinity: "cookie"  # 解決會話保持    nginx.ingress.kubernetes.io/session-cookie-name: "route"    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"spec:  rules:    - host: zizai-apollo-portal.test.thinkinpower.net      http:        paths:          - path: /            backend:              serviceName: service-apollo-portal-server              servicePort: 8070

4、配置nginx

新增nginx訪問到Ingress裡:

nginx配置檔案:zizai-apollo-portal.test.thinkinpower.net.conf

server {  listen     80;  server_name  zizai-apollo-portal.test.thinkinpower.net;  access_log  /data/logs/nginx/zizai-apollo-portal.test.thinkinpower.net.access.log  main;  error_log  /data/logs/nginx/zizai-apollo-portal.test.thinkinpower.net.error.log;  root   /data/webapps/zizai-apollo-portal.test.thinkinpower.net/test/static;  index  index.html index.htm;  client_max_body_size 50m;  location   / {    proxy_set_header Host $http_host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_pass http://kubernetes;  # 指向叢集的  }}

這樣就可以根據域名:http://zizai-apollo-portal.test.thinkinpower.net 訪問portal了。

(1)建立的部署:

(2)建立的有部署副本:

(3)建立的service:

(4)建立的ingress:

(5)建立的配置字典:

1、建立專案

2、選擇一個環境新增變數timeout

3、如果是在新增環境的過程中,重新整理頁面會有“新增補缺環境”的提示

新增補缺環境

14
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 第一行程式碼 Android(第三版)之第一章