$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
967581bdf31a my-centos:7 "bash -c /usr/sbin/in" 1 seconds ago Up 1 seconds 0.0.0.0:80->80/tcp gigantic_stallman
验证httpd是否已启动
$ docker exec -it gigantic_stallman /bin/bash -c "systemctl status httpd"
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2016-12-28 11:44:04 UTC; 2min 20s ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 61 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /docker/967581bdf31a3b741a5e857720e199614d816b05a2132271f3adf910f0ed3207/system.slice/httpd.service
├─61 /usr/sbin/httpd -DFOREGROUND
├─66 /usr/sbin/httpd -DFOREGROUND
├─67 /usr/sbin/httpd -DFOREGROUND
├─68 /usr/sbin/httpd -DFOREGROUND
├─69 /usr/sbin/httpd -DFOREGROUND
└─70 /usr/sbin/httpd -DFOREGROUND
Dec 28 11:44:04 967581bdf31a systemd[1]: Starting The Apache HTTP Server...
Dec 28 11:44:04 967581bdf31a httpd[61]: AH00558: httpd: Could not reliably d...e
Dec 28 11:44:04 967581bdf31a systemd[1]: Started The Apache HTTP Server.
一般来说,linux容器是一个独立的进程(现在是virtual machines are also considered as containers),所以在理想的情况下,我们应该创建一个只有一个进程的容器,这个进程就是我们的可交付软件。 在这个问题中,我考虑使用systemd来管理容器内的进程,因为我既不知道虚拟机和容器之间的区别,也不知道OCI规范的原则。 此外,systemd或systemV是系统管理守护进程,需要管理具有数百或数千个进程的系统。由于容器中所需的进程数量只有一个,因此我们不需要进程管理守护进程或任何其他不必要的工具,如ssh,htop,net-tools,firewalld等。
如何运行可交付软件?
在容器中运行应用程序的理想方法是将其用作容器的Entrypoint or CMD。这意味着,当我们运行容器时,它将尝试初始化入口点,并使用CMD中定义的默认命令启动它。无论哪种方式,第一个进程(PID 1)都应该是我们所需的应用程序/软件。 因此,当我们构建容器映像时,我们应该定义该容器的入口点。例如,我有一个httpd和一个redis容器。
╰──➤ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23789e2d0416 redis "docker-entrypoint.s…" 36 seconds ago Up 35 seconds 6379/tcp elegant_ganguly
9be725968ff3 httpd "httpd-foreground" 14 minutes ago Up 14 minutes 80/tcp app1
让我们检查两个容器的第一个进程(cat /proc/1/cmdline),
╰──➤ for i in $(docker ps -q); do docker inspect $i --format 'ImageName: {{.Config.Image}}'; printf "First PID: "; docker exec -i $i sh -c "cat /proc/1/cmdline";echo; done
ImageName: redis
First PID: redis-server *:6379
ImageName: httpd
First PID: httpd-DFOREGROUND
让我们尝试使用ps查看相同的内容
╰──➤ for i in $(docker ps -q); do docker inspect $i --format 'ImageName: {{.Config.Image}}'; docker run -i --rm --pid container:$i ubuntu sh -c "ps aux | head -n2"; done
ImageName: redis
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
999 1 0.4 0.0 56024 7760 ? Ssl 14:58 0:08 redis-server *:6379
ImageName: httpd
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7300 4380 ? Ss 14:44 0:00 httpd -DFOREGROUND
如果我们使用这些图像大多数时候我们不需要单独启动它,因为它可能已经被入口点调用了。 但是如果我们想为我们自己的软件创建我们自己的容器映像,我们可以通过提到入口点来实现,就像httpd和redis映像在这里和这里所做的那样。在--entrypoint的帮助下运行容器时,您还可以从命令行使用CMD和Entrypoint,或者在容器名称后提供命令,如下面(这里我使用while true; do date; sleep 1; done作为默认CMD),
╰──➤ docker run -d --rm ubuntu sh -c "while true; do date; sleep 1; done"
35c6352a55f25335e1bd0874493f2a31155ef752d008eb6718923d1f04ab2c14
现在让我们检查第一个PID,
╰──➤ docker run -i --rm --pid container:35c6352a55f25 ubuntu sh -c "ps aux | head -n2"
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2308 832 ? Ss 15:42 0:00 sh -c while true; do date; sleep 1; done
3条答案
按热度按时间p8h8hvxi1#
最好的方法是在安装
httpd
的地方创建自己的centos7映像使用
docker build -t my-centos:7 .
构建映像没有SYS_ADMIN,Systemd无法运行。这就是我设置以下变量的原因。验证container是否正在运行:
验证httpd是否已启动
qlzsbp2j2#
TL;DR:简短的回答请看其他作者的回答。
***我的问题在这里是错误的***因为它不符合IMO的集装箱化理念。由于新用户会问这类问题,我将解释一些与此问题间接相关的事情。
什么是容器?
从OCI's runtime Specification开始,大约,
1.容器包含可交付软件的单元。
1.容器将封装软件组件及其依赖项。
1.容器应该是可移植的并且与平台无关。
实现容器化的主要组件之一是
container runtime
,容器运行时是负责运行容器的软件。一些容器运行时的例子是
containerd
、docker-engine
、crio
、mcr
等。为什么这个问题是错的?
一般来说,linux容器是一个独立的进程(现在是virtual machines are also considered as containers),所以在理想的情况下,我们应该创建一个只有一个进程的容器,这个进程就是我们的可交付软件。
在这个问题中,我考虑使用
systemd
来管理容器内的进程,因为我既不知道虚拟机和容器之间的区别,也不知道OCI规范的原则。此外,
systemd
或systemV
是系统管理守护进程,需要管理具有数百或数千个进程的系统。由于容器中所需的进程数量只有一个,因此我们不需要进程管理守护进程或任何其他不必要的工具,如ssh
,htop
,net-tools
,firewalld
等。如何运行可交付软件?
在容器中运行应用程序的理想方法是将其用作容器的
Entrypoint
orCMD
。这意味着,当我们运行容器时,它将尝试初始化入口点,并使用CMD
中定义的默认命令启动它。无论哪种方式,第一个进程(PID 1)都应该是我们所需的应用程序/软件。因此,当我们构建容器映像时,我们应该定义该容器的入口点。例如,我有一个
httpd
和一个redis
容器。让我们检查两个容器的第一个进程(
cat /proc/1/cmdline
),让我们尝试使用
ps
查看相同的内容如果我们使用这些图像大多数时候我们不需要单独启动它,因为它可能已经被入口点调用了。
但是如果我们想为我们自己的软件创建我们自己的容器映像,我们可以通过提到入口点来实现,就像
httpd
和redis
映像在这里和这里所做的那样。在--entrypoint
的帮助下运行容器时,您还可以从命令行使用CMD
和Entrypoint
,或者在容器名称后提供命令,如下面(这里我使用while true; do date; sleep 1; done
作为默认CMD
),现在让我们检查第一个PID,
fhity93d3#
运行docker pull命令下载Docker映像,包括名为httpd的Apache。
使用检查Docker图像
现在运行docker命令调用下载的映像。
将本地计算机的端口80Map到容器的端口80(-p 80:80)。尝试通过在浏览器中访问服务器IP或主机名来验证apache Web服务器是否正在工作。