在 Kubernetes 上部署 Spinnaker

在 Kubernetes 上部署 Spinnaker

Spinnaker 是一種持續交付平臺,最初由 Netflix 開發,用於快速、可靠地發佈軟件變更。Spinnaker 使開發人員可以更輕鬆地專注於編寫代碼,而無需擔心底層的雲基礎設施,它可以和 Jenkins 以及其他流行的構建工具無縫集成。很早就想要體驗下 Spinnaker 了,但是由於 GFW 的原因嘗試了很多次都無功而返,這次解決了代理的問題終於順利的在 Kubernetes 集群上成功部署上了 Spinnaker。

本文將使用 helm3 來為大家演示在 Kubernetes 集群上安裝 Spinnaker,對應的環境版本如下所示:

<code>$ helm version
version.BuildInfo{Version:"v3.0.1", GitCommit:"7c22ef9ce89e0ebeb7125ba2ebf7d421f3e82ffa", GitTreeState:"clean", GoVersion:"go1.13.4"}
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.2", GitCommit:"66049e3b21efe110454d67df4fa62b08ea79a19b", GitTreeState:"clean", BuildDate:"2019-05-16T18:55:03Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}/<code>

對於 Helm3 的安裝配置其實很簡單,只需要在 kubectl 所在節點上面安裝上 Helm3 客戶端即可,默認就會讀取 kubeconfig 文件來訪問集群。我們這裡使用微軟提供的 helm chart 倉庫源:

<code>$  helm repo ls
NAME URL
stable http://mirror.azure.cn/kubernetes/charts/
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈ Happy Helming!⎈ /<code>

由於我們這裡使用的是 Kubernetes 1.16.x 版本,該版本之後將之前很多資源對象的一些舊的 API 廢棄掉了,比如 Deployment 只能使用 apps/v1 這個版本了,而我們這裡要使用的 Spinnaker 對應的 chart 包目前還是使用的以前的 API 版本,所以我們需要手動下載下來做一次更改:

<code>$ helm fetch stable/spinnaker
$ tar -xvf spinnaker-1.23.2.tgz/<code>

然後將 spinnaker chart 模板中的 Deployment、StatefulSet 這些資源對象的 apiVersion 更改成 apps/v1,也需要記住如果是 Deployment 還需要添加上 selector.matchLabels 字段,大家可以直接使用我更改後的 chart 模板 https://github.com/cnych/spinnaker-helm。

在 chart 模板的 values.yaml 文件中指定了 halyard.spinnakerVersion=1.17.6,這還是因為 apiVersion 版本的問題,該版本以上就可以兼容 Kubernetes v1.16.x 的集群,另外將默認的 gcr.io 的鏡像替換成了微軟的鏡像源 gcr.azk8s.cn,此外還有一個非常重要的就是存儲的指定,這裡我們創建了一個 StorageClass 的資源對象來提供存儲,我這裡是創建的一個 Ceph RBD 類型的存儲 rook-ceph-block,當然任何可用的 StorageClass 資源對象都是可以的:

<code>apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
reclaimPolicy: Retain
parameters:
# clusterID 是 rook 集群運行的命名空間
clusterID: rook-ceph

# 指定存儲池
pool: k8s-test-pool

# RBD image (實際的存儲介質) 格式. 默認為 "2".
imageFormat: "2"

# RBD image 特性. CSI RBD 現在只支持 `layering` .
imageFeatures: layering

# Ceph 管理員認證信息,這些都是在 clusterID 命名空間下面自動生成的

csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
# 指定 volume 的文件系統格式,如果不指定, csi-provisioner 會默認設置為 `ext4`
csi.storage.k8s.io/fstype: ext4/<code>

需要為 halyard、redis、mino 都指定對應的存儲,當然直接指定一個合適的 PVC 也是可以的,這裡可以根據實際情況決定:

<code>halyard:
...
persistence:
storageClass: rook-ceph-block
...
redis:
...
master:
persistence:
storageClass: rook-ceph-block
...
minio:
...
persistence:
storageClass: rook-ceph-block
.../<code>

接下來最重要的一步就是必須要為 halyard 配置代理,所以繼續下去的前提是你需要配置一個在 Kubernetes 的 Pod 中可以訪問的代理,比如我這裡的代理地址為 10.151.30.11:8118,則需要配置如下所示的 JAVA_OPTS 這個環境變量:

<code>halyard:
env:
- name: JAVA_OPTS
value: '"-Djava.security.egd=file:/dev/./urandom" "-Dhttp.proxyHost=10.151.30.11" "-Dhttps.proxyHost=10.151.30.11" "-Dhttp.proxyPort=8118" "-Dhttps.proxyPort=8118" "-Dhttp.nonProxyHosts=\"localhost|*.spinnaker.com\""'/<code>

獲取上面我修改過後的 Spinnaker 的 Chart 模板,將 values.yaml 文件中上面對應的配置替換成自己對應的配置即可。

