發佈日期:

對圖像做幾何變換

目標

學習對圖像應用不同的幾何變換,如平移、旋轉、仿射變換等。
你會看到這些功能:cv.getPerspectiveTransform

縮放

只是調整圖像的大小。interpolation參數有下面幾種

使用範例

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
#OR
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)

平移

平移影像,下面程式會將圖,x 軸平移 100,y 軸平移 50

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])# 2x3 矩陣,x 軸平移 100,y 軸平移 50
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()

旋轉影像

img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1) # 中心點 ((cols-1)/2.0,(rows-1)/2.0)),旋轉 90 度,尺寸 1
dst = cv.warpAffine(img,M,(cols,rows))

仿射變換

img = cv.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

透視變換

這個方法可以把3D的有角度的長方形,拉成2D的長方形,很常會用來使用在3為空間的像照片、名片等拉平的效果上

img = cv.imread('sudoku.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

發佈日期:

opencv圖像運算

理論

形態變換是一些基於圖像形狀的簡單操作。它通常在二進製圖像上執行。它需要兩個輸入,一個是我們的原始圖像,第二個稱為結構元素或內核,它決定了操作的性質。兩個基本的形態學算子是侵蝕和膨脹。然後它的變體形式如開、閉、梯度等也開始發揮作用。我們將在下圖的幫助下一一看到它們:

侵蝕cv2.erode

侵蝕的基本思想就像土壤侵蝕一樣,它侵蝕掉前景物體的邊界(總是盡量讓前景保持白色)。那它有什麼作用呢?內核在圖像中滑動(如在 2D 卷積中)。只有當內核下的所有像素都為 1 時,原始圖像中的像素(1 或 0)才會被認為是 1,否則它會被腐蝕(變為零)。

所以發生的事情是,根據內核的大小,邊界附近的所有像素都將被丟棄。因此,前景對象的厚度或大小會減少,或者圖像中的白色區域會減少。它對於去除小的白噪聲(正如我們在色彩空間章節中看到的)、分離兩個連接的對像等很有用。

在這裡,作為一個例子,我會使用一個 5×5 的內核。讓我們看看它是如何工作的:

import cv2 as cv
import numpy as np
img = cv2.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)

膨脹Dilation

它與侵蝕正好相反。這裡,如果內核下的至少一個像素為“1”,則像素元素為“1”。因此它增加了圖像中的白色區域或前景對象的大小增加。通常,在去除噪聲等情況下,腐蝕之後是膨脹。因為,腐蝕去除了白噪聲,但它也縮小了我們的對象。所以我們擴大它。由於噪音消失了,它們不會回來,但我們的對象區域增加了。它還可用於連接對象的損壞部分。

dilation = cv2.dilate(img,kernel,iterations = 1)

去噪cv2.MORPH_OPEN

在去除噪聲方面很有用。這裡我們使用函數cv2.morphologyEx()

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

關閉線條

對關閉前景對象內的小孔或對像上的小黑點很有用。這個我也有使用來把canny所找到的邊緣關起來

closing = cv2.morphologyEx (img, cv2.MORPH_CLOSE, kernel)

形態梯度

這是圖像膨脹和腐蝕之間的區別。結果將看起來像對象的輪廓。

gradient = cv2.morphologyEx (img, cv2.MORPH_GRADIENT, kernel)

Top Hat

使用cv2.MORPH_TOPHAT

tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

Black Hat

使用cv2.MORPH_GRADIENT

gradient = cv2.morphologyEx (img, cv2.MORPH_GRADIENT, kernel)

更多資訊: https://homepages.inf.ed.ac.uk/rbf/HIPR2/morops.htm

發佈日期:

使用opencv做圖片後製處理(如ps)

這個部落格有一個系列文:
12th 鐵人賽 – 【錢不夠買ps的我,只好用OpenCV來修圖了!】
分享了非常多好用的圖片後製方法
這邊分享幾個我覺得不錯的

黑強化

強化有顏色區域的深度

# do pre-process (black strengthen) in OCR
def image_filter(img, degree = 3):
    # degree is from 0 to Unlimited, bigger number => bigger strengthen
    decrease_img = (255.0/1)*(img/(255.0/1))**degree
    decrease_img = np.array(decrease_img, dtype=np.uint8)
    return decrease_img

