解决 System has not been booted with systemd as init system (PID 1). Can‘t operate.

2023-05-16

docker 容器使用systemctl

以ubuntu做为参考。

拉取容器

  • 直接拉取

    使用 docker pull ubuntu 直接拉取。

  • 通过Dockerfile拉取

    Dockerfile:

    # 基础镜像
    FROM ubuntu:18.04
    
    # build参数
    ARG user=duapple
    
    # 元数据
    LABEL maintainer="hejiang" email="2832893880@qq.com"
    
    # 安装依赖
    #RUN apt-get update && apt-get install -y sudo 
    
    # 添加用户:赋予sudo权限,指定密码
    RUN useradd --create-home --no-log-init --shell /bin/bash ${user} \
        && adduser ${user} sudo \
        && echo "${user}:123123" | chpasswd
    
    # 改变用户的UID和GID
    #RUN usermod -u 1000 ${user} && usermod -G 1000 ${user}
    
    # 指定容器起来的工作目录
    WORKDIR /home/${user}
    
    # 指定容器起来的登录用户
    USER {user}
    

    拉取:

    $ docker build -t ubuntu1804:test .
    

请添加图片描述

如果不具备上网能力,可以先不安装sudo,在进入系统后,设置好软件源以后再安装sudo。

# 配置容器

这里以docker拉取的镜像为例子。直接拉取镜像的方式,需要手动创建非root用户,其余操作与下文保持一直。
无Dockerfile的情况,新建用户脚本,执行前需要先安装sudo
add_user.sh:

#!/bin/bash

user=$1

echo "add user: ${user}"

useradd -d /home/${user} -m ${user}
passwd ${user}

usermod -g ${user} -G root ${user}

chmod u+w /etc/sudoers
echo "${user} ALL=(ALL:ALL) ALL" >> /etc/sudoers

chmod u-w /etc/sudoers

usermod -s /bin/bash ${user}
# add_user.sh duapple

注意:需要使用systemctl,就不能用非root用户启动容器,否则尽管设置了/sbin/init作为第一个进程启动,systemctl还是不能使用。(另外,为什么创建容器不直接指定运行/sbin/init?因为安装的容器可能内部并没有安装systemd,比如我用的ubuntu容器,内部就没有安装systemd,也就没有/sbin/init,这会导致启动容器失败。因此需要先进入容器,安装好systemd,在对配置进行修改。)

创建容器并运行。注意:需要设置 --privileged参数,确保能获取到真正的root权限。

$ docker run --privileged -itd --name ubuntu_test -u root ubuntu1804:test /bin/bash
$ docker exec -it ubuntu_test /bin/bash

请添加图片描述

修改root密码并安装sudo。

# passwd 
# apt update
# apt install sudo 

切换到duapple用户。测试sudo,并安装systemd。

# exit
$ docker exec -it -u duapple ubuntu_test /bin/bash
$ sudo apt install systemd
$ ls -al /sbin/init

请添加图片描述

下载ssh,进行测试。

$ sudo apt install ssh
$ sudo systemctl start ssh

此时会报错:

请添加图片描述

配置容器的第一个进程

$ exit
$ docker stop ubuntu_test
$ sudo systemctl stop docker
# sudo su
# 

修改 config.v2.json中的 PathCmd ,由 /bin/bash 设置为 /sbin/init注意:一定要先关闭docker服务,修改配置才能生效。

# vim /var/lib/docker/containers/0f22b0c68de9819eb72d02094a5d23d3ee66e4eabd3563b9190f48ac83c55f22/config.v2.json

请添加图片描述

保存修改后,重启docker,再重启docker容器,重新配置即可。

$ docker start ubuntu_test
$ docker exec -it -u duapple ubuntu_test /bin/bash
$ sudo systemctl start ssh
$ sudo systemctl status ssh

