Systemctl不能在Docker容器内的Ubuntu上使用


简介

在创建系统或应用程序时,我认为如果可以在Docker容器上构建它,则可以提高开发和维护的效率,因此我尝试了各种方法,因此将对基础知识进行总结。
*标题是我最上瘾的标题。

先决条件

[主机操作系统]
Ubuntu20.04 LTS(在GCP上)

[软图像版本]
Docker 19.03.13
容器映像操作系统Ubuntu20.04 LTS

我想做什么

1。安装和配置docker
2. 2。在Docker中创建容器
3. 3。输入容器并启动Apache
4。修改映像文件并重新映像

1. 1。安装和配置Docker

从Docker存储库安装时,请遵循以下过程。
*从14.04版开始,建议使用apt命令,因此不使用apt-get

确保未安装Docker

1
$ sudo dpkg -l docker

如果显示

dpkg-query: no packages found matching docker,则未安装。

程序包管理工具更新

1
$ sudo apt update

Docker安装

所需的软件安装

1
2
3
4
5
$ sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

添加了Docker官方GPG公钥

1
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

检查公钥是否已正确添加

1
$ sudo apt-key fingerprint

Qiita-no010_img04.jpg

添加存储库

确认存储库中没有docker。
*即使执行以下命令,也不显示任何内容。

1
$ cat /etc/apt/sources.list | grep docker

存储库设置

1
2
3
4
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

确认已添加存储库

1
2
3
$ cat /etc/apt/sources.list | grep docker
deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable
# deb-src [arch=amd64] https://download.docker.com/linux/ubuntu focal stable

检查可用版本

1
2
3
4
5
6
$ apt-cache madison docker-ce
 docker-ce | 5:19.03.13~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.12~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.11~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.10~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.9~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

安装docker

由于已添加存储库,因此再次update,然后执行install

1
2
$ sudo apt update
$ sudo apt install docker-ce

检查已安装的docker版本

1
2
3
4
5
6
7
8
9
$ sudo docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:02:52 2020
 OS/Arch:           linux/amd64
 Experimental:      false

检查守护程序是否已启动

1
2
3
4
5
6
7
8
9
10
$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2020-09-30 00:22:29 UTC; 30min ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 25020 (dockerd)
      Tasks: 9
     Memory: 36.8M
     CGroup: /system.slice/docker.service

泊坞窗

的操作检查

Hello world获取示例docker映像并运行它。

1
$ sudo docker container run hello-world

检查当前图像和容器的列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# イメージの一覧表示
$ sudo docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        9 months ago        13.3kB

# コンテナの一覧表示(停止中を含む)
$ sudo docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS  
            NAMES
e8a73ecd0c16        hello-world         "/hello"            5 minutes ago       Exited (0) 5 minutes ago          
            condescending_diffie

# 起動中のコンテナ表示
$ sudo docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS          
     NAMES

* hello-world容器未运行,因为它将在输出消息后停止。

由于确认了该操作,因此删除了容器和图像一次。

1
2
$ sudo docker container rm [コンテナID]
$ sudo docker image rm [イメージID]

码头工人设置

自动启动设置

1
2
3
$ sudo systemctl unmask docker.service
$ sudo systemctl enable docker
$ sudo systemctl is-enabled docker

已添加到docker组,以在不使用sudo的情况下执行docker命令。

1
2
3
4
5
6
# まずは[docker]グループの確認。 ※グループがない場合は自分で作成する必要がある。
$ cat /etc/group | grep docker
docker:x:998:

# [docker]グループにユーザーを追加。
$ sudo usermod -aG docker [ユーザー名]

重新启动Ubuntu后,如果您可以在不使用sudo的情况下执行命令,如下所示,则可以更改设置。
*从GCP执行重启。 (因为要在GCP上创建VM实例)

1
2
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

2. 2。在Docker

中创建容器

由于

容器是使用docker映像构建的,因此首先获取docker映像。
许多图像已经在docker站点上发布,因此使用搜索命令搜索所需图像并获取图像

确认要获取的图像

1
$ docker search 【任意なキーワード】

图像采集

1
2
3
4
5
6
7
8
9
10
# docker image pull [OPTIONS] NAME[:TAG|@DIGEST]
$ docker image pull  ubuntu:20.04

20.04: Pulling from library/ubuntu
d72e567cc804: Pull complete
0f3630e5ff08: Pull complete
b6a83d81d1f4: Pull complete
Digest: sha256:bc2f7250f69267c9c6b66d7b6a81a54d3878bb85f1ebb5f951c896d13e6ba537
Status: Downloaded newer image for ubuntu:20.04
docker.io/library/ubuntu:20.04

