GKEでPrometheus Operatorを使用する
Prometheus Operatorとは
CoreOSが2016年に発表した。
Kubernetes Operatorについての説明は割愛するが、このKubernetes OperatorもCoreOSが提唱している。
このPrometheusオペレータを使用することによって、必要な構成のPrometheusサーバのセットが実行されていることを保証する。
- データの保持期間
- 永続的なボリュームの要求(PVC)
- レプリカ数
- Prometheusのバージョン
- アラートを送信するAlertmanagerインスタンス
オペレーターを使用することによって、Prometheusドメインの知識の大部分をカプセル化して、エンドユーザーにとって意味のある部分のみを表示する。
https://github.com/coreos/prometheus-operator
https://coreos.com/operators/prometheus/docs/latest/user-guides/getting-started.html
CRD(Custom Resource Definition)によって、以下を作成する
https://coreos.com/operators/prometheus/docs/latest/design.html
- Prometheus
- SericeMonitor
- Alertmanager
以下のPrometheus環境をいい感じに作ってくれる。
https://raw.githubusercontent.com/coreos/prometheus-operator/master/Documentation/user-guides/images/architecture.png
Prometheus Operatorの導入
Kubernetesクラスタの作成
今回、GKEに導入してみる
Masterバージョン: 1.15.11-gke.3
ノードスペック: n1-standard-2
クラスタ: リージョナルクラスタ
gcloud beta container --project "project-name" clusters create "sakon-prometheus-operator" --region "asia-northeast1" \
--no-enable-basic-auth --cluster-version "1.15.11-gke.3" --machine-type "n1-standard-2" --image-type "COS" \
--disk-type "pd-standard" --disk-size "100" --metadata disable-legacy-endpoints=true \
--scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" \
--num-nodes "1" --enable-stackdriver-kubernetes --enable-ip-alias --network "projects/project-name/global/networks/sakon-network" \
--subnetwork "projects/project-name/regions/asia-northeast1/subnetworks/sakon-gke-subnet-1" \
--cluster-secondary-range-name "sakon-gkesub1-2nd-range-1" --services-secondary-range-name "sakon-gkesub1-2nd-range-2" \
--default-max-pods-per-node "110" --no-enable-master-authorized-networks \
--addons HorizontalPodAutoscaling,HttpLoadBalancing --enable-autoupgrade --enable-autorepair
Prometheus-Operatorのデプロイ
基本的には以下のgetting-startedをやる。
https://coreos.com/operators/prometheus/docs/latest/user-guides/getting-started.html
Prometheus-operatorとそれに必要なClusterRole、ClusterRoleBinding、ServiceAccountを作成。
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: prometheus-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-operator
subjects:
- kind: ServiceAccount
name: prometheus-operator
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: prometheus-operator
rules:
- apiGroups:
- extensions
resources:
- thirdpartyresources
verbs:
- "*"
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- "*"
- apiGroups:
- monitoring.coreos.com
resources:
- alertmanagers
- prometheuses
- prometheuses/finalizers
- servicemonitors
verbs:
- "*"
- apiGroups:
- apps
resources:
- statefulsets
verbs: ["*"]
- apiGroups: [""]
resources:
- configmaps
- secrets
verbs: ["*"]
- apiGroups: [""]
resources:
- pods
verbs: ["list", "delete"]
- apiGroups: [""]
resources:
- services
- endpoints
verbs: ["get", "create", "update"]
- apiGroups: [""]
resources:
- nodes
verbs: ["list", "watch"]
- apiGroups: [""]
resources:
- namespaces
verbs: ["list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus-operator
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
k8s-app: prometheus-operator
name: prometheus-operator
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: prometheus-operator
spec:
containers:
- args:
- --kubelet-service=kube-system/kubelet
- --config-reloader-image=quay.io/coreos/configmap-reload:v0.0.1
image: quay.io/coreos/prometheus-operator:v0.17.0
name: prometheus-operator
ports:
- containerPort: 8080
name: http
resources:
limits:
cpu: 200m
memory: 100Mi
requests:
cpu: 100m
memory: 50Mi
securityContext:
runAsNonRoot: true
runAsUser: 65534
serviceAccountName: prometheus-operator
$ kubectl apply -f prometheus-oprator.yml
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator created
clusterrole.rbac.authorization.k8s.io/prometheus-operator created
serviceaccount/prometheus-operator created
deployment.extensions/prometheus-operator created
$ prometheus-operator kubectl get pod
NAME READY STATUS RESTARTS AGE
prometheus-operator-5fff966576-lw6f7 1/1 Running 0 19s
サンプロとなるexample-appのデプロイ
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: example-app
spec:
replicas: 3
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: example-app
image: fabxc/instrumented_app
ports:
- name: web
containerPort: 8080
$ kubectl apply -f example-app.yml
deployment.extensions/example-app created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
example-app-66db748757-btvfp 1/1 Running 0 44s
example-app-66db748757-rdl5h 1/1 Running 0 44s
example-app-66db748757-t65fp 1/1 Running 0 44s
prometheus-operator-5fff966576-lw6f7 1/1 Running 0 11m
exampleアプリケーションのデプロイ
SericeMonitorには、サービスとそのもととなるエンドポイントオブジェクトを選択するためのラベルセレクタがある。
サンプルアプリケーションの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
$ kubectl apply -f example-app-service.yml
service/example-app created
$kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
example-app ClusterIP 10.126.124.18 <none> 8080/TCP 6s
kubernetes ClusterIP 10.124.0.1 <none> 443/TCP 30m
このサービスオブジェクトは同じ方法で選択するServiceMonitorによって検出される。 app: example-app
のラベルを持っておく必要がある。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: example-app
labels:
team: frontend
spec:
selector:
matchLabels:
app: example-app
endpoints:
- port: web
$ kubectl apply -f example-app-ServiceMonitor.yml
servicemonitor.monitoring.coreos.com/example-app created
$ kubectl get ServiceMonitor
NAME AGE
example-app 39s
Prometheus PodのRBACルールを有効にする
RBACがアクティブ化されている場合、PrometheusとPrometheus Operatorの両方のRBACルールを作成する必要がある。
上のほうで、Prometheus-OperatorのClusterRoleとClusterRoleBindingを作成したが、Promethus Podにも同様のことが必要となる。
Prometheus PodのClusterROleおよび、ColusterRoleBindingを作成する。
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources:
- configmaps
verbs: ["get"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: default
$ kubectl apply -f prometheus-ServiceAccount.yml
serviceaccount/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
ServiceMonitorを含める
最後にPrometheusオブジェクトは serviceMonitorSelector
定義してどのServiceMonitorを含めるかを指定する。
team: frontend
ラベルが指定されたため、Prometheusオブジェクトが選択する。
※これ、getting-startedのやつだとserviceaccountとか指定して無かったので、↓を参考にする。
https://github.com/coreos/prometheus-operator/blob/v0.17.0/example/rbac/prometheus/prometheus.yaml
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
labels:
prometheus: prometheus
spec:
replicas: 2
serviceAccountName: prometheus
serviceMonitorSelector:
matchLabels:
team: frontend
alerting:
alertmanagers:
- namespace: default
name: alertmanager
port: web
resources:
requests:
memory: 400Mi
$ kubectl apply -f frontend-prometheus.yml
prometheus.monitoring.coreos.com/prometheus created
$ kubectl get prometheus
NAME AGE
prometheus 12s
prometheusインスタンスを公開する
Prometheusインスタンスにアクセスするには外部に公開する必要がある。この例ではNodePortを使用してインスタンスを公開する。
apiVersion: v1
kind: Service
metadata:
name: prometheus
spec:
type: NodePort
ports:
- name: web
nodePort: 30900
port: 9090
protocol: TCP
targetPort: web
selector:
prometheus: prometheus
$ kubectl apply -f frontend-prometheus-svc.yml
service/prometheus created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
example-app ClusterIP 10.126.124.18 <none> 8080/TCP 25m
kubernetes ClusterIP 10.124.0.1 <none> 443/TCP 55m
prometheus NodePort 10.125.116.34 <none> 9090:30900/TCP 37s
prometheus-operated ClusterIP None <none> 9090/TCP 5m13s
例通りにnodeportでservice作ったが、結局port-forwardする。
kubectl port-forward svc/prometheus 9090:9090
こんな感じでメトリクスも取得できている