【docker】Docker容器的重啓策略

1. Docker容器的重啓策略

Docker容器的重啓策略是面向生產環境的一個啓動策略,在開發過程中可以忽略該策略。

Docker容器的重啓都是由Docker守護進程完成的,因此與守護進程息息相關。

Docker容器的重啓策略如下:

  • no,默認策略,在容器退出時不重啓容器

  • on-failure,在容器非正常退出時(退出狀態非0),纔會重啓容器

    on-failure:3,指定啓動的次數,在容器非正常退出時重啓容器,最多重啓3次

  • always,在容器退出時總是重啓容器

  • unless-stopped,在容器退出時總是重啓容器,但是不考慮在Docker守護進程啓動時就已經停止了的容器

容器如果被守護進程重新拉起後,容器的id和名稱都是不變的,但是對應在主機上的進程號會變化。

例如:

docker run -p 8092:80 --name apicloud -v /home/lifehaier:/var/www/html -d --restart=on-failure:3 hub.docker.terminus.io:5000/aabb:20180315

解釋:使用docker run命令運行一個容器,該容器內部監聽80端口,與宿主機系統8092端口映射,命名該容器名稱爲apicloud,宿主機系統目錄/home/lifehaier與容器內部/var/www/html路徑映射,如果容器對應的images路徑/var/www/html下面有數據的話,則被宿主機/home/lifehaier路徑下面的數據覆蓋,-d參數是讓容器後臺運行,–restart=on-failure:3是指容器在未來出現異常退出(退出碼非0)的情況下循環重啓3次;hub.docker.terminus.io:5000/aabb:20180315 是images名稱,容器基於此images進行啓動。

通過–restart選項,可以設置容器的重啓策略,以決定在容器退出時Docker守護進程是否重啓剛剛退出的容器。

  • --restart選項通常只用於detached模式的容器。

  • --restart選項不能與–rm選項同時使用。顯然,--restart選項適用於detached模式的容器,而--rm選項適用於foreground模式的容器。

2. Docker容器的退出狀態碼

docker run的退出狀態碼如下:

  • 0,表示正常退出

  • 非0,表示異常退出(退出狀態碼採用chroot標準)

    • 125,Docker守護進程本身的錯誤

    • 126,容器啓動後,要執行的默認命令無法調用

    • 127,容器啓動後,要執行的默認命令不存在

    • 其他命令狀態碼,容器啓動後正常執行命令,退出命令時該命令的返回狀態碼作爲容器的退出狀態碼

3. 不同操作,對應容器的狀態

3.1 策略爲always

3.1.1 初次創建容器

初次創建容器,並設定容器重啓策略爲always :

docker run -d --name myredis3 --restart=always myredis:exec

此時容器狀態

        "State": {
            "Status": "running",    'running'
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 19018,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-25T07:38:31.390940404Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        }
        "RestartCount": 0,
        "HostConfig": {

            "RestartPolicy": {              '記錄了重啓策略'
                "Name": "always",
                "MaximumRetryCount": 0
            },
        

3.1.2 docker stop

docker stop

        "State": {
            "Status": "exited",      'exited'
            "Running": false,
            "Paused": false,
            "Restarting": false,
           "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-25T04:15:15.052478152Z",
            "FinishedAt": "2021-07-25T04:16:57.238324749Z"
        }
        "RestartCount": 0,          '仍爲0,不影響重啓次數'

3.1.3 docker start

        "State": {
            "Status": "running",         '又變回running'
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 19018,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-25T07:38:31.390940404Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "RestartCount": 0,          '仍爲0,不影響重啓次數'

3.1.4 docker restart

docker restart :

        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 12989,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-25T07:44:12.506647419Z",
            "FinishedAt": "2021-07-25T07:44:12.145349632Z"
        }
        "RestartCount": 0,   '注意:不影響重啓次數'

注意:不影響重啓次數,說明docker restart 仍屬於正常退出場景

3.1.5 我們幹掉容器的進程

[root]$ docker inspect -f '{{.State.Pid}}' myredis4
12989

[root]$ kill -9 12989

再來看狀態:

        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 26088,
            "ExitCode": 0,      '退出碼爲0'
            "Error": "",
            "StartedAt": "2021-07-25T07:51:29.371543467Z",
            "FinishedAt": "2021-07-25T07:51:28.874326028Z"
        },
        "RestartCount": 1,     '次數+1 了'

可以反覆試下幹掉進程,理論上由於是always 策略,會一直重新拉起,不限次數。

注意: 此時退出碼爲0,理解爲進程被殺死,來不及寫狀態碼。

3.1.6 docker kill

docker kill myredis4

查看狀態:

        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 137,      '137,表示接收137好命令狀態碼'
            "Error": "",
            "StartedAt": "2021-07-25T07:51:29.371543467Z",
            "FinishedAt": "2021-07-25T08:00:22.509279442Z"
        },
        "RestartCount": 1

3.1.7 127錯誤碼,容器啓動後,要執行的默認命令不存在

我們故意在啓動redis容器後面執行aaa,是個不存在的命令:

[root@paas-controller-3:/home/ubuntu]$ docker run -d --name myredis5 --restart=always myredis:exec   aaa
a983d983c8e4db7567b3b56402cf6509c9b959b28a7f0825411e26cd9d311505            '顯示容器創建成功'
docker: Error response from daemon: oci runtime error: container_linux.go:300: starting container process caused "exec: \"aaa\": executable file not found in $PATH".

日誌顯示容器創建成功,看下容器的狀態:

        "State": {
            "Status": "created",        '狀態爲created'
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 127,       '127碼'
            "Error": "oci runtime error: container_linux.go:300: starting container process caused \"exec: \\\"aaa\\\": executable file not found in $PATH\"\n",
            "StartedAt": "0001-01-01T00:00:00Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "RestartCount": 0,

狀態爲created,說明發生異常,就沒有啓動該容器,只是創建了該容器。

3.1.8 總結

docker restart 命令讓容器正常重啓,不累加重啓次數

幹掉進程,容器會重啓,累加次數

docker kill,容器不重啓,但是給出137退出碼

另外,錯誤碼對應特定的,例如我們演示的127錯誤碼

3.2 on-failure

我們在always場景下,如果是幹掉進程,就會立即啓動該容器,但是退出碼是0,所以,我們需要針對該場景,進行一個對比。

啓動容器,設置策略爲on-failure:10

$ docker run -d --name myredis6 --restart=on-failure:10 myredis:exec
8ce68b1f63040411e6261f8569a8af3579f5506156111e0f2edbc628673e1b2d

幹掉進程:

[root@paas-controller-3:/home/ubuntu]$ docker inspect -f '{{.State.Pid}}' myredis6
3164
[root@paas-controller-3:/home/ubuntu]$ kill -9 3164
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 17901,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-25T08:22:00.859191669Z",
            "FinishedAt": "2021-07-25T08:22:00.30237101Z"
        },
         "RestartCount": 1,
         "RestartPolicy": {
             "Name": "on-failure",
             "MaximumRetryCount": 10
         },

我們發現容器也可以被重啓,說明幹掉進程仍歸類爲異常退出,只是沒記記錄ExitCode字段而已。

4. 示例與補充

示例:

docker run -d --restart=always bba-208
docker run -d --restart=on-failure:10 bba-208

補充:

#查看容器重啓次數
docker inspect -f "{{ .RestartCount }}" bba-208
#查看容器最後一次的啓動時間
docker inspect -f "{{ .State.StartedAt }}" bba-208
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章