使用 Kubernetes 在 elasticsearch 上丢失数据 - 索引被自动删除和创建

问题描述

设置

我通过 Google Kubernetes Engine 在 Kubernetes 上使用 elasticsearch:7.9.3。 elasticsearch 数据使用 20GB 的 PersistentVolumeClaim 持久化。我通过删除并重新创建 elasticsearch 部署并检查数据是否仍然可用来测试 PersistentVolumeClaim 是否设置正确 - 确实如此。

Elasticsearch 以最小的方式设置,所以它本身没有自动扩展、Kibana(本地和独立在我的系统上设置)等所有额外的东西。 deployment.yaml 如下所示:

apiVersion: apps/v1
kind: Deployment
Metadata:
  name: elasticsearch-db
spec:
  selector:
    matchLabels:
      app: elasticsearch-db
      tier: elastic
  template:
    Metadata:
      labels:
        app: elasticsearch-db
        tier: elastic
    spec:
      terminationGracePeriodSeconds: 300
      initContainers:
        # NOTE:
        # This is to fix the permission on the volume
        # By default elasticsearch container is not run as
        # non root user.
        # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults
        - name: fix-the-volume-permission
          image: busyBox
          command:
          - sh
          - -c
          - chown -R 1000:1000 /usr/share/elasticsearch/data
          securityContext:
            privileged: true
          
        
          volumeMounts:
          - name: elasticsearch-db-storage
            mountPath: /usr/share/elasticsearch/data
        # NOTE:
        # To increase the default vm.max_map_count to 262144
        # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run-prod-mode
        - name: increase-the-vm-max-map-count
          image: busyBox
          command:
          - sysctl
          - -w
          - vm.max_map_count=262144
          securityContext:
            privileged: true
        # To increase the ulimit
        # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults
        - name: increase-the-ulimit
          image: busyBox
          command:
          - sh
          - -c
          - ulimit -n 65536
          securityContext:
            privileged: true
      containers:
      - image: elasticsearch:7.9.3
        name: elasticsearch-db
        ports:
          - name: elk-rest-port
            containerPort: 9200
          - name: elk-nodes-port
            containerPort: 9300
        env:
          - name: discovery.type
            value: single-node
          - name: ES_JAVA_OPTS
            value: -xms2g -Xmx2g


        volumeMounts:
          - mountPath: /usr/share/elasticsearch/data
            name: elasticsearch-db-storage
      volumes:
        - name: elasticsearch-db-storage
          persistentVolumeClaim:
            claimName: elasticsearch-db-storage-claim

---

apiVersion: v1
kind: Service
Metadata:
  name: elasticsearch-db
spec:
  selector:
    app: elasticsearch-db
    tier: elastic
  ports:
    - name: elk-rest-port
      port: 9200
      targetPort: 9200
    - name: elk-nodes-port
      port: 9300
      targetPort: 9300
  type: LoadBalancer


---

apiVersion: v1
kind: PersistentVolumeClaim
Metadata:
  name: elasticsearch-db-storage-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

如果我没记错的话,这应该认为 1 个副本。我注意到有 7 个被驱逐的 pod,其中一个正在运行的 pod 有两次重启。

问题

我的索引是手动创建的,有两个进程通过 python 的 elasticsearch 库将大约 5 到 8 GB 的数据泵入这个系统。然而不知何故,这些数据丢失了。一些最近推送的数据仍然可用,但很可能是在问题发生后推送到服务器上的。

最可能的原因

我在日志中发现了这个。

2021-01-07 17:45:41.937 CET "SSL/TLS request received but SSL/TLS is not enabled on this node,got (16,3,1,0),[Netty4TcpChannel{localAddress=/10.32.6.14:9300,remoteAddress=/10.32.6.1:58768}],closing connection"
2021-01-08 00:38:00.604 CET "[.async-search/fQ0TsMW-TaKyYA3qpisrMg] deleting index"
2021-01-08 00:38:00.904 CET "[myindex/dreRruz0TxaQJsSi8U_BOw] deleting index"
2021-01-08 00:38:01.254 CET "[read_me/kMNmyfHoT4KAZyajnWLg2A] deleting index"
2021-01-08 00:38:01.524 CET "[read_me] creating index,cause [api],templates [],shards [1]/[1]"
2021-01-08 00:38:01.904 CET "[read_me/LaGFr3GcR4Gy-by2LUaiaw] create_mapping [_doc]"
2021-01-08 00:38:19.811 CET "[myindex] creating index,cause [auto(bulk api)],shards [1]/[1]"
2021-01-08 00:38:20.071 CET "[myindex/iQHwXEgKQb6F2Ur8JfFNIw] create_mapping [_doc]"
2021-01-08 02:30:00.002 CET "starting SLM retention snapshot cleanup task"
2021-01-08 02:30:00.003 CET "there are no repositories to fetch,SLM retention snapshot cleanup task complete"
2021-01-08 02:38:00.004 CET "triggering scheduled [ML] maintenance tasks"
2021-01-08 02:38:00.004 CET "Deleting expired data"
2021-01-08 02:38:00.005 CET "Completed deletion of expired ML data" 
2021-01-08 02:38:00.006 CET "Successfully completed [ML] maintenance tasks"
2021-01-08 04:14:35.547 CET "[.async-search] creating index,shards [1]/[1]"
2021-01-08 04:14:35.553 CET "updating number_of_replicas to [0] for indices [.async-search]"

我的理解是,删除索引也会删除数据(即使有办法恢复它,我也不关心)。

在研究这个问题时,我遇到了关于弹性搜索数据库meow attack。这种攻击本质上是删除索引并创建以 -meow 结尾的随机字符串索引(因为猫喜欢丢东西,在这种情况下是数据库表)。

green  open .kibana-event-log-7.9.3-000001 ulnmulwTSzmZ2vi6FY6NGg 1 0     4     0  21.6kb  21.6kb
yellow open read_me                        LaGFr3GcR4Gy-by2LUaiaw 1 1     1     0   4.9kb   4.9kb
green  open .kibana_task_manager_1         Q_ud7vO2RN6ImILgNwS4iQ 1 0     6 14071   1.4mb   1.4mb
green  open .async-search                  maKtb69bS-WCQQSTTOTJ4Q 1 0     0     0   3.3kb   3.3kb
green  open .kibana_1                      XqDgNGuJTzyDeVLyVaM_eQ 1 0    45     1 546.4kb 546.4kb
yellow open myindex                        iQHwXEgKQb6F2Ur8JfFNIw 1 1 30229 25118    27mb    27mb

我当前的索引看起来有些相似,但我有随机字符串并且没有喵喵在那里结束。这可能是该攻击的变体吗?诚然,在圣诞节假期之前运行它比正确保护它更重要,尽管这就是我现在正在做的工作。

如果确实是这个问题,那么只需打开身份验证就可以解决这个问题,对吗?

潜在的其他原因

在我将数据推送到服务器一两个星期的某个时候,我在推送方面收到了这个错误

elasticsearch.exceptions.TransportError: TransportError(429,'cluster_block_exception','index [myindex] 被阻止: [TOO_MANY_REQUESTS/12/磁盘使用量超过洪水阶段水印,索引 有只读允许删除块];')

错误似乎有几个可能的原因,其中之一是用完所有分配的存储,但我的理解是,这应该使数据只读,而不是删除大部分或全部。所以这可能是也可能不是我的问题的原因。同样,通过日志,我在服务器上也看到了几个这样的警告。

有几个 java.lang.OutOfMemoryError 并且通常还有很多堆栈跟踪。我相信这触发了 elasticsearch 的重启,但可能不会导致问题。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...