1
votes

Comment se connecter à l'intérieur d'un pod dans Kubernetes

J'ai mis à jour un cluster en cours d'exécution avec une nouvelle image qui, malheureusement, plante. Je souhaite me connecter au pod pour consulter les journaux. Quelle est la manière de procéder?

root@codingjediweb-857c6d584b-s2hg2:/deploy# tail -f /deploy/codingjediweb-1.0/logs/*.log
2020-07-07 06:40:37,385 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/34.91.191.238:9042-2, inFlight=0, closed=false] was inactive for 30 seconds, sending heartbeat
2020-07-07 06:40:37,389 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/34.91.191.238:9042-2, inFlight=0, closed=false] heartbeat query succeeded
2020-07-07 06:41:07,208 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/34.91.191.238:9042-1, inFlight=0, closed=false] was inactive for 30 seconds, sending heartbeat
2020-07-07 06:41:07,210 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/34.91.191.238:9042-1, inFlight=0, closed=false] heartbeat query succeeded
2020-07-07 06:41:07,271 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/10.44.1.4:9042-1, inFlight=0, closed=false] was inactive for 30 seconds, sending heartbeat
2020-07-07 06:41:07,274 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/10.44.1.4:9042-1, inFlight=0, closed=false] heartbeat query succeeded
2020-07-07 06:41:07,332 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/10.44.2.5:9042-1, inFlight=0, closed=false] was inactive for 30 seconds, sending heartbeat
2020-07-07 06:41:07,337 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/10.44.2.5:9042-1, inFlight=0, closed=false] heartbeat query succeeded
2020-07-07 06:41:07,392 [DEBUG] from com.datastax.driver.core.Connection in codingJediCluster-nio-worker-0 - Connection[/34.91.191.238:9042-2, inFlight=0, closed=false] was inactive for 30 seconds, sending heartbeat

L'application ne génère pas beaucoup de journaux de console. Les principaux journaux sont dans un fichier. Comment puis-je accéder à ce fichier?

manuchadha25@cloudshell:~ (copper-frame-262317)$ kubectl exec -it codingjediweb-857c6d584b-s2hg2 -c logging -- bash
error: unable to upgrade connection: container not found ("logging")
manuchadha25@cloudshell:~ (copper-frame-262317)$ kubectl exec -it codingjediweb-857c6d584b-s2hg2 -c codingjediweb -- bash

MISE À JOUR J'ai essayé d'implémenter la suggestion de Christoph d'utiliser deux conteneurs dans un pod - un pour l'application principale et l'autre pour la journalisation. Je suis revenu à la version stable de mon application pour être sûr que l'application est opérationnelle et qu'elle génère des journaux. Cela aiderait à tester que le modèle fonctionne. Il semble que l'application de journalisation continue d'exister / de planter.

Fichier yaml

manuchadha25@cloudshell:~ (copper-frame-262317)$ kubectl get pods
NAME                             READY   STATUS             RESTARTS   AGE
busybox                          1/1     Running            1          10h
codingjediweb-857c6d584b-n4njp   1/2     CrashLoopBackOff   6          8m46s
codingjediweb-857c6d584b-s2hg2   1/2     CrashLoopBackOff   6          8m46s

Lorsque j'applique la configuration, un seul conteneur reste en place

manuchadha25@cloudshell:~ (copper-frame-262317)$ cat codingjediweb-nodes.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: codingjediweb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: codingjediweb
  template:
    metadata:
      labels:
        app: codingjediweb
    spec:
      volumes:
      - name: shared-logs
        emptyDir: {}
      containers:
      - name: codingjediweb
        image: docker.io/manuchadha25/codingjediweb:03072020v2
        volumeMounts:
        - name: shared-logs
          mountPath: /deploy/codingjediweb-1.0/logs/
        env:
        - name: db.cassandraUri
          value: cassandra://xx.yy.xxx.238:9042
        - name: db.password
          value: 9__something
        - name: db.keyspaceName
          value: something2
        - name: db.username
          value: superawesomeuser
        ports:
        - containerPort: 9000
      - name: logging
        image: busybox
        volumeMounts:
        - name: shared-logs
          mountPath: /deploy/codingjediweb-1.0/logs/
        command: ["tail -f /deploy/codingjediweb-1.0/logs/*.log"]

une inspection plus approfondie montre que l'application principale est active

manuchadha25@cloudshell:~ (copper-frame-262317)$ kubectl logs codingjediweb-7c45484669-czcpk
Oops, cannot start the server.
play.api.libs.json.JsResult$Exception: {"obj":[{"msg":["Unable to connect with database"],"args":[]}]}
manuchadha25@cloudshell:~ (copper-frame-262317)$ kubectl logs codingjediweb-7c45484669-qn4m5
Oops, cannot start the server.
play.api.libs.json.JsResult$Exception: {"obj":[{"msg":["Unable to connect with database"],"args":[]}]}

Et l'application génère des journaux sur le bon chemin

XXX


0 commentaires

4 Réponses :


1
votes

Vous pouvez obtenir un shell dans un conteneur en cours d'exécution. Voici un moyen simple de le faire:

POD_NAME=odingjediweb-7c45484669-czcpk

kubectl exec --stdin --tty $POD_NAME -- /bin/sh

Veuillez noter que si le pod réside dans un espace de noms donné (autre que celui par défaut), vous devrez le spécifier via --namespace MY_NAMESPACE .

