Prólogo
Kubernetes nos proporciona oficialmente muchos complementos de forma predeterminada , incluido el conjunto de procesamiento de registros EFK , que incluye Elasticsearch, Fluentd y Kibana de tres componentes. Elasticsearch es un motor de búsqueda, responsable de almacenar registros y proporcionar funciones externas de consulta de registros; Fluentd es un componente de recopilación de registros, responsable de recopilar registros en el clúster y enviarlos a Elasticsearch; Kibana es un componente de visualización gráfica, responsable de consultar registros de Elasticsearch Y mostrarlo en una forma apropiada
Implementar EFK
-
Descargue el archivo de inicio correspondiente
$ cd /opt/k8s/work/efk $ for file in es-service.yaml es-statefulset.yaml fluentd-es-configmap.yaml fluentd-es-ds.yaml kibana-deployment.yaml kibana-service.yaml; do wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/$file done
-
Elasticsearch se inicia como un conjunto con estado. La imagen correspondiente no contiene el complemento de seguridad Es-X-Pack. Como
vm.max_map_count
el valor requerido por es no puede ser inferior a 262144, hay un contenedor de inicio en el archivo de inicio correspondiente es-statefulset.yaml, que se establece antes de que se inicie el contenedor de esvm.max_map_count
. Si este valor se ha establecido en el sistema, puede eliminar la configuración relacionada con este contenedor de inicio, puede vervm.max_map_count
el valor con el siguiente comando$ more /proc/sys/vm/max_map_count
-
Almacenamiento es-statefulset.yaml la configuración de almacenamiento del archivo de inicio es EmptyDir, por lo que los datos almacenados cuando se reinicia se perderán, por lo que el archivo descargado directamente solo se usa para pruebas, si desea usarlo en un entorno de producción, debe reemplazarlo con almacenamiento permanente Volumen de almacenamiento.
-
Fluentd se inicia en forma de DaemonSet, que iniciará un pod en todos los nodos. Según la configuración en fluentd-es-configmap.yaml, los registros de kubelet y el contenedor se leerán y se enviarán a es.
-
El archivo de inicio en este complemento no debe usarse directamente en el entorno de producción. Si desea usarlo en un entorno de producción, se recomienda instalar estos componentes con Helm. Las direcciones de timón correspondientes son las siguientes
-
-
Modificar la dirección espejo correspondiente en el archivo de inicio
El registro de imagen predeterminado en el archivo de inicio es quay.io, que no se puede descargar directamente en China. Aquí se utiliza el registro de Microsoft.
$ sed -i -e 's_quay.io_quay.azk8s.cn_' es-statefulset.yaml $ sed -i -e 's_quay.io_quay.azk8s.cn_' fluentd-es-ds.yaml
-
Iniciar EFK
$ kubectl apply -f .
La implementación anterior de la recopilación de registros a través de EFK proporcionada por Kubernetes se ha completado. Sin embargo, debido a limitaciones de recursos durante la ejecución de mi entorno de prueba, ES no puede iniciar dos al mismo tiempo, y esta imagen de ES proporcionada por Kubernetes requiere al menos dos grupos para formar un clúster para uso normal, por lo que solo puedo usar imágenes oficiales de ES para construirme Medio ambiente EFK.
El nodo único ElasticSearch implementa EFK
Implementar Elasticsearch
-
Edite el archivo de inicio
-
es archivo de configuración
$ cat >docker.es.co-configmap.yaml<<EOF kind: ConfigMap apiVersion: v1 metadata: name: es-config-v7.6.1 namespace: kube-system labels: addonmanager.kubernetes.io/mode: Reconcile data: elasticsearch.yml: |- cluster.name: kubernetes-logging node.name: elasticsearch-logging-0 path.data: /data discovery.type: single-node network.host: 0.0.0.0 EOF
- discovery.type: nodo único, que representa que el es correspondiente es un clúster de nodo único
- network.host: 0.0.0.0 Se puede acceder a cualquier IP
-
es archivo de inicio
$ cat >docker.es.co-statefulset.yml<<EOF # Elasticsearch deployment itself apiVersion: apps/v1 kind: StatefulSet metadata: name: elasticsearch-logging namespace: kube-system labels: k8s-app: elasticsearch-logging version: v7.4.2 addonmanager.kubernetes.io/mode: Reconcile spec: serviceName: elasticsearch-logging replicas: 1 selector: matchLabels: k8s-app: elasticsearch-logging version: v7.4.2 template: metadata: labels: k8s-app: elasticsearch-logging version: v7.4.2 spec: #serviceAccountName: elasticsearch-logging containers: - image: elasticsearch:7.6.1 name: elasticsearch-logging #imagePullPolicy: Always resources: # need more cpu upon initialization, therefore burstable class limits: cpu: 1000m memory: 4Gi requests: cpu: 100m memory: 1Gi ports: - containerPort: 9200 name: db protocol: TCP - containerPort: 9300 name: transport protocol: TCP #livenessProbe: #tcpSocket: # port: transport #initialDelaySeconds: 5 #timeoutSeconds: 10 # readinessProbe: #tcpSocket: # port: transport #initialDelaySeconds: 5 #timeoutSeconds: 10 volumeMounts: - name: elasticsearch-logging mountPath: /data - name: config-volume mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml env: - name: "NAMESPACE" valueFrom: fieldRef: fieldPath: metadata.namespace volumes: - name: elasticsearch-logging emptyDir: {} - name: config-volume configMap: name: es-config-v7.6.1 EOF
En comparación con el archivo de inicio proporcionado por kubernetes, hay dos cambios importantes aquí
- Las partes relacionadas con los permisos se han eliminado y no es necesario realizar la agrupación de componentes de descubrimiento de servicios.
- El archivo de imagen se reemplaza por elasticsearch: 7.6.1, que es la imagen oficial publicada por es en Docker Hub
-
es archivo de servicio
$ cat >es-service.yaml<<EOF apiVersion: v1 kind: Service metadata: name: elasticsearch-logging namespace: kube-system labels: k8s-app: elasticsearch-logging kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "Elasticsearch" spec: ports: - port: 9200 protocol: TCP targetPort: db selector: k8s-app: elasticsearch-logging EOF
-
-
Iniciar servicio
$ kubectl create -f docker.es.co-configmap.yaml $ kubectl create -f docker.es.co-statefulset.yml $ kubectl create -f es-service.yaml
Implementar servicio fluido
El fluentd archivo de inicio y kubernetes no nos proporcionaron ningún cambio. El único lugar que modifiqué cuando comencé localmente fue el directorio del registro del acoplador. De manera predeterminada, el registro de Docker utiliza el controlador de registro de archivos json, que se almacena en el directorio de contenedores en el directorio de trabajo de Docker. El directorio de trabajo predeterminado es / var / lib / docker, por lo que el directorio de registro de Docker predeterminado es / var / lib / docker / container, mi propio entorno cambió el directorio de trabajo a / data / k8s / docker / data al instalar docker, por lo que necesito modificar el directorio de montaje durante el inicio
-
Edite el archivo de inicio
-
Archivo DaemonSet
$ cat>fluentd-es-ds.yaml<<EOF apiVersion: v1 kind: ServiceAccount metadata: name: fluentd-es namespace: kube-system labels: k8s-app: fluentd-es addonmanager.kubernetes.io/mode: Reconcile --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd-es labels: k8s-app: fluentd-es addonmanager.kubernetes.io/mode: Reconcile rules: - apiGroups: - "" resources: - "namespaces" - "pods" verbs: - "get" - "watch" - "list" --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd-es labels: k8s-app: fluentd-es addonmanager.kubernetes.io/mode: Reconcile subjects: - kind: ServiceAccount name: fluentd-es namespace: kube-system apiGroup: "" roleRef: kind: ClusterRole name: fluentd-es apiGroup: "" --- apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-es-v3.0.0 namespace: kube-system labels: k8s-app: fluentd-es version: v3.0.0 addonmanager.kubernetes.io/mode: Reconcile spec: selector: matchLabels: k8s-app: fluentd-es version: v3.0.0 template: metadata: labels: k8s-app: fluentd-es version: v3.0.0 # This annotation ensures that fluentd does not get evicted if the node # supports critical pod annotation based priority scheme. # Note that this does not guarantee admission on the nodes (#40573). annotations: seccomp.security.alpha.kubernetes.io/pod: 'docker/default' spec: priorityClassName: system-node-critical serviceAccountName: fluentd-es containers: - name: fluentd-es image: quay.azk8s.cn/fluentd_elasticsearch/fluentd:v3.0.0 env: - name: FLUENTD_ARGS value: --no-supervisor -q resources: limits: memory: 500Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /data/k8s/docker/data/containers readOnly: true - name: config-volume mountPath: /etc/fluent/config.d ports: - containerPort: 24231 name: prometheus protocol: TCP #livenessProbe: #tcpSocket: # port: prometheus #initialDelaySeconds: 5 #timeoutSeconds: 10 #readinessProbe: #tcpSocket: # port: prometheus #initialDelaySeconds: 5 #timeoutSeconds: 10 terminationGracePeriodSeconds: 30 volumes: - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /data/k8s/docker/data/containers - name: config-volume configMap: name: fluentd-es-config-v0.2.0 EOF
- Cambie el hostPath de los contenedores varlibdocker correspondientes a / data / k8s / docker / data / container, y la ruta montada en el contenedor fluentd también debe ser / data / k8s / docker / data / container, para que sea coherente
-
Archivo de configuración, debido a que el archivo de configuración y los kubernetes no nos proporcionan cambios, no todos se publican aquí, el contenido específico se refiere a fluentd-es-configmap.yaml , solo el contenido de la parte fuente se proporciona aquí para explicar por qué el siguiente paso El directorio de registro que montamos en el contenedor fluentd debe ser consistente con la máquina host
... <source> @id fluentd-containers.log @type tail path /var/log/containers/*.log pos_file /var/log/es-containers.log.pos tag raw.kubernetes.* read_from_head true <parse> @type multi_format <pattern> format json time_key time time_format %Y-%m-%dT%H:%M:%S.%NZ </pattern> <pattern> format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/ time_format %Y-%m-%dT%H:%M:%S.%N%:z </pattern> </parse> </source> ...
En la configuración de esta parte de origen, fluentd no toma datos directamente del directorio de registro de la ventana acoplable en el contenedor que montamos, sino que extrae los datos de registro del directorio / var / log / container (/ var / log / es lo que haremos (El directorio / var / log del host está montado en él) Esto se debe a que el componente Kubenetes kubelet crea un enlace flexible en el directorio / var / log /, y coloca el nombre del pod y el nombre del contenedor en esta conexión flexible. En el nombre, por ejemplo
/var/log/containers/fluentd-es-v3.0.0-hvbw7_kube-system_fluentd-es-ef645a4009163b41d596b68d32dbcc921f032549fa168b630d10d0ea2f98eacb.log -> /var/log/pods/kube-system_fluentd-es-v3.0.0-hvbw7_c5269d8e-8543-470a-8599-8ae3a7242a46/fluentd-es/0.log
/var/log/pods/kube-system_fluentd-es-v3.0.0-hvbw7_c5269d8e-8543-470a-8599-8ae3a7242a46/fluentd-es/0.log -> /data/k8s/docker/data/containers/ef645a4009163b41d596b68d32dbcc921f032549fa168b630d10d0ea2f98eacb/ef645a4009163b41d596b68d32dbcc921f032549fa168b630d10d0ea2f98eacb-json.log
Kubelet lee el registro en / var / log / container a través de dicho enlace, y en realidad lee el registro en el contenedor. Debido a que la información de la ruta del enlace es fija, la ruta en el contenedor debe estar en el host. Se consistente.
Los beneficios de esto son relativamente fáciles de entender, porque el nombre del archivo de registro contiene el nombre del pod, el espacio de nombres y otra información de kubernetes, que puede analizarse fácilmente a través de complementos en forma fluida, lo cual es conveniente para que los usuarios lo usen para aplicaciones específicas en kibana Buscar y filtrar.
-
-
Comience con fluidez
$ kubectl create -f fluentd-es-configmap.yaml $ kubectl create -f fluentd-es-ds.yaml
Departamento de kibana
-
Edite el archivo de inicio
-
archivo de implementación
cat >cat kibana-deployment.yaml<<EOF apiVersion: apps/v1 kind: Deployment metadata: name: kibana-logging namespace: kube-system labels: k8s-app: kibana-logging addonmanager.kubernetes.io/mode: Reconcile spec: replicas: 1 selector: matchLabels: k8s-app: kibana-logging template: metadata: labels: k8s-app: kibana-logging annotations: seccomp.security.alpha.kubernetes.io/pod: 'docker/default' spec: containers: - name: kibana-logging image: elastic/kibana:7.2.0 resources: # need more cpu upon initialization, therefore burstable class limits: cpu: 1000m requests: cpu: 100m env: - name: ELASTICSEARCH_HOSTS value: http://elasticsearch-logging:9200 - name: SERVER_NAME value: kibana-logging - name: SERVER_BASEPATH value: /api/v1/namespaces/kube-system/services/kibana-logging/proxy - name: SERVER_REWRITEBASEPATH value: "false" ports: - containerPort: 5601 name: ui protocol: TCP EOF
-
archivo de servicio
cat >kibana-service.yaml<<EOF apiVersion: v1 kind: Service metadata: name: kibana-logging namespace: kube-system labels: k8s-app: kibana-logging kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "Kibana" spec: ports: - port: 5601 protocol: TCP targetPort: ui selector: k8s-app: kibana-logging EOF
-
-
启动 kibana
$ kubectl create -f kibana-deployment.yaml $ kubectl create -f kibana-service.yaml
Inicie el proxy kubecrl para acceder a kibana
$ kubectl proxy --accept-hosts='^*$' --address=192.168.0.107
Interfaz accede mediante un navegador, introduzca la http://192.168.0.107:8001/api/v1/namespaces/kube-system/services/kibana-logging/proxy/
Kibana acceso.
El patrón de índice debe configurarse para el primer acceso
Espere un momento, luego puede ver el registro correspondiente en la interfaz Discover
Como puede ver, además de los registros en el contenedor, se ha agregado mucha información sobre kubernetes.