<code>$ git clone https://github.com/cnych/spinnaker-helm spinnaker
$ kubectl create ns spinnaker
# 安裝 spinnaker
$ helm install spinnaker --namespace spinnaker ./spinnaker/<code>

由於安裝過程非常耗時,可能上面的 helm install 的過程可能會有超時提示,這個可以忽略:

<code>$ helm ls -n spinnaker
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
spinnaker spinnaker 1 2020-02-17 19:28:02.644552 +0800 CST failed spinnaker-1.23.2 1.16.2 /<code>

安裝完成後最開始會生成如下所示的幾個 Pod,其中 spinnaker-install-using-hal-th8qf 就是用來去真正安裝 Spinnaker 的一個 Job 任務:

<code>$ kubectl get pods -n spinnaker
spinnaker-install-using-hal-th8qf 0/1 Completed 0 17h
spinnaker-minio-86f5b8785-bkjfq 1/1 Running 0 17h
spinnaker-redis-master-0 1/1 Running 0 17h
spinnaker-spinnaker-halyard-0 1/1 Running 0 17h/<code>

不過由於在安裝 Spinnaker 的過程中會使用 gcr.io 的鏡像,所以會看到很多 Pod 鏡像拉取失敗的錯誤,這個時候我們可以手動編輯 Deployment 對象更改鏡像地址:

<code>$ kubectl get deploy -n spinnaker
NAME READY UP-TO-DATE AVAILABLE AGE
spin-clouddriver 0/1 1 0 17h
spin-deck 0/1 1 0 17h
spin-echo 0/1 1 0 17h
spin-front50 0/1 1 0 17h
spin-gate 0/1 1 0 17h
spin-igor 0/1 1 0 17h
spin-orca 0/1 1 0 17h
spin-rosco 0/1 1 0 17h
spinnaker-minio 1/1 1 1 17h/<code>

比如修改 spin-deck 這個 Deployment 資源對象的鏡像地址:

<code>$ kubectl edit deploy spin-deck -n spinnaker
# 然後在打開的編輯中將 gcr.io 替換成 gcr.azk8s.cn/<code>

用同樣的方法替換其他資源對象,正常替換過後隔一段時間就可以正常啟動 Pod 了,最終的 Pod 列表如下所示:

<code>$ kubectl get pods -n spinnaker           
NAME READY STATUS RESTARTS AGE
spin-clouddriver-76b8989b4f-cjw8r 1/1 Running 0 17h
spin-deck-5fd7b64b77-fnl5r 1/1 Running 0 17h
spin-echo-644c4cb6b6-gh98w 1/1 Running 0 17h
spin-front50-9d99cd697-cqbxb 1/1 Running 0 17h
spin-gate-6c49bccb6f-nhbzx 1/1 Running 0 17h
spin-igor-7c84d9bcb-rltw7 1/1 Running 0 17h
spin-orca-b5944685-wbm5p 1/1 Running 0 17h
spin-rosco-6d5f9c8f55-g89hq 1/1 Running 0 17h
spinnaker-install-using-hal-th8qf 0/1 Completed 0 17h
spinnaker-minio-86f5b8785-bkjfq 1/1 Running 0 17h
spinnaker-redis-master-0 1/1 Running 0 17h
spinnaker-spinnaker-halyard-0 1/1 Running 0 17h/<code>

到這裡就證明我們的 Spinnaker 已經安裝成功了,這個時候如果我們想要把 Spinnaker 暴露給外部用戶訪問,當然可以創建一個 NodePort 類型的 Service,或者創建一個 Ingress 資源對象即可,其實上面的 chart 模板中我們就可以通過配置指定 Ingress 資源對象的參數。由於我這裡使用的是 Traefik2.1 版本,所以單獨創建一個 IngressRoute 資源對象來暴露服務:

<code>apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: spin-deck-https
namespace: spinnaker
spec:
entryPoints:
- websecure
routes:
- match: Host(`spinnaker.qikqiak.com`)
kind: Rule

services:
- name: spin-deck
port: 9000
tls:
certResolver: ali
domains:
- main: "*.qikqiak.com"
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: redirect-https
namespace: spinnaker
spec:
redirectScheme:
scheme: https
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: spin-deck-http
namespace: spinnaker
spec:
entryPoints:
- web
routes:
- match: Host(`spinnaker.qikqiak.com`)
kind: Rule
services:
- name: spin-deck
port: 9000
middlewares:
- name: redirect-https/<code>

直接創建上面的資源對象即可,對 Traefik2 使用不是很熟悉的,可以查看前面的文章 一文搞懂 Traefik2.1 的使用 瞭解更多,然後直接對域名 spinnaker.qikqiak.com 做好 DNS 解析即可在瀏覽器中訪問 Spinnaker 了:

在 Kubernetes 上部署 Spinnaker

spinnaker dashboard

到這裡就安裝成功了,當然這只是萬里長征的第一步呢,後面我們再慢慢的去了解 Spinnaker 到底有哪些值得我們關注的功能。



分享到:


相關文章: