2019年6月28日 星期五

istio 的安裝設定調整 (2)

istio 預設選項裡 kiali 和 tracing 是 disable 的,不過這次安裝我想測試這部分的功能,所以把 values.yaml 這兩個選項都 enable 起來試看看。另外為了測試 tracing 功能,所以安裝了 istio 提供的範例程式 bookinfo。其中 bookinfo 的瀏覽網址會是 istio ingress 的 ip 加上 /productpage ,例如 http://10.10.10.185/productpage

裝好後,應該會有兩個 UI ,分別來自 jaeger 和 kiali。為了方便測試,我把這兩個 UI 相關的 svc 的 type 都改成 LoadBalancer,這兩個 svc 名稱分別為 jaeger-query 和 kiali。

然後開始瀏覽 bookinfo 的 page ,發現 jaeger-query 的網頁完全沒有 bookinfo 的紀錄。
這邊是我遇到的第一個坑。

jaeger 分成三個元件,query (即 web UI)、agent、collector,從 istio 安裝的 namespace 裡可以看到三個對應的 svc ,即 jaeger-query、jaeger-agent、jaeger-collector。不過仔細一看,這三個 service 都對應到同一個 labels 的 pods (app: jaeger),也就是 istio-tracing。

這是因為 istio 預設使用的是 all-in-one 的 jqeger image,所以這三個 svc 其實都是同一個 pod 在處理 (其實不止這三個,zipkin 這個 svc 也是指向 istio-tracing 這個 pod) 。

不過問題不在這,問題在於 istio 預設的 tracing 採樣率設定為 1 ...%,也就是 100 個 requests 裡只取樣 1 次。這對於實際上線時是有必要的,但對測試 istio 本身的功能是很不方便的。所以要調整一下取樣率,來把它設定為 100%。

查了一下設定的地方,是在 istio-sidecar-injector 這個 configMap 裡的 traceSampling。不過因為是以 json 格式的方式儲存,所以直接修改 confgMap 不太方便。

比較簡單的設定方式,就是修改 values.yaml ,不過 values.yaml 看不出來設定的地方,所以要參考 istio 提供的 values-istio-demo.yaml 裡面 pilot 的部分,把 traceSampling 設定為 100.0,然後更新設定即可。

更新後,每次瀏覽 bookinfo 後,都可以在 jaeger 的 UI 上看到資料了。
接下來看 kiali 的 UI,在登入的部分遇到第二個坑。

進入到 kiali UI 遇到的第一個問題,它會顯示沒有設定帳號密碼之類的訊息。
kiali 會檢查有沒有 kiali 這個 secret,有的話會掛載起來當帳號密碼來源。所以最簡單的解決方式就是手動建立
kubectl create secret generic kiali -n istio-system --from-literal "username=root" --from-literal "passphrase=1234"

建立完之後,刪除 kiali pods ,讓它自動重建一個 pod ,這樣才會把 secret 掛載起來,然後就可以用設定好的資料登入了。

在處理完上面這些後,才發現在 values-istio-demo.yaml 的 kiali 的部分,有一個 createDemoSecret 的選項,所以看起來如果有先設定這個話,是可以自動建立好登入用的帳號密碼。
2019/07/03 補充:如果設定為 createDemonSecret,會自動建立帳號密碼都為 admin 的 secret。

登入後會出現訊息說找不到 grafana 和 jaeger service。官網是這樣說明的

This task does not discuss Jaeger and Grafana. If you already installed them in your cluster and you want to see how Kiali integrates with them, you must pass additional arguments to the helm command, for example:
$ helm template \ --set kiali.enabled=true \ --set "kiali.dashboard.jaegerURL=http://jaeger-query:16686" \ --set "kiali.dashboard.grafanaURL=http://grafana:3000" \ install/kubernetes/helm/istio \ --name istio --namespace istio-system > $HOME/istio.yaml $ kubectl apply -f $HOME/istio.yaml
不過上面沒有說明到的部分是,kiali 並不是直接取得 jaeger 和 grafana 的資料再顯示到瀏覽器上,而是提供網址讓瀏覽器自己用 ajax 的方式去 jaeger 和 grafana 要資料。