请添加图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解决 System has not been booted with systemd as init system (PID 1). Can‘t operate. 的相关文章

  • 在 Linux 中使用 C、C++ 发出系统命令

    我知道在 DOS Windows 应用程序中 您可以使用以下行从代码发出系统命令 system pause or system myProgram exe 来自 stdlib h 是否有类似的 Linux 命令 如果有 我会在哪个头文件中找
  • 龙卷风中断系统调用

    我时不时地收到此错误 并且不确定如何调试 Traceback most recent call last File usr lib python2 7 dist packages tornado ioloop py line 662 in
  • 如何查看Android系统版本?

    有谁知道如何检查系统版本 例如1 0 2 2等 以编程方式 如何使用它的示例 if android os Build VERSION SDK INT gt android os Build VERSION CODES GINGERBREAD
  • 如何用简单的PHP在同一页面发帖?

    我正在尝试仅使用 PHP 创建一个注册系统 这就是一个例子 但我想我做错了什么 我试图在 StackOverFlow 帖子中找到类似的解决方案 但没有得到任何确切的解决方案 如果有人能帮助我找到下面代码中的错误 那就太好了
  • Java系统属性和环境变量

    系统属性有什么区别系统 getProperties http download oracle com javase 6 docs api java lang System html getProperties 28 29和环境变量系统 ge
  • 最小化时如何将.net应用程序放入系统托盘中?

    任何人都可以建议一个好的代码示例vb net c 代码 用于在最小化时将应用程序放入系统托盘中 将 NotifyIcon 控件添加到窗体中 然后使用以下代码 private void frm main Resize object sende
  • 如何知道我的代码正在哪个物理处理器和哪个物理核心上运行

    在 C 程序中 我如何知道我的代码正在哪个物理处理器和内核上运行 我正在使用 Linux 和 gcc 4 4 3 sched getcpu http linux die net man 3 sched getcpu 调用返回虚拟CPU号 虚
  • 为位于系统托盘中的 Java 程序创建键盘挂钩

    基本上我有一个在系统托盘中运行的java程序 并且想添加它 因此如果用户按下CTRL SHIFT 1 它会选择位于托盘中的java程序的右键单击选项之一 我想我正在寻找的是有关执行此操作的教程 或者最简单的方法是什么 我以前从未做过这样的事
  • pthread_cond_timedwait 立即返回

    我有一个奇怪的问题 我有以下代码 dbg condwait timeout d d n abs timeout gt tv sec abs timeout gt tv nsec ret pthread cond timedwait q gt
  • .NET进程监视器

    有没有办法确定特定机器上次运行进程的时间 我可以使用以下内容来确定进程是否正在运行 但如果该进程已停止 则应用程序无法获取该进程 Process process Process GetProcessesByName processName
  • 如何检查命令是否可用或存在?

    我正在 Linux 上用 C 语言开发一个控制台应用程序 现在 它的可选部分 不是必需的 取决于可用的命令 二进制文件 如果我检查system 我越来越sh command not found作为不需要的输出 并将其检测为存在 那么我该如何
  • 如何用C++读取系统信息?

    我正在尝试使用 C 获取 Linux 系统上的操作系统版本 硬盘空间 可用磁盘空间以及已安装 RAM 等信息 我知道我可以使用system 运行不同的 Linux 命令并捕获它们的输出 这就是我目前正在做的 但我想知道是否有更好的方法 C
  • 如果系统命令/反引号中的脚本失败,则主脚本需要退出状态!=0

    Code of inter pl is use strict use warnings my var1 cat gra def ment ckfile txt ckfile txt doesn t exist print Hello Wor
  • Delphi:系统菜单打开了吗?

    在 Delphi 中 我需要一个函数来确定系统菜单 分别是窗口菜 单 单击图标时出现的菜单 是否打开 原因是我正在编写一个反键盘记录器功能 它将垃圾发送到当前活动的编辑控件 这也阻止了键盘记录器读取 WinAPI 消息来读取内容 但是 如果
  • 使用Intent打开系统应用程序

    我正在尝试制作一个简单的应用程序 当用户从主屏幕或应用程序抽屉单击时 该应用程序会将用户发送到特定的 系统安装的 应用程序 系统设置 日历 浏览器等 例如 我目前尝试在启动应用程序时打开系统设置 就像设置快捷方式一样 可以按照我想要的方式实
  • PHP 系统() 参数

    我有以下代码执行C 程序 and 输出它 div div 我怎样才能做到这一点您可以将参数传递给 c 程序 这样说 如果这是c program include
  • Perl system() 调用会终止吗?

    Can a system 打电话可以永远die在 Perl 5 中 换句话说 为了 100 防崩溃 执行以下操作的程序system call 是否需要将其包装成eval block 或者这是完全没有必要的 我在 中没有发现任何提及这种可能性
  • JUnit Eclipse 显示 System.out.print() 的

    我正在使用 JUnit 3 和 Eclipse 3 4 当我运行 JUnit 测试用例时 一切正常并且测试完美完成 唯一的事情是我想查看我正在运行的类的输出 所有类都具有一些输出值的基本 System out print 因此 当我运行测试
  • 将参数传递给调试器中的 perl 文件并在系统执行的文件中设置断点

    因此 我使用 perl d file pl 在 perl 调试器中运行一个文件 但 file pl 也应该接受参数 如何向 file pl 提供参数 还有一个问题 file pl 中有这一行 system file2 pl 如果 file2
  • 如何用Java写入OS系统日志?

    Mac OS 有一个名为 Console 的应用程序 其中包含记录的消息 错误和故障 我相信 Windows 中的等效项是事件查看器 我想 Linux 上也有一个 但我不知道它是什么 也不知道它在哪里 是否可以像这样从 Java 输出获取消

随机推荐