Stack Elastic sous ECK et accès à "Welcome to Nginx"

Bonjour,

Je débute avec la stack Elastic et Kubernetes. J'essaie de faire fonctionner la stack Elastic avec ECK. Je ne travaille qu'en local avec :

  • Windows 10 PRO
  • Docker Desktop
  • WSL 1 + Ubuntu 18.04

Pour le moment, j'ai Filebeat, Elasticsearch et Kibana qui sont en running. A terme je devrai ajouter Logstash. Mais pour le moment, pour tester que les données passent bien à travers la stack, j'essaie juste d'ajouter un Nginx, mais je n'arrive pas à accéder à la page "Welcome to Nginx" dans Chrome.

Pour commencer, voici les fichiers que j'utilise :

Fichier .yaml pour filebeat :

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: beats
  labels:
    k8s-app: filebeat
data:
  filebeat.yml: |-
    filebeat.autodiscover:
      providers:
        - type: kubernetes
          host: ${NODE_NAME}
          hints.enabled: true
          hints.default_config:
            type: container
            paths:
              - /var/log/containers/*${data.kubernetes.container.id}.log
    processors:
      - add_cloud_metadata:
      - add_host_metadata:
    output.elasticsearch:
      hosts: ['https://${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      ssl.certificate_authorities:
      - /mnt/elastic/tls.crt

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: beats
  labels:
    k8s-app: filebeat
spec:
  selector:
    matchLabels:
      k8s-app: filebeat
  template:
    metadata:
      labels:
        k8s-app: filebeat
    spec:
      serviceAccountName: filebeat
      terminationGracePeriodSeconds: 30
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
        - name: filebeat
          image: docker.elastic.co/beats/filebeat:7.8.0
          args: [
            "-c", "/etc/filebeat.yml",
            "-e",
          ]
          env:
            - name: ELASTICSEARCH_HOST
              value: monitor-es-http
            - name: ELASTICSEARCH_PORT
              value: "9200"
            - name: ELASTICSEARCH_USERNAME
              value: elastic
            - name: ELASTICSEARCH_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: elastic
                  name: monitor-es-elastic-user
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
          securityContext:
            runAsUser: 0
            # If using Red Hat OpenShift uncomment this:
            #privileged: true
          resources:
            limits:
              memory: 200Mi
            requests:
              cpu: 100m
              memory: 100Mi
          volumeMounts:
            - name: config
              mountPath: /etc/filebeat.yml
              readOnly: true
              subPath: filebeat.yml
            - name: data
              mountPath: /usr/share/filebeat/data
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
            - name: varlog
              mountPath: /var/log
              readOnly: true
            - name: es-certs
              mountPath: /mnt/elastic/tls.crt
              readOnly: true
              subPath: tls.crt
      volumes:
        - name: config
          configMap:
            defaultMode: 0600
            name: filebeat-config
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers
        - name: varlog
          hostPath:
            path: /var/log
        # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
        - name: data
          hostPath:
            path: /var/lib/filebeat-data
            type: DirectoryOrCreate
        - name: es-certs
          secret:
            secretName: monitor-es-http-certs-public

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: filebeat
subjects:
  - kind: ServiceAccount
    name: filebeat
    namespace: beats
roleRef:
  kind: ClusterRole
  name: filebeat
  apiGroup: rbac.authorization.k8s.io

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: filebeat
  labels:
    k8s-app: filebeat
rules:
  - apiGroups: [""] # "" indicates the core API group
    resources:
      - namespaces
      - pods
    verbs:
      - get
      - watch
      - list

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: filebeat
  namespace: beats
  labels:
    k8s-app: filebeat

Fichier .yaml pour Elasticsearch, Kibana et Volume :

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: monitor
  namespace: beats
spec:
  version: 7.8.0
  nodeSets:
    - name: mdi
      count: 1
      config:
        node.store.allow_mmap: false
        node.master: true
        node.data: true
        node.ingest: true
        xpack.security.authc:
          anonymous:
            username: anonymous
            roles: superuser
            authz_exception: false

      volumeClaimTemplates:
        - metadata:
            name: elasticsearch-data
          spec:
            storageClassName: es-data
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 5Gi

---
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: monitor
  namespace: beats
spec:
  version: 7.8.0
  count: 1
  elasticsearchRef:
    name: "monitor"
  http:
    service:
      spec:
        type: LoadBalancer

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: es-data
  namespace: beats
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: es-pv-data
  namespace: beats
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: es-data
  hostPath:
    path: /c/Users/ID_USER/workspace/workshop-k8s-dev-to-prod/platforms/workshop/workshop-k8s/workshop-eck/eck_example/es-data

Fichier .yaml pour Nginx :

---
apiVersion: v1
kind: Service
metadata:
  namespace: beats
  name: nginx
  labels:
    app: nginx
spec:
  type: NodePort
  ports:
    - port: 8080
      protocol: TCP
      targetPort: http
  selector:
    app: nginx

---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: beats
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - name: http
              containerPort: 8080

L'injection de données directement dans Elasticsearch (avec curl et account.json par exemple) fonctionne bien. Je récupère l'index dans Kibana et ces données sont bien persistées dans le persistent volume.

Pour tester la récolte de données avec Filebeat, je voudrais juste pouvoir faire des F5 sur la page d'accueil Nginx et vérifier que les logs correspondants sont bien récupérés. J'avais déjà utilisé cette méthode précédemment pour un déploiement de la stack avec Docker Compose (en guise d'entrainement.

Donc ici, une fois les pods, services... déployés (kubectl apply sur les fichiers au-dessus), j'utilise la commande :

kubectl -n beats port-forward service/nginx 8080

(J'utilise le même type de commande pour accéder à Kibana ou la page de contrôle d'Elasticsearch et là ça fonctionne).

Mais ensuite dans Chrome, je ne parviens pas à afficher la page Nginx :

Handling connection for 8080
E0711 16:18:44.944162    6792 portforward.go:400] an error occurred forwarding 8080 -> 8080: error forwarding port 8080 to pod 50cf19ab998c488b6d067309ae9b5affa9d6008344e5fba8e09e24d9671c8306, uid : exit status 1: 2020/07/11 12:53:26 socat[52337] E connect(16, AF=2 127.0.0.1:8080, 16): Connection refused
  • Avec "https://localhost:8080", j'obtiens "Cette page ne fonctionne pas..." et le même type de message qu'au-dessus dans la console.

Je précise que je récupère le même type d'erreur si le service Nginx est de type LoadBalancer.
Voilà à peu près tout ce que je peux dire de mon problème pour le moment. Je continue à fouiller à droite et à gauche. Dites-moi si jamais il y a besoin d'autres informations.

En tout cas, merci par avance pour l'aide que vous pourrez m'apporter.

Guillaume.

Hello Guillaume,

Si je comprend bien votre problème est lié à l'accès à NGINX via port-forwarding, et n'a à priori pas trop de rapport avec ECK et Elastic?

Cela semble hors-scope pour ce forum. Voici quelques pistes quand même en espérant que ça puisse vous aider:

  • le Pod nginx est-il Ready?
  • y a-t'il un message d'erreur dans les logs de nginx?
  • avez-vous déjà un service en local qui utilise le port 8080? Dans ce cas essayez le port-forward sur un autre port local.

Bonjour Sébastien,

Merci pour votre réponse et les pistes fournies.
J'ai hésité en effet à poster ici mais comme j'utilise beaucoup la suite Elastic dans le cadre du travail qui m'est demandé, dans le doute je me suis dirigé ici.

Pour répondre aux pistes que vous me donnez :

  • Voici l'état des pods avec ma configuration :
----- Pods -----
NAME                              READY   STATUS    RESTARTS   AGE
elasticsearch-es-elastic-node-0   1/1     Running   0          3m16s
filebeat-krw7b                    1/1     Running   0          3m19s
kibana-kb-7c4d87745d-5lgm5        1/1     Running   0          3m16s
nginx-c79865646-882gw             1/1     Running   0          11s
  • Je ne sais pas trop si c'est de cela dont vous parlez mais voici ce que retourne la commande kubectl -n beats logs po/nginx-c79865646-882gw :
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
  • J'ai le même problème avec le port 8085. Pour déterminer quels sont les ports utilisés, j'ai bien essayé la commande netstat dans le terminal (Terminator) mais je ne récupère aucune information :
netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags       Type       State         I-Node   Path

Dans PowerShell, je récupère ça pour le port 8085 :

PS C:\windows\system32> netstat -abn
[...]
 TCP    127.0.0.1:8085         0.0.0.0:0              LISTENING
 Impossible d’obtenir les informations de propriétaire
[...]
  • Concernant le sujet hors scope, existe-t-il une section de ce forum plus pertinente où poster ce sujet ?

  • A défaut, quel autre forum pourriez-vous me conseiller, s'il-vous-plaît ?

Guillaume.

J'ai testé en local: NGINX utilise le port 80 par défaut, il faut donc changer:

  • le déploiement nginx: containerPort: 80
  • le service correspondant: port: 80

C'est toujours possible de faire un port-forward vers 8080 en local si besoin:
kubectl -n beats port-forward service/nginx 8080:80

A défaut, quel autre forum pourriez-vous me conseiller, s'il-vous-plaît ?

StackOverflow?

Bonjour Sébastien,

Un seul mot ici : un très grand Merci pour votre aide !
J'ai enfin réussi à accéder à cette fameuse page "Welcome to Nginx" avec les réglages que vous m'avez cités.
Comme dit précédemment, je débute avec tous ces outils, Stack Elastic, Docker, K8S (je suis en stage de fin d'études) et je me mélange encore les pinceaux en ce qui concerne la gestion des ports, notamment.
Bref. Je vais pouvoir avancer sur ce travail (et j'aurai donc peut-être l'occasion de revenir par ici :wink: ).

Je vous souhaite bonne continuation !

Guillaume.