也就是說,上面設定的兩個網址,必須是瀏覽器認得的,而不是 kuberentes 內部的 cluster name or ip。

因為我把 jaeger 和 grafana 的 svc type 都改成 LoadBalancer,所以要設定一個讓瀏覽器可以認得的 url ,例如 http://10.10.10.190:16686/jaeger

修改完後,可以在 kiali 上看到 jaeger 產生的圖了,但是 grafana 還是不行。
查了又查,改了又改,發現 kiali 裡設定的 grafana url 怎麼改,都不會改變瀏覽器去取得 grafana 資料的路徑。看到網路上有人說這是 istio 裡 kiali 的 bug,所以這部分就暫時先不去管了。
2019/07/03 補充:雖然 kiali 都會出現找不到 grafana service 的訊息,但只要有設定好,還是可以出現圖。

另外,如果像前一篇提到的方式,沒有安裝 istio 本身的 prometheus 的話,kiali 也會出現連不到 prometheus 之類的訊息,所以要去設定 kiali 的 configMap,加上 prometheus 的 url。不過這邊是 kiali 直接去抓 prometheus 的資料,所以只要設定 cluster 內部認得的 domain name 即可,例如
    external_services:
      prometheus:
        url: http://prometheus-prometheus-oper-prometheus.monitoring:9090

istio 的安裝設定調整 (1)

關於 istio 的安裝設定,先從外圍的 prometheus 和 grafana 講起,這次安裝的版本是 istio 1.2.0

istio 官方文件的安裝方式裡,預設會安裝一份 prometheus ,也可以調整選項把 grafana 的安裝給 enable。

因為已經安裝了 prometheus-operator ,希望能夠整合到一起。
比較簡單的方式,就是讓 istio 依照預設也安裝一份 prometheus ,然後從 prometheus-operator 的 granfana 新增一個 data source 即可。
不過最好的情況,當然還是維持只有一個 prometheus 是比較好的做法。

這邊有一篇文章說明了如何用 prometheus-oprator 來收集 isito 的資訊。
我是設定好後才看到上面那篇文章,做法上大致相同,只是我用的方式比較刻苦一點。

先取得 istio 裡的 prometheus 的 config ,最簡單的方法是先依預設方式安裝好一份 istio ,然後從裝好的 prometheus 裡取出設定檔,或者依照上面那篇文章提供的設定內容。

原本以為直接修改 prometheus  secrets 裡的設定就好,發現 secrets 裡的設定檔是壓縮過的格式 prometheus.yaml.gz 。不過想說這也不是什麼大問題,取出來解壓縮,修改完在壓縮後更新回去就好。
kubectl -n monitoring get secrets prometheus-prometheus-prometheus-oper-prometheus -o jsonpath='{.data.prometheus\.yaml\.gz}' | base64 -d | gunzip > /tmp/prometheus.yaml

然後把前面取出的設定整合到 /tmp/prometheus.yaml ,然後 gzip、base64 最後 kubectl edit 貼回 secret 就搞定。

咦?不 work 。仔細一看,kubectl edit 修改完儲存後,再進去又變回原本的內容。

仔細查看 prometheus-operator 的機制,是要透過另外的 secrets 來新增 scrape config
最簡單的方式,就是在 prometheus-operator values.yaml 的 additionalScrapeConfigs 加上自訂的 scrape config

如果之前沒有設定過 additionalScrapeConfigs ,那在這次設定完之後,會發現安裝的 namespace 下多了一個 secrets prometheus-prometheus-oper-prometheus-scrape-confg,新增的設定就在這個 secret 裡
kubectl -n monitoring get secrets prometheus-prometheus-oper-prometheus-scrape-confg -o jsonpath='{.data.additional-scrape-configs\.yaml}' | base64 -d


這個沒有 gzip 壓縮過了,之後如果要再新增 scrape config,可以直接修改這個 secret,就可以不用再透過 values.yaml 了。雖然透過 helm 來更新還是比較方便的,不過經常是因為在測試設定的方式來做更新,一直透過 helm 會讓安裝版本記錄更動太多。比較好的方式是測試設定正確後,再修改 values.yaml 做更新,這樣可以確保 helm history 裡的安裝歷史紀錄的版本都是可以運作的。

