Docker中常見的異??偨Y(jié)

本篇內(nèi)容主要講解“Docker中常見的異??偨Y(jié)”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Docker中常見的異常總結(jié)”吧!

本篇內(nèi)容主要講解“Docker中常見的異??偨Y(jié)”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Docker中常見的異??偨Y(jié)”吧!

異常一

創(chuàng)新互聯(lián)建站一直秉承“誠信做人,踏實做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個客戶多一個朋友!為您提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計、成都網(wǎng)頁設(shè)計、成都微信小程序、成都網(wǎng)站開發(fā)、成都網(wǎng)站制作、成都軟件開發(fā)、重慶APP軟件開發(fā)是成都本地專業(yè)的網(wǎng)站建設(shè)和網(wǎng)站設(shè)計公司,等你一起來見證!

docker ps 無響應, Node 節(jié)點表現(xiàn)為 NotReady。

運行信息$ docker -v$ Docker version 17.03.2-ce, build f5ec1e2$ docker-containerd -v$ containerd version 0.2.3 commit:4ab9917febca54791c5f071a9d1f404867857fcc$ docker-runc -v$ runc version 1.0.0-rc2$ commit: 54296cf40ad8143b62dbcaa1d90e520a2136ddfe$ spec: 1.0.0-rc2-dev啟用 Docker Debug 模式

有兩種方法可以啟用調(diào)試。 建議的方法是在 daemon.json 文件中將 debug 設(shè)置為 true。 此方法適用于每個 Docker 平臺。

1.編輯 daemon.json 文件,該文件通常位于 /etc/docker/ 中。 如果該文件尚不存在,您可能需要創(chuàng)建該文件。 2.增加以下設(shè)置

{  "debug": true}

3.向守護程序發(fā)送 HUP 信號以使其重新加載其配置。

sudo kill -SIGHUP $(pidof dockerd)

可以看到 Docker debug 級別的日志:

Dec 14 20:04:45 dockerd[7926]: time="2018-12-14T20:04:45.788669544+08:00" level=debug msg="Calling GET /v1.27/containers/json?all=1&filters=%7B%22label%22%3A%7B%22io.kubernetes.docker.type%3Dpodsandbox%22%3Atrue%7D%7D&limit=0"Dec 14 20:04:45 dockerd[7926]: time="2018-12-14T20:04:45.790628950+08:00" level=debug msg="Calling GET /v1.27/containers/json?all=1&filters=%7B%22label%22%3A%7B%22io.kubernetes.docker.type%3Dcontainer%22%3Atrue%7D%7D&limit=0"Dec 14 20:04:46 dockerd[7926]: time="2018-12-14T20:04:46.792531056+08:00" level=debug msg="Calling GET /v1.27/containers/json?all=1&filters=%7B%22label%22%3A%7B%22io.kubernetes.docker.type%3Dpodsandbox%22%3Atrue%7D%7D&limit=0"Dec 14 20:04:46 dockerd[7926]: time="2018-12-14T20:04:46.794433693+08:00" level=debug msg="Calling GET /v1.27/containers/json?all=1&filters=%7B%22label%22%3A%7B%22io.kubernetes.docker.type%3Dcontainer%22%3Atrue%7D%7D&limit=0"Dec 14 20:04:47 dockerd[7926]: time="2018-12-14T20:04:47.097363259+08:00" level=debug msg="Calling GET /v1.27/containers/json?filters=%7B%22label%22%3A%7B%22io.kubernetes.docker.type%3Dpodsandbox%22%3Atrue%7D%7D&limit=0"Dec 14 20:04:47 dockerd[7926]: time="2018-12-14T20:04:47.098448324+08:00" level=debug msg="Calling GET /v1.27/containers/json?all=1&filters=%7B%22label%22%3A%7B%22io.kubernetes.docker.type%3Dcontainer%22%3Atrue%7D%2C%22status%22%3A%7B%22running%22%3Atrue%7D%7D&limit=0"Dec 14 20:04:47 dockerd[7926]:

dockerd一直在請求 list containers 接口,但是沒有響應。

打印堆棧信息$ kill -SIGUSR1 $(pidof dockerd)

生成的調(diào)試信息可以在以下目錄找到:

...goroutine stacks written to /var/run/docker/goroutine-stacks-2018-12-02T193336z.log...daemon datastructure dump written to /var/run/docker/daemon-data-2018-12-02T193336z.log

