我试图在生产kubernetes集群上部署EFK堆栈(使用kubespray安装),我们有3个节点,1个主服务器+2个工作人员,我需要使用elasticsearch作为状态集,并使用主节点中的本地文件夹来存储日志(用于持久的本地存储),我的配置是:
kind: Namespace
apiVersion: v1
metadata:
name: kube-logging
---
kind: Service
apiVersion: v1
metadata:
name: elasticsearch
namespace: kube-logging
labels:
app: elasticsearch
spec:
selector:
app: elasticsearch
clusterIP: None
ports:
- port: 9200
name: rest
- port: 9300
name: inter-node
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
namespace: kube-logging
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
namespace: kube-logging
spec:
storageClassName: local-storage
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp/elastic
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: es-cluster
namespace: kube-logging
spec:
serviceName: elasticsearch
replicas: 2
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
resources:
limits:
cpu: 1000m
memory: 2Gi
ports:
- containerPort: 9200
name: rest
protocol: TCP
- containerPort: 9300
name: inter-node
protocol: TCP
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
env:
- name: cluster.name
value: k8s-logs
- name: node.name
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: discovery.seed_hosts
value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
- name: cluster.initial_master_nodes
value: "es-cluster-0,es-cluster-1,es-cluster-2"
- name: ES_JAVA_OPTS
value: "-Xms512m -Xmx512m"
initContainers:
- name: fix-permissions
image: busybox
command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
securityContext:
privileged: true
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
- name: increase-vm-max-map
image: busybox
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext:
privileged: true
- name: increase-fd-ulimit
image: busybox
command: ["sh", "-c", "ulimit -n 65536"]
securityContext:
privileged: true
volumeClaimTemplates:
- metadata:
name: data
labels:
app: elasticsearch
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: local-storage
resources:
requests:
storage: 5Gi
---这是我的配置,但当它被应用时,弹力搜索的两个吊舱之一仍然处于待定状态。当我为这个荚描述kubectl时,这是我得到的错误:“1个节点没有找到可用的持久卷来绑定。”
我的配置正确吗?我必须使用PV +存储库+ volumeClaimTemplates吗?提前谢谢你。
这些是我的成果:
[root@node1 nex]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 5Gi RWO Retain Bound kube-logging/data-es-cluster-0 local-storage 24m
[root@node1 nex]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-es-cluster-0 Bound my-pv 5Gi RWO local-storage 24m
data-es-cluster-1 Pending local-storage 23m
[root@node1 nex]# kubectl describe pvc data-es-cluster-0
Name: data-es-cluster-0
Namespace: kube-logging
StorageClass: local-storage
Status: Bound
Volume: my-pv
Labels: app=elasticsearch
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 5Gi
Access Modes: RWO
VolumeMode: Filesystem
Mounted By: es-cluster-0
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 24m persistentvolume-controller waiting for first consumer to be created before binding
[root@node1 nex]# kubectl describe pvc data-es-cluster-1
Name: data-es-cluster-1
Namespace: kube-logging
StorageClass: local-storage
Status: Pending
Volume:
Labels: app=elasticsearch
Annotations: <none>
Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
Mounted By: es-cluster-1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 4m12s (x82 over 24m) persistentvolume-controller waiting for first consumer to be created before binding
[root@node1 nex]#发布于 2020-06-09 20:57:45
我的配置正确吗?我必须使用PV +存储库+ volumeClaimTemplates吗?提前谢谢你。
除了@Arghya在他的回答中已经提出的建议之外,我还想在您当前的设置中强调一件事情。
如果您认为您的Elasticsearch Pods只会调度在一个特定的节点上(在您的例子中是您的主节点),那么您仍然可以使用本地卷类型。但是,不要将其与hostPath混淆。在您的PV定义中,我注意到您使用了hostPath键,因此很可能您还没有完全意识到这两个概念之间的差异。虽然它们非常相似,但本地类型比hostPath具有更大的功能和一些不可否认的优势。
正如您可以在文档中看到的那样
本地卷表示安装的本地存储设备,如磁盘、分区或目录。
因此,这意味着,除了特定的目录之外,您还可以挂载本地磁盘或分区(/dev/sdb、/dev/sdb5等)。它可以是一个具有严格定义容量的LVM分区。请记住,在挂载本地目录时,您无法强制执行实际使用的容量,因此即使定义了5Gi,即使超出了这个值,也可以将日志写入本地目录。但是logical volume的情况并非如此,因为您可以定义它的容量,并确保它不会占用比您提供的更多的磁盘空间。
第二个区别是:
与
hostPath卷相比,local卷可以以一种持久和可移植的方式使用,而无需手动将Pods调度到节点,因为系统通过查看PersistentVolume上的节点关联来了解卷的节点约束。
在本例中,是PersistentVolume定义了节点关联,因此使用后续local-storage存储类和相应PersistenVolume的任何Pod (可以由StatefulSet管理)都将自动调度到正确的节点上。
正如您可以进一步阅读的那样,nodeAffinity实际上是此类PV中所需的字段。
使用本地卷时需要PersistentVolume
nodeAffinity。它使Kubernetes调度程序能够使用本地卷正确地调度Pods到正确的节点。
据我所知,您的kubernetes集群是在本地/在前提下建立的。在这种情况下,NFS可能是一个正确的选择。
如果您使用了一些云环境,那么您可以使用特定云提供商(如GCEPersistentDisk或AWSElasticBlockStore )提供的持久存储。库伯奈特斯目前支持的持久卷类型的完整列表,您可以找到这里。
因此,同样,如果您担心StatefulSet中的节点级冗余,并且希望您的2 Elasticsearch Pods总是被调度在不同的节点上,就像@Arghya已经建议的那样,使用NFS或其他一些非本地存储。
但是,如果您不关心节点级的冗余,而且您完全同意两个Elasticsearch Pods都运行在同一个节点上(在您的示例中是主节点),请跟随我:)
正如@Arghya Sadhu正确指出的那样:
即使已经绑定到PVC的PV有备用容量,也不能再绑定到另一个PVC,因为它是PV和PVC之间的一对一映射。
虽然PV和PVC之间总是一对一的映射,但这并不意味着您不能在许多Pods中使用单个PVC。
注意,在您的StatefulSet示例中,您使用了volumeClaimTemplates,这基本上意味着,每次创建由StatefulSet管理的新Pod时,都会根据该模板创建一个新的相应的PersistentVolumeClaim。因此,如果您定义了例如10Gi PersistentVolume,那么无论您在声明中请求所有10Gi还是其中的一半,只有第一个PVC才能成功地绑定到您的PV。
但是,与使用volumeClaimTemplates和为每个有状态Pod创建单独的PVC不同,您可以让它们使用单个手动定义的PVC。请查看以下示例:
我们首先需要的是一个存储类。它看起来非常类似于您的客户中的一个:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer这个设置和您的设置之间的第一个区别是在PV定义中。我们使用的不是hostPath,而是本地卷:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /var/tmp/test ### path on your master node
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- your-master-node-name注意,除了定义local路径之外,我们还定义了nodeAffinity规则,以确保获得此特定PV的所有Pods都将自动调度在主节点上。
然后我们就有了手动应用的PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 10Gi
storageClassName: local-storage这个PVC现在可以用于由StatefulSet管理的所有Pods (在您的示例2中)。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 2 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: mypd
mountPath: /usr/share/nginx/html
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim请注意,在上面的示例中,我们不再使用volumeClaimTemplates,而是使用一个单独的PersistentVolumeClaim,它可以被我们所有的Pods使用。豆荚仍然是唯一的,因为它们是由StatefulSet管理的,但是它们使用的不是唯一的PVCs,而是通用的。由于这种方法,两个Pods可以同时将日志写入单个卷。
在我的示例中,我使用了nginx服务器,使每个想要快速尝试它的人都能尽可能轻松地复制,但我相信您可以很容易地根据您的需要调整它。
https://stackoverflow.com/questions/62253584
复制相似问题