把 prometheus 搞定後,剩下的 grafana 就比較簡單了。

我是直接把 istio 目錄下的 charts/grafana/dashboards/ 裡的所有 json file ,一個一個從 grafana UI 裡做 import 。如果有些 dashboard 沒資料,可能是因為 promethues scape config 沒設定好的關係,不過至少 gallary pilot mixer 三個 dashboard 應該是有資料的。

簡單的部分先到這邊了。

2019年6月20日 星期四

讓 prometheus-operator 監控 cluster 外部的 metrics

故事的緣起是在 enable 公司的 ceph dashboard plugin 時,發現 ceph 還有一個 prometheus 的 plugin ,這個 plugin 是一個 prometheus exporter ,也就是 enable 這個 plugin 後,就可以從
http://[ceph ip]:9283/metrics

取得 ceph 的 metrics data。那要如何設定讓 kubernetes 內的 prometheus 可以抓到 ceph 的 metrics ?故事就是這樣開始的...

我是用 prometheus-operator 的方式安裝的,這篇對 prometheus-operator 的架構有很不錯的介紹。從這邊可以知道,要新增 metrics 的關鍵在於 servicemonitor 這個 resource ,這是安裝 prometheus-operator 新增的 CRD resource 。

所以新增一個 servicemonitor 去設定要拉 metrics 的來源 service 就好了,簡單吧?
事情好像沒想像中那麼美好,ceph 是在 kubernetes 外部,cluster 內部沒有 ceph 相關的 svc 設定,這段要自己搞定。

凡事問 google ,找到這篇,節省了非常多的時間。

建立 ep => 建立 svc => 建立 servicemonitor 
打完收工。

喔,不,文章中有一些小地方需要修正一下。
最主要的關鍵是文章裡 "BOOM" 那行找到的 label ,和現在 prometheus-operator 的設定不一樣,這應該是版本的關係。

修正 label 的部分,以及一些必要的修改 (像 ip 之類的),剩下的還有一些小錯誤要修正,調整完後就差不多真的完工了。

kubectl apply 上面設定好的 yaml 後,就可以從 prometheus 的 UI 來驗證一下
* 從 Status 的 target 和 service discovery 可以看到新增的 servicemonitor 名稱
* 從資料篩選的地方輸入 ceph 就會自動跳出很多符合的名稱可以篩選,例如 ceph_bluefs_bytes_written_slow

prometheus 這邊搞定後,就往 grafana 前進,隨便找個 for ceph 的 dashboard ,例如編號 7056,從 grafana 匯入這個 dashboard ,就可以從 grafana 看到 ceph 的資料了。

就數值的部分和 ceph 本身的 dashboard 看起來都差不多,不過有一些小地方可能有點問題。畢竟是用別人現成的 dashboard,這個微調的部分就暫時不管了。

這樣對 prometheus-operator 的瞭解又多了一點,之後要拉其他的 application 的 metrics 就比較有把握了。

Log collect by Loki

比較常看到的 log collect 會使用 ELK 或 EFK 的架構,因為之前有安裝過 ELK 覺得太笨重,所以想試看看 Loki ,這樣 metrics (Prometheus) 和 logging (Loki) 就可以共用一套前端 (Grafana) 來處理。

Loki 基本上非常好安裝,用 helm 安裝的話甚至連 values.yaml 都不用修改。
helm repo add loki https://grafana.github.io/loki/charts
helm repo update
helm install -n loki --namespace logging loki/loki-stack

然後因為我原本就已經有安裝 prometheus 和 grafana ,所以直接到 grafana 的 UI 去設定。新增一個 data source ,選擇 Loki。在設定 loki url 的地方,如果 loki 安裝的 namespace 和 grafana 一樣,就可以直接照官方設定為 http://loki:3100/

因為我是設定在不同的 namespace,所以要修改為
http://loki.logging:3100