白平衡

圖像光照校正處理

def mean_white_balance(img):
    b, g, r = cv2.split(img)
    r_avg = cv2.mean(r)[0]
    g_avg = cv2.mean(g)[0]
    b_avg = cv2.mean(b)[0]
    k = (r_avg + g_avg + b_avg) / 3
    kr = k / r_avg
    kg = k / g_avg
    kb = k / b_avg
    r = cv2.addWeighted(src1=r, alpha=kr, src2=0, beta=0, gamma=0)
    g = cv2.addWeighted(src1=g, alpha=kg, src2=0, beta=0, gamma=0)
    b = cv2.addWeighted(src1=b, alpha=kb, src2=0, beta=0, gamma=0)
    balance_img = cv2.merge([b, g, r])
    return balance_img

雙邊濾波

雙邊濾波(Bilateral filter)是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值相似度的一種折衷處理,同時考慮空域信息和灰度相似性,達到保邊去噪的目的。具有簡單、非迭代、局部的特點。

image = cv2.bilateralFilter(image, 5, 30, 30)
發佈日期:

使用opencv來找出紅色區塊

使用HSV色碼轉換器

一個好用的線上工具
色碼轉換器: https://www.peko-step.com/zhtw/tool/hsvrgb.html

若要將轉換過的顏色套用到python的色碼,記得將S,V的範圍改為0-255
然後從網站上看到的H的值(如這邊為26)要除以2,也就是13

以上圖來說,上面顯示的色碼為HSV:(26,90,223),然後填進python裡面要使用HSV:(13,90,223)

python裡面的HSV識別空間

一般對顏色空間的圖像進行有效處理都是在HSV空間進行的,然後對於基本色中對應的HSV分量的範圍為:
H: 0 — 180
S: 0 — 255
V: 0 — 255

基本HSV的顏色劃分


HSV的意義

HSB又稱HSV,表示一種顏色模式:在HSB模式中,H(hues)表示色相,S(saturation)表示飽和度,B(brightness)表示亮度HSB模式對應的媒介是人眼。
HSL 和HSV 二者都把顏色描述在圓柱體內的點,這個圓柱的中心軸取值為自底部的黑色到頂部的白色而在它們中間是的灰色,繞這個軸的角度對應於“色相”,到這個軸的距離對應於“飽和度”,而沿著這個軸的距離對應於“亮度”,“色調”或“明度”。這兩種表示在用目的上類似,但在方法上有區別。


二者在數學上都是圓柱,但HSV(色相,飽和度,明度)在概念上可以被認為是顏色的倒圓錐體(黑點在下頂點,白色在上底面圓心),HSL在概念上表示了一個雙圓錐體和圓球體(白色在上頂點,黑色在下頂點,最大橫切面的圓心是半程灰色)。注意儘管在HSL 和HSV 中“色相”指稱相同的性質,它們的“飽和度”的定義是明顯不同的。

抓取圖片中膚色大小大小

import cv2
def find_white_color_size(image, upper, lower, upper2 = None, lower2 = None):
    imageHSV = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(imageHSV, lower, upper)
    if lower2 is not None and upper2 is not None:
        mask2 = cv2.inRange(imageHSV, lower2, upper2)
        mask = cv2.bitwise_or(mask, mask2)
    area = 0;
    for i in range(len(mask)):
        filter_color = mask[i] > 0
        area += len(mask[i][filter_color])
    return area

lower_red1 = np.array([0, 70, 100], dtype=np.uint8)
upper_red1 = np.array([20, 120, 240], dtype=np.uint8)
lower_red2 = np.array([150, 70, 100], dtype=np.uint8)
upper_red2 = np.array([180, 120, 240], dtype=np.uint8)
print('color size:',find_white_color_size(card_image, upper_red1, lower_red1, upper_red2, lower_red2))
發佈日期:

python的socket-io-client 4.5.1不會自動重連問題

問題版本

python-socketio 4.5.1
相關討論串: https://github.com/miguelgrinberg/python-socketio/issues/485
can not reconnect after 503 error