Une fois que vous avez une session en cours, vous pouvez cd dans votre fichier journal et l'afficher.

Pour plus d'informations, visitez https://kubernetes.io/docs/tasks / debug-application-cluster / get-shell-running-container /


2 commentaires

Merci. J'ai essayé mais j'ai obtenu l'erreur erreur: impossible de mettre à niveau la connexion: conteneur introuvable ("codingjediweb")


Pour obtenir un shell, le conteneur doit être en état de fonctionnement. Il semble que le vôtre ne soit pas en état de marche. Essayez de supprimer le pod et attendez qu'un nouveau se présente pour réessayer. Notez qu'il y a probablement une fenêtre très courte avant qu'il ne se rembourse.



-1
votes

Si vous souhaitez afficher les journaux, exécutez simplement ce qui suit.

kubectl enregistre


2 commentaires

Notez que l'OP mentionnait "L'application ne génère pas beaucoup de journaux de console. Les journaux principaux sont dans un fichier. Comment puis-je accéder à ce fichier?"


Ohh ouais, tu as raison. J'ai raté cette partie. Désolé pour ça. Se connecter définitivement aux pods en utilisant votre réponse est la bonne façon.



1
votes

Vous pouvez créer un deuxième conteneur dans votre pod pour la journalisation. Montez simplement le répertoire du journal dans les deux conteneurs. Le second conteneur peut être basé sur une image busybox et faire un tail -f xyz.log .

kubectl cp <some-pod>:/path/to/logs -c logging /path/to/local/dir 

Vous pouvez maintenant afficher les journaux avec

kubectl exec -it <pod name> -c logging -- sh

Mettre à jour

Comme le nom de votre fichier journal est dynamique, vous pouvez utiliser le conteneur busybox avec une commande de sommeil infinie, quelque chose comme avec true ; dormir 86400; done devrait le faire. Maintenant, le conteneur de journalisation ne fait rien, mais monte toujours votre fichier journal. L'autre conteneur plantera, mais le conteneur de journalisation doit être en cours d'exécution. Vous pouvez que ssh dedans:

Kubectl logs <podname> -c logging -f

Ou une autre idée:

Vous pouvez copier le répertoire des journaux du pod sur votre système local et examiner les journaux .

volumes:
  - name: shared-logs
    emptyDir: {}
  containers:
  - name: main-app
    image: <your-image>
    volumeMounts:
    - name: shared-logs
      mountPath: <path/to/logs>
  - name: logging
    image: busybox
    volumeMounts:
    - name: shared-logs
      mountPath: <path/to/logs>
    command: ["tail -f <path/to/logs/*.log>"]


7 commentaires

Service.log est-il supposé être le nom de mon fichier journal ou s'agit-il d'un nom standard? Mon fichier journal a un nom dynamique :(


J'avais deux autres idées et j'ai mis à jour ma réponse. J'espère qu'on le fait :)


L'idée d'origine est bonne. Mettez simplement à jour vers tail -f pour le nom dynamique


Merci. J'ai mis à jour la question. Il semble que le conteneur de journalisation se ferme prématurément.


Serait-ce une condition de course? la journalisation exécute tail -f avant que l'application ne commence à générer des journaux?


J'ai ouvert ce nouveau numéro pour savoir comment ajouter la boucle while. Pouvez-vous jeter un oeil à ceci (désolé, trop nouveau pour Kubernetes) - stackoverflow.com/questions/62782554/...


ça marche. commande: ['sh', '-c', "while true; do sleep 86400; done"] . Merci.



1
votes

Une autre façon d'obtenir les journaux consiste à utiliser un volume dans votre nœud avec hostPath .

Vous pouvez créer un hostPath puis le monter en tant que volume dans votre pod. Lorsque le conteneur s'exécute, il génère le journal dans ce répertoire qui est conservé sur le disque de votre nœud.

Remarque: Si vous avez plus d'un nœud, le répertoire doit exister dans chacun d'eux.

Pour utiliser le dir / mnt / data de votre nœud, créez le répertoire avec mkdir -p / mnt / data et appliquez le yaml ci-dessous pour créer la revendication de volume persistant et de volume persistant:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: codingjediweb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: codingjediweb
  template:
    metadata:
      labels:
        app: codingjediweb
    spec:
      volumes:
        - name: task-pv-storage
          persistentVolumeClaim:
            claimName: task-pv-claim
      containers:
      - name: codingjediweb
        image: docker.io/manuchadha25/codingjediweb:03072020v2
        env:
        - name: db.cassandraUri
          value: cassandra://xx.yy.xxx.238:9042
        - name: db.password
          value: 9__something
        - name: db.keyspaceName
          value: something2
        - name: db.username
          value: superawesomeuser
        ports:
        - containerPort: 9000
        volumeMounts:
          - mountPath: "/deploy/codingjediweb-1.0/logs/"
            name: task-pv-storage

Ajoutez le persistentVolumeClaim et volumeMounts dans votre fichier de déploiement, exemple:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi


1 commentaires

Merci. Je n'ai pas encore testé cela. D'après ce que j'ai lu, toutes les répliques doivent être sur le même nœud pour que nodePath fonctionne.Mon application dispose de deux répliques. Je ne pense pas qu'ils fonctionnent sur le même nœud (hôte) - "Étant donné que le chemin d'hôte n'est disponible que pour un seul hôte, toutes les répliques doivent être déployées dans un même nœud (sinon vous devrez peut-être utiliser nfs)."