---
# System prepended metadata

title: OpenShift 4 KEDA Example

---

# OpenShift 4 KEDA Example

實現基於自定指標的應用彈性擴展
## 安裝配置Custom Metrics Autoscaler

在OpenShift 的OperatorHub 中找到Custom Metrics Autoscaler，然後使用預設配置安裝它。默認會安裝將其安裝到openshift-keda 項目中。
進入安裝好的Custom Metrics Autoscaler，然後在openshift-keda 項目中使用預設配置創建一個KedaController 實例。
```
cat << EOF | oc apply -f -
apiVersion: keda.sh/v1alpha1
kind: KedaController
metadata:
  name: keda
  namespace: keda
spec:
  operator:
    logLevel: info
    logEncoder: console
  metricsServer:
    logLevel: '0'
  serviceAccount: {}
  watchNamespace: ''
EOF
```
完成後可查看運行的資源。

```
$ oc get deployment -n keda
NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
custom-metrics-autoscaler-operator   1/1     1            1           5m
keda-metrics-apiserver               1/1     1            1           3m
keda-operator                        1/1     1            1           3m
```

## 配置可基於自定指標彈性擴展的應用
部署應用
為了能使用到基於Prometheus 的OpenShift Monitoring 環境監視應用的定制指標，我們需要在OpenShift 中運行以下YAML，設置允許OpenShift Monitoring 監視用戶命名空間的資源。
```
cat << EOF | oc apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |
        enableUserWorkload: true
EOF
```

在OpenShift 中創建一個測試項目`test`。
在測試項目中執行以下YAML，創建測試應用相關資源。測試應用通過接口會向Prometheus 提供其運行指標。

```
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test-app
  name: test-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-app
  template:
    metadata:
      labels:
        app: test-app
        type: keda-testing
    spec:
      containers:
      - name: prom-test-app
        image: quay.io/zroubalik/prometheus-app:latest
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: test-app
  annotations:
    prometheus.io/scrape: "true"
  name: test-app
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    type: keda-testing
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
  name: keda-testing-sm
spec:
  endpoints:
  - scheme: http
    port: http
  namespaceSelector: {}
  selector:
    matchLabels:
       app: test-app
``````
查看測試應用部署情況。
```
$ oc get deploy test-app
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
test-app   1/1     1            1           94s
```

創建從Thanos 獲取應用定制指標的Service Account 和Role
在部署測試應用的project下執行以下命令，創建一個ServiceAccount。
`$ oc create serviceaccount thanos -n test` 

執行命令查看ServiceAccount 相關token。下面將使用其中的thanos-token-gjprx 作為訪問憑證。
```
$ oc describe serviceaccount thanos
Name:                thanos
Namespace:           test
Labels:              <none>
Annotations:         <none>
Image pull secrets:  thanos-dockercfg-zbh7g
Mountable secrets:   thanos-token-nmqpv
                     thanos-dockercfg-zbh7g
Tokens:              thanos-token-gjprx
                     thanos-token-nmqpv
Events:              <none>
```


執行以下YAML 創建TriggerAuthentication，其中的bearerToken 和ca 都使用了在ServiceAccount 中的thanos-token-gjprx 作為參數。
```
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: keda-trigger-auth-prometheus
spec:
  secretTargetRef:
  - parameter: bearerToken
    name: thanos-token-gjprx       # update this
    key: token
  - parameter: ca
    name: thanos-token-gjprx       # update this
    key: ca.crt
```

執行以下YAML 創建Role，用它來訪問Thanos 以查詢到應用指標。
```
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: thanos-metrics-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
```

執行命令，將Role 賦給ServiceAccount。
```
$ oc adm policy add-role-to-user thanos-metrics-reader -z thanos --role-namespace=test
```
為擴展部署創建ScaledObject
執行以下YAML 創建ScaledObject。它關聯了Deployment 對象，並說明了擴展上下限、查詢的定制指標的Thanos 訪問地址和查詢輪訓時間等內容。
```
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: prometheus-scaledobject
spec:
  scaleTargetRef:
    name: test-app
  minReplicaCount: 1
  maxReplicaCount: 10
  pollingInterval: 5
  cooldownPeriod:  10
  triggers:
  - type: prometheus
    metadata:
      serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9092
      namespace: test                         # replace <NAMESPACE>
      metricName: http_requests_total
      threshold: '5'
      query: sum(rate(http_requests_total{job="test-app"}[1m]))
      authModes: "bearer"
    authenticationRef:
      name: keda-trigger-auth-prometheus
```

查看ScaledObject 對象的狀態。

```
$ oc get scaledobject prometheus-scaledobject -n ci-cd
NAME                      SCALETARGETKIND      SCALETARGETNAME   MIN   MAX   TRIGGERS     AUTHENTICATION                 READY   ACTIVE   FALLBACK   AGE
prometheus-scaledobject   apps/v1.Deployment   test-app          1     10    prometheus   keda-trigger-auth-prometheus   True    False    False      9m
```

測試驗證
執行以下YAML，運行一個Job 向運行應用進行並發壓力訪問。
```
cat << EOF | oc apply -f -
apiVersion: batch/v1
kind: Job
metadata:
  name: generate-requests
spec:
  template:
    spec:
      containers:
      - image: quay.io/zroubalik/hey
        name: test
        command: ["/bin/sh"]
        args: ["-c", "for i in $(seq 1 30);do echo $i;/hey -c 5 -n 100 http://test-app.test.svc;sleep 1;done"]   # replace <NAMESPACE>
      restartPolicy: Never
  activeDeadlineSeconds: 120
  backoffLimit: 2
EOF
```

在OpenShift 控制台監控test-app 部署對應的Pod 數量，或執行以下命令查看Pod 數量。確認數量會從1 增加，最後會降到1。
```
 $ watch oc get deployment test-app
```
