メインコンテンツへスキップ
  1. Blogs/

ElasticSearchを使ったlog収集5 -ECK外のagentを登録する-

·2176 文字·
Blog ElasticSearch
hiroki
著者
hiroki
クラウドを作るお仕事をしてます。
目次
ElasticSearch - 関連記事
5: << この記事 >>

はじめに
#

Elastic Cloud on Kubernetes(ECK)を使っていると、物理機器やVMのlogなどECK外部のlogを収集したいことがあると思います。

alt text

この場合ECK内部のAgentは外部公開されていないので、ECK外部にAgentを構築 + Fleetに登録するのですが、非常に難しく様々なIssueが存在します。

今回はこの問題と、対応方法を紹介します。

1. 問題
#

なぜ外部のElastic AgentがECKのfleet-serverに登録できないかは、以下のIssueに原因が全て記載されています。

https://github.com/elastic/elastic-agent/issues/2762

2. 対応方法
#

原因に軽く触れつつ、解決方法を紹介します。

1. Ingressでfleet-serverを外部公開

外部のAgentがECKのfleet-serverにアクセスするためには、なんらかの手段でfleetを外部公開する必要があります。 この時ECK in production environmentにもあるように、ECKはTLSで公開することが推奨になるので、Ingressを使ってElasticSearch,Kibana,Fleetを公開するケースが多いと思います。

従ってIngressを使ってECKにHTTPSでアクセスできるようにします。

ElasticSearch, Kibanaについては、公式のHelm ChartでIngress対応したようです。 AWS, GCPを使っている場合はこちらを参照すると良いでしょう。
# SAMPLE (nginx ingress controller + cert-manager + let's encrypt)
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kibana-ingress
  namespace: elastic-stack
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - "*.k8s.hirohirolab.com"
    secretName: quickstart-example-tls # https://cert-manager.io/docs/tutorials/acme/nginx-ingress/
  rules:
  - host: elastic.k8s.hirohirolab.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: elasticsearch-es-http
            port:
              number: 9200
  - host: kibana.k8s.hirohirolab.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kibana-kb-http
            port:
              number: 5601
  - host: fleet.k8s.hirohirolab.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: fleet-server-agent-http
            port:
              number: 8220
Ingressの振り分け先をルートディレクトリ以外(- path: /)を選んでしまうと、redirectの関係から404 Not Foundになるようです。Github-issue: Document edge cases around Fleet/Agent setups with Ingress

2. Fleetの通信をIngress経由に変更

FleetをIngressで公開しましたが、defaultの設定ではhttps://elasticsearch-es-http.elastic-stack.svc:9200とSerivce経由でアクセスするため、外部のAgentはアクセス不可になります。

alt text

従ってfleet-serverの通信をIngress経由に変更します。

  • before
# https://github.com/elastic/cloud-on-k8s/blob/c25ae520dbba3d83231b96fb9e10dc081546ff39/deploy/eck-stack/examples/agent/fleet-agents.yaml#L40
      xpack.fleet.agents.elasticsearch.hosts: ["https://elasticsearch-es-http.elastic-stack.svc:9200"]
      xpack.fleet.agents.fleet_server.hosts: ["https://fleet-server-agent-http.elastic-stack.svc:8220"]
  • after
# THIS IS A SAMPLE. INPUT YOUR FLEET AND ELASTIC URL.
      xpack.fleet.agents.elasticsearch.hosts: ["https://elastic.k8s.hirohirolab.com"]
      xpack.fleet.agents.fleet_server.hosts: ["https://fleet.k8s.hirohirolab.com"]

すると以下のようにIngress経由でのFleet通信に切り替わります。

alt text

3. Agentの証明書管理(問題)

これによりECK外部のAgentは登録できるようになりますが、今度はECK内部のAgentは以下のような証明書エラーになります。

alt text

この原因はECK内部のAgentは、ECKが生成した独自の自己証明書をFLEET_CAに格納するためです。