*这次,在Ubuntu 20.04之上为主机OS创建Ubuntu 20.04的容器。

从图像

创建容器

1
2
3
4
$ docker container run -it -d --name test-ubuntu20-4 ubuntu:20.04

# ポート番号を紐づけたい時
# docker container run -it -d -p 8080(Ubuntu側のポート):5000(コンテナ側のポート) --name webgis-server ubuntu:20.04

* 1)。如果本地主机上不存在该映像,它将在运行时docker container run从存储库中自动提取该映像,以为您创建一个容器。
* 2)。如果没有"选项"命令,则容器将在启动后立即退出。

检查运行中的容器

1
2
3
4
5
$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS          
     NAMES
19b7ac7c40ad        ubuntu:20.04        "/bin/bash"         8 seconds ago       Up 7 seconds                      
     test-ubuntu20-4

3. 3。输入容器并启动Apache

输入先前创建的容器(test-ubuntu20-4)

1
$ docker attach test-ubuntu20-4

*使用exit退出后,该容器将停止,因此再次输入时,请使用docker container start [コンテナ名]将其启动。

软件包管理工具的更新。

1
# apt update

Apache安装

1
# apt install -y apache2

*初次安装某些软件包时,系统会询问您输入时区和时区,因此请进行以下设置。
地理区域:6(亚洲)
时区:79(东京)

检查Apache的启动状态。

1
2
# systemctl status apache2
bash: systemctl: command not found

由于显示了以上消息,因此无法操作,请安装软件包以便可以使用systemctl。 (可以使用service apache2 ~~~~命令完成简单的启动。)

1
# apt install -y systemd

再次检查Apache的启动状态。

1
2
3
# systemctl status apache2
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

PID1似乎有问题,所以让我们检查一下。

1
2
3
4
# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.5  0.1   4240  3384 pts/0    Ss   16:40   0:00 /bin/bash
root           8  0.0  0.1   5888  2912 pts/0    R+   16:40   0:00 ps aux


实际上,当我使用docker container run -it -d --name ubuntu:20.04命令创建容器时,该容器中Ubuntu的[PID:1]的COMMAND变为/sbin/bash
这样,似乎无法使用systemctl命令。

*创建第一个容器时,我尝试使用以下命令将初始过程指定为/sbin/init,但是据说/sbin/init在图像中不存在。

1
2
3
4
5
# テスト実行のため、今回の一連の作業としては実行不要。
$ docker container run -it -d --privileged --name webgis-server ubuntu:20.04 /sbin/init

docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process c
aused "exec: "/sbin/init": stat /sbin/init: no such file or directory": unknown.

可能会在

/sbin/init存在的地方对Ubuntu进行映像!

4。修改映像文件并重新映像

创建

/sbin/init作为/usr/lib/systemd/system/的符号链接。

1
# ln -s  /usr/lib/systemd/system/ /sbin/init

因为它是在原始映像上安装了Apache2和Systemd并创建了/sbin/init的容器,所以请从已停止一次的容器中创建一个映像。

1
2
3
4
5
6
7
8
9
$ docker commit test-ubuntu20-4 test-ubuntu20-4:add-init
sha256:5f25a8ff7149b22665aeb4d076919ba06d7e5c3f06c77834e60c6a7e042e6bf2

# イメージの一覧を確認
$ $ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
test-ubuntu20-4     add-init            91fffb874bf9        About a minute ago   202MB
ubuntu              20.04               9140108b62dc        2 weeks ago          72.9MB
hello-world         latest              bf756fb1ae65        9 months ago         13.3kB

从图像文件

重新创建容器

根据先前创建的图像创建容器

1
2
3
4
5
6
$ docker container run -it -d --privileged --name test-ubuntu20-4-2 test-ubuntu2
0-4:add-init /sbin/init

af59767d9b17c60fcb5284ec3669bc61edb5f4a7e5a019b5c572997553d43e9f
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process c
aused "exec: "/sbin/init": permission denied": unknown.


有人说我这次没有访问权限,毕竟似乎很难用[PID1 = / sblin / init]来启动它。
我已经研究了各种东西,但是基本上systemd不能用作docker容器中的进程管理工具。
(如果强制执行,您可能无能为力,但这样做似乎没有任何根据。)

参考站点1
参考站点2

摘要

首先,我简要总结了安装docker和创建容器的过程,但是由于VM和容器之间用于操作的内核不同,因此无法以相同的方式使用进程管理工具。
在容器中创建服务时,请了解以[PID1 = init]为前提进行守护的程序无法正常工作。
当使用Docker完成流程管理时,Supervisor似乎很常见。