systemd.socket 中文手册
名称
systemd.socket — 套接字单元配置
大纲
socket
.socket
描述
以".socket
" 为后缀的单元文件,封装了一个用于进程间通信的套接字(socket)或管道(FIFO),以支持基于套接字的启动。
本手册列出了所有专用于此类单元的配置选项(亦称"配置指令"或"单元属性")。systemd.unit(5)中描述了通用于所有单元类型的配置选项,它们位于 [Unit] 与[Install] 小节。此类单元专用的配置选项位于 [Socket] 小节。
其他相关的选项还包括:systemd.exec(5)中的选项定义了ExecStartPre=
, ExecStartPost=
,ExecStopPre=
, ExecStopPost=
命令的执行环境;systemd.kill(5)中的选项定义了进程的结束方式;systemd.resource-control(5)中的选项定义了进程的资源限制。
每个套接字单元都必须有一个与其匹配的服务单元(详见systemd.service(5)手册),以处理该套接字上的接入流量。匹配的 .service 单元名称默认与对应的 .socket 单元相同,但是也可以通过 Service=
选项(见下文)明确指定。如果 Accept=no
(见下文),那么匹配的 .service 单元必须要么与 .socket 单元同名,要么必须通过 Service=
选项明确指定。如果 Accept=yes
(见下文),那么匹配的 .service 单元必须是与 .socket 单元同名的模版单元。举例来说也就是:当 Accept=no
时,foo.service
可以与 foo.socket
匹配;而当 Accept=yes
时,仅有 foo@.service
可以与 foo.socket
匹配。
注意,foo.socket
单元文件内并不隐含WantedBy=foo.service
或 RequiredBy=foo.service
依赖。这就意味着匹配的服务单元可以在该套接字不存在的情况下启动(此时服务需要自己创建并打开所需的套接字)。为了避免这个问题,可以向 foo.service
服务单元文件中明确添加一个 Requires=foo.socket
依赖。
套接字单元可用于实现服务的按需启动以及并行启动。
注意,要想配置为基于套接字启动,守护进程必须有能力从 systemd 接手已经创建好的套接字。这既可以通过调sd_listen_fds(3)接口实现,也可以通过传统的inetd(8)风格的套接字传递方式实现(需要在服务单元文件中设置 StandardInput=socket
)。
虽然所有通过 .socket
单元创建的网络套接字都位于宿主系统的网络名字空间中(参见 network_namespaces(7) 手册),但是,这并不意味着基于套接字启动的服务也必须位于宿主系统的网络名字空间中。实际上,我们建议尽可能将服务运行在它自己的网络名字空间中(例如通过 PrivateNetwork=yes
实现,参见systemd.exec(5) 手册),并且仅接受宿主系统网络名字空间中与其关联的套接字。这样就可以确保仅允许通过关联套接字在宿主系统的网络名字空间中通信,同时,服务内部创建的套接字又被限制在服务自己的网络名字空间中,这种配置方式显然更加安全可靠。
自动依赖
隐含依赖
下列依赖关系是自动隐含的:
socket 单元会自动添加对匹配的 service 单元的
Before=
依赖。引用了文件系统路径(例如UNIX套接字或FIFO)的 socket 单元,会自动添加对访问该路径所需的所有 mount 单元的
Requires=
与After=
依赖。使用了
BindToDevice=
选项的 socket 单元,会自动添加对封装了目标网络接口的 device 单元的BindsTo=
与After=
依赖。
还有一些其他依赖关系是由systemd.exec(5)与systemd.resource-control(5) 中的某些资源限制选项自动隐含添加的。
默认依赖
除非明确设置了 DefaultDependencies=no
,否则 socket 单元将会自动添加下列依赖关系:
Before=
sockets.target
After=sysinit.target
,Requires=sysinit.target
,Before=shutdown.target
,Conflicts=shutdown.target
。这样可以确保普通的套接字单元: (1)在系统启动时先于普通服务启动,(2)在系统关闭之前先被干净的停止。只有那些必须在系统启动早期建立的套接字,或者必须在系统关闭的末尾才能结束的套接字,才可以设置DefaultDependencies=no
选项
套接字单元文件中必须包含一个 [Socket] 小节,其中包含了套接字或管道的相关信息。能在 [Socket] 小节中使用的选项,有许多亦可用于其他类型的单元文件(参见systemd.exec(5)与systemd.kill(5)手册)。这里只列出仅能用于 [Socket] 小节的选项(亦称"指令"或"属性"):
ListenStream=
,ListenDatagram=
,ListenSequentialPacket=
分别为 字节流(
SOCK_STREAM
)、 数据报(SOCK_DGRAM
)、 顺序包(SOCK_SEQPACKET
) 指定套接字的监听地址(还可能包括端口)。可以接受的地址格式如下:如果地址以 "
/
" 开头,那么将被视为文件系统上的一个 UNIX套接字(AF_UNIX
)。如果地址以 "
@
" 开头,那么将被视为抽象名字空间内的一个 UNIX套接字(AF_UNIX
)。"@
" 将会在绑定前被替换为NUL
字符,详见 unix(7) 手册。如果地址是一个纯数字,那么将被视为在IPv6地址上监听的一个端口号。取决于
BindIPv6Only=
选项(见下文) 的设置,绑定的端口可能同时接受IPv6与IPv4连接(默认)、或只接受 IPv6 连接。如果地址是一个符合"v.w.x.y:z"格式的字符串,那么将被视为 在指定的IPv4地址"v.w.x.y"的"z"端口上监听。
如果地址是一个符合"[x]:y"格式的字符串,那么将被视为在指定的IPv6地址"x"的"y"端口上监听。绑定的端口也可能同时接受IPv6与IPv4连接。这取决于
BindIPv6Only=
选项(见下文)的设置。如果地址是一个符合 "
vsock:x:y
"格式的字符串,那么将被视为一个AF_VSOCK
(Linux VM socket) 套接字,并在指定的 CID(地址) "x
" 端口 "y
" 上监听。其中,CID 是一个独一无二的32位整数,概念上相当于一个IP地址。 CID 是可选的,设为空字符串表示省略。[译者注] virtio-vsock 是一个半虚拟化设备,它可以让宿主机内的应用程序与客户机内的应用程序直接使用套接字API进行通信。注意,顺序包
SOCK_SEQPACKET
(也就是ListenSequentialPacket=
) 仅可用于 UNIX套接字(AF_UNIX
)。当字节流SOCK_STREAM
(也就是ListenStream=
) 应用于IP套接字时,其含义是TCP套接字,当数据报SOCK_DGRAM
(也就是ListenDatagram=
) 应用于IP套接字时,其含义是UDP套接字。如果多次使用这些选项,那么当其中任意一个套接字上有流量进入时,对应的服务都将被启动,并且所有这些选项列出的套接字都将被传递给对应的服务,无论这些套接字上是否有流量进入。如果为某个选项指定了一个空字符串,则表示 清空该选项之前设置的所有监听地址。
通过使用
Service=
选项,可以让多个套接字单元对应到同一个服务单元,也就是由同一个服务单元接收多个套接字单元中配置的所有套接字。同一个套接字单元内配置的多个套接字按其在单元文件中出现的顺序传递,但是在多个套接字单元之间 并不遵守任何顺序。如果在此处配置了某个IP地址,我们通常希望在对应的网络接口实际可用之前就开始监听 (甚至不管该接口是否真的可用)。如果这正是你所期盼的效果,那么可以使用
FreeBind=
选项(见下文) 达到此目的。ListenFIFO=
设置一个要监听的文件系统管道(FIFO),必须使用绝对路径。该选项的行为与
ListenDatagram=
选项 非常相似。ListenSpecial=
设置一个要监听的特殊文件,必须使用绝对路径。该选项的行为与
ListenFIFO=
选项非常相似。此选项可用于监听/dev
中的字符设备文件以及/proc
与/sys
中的特殊文件。ListenNetlink=
设置一个要监听的 Netlink 套接字。必须设为一个合理的
AF_NETLINK
名称(例如audit
或kobject-uevent
),并且可以在其末尾附加一个可选的"Netlink多播组ID(一个整数)"后缀,AF_NETLINK
名称与其后缀之间以空格分隔。该选项的行为与ListenDatagram=
选项 非常相似。ListenMessageQueue=
设置一个 要监听的 POSIX 消息队列。必须设为一个合理的 POSIX 消息队列名称(以"/"开头)。该选项的行为与
ListenFIFO=
选项非常相似。在 Linux 系统上,POSIX 消息队列描述符实际上就是一个文件描述符,并且可以在进程之间继承。ListenUSBFunction=
设置一个监听的 USB FunctionFS 端点位置以实现 USB gadget 功能,必须设为一个绝对路径形式表示的 functionfs 挂载点。此处设置的路径将被用于打开 FunctionFS 端点
ep0
(其行为与前述的ListenFIFO=
选项类似)。如果使用了此选项,那么对应的 service 单元 必须设置了USBFunctionDescriptors=
与USBFunctionStrings=
选项。SocketProtocol=
指定套接字的协议:
udplite
表示 UDP-Lite(IPPROTO_UDPLITE
);sctp
表示 SCTP(IPPROTO_SCTP
)。BindIPv6Only=
控制 IPV6_V6ONLY 套接字选项(详见 ipv6(7) 手册),可设为
default
,both
,ipv6-only
之一。both
表示该 IPv6 套接字既可以通过 IPv4 访问,也可以通过 IPv6 访问; 而ipv6-only
则表示仅可以通过 IPv6 访问。默认值default
则表示使用/proc/sys/net/ipv6/bindv6only
中的设置 (默认值等价于both
)。Backlog=
设置半链接队列的最大长度,也就是最大允许多少个连接处于"等待接入"的状态。必须设为一个正整数。此选项仅对字节流(SOCK_STREAM)以及顺序包(SOCK_SEQPACKET)套接字有意义。详见 listen(2) 手册。默认值为 SOMAXCONN(128)
BindToDevice=
设置 SO_BINDTODEVICE 套接字选项(详见 socket(7) 手册),也就是将套接字绑定到特定的网络接口。如果设置了此选项,那么仅接收指定的网络接口上的流量,并且会自动创建到该网络接口的 device 单元(systemd.device(5)) 的依赖关系(参见上面"隐含依赖"小节)。
SocketUser=
,SocketGroup=
接受一个 UNIX 用户/组 名称。设置 AF_UNIX 套接字文件与 FIFO 管道文件的属主与属组。默认未设置这两个选项,表示文件的属主与属组都是root(运行于系统上下文) 或调用systemd的用户及其属组(运行于用户上下文)。如果仅指定了用户,那么属组将被自动设为 该用户的默认组(主组)。
SocketMode=
设置创建文件节点时的 默认访问模式,仅用于文件系统上的套接字文件与管道文件。默认值是 0666 。
DirectoryMode=
当监听文件系统上的套接字或管道时,将会自动创建所需的父目录。此选项设置了创建父目录时的 默认访问模式。默认值是 0755 。
Accept=
若设为
yes
,则会为每个进入的连接派生一个服务实例,并且仅将该连接传递给服务实例。若设为no
(默认值),则会将套接字自身传递给匹配的服务单元,并且仅为所有进入的连接派生单独一个服务实例。此选项对数据报(SOCK_DGRAM)套接字与管道(FIFO)没有意义 (相当于始终设为no
)。出于性能考虑,守护进程应该改造为仅使用Accept=no
的设置。监听AF_UNIX
套接字的守护进程 可以(但非必须)调用 close(2) 关闭套接字,但是禁止删除文件系统上的套接字文件。当Accept=no
时,守护进程应该禁止调用 shutdown(2) 关闭套接字; 而当Accept=yes
时则可以(但非必须)这么做。设置Accept=yes
的唯一目的 在于可以不经修改的直接使用为 inetd(8) 设计的 守护进程。对于 IPv4 与 IPv6 连接来说,
REMOTE_ADDR
环境变量将会包含远端的IP地址,而REMOTE_PORT
环境变量则会包含远端端口。变量值的格式与 CGI 中使用的格式相同。而对于 SOCK_RAW 来说,端口就是IP协议。Writable=
接受一个布尔值,表示以什么模式打开指定的文件。仅可与
ListenSpecial=
一起使用。设为 yes 表示以读写模式打开; 设为 no(默认值) 表示以只读模式打开。MaxConnections=
接受一个整数值,表示当
Accept=yes
时,允许同时服务的最大连接数量,也就是允许派生的最大服务实例数量。若有超出该数量的连接进入,则会被拒绝,只到有至少一个正在被服务的连接退出。当Accept=no
时,此选项没有意义。默认值是 64 。MaxConnectionsPerSource=
在每一个源IP地址上允许的最大连接数。此选项与上文的
MaxConnections=
非常相似。默认未启用此限制。KeepAlive=
若设为 yes 则表示在该套接字的所有TCP连接上启用"KeepAlive"检测。所谓"KeepAlive"检测,其含义是,若某个TCP连接空闲(持续没有任何数据交换)超过指定的时间,则自动发送"KeepAlive"消息要求对方确认,以判断对方主机是否崩溃或网络不可达。默认空闲时长取决于
/proc/sys/net/ipv4/tcp_keepalive_time
的设置(默认为2小时)。此选项实际上是设置了 SO_KEEPALIVE 套接字选项的值。详见 socket(7) 与 TCP Keepalive HOWTO 文档。默认值no
则表示不发送"KeepAlive"消息。KeepAliveTimeSec=
设置开始发送"KeepAlive"消息前允许TCP连接空闲的秒数。此选项实际上是设置了 TCP_KEEPIDLE 套接字选项的值。如果某个TCP连接空闲(持续没有任何数据交换)超过了这个秒数,则自动发送"KeepAlive"消息要求对方确认。详见 socket(7) 与 TCP Keepalive HOWTO 文档。默认值为 7200 秒。
KeepAliveIntervalSec=
设置两次发送"KeepAlive"消息之间的间隔秒数。也就是如果对方没有回应"KeepAlive"消息的话,隔多少秒之后再次发送"KeepAlive"消息。此选项实际上是设置了 TCP_KEEPINTVL 套接字选项的值。详见 socket(7) 与 TCP Keepalive HOWTO 文档。默认值为 75 秒。
KeepAliveProbes=
设置最多发送多少个"KeepAlive"消息。超过这个数量之后,若依然没有收到回应,则认为对方主机已经崩溃或网络不可达。此选项实际上是设置了 TCP_KEEPCNT 套接字选项的值。详见 socket(7) 与 TCP Keepalive HOWTO 文档。默认值为 9 个。
NoDelay=
接受一个布尔值,设置是否"立即发送"数据。此选项实际上是设置了 TCP_NODELAY 套接字选项的值(详见 tcp(7) 手册)。默认值
no
表示启用 TCP Nagle's 算法,也就是将多个小数据包组合为一个大数据包发送,以提高网络带宽的利用效率。但是这样做的缺点是可能会增加数据包的发送延迟。不适合频繁发送小包且对实时性要求较高的应用(例如网络游戏)。Priority=
设置从此套接字发送的数据包的网络优先级,必须设为一个整数。此选项实际上是设置了 SO_PRIORITY 套接字选项的值。详见 socket(7) 手册。
DeferAcceptSec=
若设置此选项,则必须设为一个整数(秒数),表示只在确实有应用层数据到达这个套接字的时候,才会唤醒套接字的监听进程,而不是在建立连接之后(也就是完成三次握手之后)立即被唤醒,同时内核将会忽略不含任何数据的初始空ACK包。此选项实际上是设置了
TCP_DEFER_ACCEPT
套接字选项的值。详见 tcp(7) 手册。此处设置的秒数表示内核在回退到常规行为(正常处理不含任何数据的初始空ACK包)前,最多可以花多少秒等候应用层数据的到达。对于需要客户端首先发送数据的网络服务(例如HTTP服务器)来说,使用此选项可以明显提升运行性能,因为服务进程只在确实有客户端数据进入时才会被唤醒。如果客户端也开启了
TCP_DEFER_ACCEPT
选项,那么建立初始连接所花的时间将会被降低,因为客户端内核将会在本该发送不含任何数据的初始ACK包的时候(也就是第三次握手),直接发送应用层数据。此选项默认未设置,表示默认禁用此特性。
ReceiveBuffer=
,SendBuffer=
设置套接字的接收与发送缓冲区的大小。此两个选项实际上是设置了 SO_RCVBUF 与 SO_SNDBUF 套接字选项的值。详见 socket(7) 手册。选项值可以使用 K, M, G 后缀(以1024为基数)。
IPTOS=
设置从该套接字发送的IP包的 Type-Of-Service 字段的值,此选项实际上是设置了 IP_TOS 套接字选项的值。详见 ip(7) 手册。必须设为一个整数或
low-delay
,throughput
,reliability
,low-cost
之一。IPTTL=
设置从该套接字发送的IPv4包的 Time-To-Live 字段或IPv6包的 Hop-Count 字段的值,必须设为一个整数。此选项实际上是设置了 IP_TTL 或 IPV6_UNICAST_HOPS 套接字选项的值。详见 ip(7) 与 ipv6(7) 手册。
Mark=
设置从该套接字发送的IP包的防火墙标记(mark),必须设为一个整数,防火墙逻辑可根据此标记对包进行过滤。此选项实际上是设置了 SO_MARK 套接字选项的值,详见 iptables(8) 手册。
ReusePort=
接受一个布尔值。若设为 yes 则允许多个套接字 bind(2) 到同一个TCP或UDP端口。此选项实际上是设置了 SO_REUSEPORT 套接字选项的值,详见 socket(7) 手册。
SmackLabel=
,SmackLabelIPIn=
,SmackLabelIPOut=
设置一个字符串值。分别控制 "
security.SMACK64
", "security.SMACK64IPIN
", "security.SMACK64IPOUT
" 扩展属性的值。也就是分别设置 管道(FIFO)的安全标签、进入流量的安全标签、发出流量的安全标签。详见 Smack.txt 内核文档。SELinuxContextFromNet=
接受一个布尔值。 若设为 yes 则 systemd 将尝试根据网络对端的信息 猜测出实例化服务的SELinux标签。 注意, 仅有"安全标签"是根据网络对端信息猜测出来的, 而SELinux上下文中的其他部分, 则要么来自于被此套接字单元触发的目标二进制文件, 要么来自于
SELinuxContext=
选项的值。 此选项仅在Accept=yes
并且已启用了 MLS/MCS SELinux 策略时才有意义。 默认值是 "no
"PipeSize=
设置管道(FIFO)缓冲区大小(字节)。详见 fcntl(2) 手册。选项值可以使用以1024为基数的 K, M, G 后缀。
MessageQueueMaxMessages=
,MessageQueueMessageSize=
在创建消息队列时,分别设置 mq_maxmsg 与 mq_msgsize 字段的值,必须设为整数。注意,这两个选项必须同时设置或者同时不设置,不允许仅设置其中一个。详见 mq_setattr(3) 手册。
FreeBind=
接受一个布尔值。若设为 yes 则可以将此套接字绑定到非本地IP地址。这样就可以在指定的IP地址实际可用之前先监听它。此选项实际上是设置了 IP_FREEBIND 套接字选项的值。出于健壮性考虑,当你希望将套接字绑定到特定的IP地址时,应该将此选项设为 yes 。默认值为
no
。Transparent=
可设为 yes 或 no(默认) 。此选项实际上是设置了 IP_TRANSPARENT 套接字选项的值。默认值为
no
Broadcast=
可设为 yes 或 no(默认) ,表示是否允许发送广播包。此选项实际上是设置了 SO_BROADCAST 套接字选项的值。默认值为
no
PassCredentials=
可设为 yes 或 no(默认) ,表示是否允许
AF_UNIX
套接字 接收对端进程在辅助消息中发送的证书。此选项实际上是设置了 SO_PASSCRED 套接字选项的值。默认值为no
PassSecurity=
可设为 yes 或 no(默认) 。表示是否允许
AF_UNIX
套接字接 收对端进程在辅助消息中发送的安全上下文。此选项实际上是设置了 SO_PASSSEC 套接字选项的值。默认值为no
TCPCongestion=
设置TCP拥塞控制算法。必须设为 "westwood", "veno", "cubic", "lp" 之一,或者内核IP栈支持的其他算法。此选项仅对字节流(SOCK_STREAM)套接字有意义。
ExecStartPre=
,ExecStartPost=
设置在创建与绑定监听套接字/管道之前、之后执行的命令行(命令+参数)。命令行必须以一个绝对路径表示的可执行文件开始,并且其后的那些参数将依次作为"argv[1] argv[2] …"传递给被执行的进程。如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。这两个选项与 systemd.service(5) 中的同名选项类似,遵守的语法规则也相同。
ExecStopPre=
,ExecStopPost=
设置在关闭与删除监听套接字/管道之前、之后执行的命令行(命令+参数)。命令行必须以一个绝对路径表示的可执行文件开始,并且其后的那些参数将依次作为"argv[1] argv[2] …"传递给被执行的进程。如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。这两个选项与 systemd.service(5) 中的
ExecStartPre=
选项类似,遵守的语法规则也相同。TimeoutSec=
设置等候
ExecStartPre=
,ExecStartPost=
,ExecStopPre=
,ExecStopPost=
执行完成的最长时间限制。如果某个命令执行超时,那么该套接字/管道将被视为失败并且会被强制关闭并删除。所有正在执行中的命令都可以通过SIGTERM
信号终止,并且如果继续等待此处设置的时长之后仍未终止,那么将使用SIGKILL
信号强制终止(参见 systemd.kill(5) 中的KillMode=
选项)。若设为一个无单位后缀的纯整数,则表示秒数。否则可以设为例如"5min 20s"这样的时长。设为 "0
" 表示永不超时。默认值是DefaultTimeoutStartSec=
选项的值(参见 systemd-system.conf(5) 手册)。Service=
设置当有流量进入时 需要启动的服务单元的名称。仅可用于
Accept=no
的套接字。默认值是与套接字单元自身同名的服务单元(剔除后缀)。在大多数情况下,不需要明确设置此选项。设置此选项可能导致自动添加额外的依赖关系 (参见上面的"自动依赖" 小节)。RemoveOnStop=
若设为 yes 则此套接字单元创建的所有文件 都将在该单元停止后被删除。此选项仅对文件系统上的 AF_UNIX套接字、POSIX消息队列、管道(FIFO)、 以及指向这些文件的
Symlinks=
软连接有意义。通常反对使用此选项,因为即使套接字单元已经被停止,对应的服务单元也可能还在继续运行。默认值是 no 。Symlinks=
设置在文件系统上创建
AF_UNIX
套接字、POSIX消息队列、管道(FIFO)文件的时候,同时创建指向该文件的软连接。此选项的参数是一个文件系统路径列表,表示软连接的路径。设置此选项之后,就可以随着套接字的生命周期一起管理其别名(软连接)。此选项仅可用于仅配置了一个AF_UNIX
套接字、POSIX消息队列、管道(FIFO)的单元。注意,即使某个软连接创建失败,也不会导致该 socket 单元启动失败。设为空字符串表示清空所有先前已设置的路径列表。默认值为空。FileDescriptorName=
为该单元封装的所有文件描述符取一个名字。这有助于已启动的服务定位特定的文件描述符 (如果传递了多个文件描述符的话)。服务单元可以使用 sd_listen_fds_with_names(3) 为接收到的文件描述符取得此处设置的名称。名称仅可包含除控制字符与冒号(:)之外的ASCII字符,且不能超过255个字符。如果未设置此选项,那么默认的名称将等于此单元的名称 (包括
.socket
后缀)。TriggerLimitIntervalSec=
,TriggerLimitBurst=
设置该套接字单元的启动频率限制。
TriggerLimitIntervalSec=
用于设置时长,设为 0 表示不作限制。默认值为2秒。可以使用 "us
", "ms
", "s
", "min
", "h
" 等时间后缀(参见 systemd.time(7) 手册)。TriggerLimitBurst=
用于设置在一段给定的时长内,最多允许启动多少次,设为 0 表示不作限制。如果Accept=yes
,那么默认值是 200 次(也就是默认在2秒内最多允许启动200次),否则默认值是 20 次(也就是默认在2秒内最多允许启动20次)。一旦触碰到了启动频率限制,那么该套接字单元将立即进入失败(failed)状态,并且直到该套接字单元下次重启之前,都不能接受任何连接。注意,在服务排队启动之前,此限制就已经生效了。
更多选项参见systemd.exec(5)与systemd.kill(5)手册。
参见
systemd(1), systemctl(1), systemd-system.conf(5), systemd.unit(5), systemd.exec(5), systemd.kill(5), systemd.resource-control(5), systemd.service(5), systemd.directives(7), sd_listen_fds(3), sd_listen_fds_with_names(3)
更多详情,参见"systemd for Developers"系列: Socket Activation, Socket Activation, part II, Converting inetd Services, Socket Activated Internet Services and OS Containers.