這個只要略懂 kubernetes 內部 DNS 運作方式的話,應該很好理解和判斷。
設定好之後,到 grafana 選單的 Explore 選項,就可以看到 log data 慢慢出現了。

loki 是用 promtail 來收集 log ,所以會看到 promtail 這個 DaemonSet 在每一個 node 上。而 promtail 預設是收集 container 的 log  ,也就是 /var/lib/docker/contaibners 及 /var/log/pods 裡的 log。 promtail 的設定可以參考 helm chart 裡的 charts/promtail/values.yaml 這個檔案。

如果要將前一篇的 audit log (或者連 host 的 syslog 一起) 也放進 loki 的話,理論上應該是改 promtail 設定是最適合的。 不過對 helm chart 不熟,對 promtail 設定的語法也不熟 (語法和 prometheus 一樣) ,而且也想嘗試用其他方式餵資料給 loki 看看,所以選擇用 fluentd 來做。

我是直接找一個現成的專案來試,這個專案把 loki plugin for fluentd 包進去,只要改幾個地方就可以運作了。

先修改 values.yaml,設定 loki 的 url ,因為我預定安裝在和 loki 一樣的 namesapce ,所以只要設定
http://loki:3100

還有設定 source 的 log path ,例如
path /var/log/kubernetes/kube-audit

另外要修改 templates/05-deployment.yaml 這個檔案,裡面有一個 nodeSelector 設定,目的是篩選 master node 來 deploy (因為只有 master node 上會有 audit log)。
但是預設的 nodeSelector 的篩選條件 (role: master) 和我現有的環境不符合,我也不想為了這個去設定 node 的 label ,所以修改這邊的設定為
node-role.kubernetes.io/master:
另外因為我這邊是多台 master node ,如果以 deployment 方式部署較不適合,所以把 Deployment 改為 DaemonSet ,在這份 yaml 中,直接這樣修改是沒問題的。
都修改完之後,就可以 deploy 了。
helm install --name=fluentd-loki ./ --namespace=logging

然後就可以到 grafana 的 UI 去做驗證了。
選擇 label 為 {env="dev"} 就可以看到透過 fluentd 取得的 audit log 了。
那這個 label 是哪來的? 

回頭看 values.yaml 的設定裡,有一個 extra_labels ,就是設定透過 fluentd 傳進去的 log 會有什麼 label 。

接著可以參考 grafana 官網,看看怎樣篩選需要的 log ,例如要找出 audit log 裡,verb 是 create 類型的,可以這樣篩選
{env="dev"} verb="create"


到此先告一段落囉。

2019年6月19日 星期三

kubernetes 內建的 audit 機制

官方資料裡有關於 audit 尚稱完整的說明,不過在實際上與設定上還是有一些需要摸索的地方,在這邊做個紀錄。

audit 的功能,是透過 kubernetes API Server 來做,所以首先是要修改 apiserver 的設定。如果是用 kubeadm 安裝,設定檔是在 /etc/kubernetes/manifests/kube-apiserver.yaml

不過在修改設定檔之前,要先設定好 audit 相關的 policy file 提供給 apiserver ,因為 apiserver 是屬於 static pod ,一修改設定就會直接重啟 pod。

Policy 設定的方式稍後再說,先用官方提供的最簡範例
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata

為了方便測試 (稍後說明),將上面內容存放在 /etc/kubernetes/pki/audit-policy.yaml ,然後就可以開始修改 apiserver 的設定檔了。

修改的內容最主要是開啟 audit 及相關參數,這邊先只設定必要的參數,分別是 policy file 的路徑、audit log 的路徑、以及 log 的格式
    - --audit-policy-file=/etc/kubernetes/pki/audit-policy.yaml
    - --audit-log-path=/var/log/kube-audit
    - --audit-log-format=json

前面提到 policy file 放置的路徑是為了方便,原因在於 apiserver 是一個 pod , pods 裡是看不到 host 的檔案的,而觀察一下 apiserver 的 yaml 設定,可以發現 /etc/kubernetes/pki 這個路徑是有掛載在 pod 裡,所以為了方便,把 policy file 放在這邊就不需要額外設定,就可以讓 apiserver 取得。如前所述,修改完設定檔後,apiserver pod 會自動重啟。

