Ubuntu ターミナルで次を実行します。
sudo strace -f -p `pidof containerd` -o strafce_log
他の端末で私は実行します
docker run ubuntu
その結果、両方の端末が停止する。 :( docker サービスを停止すると、もう起動できなくなります。
コンテナは状態を維持し、created
コンテナで実行されるすべてのコマンドが中断されます(docker logs
、、、)docker rm
system prune
他のコンテナまたはイメージに対するDockerコマンドは正常に機能します。 Docker psも動作します
私もオンラインで確認する必要があることを見つけましたcat /var/log/syslog | grep docker
。残念ながら、そこには何もありません。
Dockerまたはコンテナが何をしているのかについての追加のログや情報を入手できる場所を教えてください。
ベストアンサー1
生成されたログを分析した結果というプロセスが終了すると停止することがsudo strace -ff -p $(pidof containerd) -o strace_log
わかりました。これが私を作るexecve()
runc init
runc GHページのバグレポートこれは、pthreadを使用するすべてのプログラムで再現できるカーネルのバグであることを説明し、execve()
問題を再現するために使用できる短いGoプログラムを提供します。
package main
import (
"os"
"syscall"
)
func main() {
syscall.Exec("/bin/echo", []string{"/bin/echo", "Hello"}, os.Environ())
}
これはカーネルのバグであることを知っており、ホストが起動できない、または仮想マシンを使用できない危険なしにLinuxカーネルをすばやく構築して交換できるように、Raspberry Piをテストに使用し、RaspbianはGoがインストールされていないため次のCプログラムを使用しました。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
void *foo(void *p)
{
(void) p;
while(1)
{
puts("in thread");
sleep(2);
}
}
int main(void)
{
printf("pid: %jd\n", (intmax_t) getpid());
pthread_t tid;
pthread_create(&tid, NULL, foo, NULL);
char *envp[] = {"var"};
char *ls_args[] = { "/bin/ls" , "-l", NULL};
if (execve(ls_args[0], ls_args, envp) < 0) {
perror("execve error");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
ビルドgcc strace-test.c -o strace-test -pthread
して
strace -f ./strace-test
詰まっていることを確認してください。
straceを修正することになっていたパッチが2016年にLinuxカーネルメーリングリストに送信されました。
しかし、まだ承認されておらず、議論全体を読んで理由を把握できます。それにもかかわらず、私はこのパッチを自分のローカルコンピュータに適用しました。
Raspberry Pi Linuxカーネルツリーrpi-5.6.y ブランチの場合、Raspberry Pi でカーネルを再構築して交換した後、それstrace -f ./strace-test
以上ハングしなくなります。 2016年以降、Linuxソースコードにいくつかの変更があり、パッチが完全に適用されていません。 FWIW、私が適用した完全なパッチは次のとおりです。
diff --git a/kernel/fork.c b/kernel/fork.c
index 60a1295..c26aaa1 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1224,7 +1224,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
struct mm_struct *mm;
int err;
- err = mutex_lock_killable(&task->signal->cred_guard_mutex);
+ err = mutex_lock_interruptible(&task->signal->cred_guard_mutex);
if (err)
return ERR_PTR(err);
diff --git a/kernel/signal.c b/kernel/signal.c
index 9ad8dea..ea7c7b5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -108,6 +108,10 @@ static bool sig_ignored(struct task_struct *t, int sig, bool force)
if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
return false;
+ /* Do not ignore signals sent from child to the parent */
+ if (current->ptrace && current->parent == t)
+ return 0;
+
/*
* Tracers may want to know about even ignored signal unless it
* is SIGKILL which can't be reported anyway but can be ignored