LoginSignup
0
0

More than 5 years have passed since last update.

kube-awsで作ったクラスタのetcdをprometheusのservice-discoveryで検出してメトリクスを取る

Posted at

タイトルを削れなかった

ターゲット

  • kube-aws使っててちょっとわかる(なのでawsとkubernetesも当然)
  • prometheus使っててちょっとわかる(kubernetesで運用してるとなお好都合)
  • etcdのメトリクス取りたい!(いなさそう)

目次

  1. etcdのインスタンスを検出する
  2. etcdのメトリクスを取得する
  3. その他つらつら

1. etcdのインスタンスを検出する

理屈

kube-awsにより作られたkubernetesクラスタは、etcdのinstanceがcontrollerから独立しており、kubernetesクラスタの外にある状態になっています(見た感じそうなってるからそのはず)。

通常、prometheusをkubernetesで使う場合は、service-discoverykubernetes_sd_configを使って監視対象のリソースを探します。
が、上記の通りetcdのinstanceはkubernetesクラスタの外にあるためこれでは検出できません。
かと言ってクラスタを作った後にetcdのipを調べてprometheusのconfigのtargetsに書いていくなんてことはまっぴら御免です。
ですので、etcdのinstanceはec2_sd_configを使って検出します。

何もしないとprometheusに設定したuser/roleから見える全てのインスタンスを検出してしまい、とても散らかるので必要なものだけに絞っていきます。
今回はtagにkube-aws:role: etcdと、ちょうど良さそうなものがついていたのでこれを使います。

aaa.png

kube-awsの変更でこのtagがつかなくなる、なんてことがあるかもしれないので、自分でオリジナルのタグを付けるのもいいかもしれません。(cluster.yamlの記述でそういうのできたりするんですかね、よくわかってない)

ステージングのインスタンスも検出してしまう!なんて時は他にも自分の環境に応じて条件を加えます。
私の場合はvpcでの絞り込みも追加しました。

方法

prometheusのconfigにこんな感じのセクションを追加します

configmap.yaml
#scrape kube-aws etcd
- job_name: 'kube-aws-etcd'
  ec2_sd_configs:
    - region: ap-northeast-1
      port: 2379 #etcdのポート
  relabel_configs:
    - source_labels: [__meta_ec2_tag_kube_aws_role]
      regex: 'etcd'
      action: keep
    - source_labels: [__meta_ec2_vpc_id]
      regex: 'vpc-1234abcd'
      action: keep

2. etcdのメトリクスを取得する

理屈

etcdはデフォルトで/metircsにprometheus用のメトリクスを出力しています。
なので通常であれば、検出したインスタンスの/metricsにアクセスするだけです。
しかし今回はひとつ壁があって、アクセスするのにkeyやらcertやらが必要になっています。
(ここはドキュメントやコードを読まずにひたすら総当たりで調べたので何か間違ってたらすいません。とにかく取得はできますので…)

これはkube-awsでクラスタを作る際の、kube-aws render credentialsによって生み出される(だったような)

  • credentials/etcd-client-key.pem
  • credentials/etcd-client.pem

を使います。

これらはnodeを作る際、/etc/kubernetes/ssl/に配置されるようで、それならprometheusコンテナでvolumeマウントして使えばいい
…と思ったのですが、rootにしかread権限がついてなかったので諦めて、普通にsecretを作りました。
prometheusをrootで起動してる人はマウントで使えるかもしれません。

方法

まずはsecretですが、上記のpemを例によってbase64エンコードして作ります

secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: etcd-secret
  namespace: default
type: Opaque
data:
  etcd-client.pem: "kekkounagaidehogehogehogehoge"
  etcd-client-key.pem: "koitsumonagaidehogehogehogehoge"

私の場合はこんな感じのスクリプトでsecretを作ってます

make_secret.sh
FILE="secret.yaml"
cat << EOF >>${FILE}
apiVersion: v1
kind: Secret
metadata:
  name: etcd-secret
  namespace: default
type: Opaque
data:
EOF
echo '  etcd-client.pem: "'$(/bin/cat credentials/etcd-client.pem | base64)\" >>${FILE}
echo '  etcd-client-key.pem: "'$(/bin/cat credentials/etcd-client-key.pem | base64)\" >>${FILE}

configは1.のものにちょっと手を加えて

configmap.yaml
#scrape kube-aws etcd
- job_name: 'kube-aws-etcd'
  scheme: https
  tls_config:
    key_file: /mnt/ssl/etcd-client-key.pem #deploymentでmountするpathとsecretのdataのname
    cert_file: /mnt/ssl/etcd-client.pem #上に同じ
    insecure_skip_verify: true
  ec2_sd_configs:
    - region: ap-northeast-1
      port: 2379 #etcdのポート
  relabel_configs:
    - source_labels: [__meta_ec2_tag_kube_aws_role]
      regex: 'etcd'
      action: keep
    - source_labels: [__meta_ec2_vpc_id]
      regex: 'vpc-1234abcd'
      action: keep
    - action: labelmap
      regex: __meta_ec2_(.+)

こんな感じのものを追加します。

deploymentは今回に関係ある部分を抜粋するとこんな感じ

deployment.yaml
spec:
  template:
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus:latest
          volumeMounts:
            - name: etcd-ssl-volume
              mountPath: /mnt/ssl/ #configと揃っていればなんでも
            - name: secrets-volume
      volumes:
        - name: etcd-ssl-volume
          secret:
            secretName: etcd-secret
            defaultMode: 420

Pod派の人やprometheusをkubernetesで運用してない人はよしなにやりましょう。

要は、ec2_sd_configでインスタンスを探して、etcd-client.pemetcd-client-key.pemを使って:2379/metricsにアクセスすればいいのです。

問題なければこんな感じに通るはずです。(label整理してない)
bbb.png

grafanaでdashboardにすればそれっぽい
ccc.jpg

3.その他つらつら

これで取れるのはあくまでetcdのメトリクスであって、etcdインスタンスのメトリクスは取れません。
ちょっとしたcpuやmemoryのメトリクスならprocess_cpu_seconds_totalgo_memstats_*がありますが、足りないならnode-exporter等を配置する必要があります。
しかしこれは現状etcdインスンタンスが立った後に直接ログインしてインストールして公開して必要ならアクセス制限して…などの作業が必要になるため現実的ではありません(し、実際に可能かどうかも私にはわかりません)。
最初に述べたとおりkubernetesクラスタの外なので当然daemonsetも届きません。

なのでcloudwatch_exporterでcloudwatchのmetricsをprometheusに取り込むか、grafanaを使っているならcloudwatchを直接データソースにしてしまうなどが現実的かと思います。
(私は先述の「ちょっとしたcpuやmemoryのメトリクス」で間に合わせてます。)
kube-awsでクラスタを作る時にetcdインスタンスにnode-exporterが入ったりしてくれれば…

kube-awsはあまりしっかり触ってないので何か間違っていたらすみません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0