接下來用 kubectl exec 的方式進到 apiserver pod ,確認一下 pod 裡的 /var/log/kube-audit 是否有產生。以上面設定的 policy 內容來說,會把所有事件的 metadata 都記錄下來,所以如果有設定正確的話,應該會看到 audit log 如雪片般的飛來。

不過把 log file 放在 pod 裡,這樣不容易管理與稽核,這時有四種做法。

第一種是把 audit log 改送到 stdout (修改 log path 的設定變成 --audit-log-path=-),這樣就會和其他的 container 一樣,會把 log 寫在 host 的 /var/lib/docker/containers/ 裡。不過這種做法,會因為 apiserver 的 log format 是 json ,要和其他 container log 一起管理會產生差異,所以我放棄這種方式。

第二種方式是透過 sidecar。有些 app/image 沒有把 log 丟到 stdout/stderr ,就要透過 sidecar 的方式去收集 log ,常見的做法是把 fluentd 作為 sidecar 來搜集 log 。不過因為 apiserver 是 static pod,我也不太傾向用 sidecar 的方式來處理。

第三種是把 audit log 設定為 webhook ,把 log 送到指定的 url 。因為 apiserver static pod ,這種方式需要在 cluster 外部設定好可以收 log 的 webhook ,如 logstash 或 fluentd 等。因為我目標是把 log 整合在 cluster  內部的 app ,所以也沒採取這種方式。

最後一種方式就是直接把 host 上的路徑掛載到 apiserver 上產生 log 的路徑下。
例如我規劃把 audit log 會寫到 host 的 /var/log/kubernetes/ 下,就修改 apiserver 設定檔,增加內容如下
# 指定 host 路徑
  - hostPath:
      path: /var/log/kubernetes
      type: DirectoryOrCreate
    name: k8s-audit
# 指定掛載路徑
    - mountPath: /var/log
      name: k8s-audit
設定正確的話,就可以看到 host 的 /var/log/kuberentes/kube-audit 裡的 audit log 如雪片般的飛來。

在思考如何把 audit log 和其他 log 一起管理之前,先來調整一下 policy file ,否則 log file 成長的會非常快。

官網上對於 policy file 有一些基本的介紹,不過這篇寫得比較完整

設定檔裡面的幾個主要的項目:

* omitStages
  指 audit log 發出來的時機
  選項有 RequestReceived / ResponseStarted / ResponseComplete / Panic

* level
  記錄 log 內容的完整程度,None 就是不紀錄
  選項有 None / Metadata / Request / RequestResponse

然後參考 rules 裡的其他設定項,如 verbs、users、resources 等,仔細看會發現和 kuberntes RBAC 的設定方式一樣,例如 verbs 的選項有
["get", "list", "watch", "create", "update", "patch", "delete"]


所以假設今天要設定的規則是,只記錄 namespace 的 create 和 delete,其他通通不記錄,那 rules 的寫法會如下
apiVersion: audit.k8s.io/v1beta1
kind: Policy
omitStages:
  - "RequestReceived"
rules:
  - level: Request
    verbs: ["create", "delete"]
    resources:
    - group: ""
      resources: ["namespaces"]
  - level: None

到這邊可能遇到兩個問題

* 修改 policy file 並不會讓 apiserver pod 重啟,如果用 kubectl delete pod 的方式對 static pod 也是無效的,所以最簡單的方式,就是把 apiserver 的設定檔移到別的路徑下再移回來,就可以讓 apiserver pod 重啟了。

* 如果 master node 不止一台,而且有用 haproxy 之類的擋在前面做 load balance ,就會遇到和我一樣的問題。因為對 api server 的 request 是會輪詢的,所以要測試時會出現非預期的結果。我一開始沒注意到這個問題,想說一樣的 kubectl create ns 指令,為什麼有時候有產生 audit log ,有時候沒有。後來修改 kubectl context 直接指向有變更設定的 apiserver ,就可以很正常的依測試產生 audit log 了。


audit 的部份到這邊告一段落,接下來把 host 上面的 audit log 和其他 log 整合一起,就是另一個故事了。