解決方法

自己寫重連的程式碼

import socketio
from threading import Timer

timer = None
address = "http://127.0.0.1:2027"
sio = socketio.Client(reconnection=False, logger=False, engineio_logger=False)
isConnected = False

def connectSocket():
    global timer
    try:
        sio.connect(address, transports='polling')
    except:
        if timer is not None:
            timer.cancel()
        timer = Timer(1.0, connectSocket)
        timer.start()

def close():
    global sio
    global timer
    global isConnected
    sio.disconnect()
    isConnected = False
    if timer is not None:
        timer.cancel()

@sio.event
def test():
    print('(test)'


def send(data):
    sio.emit('send', data)


@sio.event
def connect():
    global isConnected
    print('(connect)')


@sio.event
def disconnect():
    global timer
    global isConnected
    print('(disconnected)')
    sio.disconnect()
    isConnected = False
    if timer is not None:
        timer.cancel()
    timer = Timer(1.0, connectSocket)
    timer.start()

發佈日期:

把普羅米修斯的資料打到ELK

下載Metricbeat的docker版本​

官網介紹: https://www.elastic.co/beats/metricbeat
其中給普羅米修斯使用的模組為: https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-prometheus.html
官方映像檔: https://hub.docker.com/r/elastic/metricbeat
下載映像檔

docker pull docker.elastic.co/beats/metricbeat:8.5.3

新建一個Metricbeat的Pod​

設定metrucbeat的deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: metricbeat
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      workload.user.cattle.io/workloadselector: apps.deployment-srs3-metricbeat
  template:
    spec:
      affinity: {}
      containers:
      - image: dev-registry.xycloud.org/ldr/streaming/metricbeat
        imagePullPolicy: Always
        name: metricbeat
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /usr/share/metricbeat/metricbeat.yml
          name: vol0
          subPath: metricbeat.yml
        - mountPath: /usr/share/metricbeat/prometheus.yml
          name: vol0
          subPath: prometheus.yml
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: regsecret
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - configMap:
          defaultMode: 420
          name: filebeat-config
        name: vol0

設定兩個config​

metricbeat.yml​

metricbeat.config.modules:​
  path: ${path.config}/modules.d/*.yml​
  reload.enabled: false​
metricbeat.max_start_delay: 10s​
output.logstash:​
  enabled: true​
  hosts: ["logstash-logstash.tool-elk.svc.cluster.local:5043"]​
  index: 'metricbeat'​
  logging.level: info​
logging.metrics.enabled: false​
logging.metrics.period: 30s​

prometheus.yml​

- module: prometheus​
  metricsets: ["query"]​
  hosts: ["http://rancher-monitoring-prometheus.cattle-monitoring-system.svc.cluster.local:9090"]​
  period: 10s​
  queries:​
  - name: "stream_total_clients_by_pod"​
    path: "/api/v1/query"​
    params:​
      query: "stream_total_clients_by_pod"​

把這兩個config mount進pod的在/usr/share/metricbeat​

發佈日期: 1 則留言

Prometheus Rule for Alert​

Prometheus Rule功能介紹

Prometheus Rule 是用於在 Prometheus 中定義規則的 YAML 配置文件。它可以根據指定的表達式或條件對 metrics 進行匹配和計算,並在達到一定條件時生成警報或創建新的 metrics。

Prometheus Rule 的主要功能如下:

  • Metrics 計算:通過表達式對符合條件的 metrics 進行匹配和計算,生成新的 metrics。
  • 警報:當符合指定條件的 metrics 達到一定閾值時,生成警報。
  • 規則繫結:可以為指定的 metrics 繫結指定的規則,進行自動化的警報觸發。
  • 標註註釋:在生成警報時可以加上自定義的標註和註釋,方便後續的統計和分析。

通常在配合 Grafana 等圖形化界面使用時,Prometheus Rule 可以讓用戶方便的自定義需要監控的 metrics,並在 Grafana 上實現對這些 metrics 的實時監控和報警,以實現系統的實時監控和異常處理。

設定Prometheus Rule

這是一個 PrometheusRule YAML 配置文件,用於定義 Prometheus 規則,以檢測和警報指定的 metrics。

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  labels:
    name: srs-online-member
  name: srs-online-member
  namespace: stu-srs
spec:
  groups:
  - name: srs-online-member
    rules:
    - expr: sum(stream_clients_clients{container="json-exporter", name=~".+",namespace=~"stu-srs",pod=~"srs-edge.+"})
        by (pod)
      labels:
        name: online-member-high
        namespace: stu-srs
        service: eventqueue
      record: stream_total_clients_by_pod
  - name: quay-alert.rules
    rules:
    - alert: online-member-full
      annotations:
        message: online-member-full {{ $labels.pod }} at {{ $value }}%
      expr: sum(stream_clients_clients{container="json-exporter", name=~".+",namespace=~"stu-srs",pod=~"srs-edge.+"})
        by (pod) > 1000
      for: 5m
      labels:
        severity: warning

該文件定義了兩個規則組,每個規則組包含一個或多個規則。

第一個規則組名為 srs-online-member,包含一個規則。該規則通過表達式 sum(stream_clients_clients{container="json-exporter", name=~".+",namespace=~"stu-srs",pod=~"srs-edge.+"}) by (pod) 求和符合條件的 metrics,這些 metrics 包含在 stream_clients_clients 中,該 metrics 必須滿足以下條件:在命名空間 stu-srs 中,容器名稱為 json-exporter,Pod 名稱符合正則表達式 srs-edge.+。

如果條件滿足,Prometheus 將會創建一個名為 stream_total_clients_by_pod 的時間序列,其中 pod 是標籤,值是符合條件的 Pod 名稱,這樣可以讓你在 Grafana 等圖形化界面上顯示時間序列並進行分析。

第二個規則組名為 quay-alert.rules,包含一個警報規則。該規則通過表達式 sum(stream_clients_clients{container="json-exporter", name=~".+",namespace=~"stu-srs",pod=~"srs-edge.+"}) by (pod) > 1000 檢查符合條件的 metrics 是否大於 1000。如果條件滿足 5 分鐘以上,Prometheus 將會發出名為 online-member-full 的警報,並設置一些額外的標籤和注釋以便進一步分析。

設定alert規則

我們也可以在Rule裡面設定Alert的規則,當有labels的Severity為warning時,就代表這個rule為一個告警,下面是代表當pod的人數大於1000多過五分鐘時,會觸發告警

  - name: quay-alert.rules
    rules:
    - alert: online-member-full
      annotations:
        message: online-member-full {{ $labels.pod }} at {{ $value }}%
      expr: sum(stream_clients_clients{container="json-exporter", name=~".+",namespace=~"default",pod=~"my-pod.+"})
        by (pod) > 1000
      for: 5m
      labels:
        severity: warning

可以在Prometheus Web UI的Alert頁籤裡找到這個設定值​

發佈日期:

Prometheus 資料顯示端​

架構圖所在位置

Prometheus Web UI

如何在Rancher裡面查看Web UI​

將Web UI轉到自己的電腦查看​

kubectl -n cattle-monitoring-system port-forward prometheus-rancher-monitoring-prometheus-0 9090:9090

Web UI是普羅米修斯內建附帶的狀態查看頁面,可以從這邊來看現在普羅米修斯所使用的config或者endpoint的設定

Grafana

Grafana完整的支持PromQL,並且提供自動補完功能,非常方便
安裝

sudo apt-get install -y apt-transport-https
sudo apt-get install -y software-properties-common wget
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key

添加此存儲庫以獲得穩定版本:

echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list

接著

sudo apt-get update
# Install the latest OSS release:
sudo apt-get install grafana
# Install the latest Enterprise release:
sudo apt-get install grafana-enterprise

在k8s安裝請詳見: https://grafana.com/docs/grafana/latest/setup-grafana/installation/kubernetes/

PromQL 基本使用

PromQL 查詢結果主要有3 種類型:​

  • 瞬時數據(Instant vector): 包含一組時序,每個時序只有一個點,例如:http_requests_total​
  • 區間數據(Range vector): 包含一組時序,每個時序有多個點,例如:http_requests_total[5m]​
  • 純量數據(Scalar): 純量只有一個數字,沒有時序,例如:count(http_requests_total)​

另外,可到target畫面找該目標可用以識別的labels來區別​
不同的資料來源。例如: SRS core和edge都是SRS都吃相同的​
資料,要讓Grafana個別顯示出資料就是需要label來做搜尋,​
就可以用完全相同的exporter在不同的服務中。​

更多的PromQL教學: https://prometheus.io/docs/prometheus/latest/querying/basics/​

提供了許多運算功能: https://prometheus.io/docs/prometheus/latest/querying/operators/#aggregation-operators​
可使用運算子=~後面的值接regular expression來做模糊搜尋(eg: name=~“.+“ )​

將普羅米修斯的資料放上.Net專案

普羅米修斯也有提供API讓程式呼叫並取得資料,而且各種語言都有第三方推出套件可以簡易的與普羅米修斯的API取資料​
.Net的參考套件​
https://github.com/prometheus-net/prometheus-net​
可以使用.NET從普羅米修斯取資料,並開發自己想要的監控內容​

發佈日期:

Relabel設定

當我們在看使用Prometheus-operator產生出來的yaml檔案時,會發現裡面用了許多的source_labels標籤,這個是讓operator可以進一步處理資料標籤的方式(如增/刪要送出的資料、端點)

relabel_config


Endpoint 的值是由 __scheme__ + __address__ + __metrics_path__ 所組成​

  • 添加新標籤​
  • 更新現有標籤​
  • 重寫現有標籤​
  • 更新指標名稱​
  • 刪除不需要的標籤​
  • 刪除不需要的指標​
  • 在特定條件下刪除指標​
  • 修改標籤名稱​
  • 從多個現有標籤構建標籤

更多教學

請見: [Prometheus] Service Discovery & Relabel
https://godleon.github.io/blog/Prometheus/Prometheus-Relabel/

發佈日期:

設定prometheus-operator

先決條件

需要一個具有管理員權限的 Kubernetes 集群。

安裝prometheus-operator

安裝prometheus-operator的自定義資源定義 (CRD) 以及運營商本身所需的 RBAC 資源。
運行以下命令以安裝 CRD 並將 Operator 部署到default命名空間中:
LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)
curl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f –
可以使用以下命令檢查是否完成:
kubectl wait –for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n default

佈署範例

這邊是使用OpenShift的yaml去設定相關佈署資訊,更多請見: https://docs.openshift.com/container-platform/4.11/rest_api/monitoring_apis/prometheus-monitoring-coreos-com-v1.html
部署一個簡單的Pod,其中包含 3 個image,用於偵聽端口並公開指標8080

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-app
        image: fabxc/instrumented_app
        ports:
        - name: web
          containerPort: 8080

用一個 Service 對象公開應用程序,該對象選擇所有app標籤具有example-app值的 Pod。Service 對像還指定公開指標的端口。

kind: Service
apiVersion: v1
metadata:
  name: example-app
  labels:
    app: example-app
spec:
  selector:
    app: example-app
  ports:
  - name: web
    port: 8080

最後,我們創建一個 ServiceMonitor 對象,它選擇所有帶有app: example-app標籤的服務對象。ServiceMonitor 對像還有一個team 標籤(在本例中team: frontend為 )來標識哪個團隊負責監視應用程序/服務。

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-app
  labels:
    team: frontend
spec:
  selector:
    matchLabels:
      app: example-app
  endpoints:
  - port: web

部署普羅米修斯

apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - nodes/metrics
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources:
  - configmaps
  verbs: ["get"]
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: default

更多訊息請見: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/rbac.md
之前,我們已經創建了帶有team: frontend label 的 ServiceMonitor 對象,這裡我們定義 Prometheus 對象應該選擇所有帶有team: frontendlabel 的 ServiceMonitor。這使前端團隊能夠創建新的 ServiceMonitors 和服務,而無需重新配置 Prometheus 對象。

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
spec:
  serviceAccountName: prometheus
  serviceMonitorSelector:
    matchLabels:
      team: frontend
  resources:
    requests:
      memory: 400Mi
  enableAdminAPI: false

要驗證是否已啟動並正在運行,請運行:

kubectl get -n default prometheus prometheus -w