查看 goroutine-stacks-2018-12-02T193336z.log 文件內(nèi)容,

goroutine 248 [running]:github.com/docker/docker/pkg/signal.DumpStacks(0x18fe090, 0xf, 0x0, 0x0, 0x0, 0x0)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/pkg/signal/trap.go:82 +0xfcgithub.com/docker/docker/daemon.(*Daemon).setupDumpStackTrap.func1(0xc421462de0, 0x18fe090, 0xf, 0xc4203c8200)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/daemon/debugtrap_unix.go:19 +0xcbcreated by github.com/docker/docker/daemon.(*Daemon).setupDumpStackTrap        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/daemon/debugtrap_unix.go:32 +0x10agoroutine 1 [chan receive, 91274 minutes]:main.(*DaemonCli).start(0xc42048a840, 0x0, 0x190f560, 0x17, 0xc420488400, 0xc42046c820, 0xc420257320, 0x0, 0x0)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/cmd/dockerd/daemon.go:326 +0x183emain.runDaemon(0x0, 0x190f560, 0x17, 0xc420488400, 0xc42046c820, 0xc420257320, 0x10, 0x0)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/cmd/dockerd/docker.go:86 +0xb2main.newDaemonCommand.func1(0xc42041f200, 0xc42045df00, 0x0, 0x10, 0x0, 0x0)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/cmd/dockerd/docker.go:42 +0x71github.com/docker/docker/vendor/github.com/spf13/cobra.(*Command).execute(0xc42041f200, 0xc42000c130, 0x10, 0x11, 0xc42041f200, 0xc42000c130)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:646 +0x26dgithub.com/docker/docker/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0xc42041f200, 0x16fc5e0, 0xc42046c801, 0xc420484810)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:742 +0x377github.com/docker/docker/vendor/github.com/spf13/cobra.(*Command).Execute(0xc42041f200, 0xc420484810, 0xc420084058)        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:695 +0x2bmain.main()        /root/rpmbuild/BUILD/docker-ce/.gopath/src/github.com/docker/docker/cmd/dockerd/docker.go:106 +0xe2goroutine 17 [syscall, 91275 minutes, locked to thread]:...

至此,我們可以確定,containerd 無響應導致的 docker ps 無響應,在堆棧中我們也可以看到調(diào)用 containerd 無響應是因為加了lock.

查看dmesg

通過 dmesg 查看系統(tǒng)異常信息,發(fā)現(xiàn) cgroup 報 OOM 溢出錯誤。

[7993043.926831] Memory cgroup out of memory: Kill process 20357 (runc:[2:INIT]) score 970 or sacrifice child

查看了大部分機器的 dmesg 信息,發(fā)現(xiàn)都有 OOM 這個錯誤,至此我們懷疑是由于某個容器 OOM 導致的 containerd 無響應.

模擬OOM

既然懷疑是容器 OOM 異常導致的 containerd 無響應,那我們干脆自己創(chuàng)造現(xiàn)場模擬一下。

首選我們創(chuàng)建一個 OOM 的部署,通過 nodeSelector 讓這個部署調(diào)度到指定 Node。

apiVersion: extensions/v1beta1kind: Deploymentmetadata:  labels:    wayne-app: oomtest    wayne-ns: test    app: oomtest  name: oomtestspec:  selector:    matchLabels:      app: oomtest  template:    metadata:      labels:        wayne-app: oomtest        wayne-ns: test        app: oomtest    spec:      nodeSelector:        kubernetes.io/hostname: test-001      containers:        - resources:            limits:              memory: 0.2Gi              cpu: '0.2'            requests:              memory: 0.2Gi              cpu: '0.1'          args:            - '-m'            - '10'            - '--vm-bytes'            - 128M            - '--timeout'            - 60s            - '--vm-keep'          image: progrium/stress          name: stress

發(fā)現(xiàn)過了一會 test-001 這臺 Node 出現(xiàn)了 docker ps 無響應的情況,查看 dmesg 以及 containerd 的堆棧信息,發(fā)現(xiàn)和之前的 Node 出現(xiàn)的異常一致。至此,基本可以確定是某個容器 OOM 導致的 containerd hung 住。

原因分析

通過查找社區(qū) Issues 及相關(guān) PR,最后發(fā)現(xiàn)根本原因是 runc 的bug。

使用 runc start 或 runc run 啟動容器時,stub process(runc [2:INIT])打開一個 fifo 進行寫入。 它的父 runc 進程 將打開相同的 fifo 閱讀。 通過這種方式,它們可以同步。