2019年6月13日 星期四

alertmanager 初探

環境是延續之前安裝的 prometheus-operator

alertmanager 裡的設定主要分為幾個項目:

* receivers : 設定有哪些可以接收 alert 的接收端
* routes: 設定哪些 rules 要送到哪些 receiver
* templates: alert 的內容可以套用預先定義好的 template

prometheus-operator 裡預設的 receivers 是 null ,也就是完全不會發通知出去,這設定可以從 alertmanager 的 UI 的 Status 看到。

如果要從 command line 看 alertmanager 的設定,可以用以下指令
kubectl -n monitoring get secrets alertmanager-prometheus-prometheus-oper-alertmanager -o jsonpath='{.data.alertmanager\.yaml}' | base64 -d



首先替 alertmanager 加上 receiver 的設定,一樣還是修改 values.yaml 再用 helm upgrade 更新會比較方便。找到 values.yaml 關於 alertmanaget 的 config 的地方,修改成如下 (以通知到 slack channel 為例) :
config:
  global:
    slack_api_url: SLACK_HOOK_URL  // 置換成自己設定好的 slack hook url
  route:
    group_by: ['alertname', 'datacenter', 'app', 'job']
    receiver: 'slack-notifications'
  receivers:
    - name: 'slack-notifications'
      slack_configs:
      - channel: '#k8s-alertmanager'
         text: '{{ template "slack.k8sbridge.txt" . }}'

最後那行是說 text 要套用指定的 template,所以同樣在 values.yaml 設定 template 的部分
templates:
  - '*.tmpl'
這兩行是告訴 alertmanager 要 include 預設路徑下的所有 .tmpl 檔案
然後把後面 templatesFiles 那一大段都 uncomment,只修改 define 的 tempalte name,要對應前面設定的 text 裡的 template name,例如:
  templateFiles:
    template_1.tmpl: |-
        {{ define "cluster" }}{{ .ExternalURL | reReplaceAll ".*alertmanager\\.(.*)" "$1" }}{{ end }}
        {{ define "slack.k8sbridge.tet" }}

設定完以後,用 helm upgrade ,沒問題的話就會看到指定的 slack channel 裡出現 alertmanager 送出來的訊息。


2019-09-21 補充:
helm 安裝的 prometheus-operator 的 values.yaml 裡的 templateFiles 裡的範例,少了兩個最後的 {{ end }}
這個 template 語法和 go-template 是一樣的,所以 {{ define "xxxx" }} 和 {{ range }} 後面都要配對一個 {{ end }}

之前設定時,正好去忙別的事,沒有 check log 驗證設定是否正確。這兩天看到 alertmanager log 裡有錯誤訊息,抽時間來修正一下。

2019年6月11日 星期二

helm 的零碎小知識

記錄一下 helm 常使用的指令及一些小細節

安裝 helm 時,會先用 helm init 建立和 kubernetes cluster 的關係,也就是會 deploy 一個叫 tiller 的 deployment 到 kubernetes (預設在 namespace kube-system) 。

後續所有套件安裝的資訊以及將套件 deploy 到 kubernetes 都是透過 tiller 進行,因此 tiller 需要足夠的權限,而 tiller 的權限則是在 helm init 決定]。所以在 helm init 前,需要在 namespace kube-system 先建立好一個 service account,並且給予足夠的權限。然後在 helm init 時,用 --service-account 指定建立好的 service account。

helm 基本指令的使用都還蠻直覺的,不過在看指令前,先簡單了解一下 helm 的套件運作方式。

在 kubernetes 裡,部署、設定、管理之類的動作都是透過 yaml 進行,而一個軟體的部署可能會用到很多個 yaml 檔來設定,而且其中可能很多設定內容都是重複的。helm 做的事情就是把要讓使用者設定的項目提取出來,放在 values.yaml 裡,然後在安裝時,把 values.yaml 裡的設定內容轉化成真正的 yaml 檔案後,再部署到 kubernetes 裡。

所以用 helm 安裝套件時,大部分的情況都是會需要變更 values.yaml 的設定後再部署。也就是說大部分的安裝指令會類似如下:
helm install -f values.yaml -n pm --namespace monitoring stable/prometheus