root@v0-dev-03:~/project/kubernetes-ingress# kubectl exec -it eck-stack-with-fleet-eck-agent-agent-84thl -n elastic-stack -- /bin/bash
root@v0-k8s-03:/usr/share/elastic-agent# export | grep CA
declare -x FLEET_CA="/mnt/elastic-internal/fleetserver-association/elastic-stack/fleet-server/certs/ca.crt" # Insert By elastic-operator

fleet-serverをIngress経由のアクセスに変更したためFLEET_CAの証明書ではなく、Ingressに登録した証明書でのアクセスになります。この結果、証明書検証ができずエラーになります。

4 FLEET_CA, FLEET_URLの上書き

上記解決にはFLEET_CA=""と上書きをすれば、一般の証明書(Lets Encryptなど外部のCA認証済み)を解決できるようになります。公式doc参照 またFLEET_URLもIngress経由のURLになってないので、変更する必要があります。

root@v0-k8s-03:/usr/share/elastic-agent# export | grep FLEET_URL
declare -x FLEET_URL="https://fleet-server-agent-http.elastic-stack.svc:8220"

これら環境変数はelastic-operatorによって設定されてしまいますが、公式docによると環境変数の上書きができるようです。

公式のhelmでは、daemonSetの欄に追加する形になります。

# https://github.com/elastic/cloud-on-k8s/blob/c25ae520dbba3d83231b96fb9e10dc081546ff39/deploy/eck-stack/examples/agent/fleet-agents.yaml#L98
daemonSet:
    podTemplate:
    spec:
        serviceAccountName: elastic-agent
        hostNetwork: true
        dnsPolicy: ClusterFirstWithHostNet
        automountServiceAccountToken: true
        securityContext:
        runAsUser: 0
    # OVERRIDE ENV VARS
        containers:
        - name: agent
        env:
        - name: FLEET_CA
            value: ""
        - name: FLEET_URL
            value: "https://fleet.k8s.hirohirolab.com" # THIS IS A SAMPLE. INPUT YOUR FLEET URL.

5. 完了

この状態でdeployすれば、以下のように環境変数が上書きされて展開され、statusもHEALTHYになります。

root@v0-dev-01:~/project/elasticsearch/cloud-on-k8s# kubectl exec -it eck-stack-with-fleet-eck-agent-agent-84thl  -n elastic-stack -- /bin/bash
root@v0-k8s-01:/usr/share/elastic-agent# export | grep -E "FLEET_CA|FLEET_URL"
declare -x FLEET_CA=""
declare -x FLEET_URL="https://fleet.k8s.hirohirolab.com"
root@v0-k8s-01:/usr/share/elastic-agent# elastic-agent status
┌─ fleet
│  └─ status: (HEALTHY) Connected
└─ elastic-agent
   └─ status: (HEALTHY) Running

alt text

おわりに
#

これでECK外部のAgentも、ECK内部のAgentもIngress経由でfleet-serverと接続することができるようになりました。

TLS通信しなくてもOKだったり、Ingressを用意するのが大変な場合は、fleet-serverをLoadBalancerやNodePortで公開して、FLEET_INSECURE=1で上書きしても解決できると思います。(未検証ですが)

おまけ
#

Elastic AgentではなくBeats/LogstashでECK外部のlogを収集する場合は簡単で、公式のhelmにBeatsが外部公開されるexampleが既に用意されています。

# https://github.com/elastic/cloud-on-k8s/blob/c25ae520dbba3d83231b96fb9e10dc081546ff39/deploy/eck-stack/examples/logstash/basic-eck.yaml#L105C1-L114C31
services:
  - name: beats
    service:
      spec:
        type: ClusterIP
        ports:
          - port: 5044
            name: "filebeat"
            protocol: TCP
            targetPort: 5044

またpurestorage(物理ストレージ)のSyslogをECKに転送する方法の紹介もあります。link

ElasticSearch - 関連記事
5: << この記事 >>

Related

ElasticSearchを使ったlog収集4 -kubernetes integration-
·2800 文字
Blog ElasticSearch Kubernetes
ElasticSearchを使ったlog収集2 -Elastic Agentの追加-
·3798 文字
Blog ElasticSearch
ElasticSearchを使ったlog収集1 -Elastic Agentとは?-
·3778 文字
Blog ElasticSearch