如果 stub process 在錯誤的時間退出,那么父 runc 進程 會永遠被阻塞。

當兩個 runc 操作相互競爭時會發(fā)生這種情況:runc run / start 和 runc delete。 它也可能由于其他原因而發(fā)生, 例如 內(nèi)核的 OOM killer 可以選擇殺死 stub process。

解決方案:

通過解決 exec fifo 競爭來解決這個問題。 如果 在我們打開 fifo 之前 stub process 退出,那么返回一個錯誤。

小結(jié)

containerd 官方已經(jīng)在 v1.0.2 版本合并了這個修改。因此這個問題可以通過升級 Docker 版本解決。我們目前已經(jīng)將部分機器升級到 Docker 18.06。 已升級的機器暫時未發(fā)現(xiàn)類似問題。

相關(guān)issues: https://github.com/containerd/containerd/issues/1882 https://github.com/containerd/containerd/pull/2048 https://github.com/opencontainers/runc/pull/1698

異常二

Docker 在 Centos 系統(tǒng)下以 direct-lvm 模式運行, 無法啟動

Error starting daemon: error initializing graphdriver: devicemapper: Non existing device docker-thinpoolDec 14 03:21:03 two-slave-41-135 systemd: docker.service: main process exited, code=exited, status=1/FAILUREDec 14 03:21:03 two-slave-41-135 systemd: Failed to start Docker Application Container Engine.Dec 14 03:21:03 two-slave-41-135 systemd: Dependency failed for kubernetes Kubelet.Dec 14 03:21:03 two-slave-41-135 systemd: Job kubelet.service/start failed with result 'dependency'.根本原因

這個問題發(fā)生在使用 devicemapper 存儲驅(qū)動時Docker試圖重用之前使用 LVM thin pool。例如,嘗試更改節(jié)點上的 Docker 的數(shù)據(jù)目錄時會發(fā)生此問題。由于安全措施旨在防止 Docker 因配置問題而意外使用和覆蓋 LVM thin pool 中的數(shù)據(jù),因此會發(fā)生此錯誤。

解決方案

要解決阻止Docker啟動的問題,必須刪除并重新創(chuàng)建邏輯卷,以便Docker將它們視為新的thin pool。

警告:這些命令將清除Docker數(shù)據(jù)目錄中的所有現(xiàn)有鏡像和卷。 請在執(zhí)行這些步驟之前備份所有重要數(shù)據(jù)。

1.停止 Docker

sudo systemctl stop docker.service

2.刪除 Dodcker 目錄

sudo rm -rf /var/lib/docker

3.刪除已經(jīng)創(chuàng)建的 thin pool 邏輯卷

$ sudo lvremove docker/thinpoolDo you really want to remove active logical volume docker/thinpool? [y/n]: y  Logical volume "thinpool" successfully removed

4.創(chuàng)建新的邏輯卷

lvcreate -L 500g --thin docker/thinpool --poolmetadatasize 256m

根據(jù)實際磁盤大小調(diào)整 thinpool 和 metadata 大小

Docker自動direct-lvm模式配置

如果您想要讓Docker自動為您配置direct-lvm模式,請繼續(xù)執(zhí)行以下步驟。

1.編輯/etc/docker/daemon.json文件以將dm.directlvm_device_force = value從false更改為true。 例如:

{  "storage-driver": "devicemapper",  "storage-opts": [    "dm.directlvm_device_force=true"  ]}

2.除了刪除邏輯卷之外,還要刪除docker卷組:

$ sudo vgremove docker

3.啟動Dokcer

sudo systemctl start docker.service總結(jié)

Docker 雖然是目前最常用的容器解決方案,但它仍舊有很多不足。

Docker 的隔離性比較弱,混布容易導致業(yè)務(wù)互相影響,可能因為一個服務(wù)有問題就會影響其他服務(wù)甚至影響整個集群。

Docker 自己存在一些 bug, 由于歷史原因,很多 bug 無法完全歸因于內(nèi)核或者 Docker,需要 Docker 和內(nèi)核配合修復。

本文標題:Docker中常見的異常總結(jié)
文章地址:http://bm7419.com/article2/ehicic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管微信公眾號、外貿(mào)網(wǎng)站建設(shè)品牌網(wǎng)站設(shè)計、動態(tài)網(wǎng)站、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護公司