會指定安裝後的名稱、要安裝到哪個 namespace、以及要讀取哪個 yaml 檔裡的設定。

但是一般來說,除非對要安裝的套件很熟了,否則不會知道 values.yaml 裡設定了什麼,所以要先透過 helm 指令,將套件抓下來後,取得裡面的 values.yaml 來修改。
helm fetch stable/prometheus

這樣就可以把 promethues 這個套件下載回來,下載的套件是一個 tarball ,解開來後,裡面就會有一個 values.yaml ,可以修改完後,用上述的指令進行安裝。

然而通常情況是,很多套件一開始使用時,values.yaml 設定的結果還需要調整。
有些小地方,可能直接用 kubectl 指令做一些調整就好,但是有些設定可能需要修改 values.yaml 再跑 upgrade 會方便一些。
helm upgrade -f values.yaml pm stable/prometheus

在刪除套件時,因為我大部分都是測試性質,不太會有 rollback 需求,所以通常都會完整的移除套件。有沒有加 --purge 參數的差別可以看這篇
helm delete pm --purge

另外較常用的指令大約就是
helm ls  #查看已安裝的套件
helm status pm # 查看已安裝套件名稱為 pm 的安裝資訊

最後是關於 private repo for helm
我是用 harbor 當 helm 的 repo,在啟動 harbor 時,加上 --with-chartmuseum 參數,harbor 就可以做為 helm 的 private repo。

要讓 helm 使用 private repo ,要先進行一些設定

* 新增 repo 的 url 到 helm,用 helm repo add 指令
* 安裝 helm plugin ,後續才能用 helm push 把套件推送到 repo 上。

關於這部分,這篇有蠻完整的介紹。
我個人覺得這部分的使用有點麻煩,因為我架設的 harbor 有使用 ssl ,因此要 helm repo add 或 helm push 時,都要指定一堆憑證路徑的參數 (--ca-file --cert-file --key-file)。
雖然這可以透過一些方式來簡化,但要自動化處理時,要把這些加入流程又要注意 security 會有點繁瑣。

2019年6月8日 星期六

CKA 小記

距離當初考 CKA 三個月了,簡單記錄一下考試的經驗。

題目共 24 題,其中 6~9 分的大約 4 題,其他 20 題則是 1~4 分。

在分數比較多的 4 題裡,大致上是如下題型:

1. 提供 ca 等憑證的路徑,建立起 master node ,也就是官網裡的 tls bootstrapping 的部分

2. secrets 的設定使用的情境

3. cluster 內的 DNS 查詢,也就是會先要求建立一個 pod 和 service ,然後用 nslookup 分別作正反查

4. 用 etcdctl 對 etcd 做備份

剩下的 20 題裡,大約有 2 題是要求找出 cluster 運作出問題的地方 (一題是針對 worker node ,另一題是針對 master node)。剩下的大部分都是比較基本的 kubectl 操作,從最簡單的 "找出 cpu 使用最高的 pod",到比較複雜一點的 "deployment 的 rollout history and rollback",不會有太刁鑽的題目。

雖然考試會用到 5~6 個 cluster ,但前 18 題左右都是在第一個 cluster 裡面考基本的題型,然後後面 3 個 cluster 則是建立或除錯 cluster,最後可能有一個是要設定 storage 相關的題目。

也就是說,即使放棄掉比較偏系統維運方面的題目,大致上也還有 80 分上下是可以透過 minikube 之類的環境就可以輕易做練習來準備的範圍。

所以如果單純以準備考試來說,基本操作的熟練度要夠,以及針對已知題型的練習也足夠,那要低空飛過只求及格是不會太難的。當然臨場的反應、細心還有緊張程度都會有些影響,這就只能靠個人去控制了。

如果去網路上查 CKA 如何準備,十篇大概會有七八篇會推薦 kubernetes the hard way ,主要是針對 tls bootstrapping 那一題。

