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
4 Réponses :
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 /
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.
Si vous souhaitez afficher les journaux, exécutez simplement ce qui suit.
kubectl enregistre
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.
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>"]
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.
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 Ajoutez le / 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
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
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)."