不過我個人是覺得,如果是新手,為了準備這題,所花費準備的時間可能是其他所有題目的好幾倍,而且可能會相當挫折。把 kubernetes the hard way 從頭理解一遍當然是不錯,但是就準備考試本身來說,反而可能會是個不利的因素。除非已經是有一定熟悉度,目標往滿分邁進,否則我會建議掌握基本分和基本題型會輕鬆許多。

如果希望事先了解一下考試的介面,可以參考 arush 提供的測試環境
雖然和實際考試的有所差異,但可以作為參考和練習。

另外當初為了準備考試,有用 asciinema 錄製一些操作記錄,有興趣也可以參考。


就和所有的認證一樣,考過不代表高手,高手也不是一定就能考過。準備是必要的 (對大多數人而言),而考過只是代表一個起步而已。起步早晚不是重點,能一步步走下去才是考驗。



2019年6月6日 星期四

Prometheus-Operator 安裝設定

用 helm 安裝的 prometheus-operator 預設就有 mixin 的相關設定及 grafana dashboard ,會比用 helm 安裝的 prometheus 方便許多 (要自己安裝 grafana 及相關設定,如果要安裝 mixin 還要設定 prometheus rules 及 grafana dashboard 等)

用 helm 安裝的話,好像沒什麼好寫的,呃
helm install stable/prometheus-operator --name prometheus --namespace monitoring

搞定了!
先把 promthues 和 grafana 的 service type 改為 Loadbalancer ,來看看安裝結果。

咦?首先從 prometheus 的 UI -> Status -> Targets 看到 etcd 的 endpoints 狀態是 down
cluster 正常的情況下, etcd 的狀態不可能是 down 的,所以這應該是 prometheus 設定問題。

查了一下資料,這是因為 etcd 預設是需要憑證才能 access (如果是用 kubeadm 安裝的話)。就好像用 etcdctl 的話,要指定 ca crt key 等憑證的參數才能 access etcd 一樣。

從查到的資料來看,文章裡的解決方法,已經不適合目前安裝的版本 (prometheus-operator-5.7.0)。

目前的版本已經考慮到這個情況,在 values.html 已經提供可參考的設定方式。
helm fetch stable/prometheus-operator
tar zxvf prometheus-operator-5.7.0.tgz

然後修改 prometheus-operator/values.yaml 及相關設定,流程大致如下:

1. 尋找 etcd 相關的設定,可以看到有提供相關的設定,在 serviceMonitor 的後面調整為
schema: https
caFile: "/etc/prometheus/secrets/etcd-certs/ca.crt"
certFile: "/etc/prometheus/secrets/etcd-certs/healthcheck-client.crt"
keyFile: "/etc/prometheus/secrets/etcd-certs/healthcheck-client.key"

2. 尋找 secrets 的設定,調整為
secrets:
   - etcd-certs

3. 先還不要更新 helm package ,上面第二個設定的意思是,要把能夠 access etcd  的幾個憑證檔放到 etcd-certs 這個 secrets (這個 secrets 不存在,是要自行建立的)
kubectl -n monitoring create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key --from-file=/etc/kubernetes/pki/etcd/ca.crt
   注意,這是要在 master node 上執行的,因為如果是用 kubeadm 安裝的話,這幾個憑證在 master node 才有。如果 etcd 是自行安裝,或是透過其他方式如 kubespray 安裝的話,就要自行調整產生 secrets 的方法了。

4. 可以更新 helm package 了
helm upgrade -f prometheus-operator/values.yaml prometheus stable/prometheus-operator

到這邊算是修改完成了,從 prometheus UI 上已經可以看到 etcd dashboard 裡有資料了。

遇到問題的話,可以檢查幾個地方

1. 檢查 servicemonitors 裡 etcd 相關的設定, servicemonitors 是 operator 建立的 CRD
kubectl -n monitoring edit servicemonitors prometheus-prometheus-oper-kube-etcd
   看裡面的設定是否有包含 values.yaml 裡有關憑證的設定

2. 檢查 pods 路徑下是否有確實把指定的 secrets 掛載起來
#kubectl -n monitoring exec -it prometheus-prometheus-prometheus-oper-prometheus-0
$ ls /etc/prometheus/secrets/etcd-certs/