Integrating CloudLinux with Atomia

Tags: 506 views 0

How to integrate CloudLinux with Atomia.

Overview

With the CloudLinux integration in Atomia, you can take advantage of the added security and performance that comes with using CloudLinux as your server operating system.

Atomia has chosen to integrate with the following components of CloudLinux:

  • Cagefs: All users will be isolated in their own cage, ensuring that they only have access to their own files.
  • LVE: With LVE, it is possible to limit the usage of users in order to avoid users consuming to much server resources. It also adds extensive statistics information, enabling Atomia to show process usage in the Control Panel.
  • PHP selector: Users will have the possibility to select from a list of pre configured PHP versions as well as enable/disable PHP extensions.
  • Apache mod_lsapi: Apache mod_lsapi is a module based on LiteSpeed Technologies API for PHP, Ruby and Python. It offers excellent PHP performance, low memory footprint coupled with great security and support for opcode caching.

Selecting PHP version

The PHP version selection for CloudLinux is compatible with our standard PHP version selection that already exists in the Hosting Control Panel. The list of available versions is fetched dynamically from the CloudLinux agent. This means no additional configuration is required in the Hosting Control Panel for the PHP selection through CloudLinux to work. Different PHP versions per website in an account are supported.

The current PHP version for a website is defined by the shared storage (typically on path /storage/configuration/maps/phpvr.map). By using mod_rewrite in combination with CloudLinux mod_lsapi we are able to use the correct php binary for the requests. The actual configuration is done in two files:

# File: /etc/httpd/conf/phpversions.conf

<IF "%{ENV:PHPVR} == '4.4'">
   AddType application/x-lsphp44 .php
</IF>
<ELSEIF "%{ENV:PHPVR} == '5.1'">
   AddType application/x-lsphp51 .php
</ELSEIF>
<ELSEIF "%{ENV:PHPVR} == '5.2'">
   AddType application/x-lsphp52 .php
</ELSEIF>
<ELSEIF "%{ENV:PHPVR} == '5.3'">
   AddType application/x-lsphp53 .php
</ELSEIF>
<ELSEIF "%{ENV:PHPVR} == '5.4'">
   AddType application/x-lsphp54 .php
</ELSEIF>
<ELSEIF "%{ENV:PHPVR} == '5.5'">
   AddType application/x-lsphp55 .php
</ELSEIF>
<ELSEIF "%{ENV:PHPVR} == '5.6'">
   AddType application/x-lsphp56 .php
</ELSEIF>
<ELSEIF "%{ENV:PHPVR} == '7.0'">
   AddType application/x-lsphp70 .php
</ELSEIF>

And:

# File /etc/container/php.handler (symlinked from /storage/configuration/cloudlinux/cagefs_container/php.handler)

application/x-lsphp44 /opt/alt/php44/usr/bin/lsphp
application/x-lsphp51 /opt/alt/php51/usr/bin/lsphp
application/x-lsphp52 /opt/alt/php52/usr/bin/lsphp
application/x-lsphp53 /opt/alt/php53/usr/bin/lsphp
application/x-lsphp54 /opt/alt/php54/usr/bin/lsphp
application/x-lsphp55 /opt/alt/php55/usr/bin/lsphp
application/x-lsphp56 /opt/alt/php56/usr/bin/lsphp
application/x-lsphp70 /opt/alt/php70/usr/bin/lsphp

In order to populate these files, the agent has a sync command available. It checks the current existing PHP versions in your CloudLinux installation and produces the correct configuration files. The sync can be executed by doing a PUT request to http://agent-url/php/sync. This is done automatically by the Atomia Installer when installing.

Installing CloudLinux

Installation of the CloudLinux servers is done through the Atomia Installer, which features a manifest for setting up an Atomia compatible CloudLinux web server.

By default, Atomia is set up with Ubuntu as the operating system for serving websites. For provisioning to work properly on CloudLinux, some small modifications are needed.

    1. Replace group 33 with 48 in ProvisioningDescription.xml with the transformation below:
<?xml version="1.0" encoding="utf-8"?>
<provisioningDescription xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <initProperties xdt:Locator="XPath(//initProperty[@value='33'])" xdt:Transform="SetAttributes(value)" value="48" />
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='Group']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='PosixGid']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
    <expression xdt:Locator="XPath(//serviceProperty[@name='GID']/expression[text()='33'])" xdt:Transform="Replace" >48</expression>
</provisioningDescription>
    1. Enable the actual provisioning of CloudLinux services in the same file (ProvisioningDescription.xml) with the following transformation:
<?xml version="1.0" encoding="utf-8"?>
<provisioningDescription xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <complexServiceProperty xdt:Locator="XPath(//complexServiceProperty[@name='EnableCloudLinux'])" name="EnableCloudLinux" description="If set to true CloudLinux services will be provisioned" xdt:Transform="SetAttributes(defaultValue)" defaultValue="true" />
</provisioningDescription>

Defining LVE packages

If you want to segment your customers with different LVE usage limits, the easiest way of doing it is through the use of LVE packages. To create these, define the packages on any CloudLinux node. You only need to do it on one node as the configuration is shared.

    1. Create your packages with the following command:
lvectl package-set MyPackage --pmem=1G --speed=100%
    1. You can add more limitations from the list below:
--speed=N%               limit CPU usage in percentage; 100% is one core
--speed=Nmhzghz         limit CPU usage in mhzghz
--io=N                   define io limits (KB/s)
--nproc=N                limit number of processes
--pmem=N                 limit physical memory usage for aplications inside LVE
--iops=N                 limit io operations per second
--vmem=N                 limit virtual memory for applications inside LVE
--maxEntryProcs=N        limit number of entry processes
    1. Go to Admin Panel > Products > Packages > List of package configuration and click on Edit for the package that you would like to enable CloudLinux for.
    2. Under Package limitations, add a limitation of 1 for the following services: CsCloudLinux, LVE, Cagefs.
    3. Under Package initialization, add a new service (CloudLinux) with the argument Package. The value should be the LVE package (defined above) that this Atomia package should use.
    4. Click Save.
    5. If you are using the old way of defining packages (through the provisioning description), the package should be modified by adding the definitions below in the correct place. Please note that the other parameters have been cropped out.
 <serviceLimitationList>
      <globalLimitation>
        <group maxCount="1">
          <service name="CsCloudLinux" />
        </group>
        .
        .
      </globalLimitation>
    </serviceLimitationList>
    .
    .
    <init>
      <arguments>
        <argument serviceName="CsBase" propertyName="CLPackageName" propertyValue="Package1" />
        .
        .
      </arguments>
    </init>
<complexService name="CsBase" description="Base complex service for shared hosting">
	<complexServicePropertyList>
		<complexServiceProperty name="CLPackageName" description="CloudLinux LVE Package" defaultValue="VE_DEFAULT" />
		.
		.
	</complexServicePropertyList>
	<partList>
		<partService name="CsCloudLinux" canAddSame="false">
			<propertyTransformation>
				<simpleTransformer>
					<serviceProperty name="Package">
						<expression>$CsBase::CLPackageName</expression>
					</serviceProperty>
					.
					.
				</simpleTransformer>
			</propertyTransformation>
		</partService>
	</partList>
</complexService>
<package name="DnsPackage">
    <actionHooks>
        <onBeforeChangePackage argument="{... , 'update_properties_for_service_per_package' : [{'Package':'Package1','Services':[{'ServiceName':'CsBase','Properties':[{'Name':'CLPackageName','Value':'LVEPackage1'}]}]}]}"/>
    </actionHooks>
</package>

update_properties_for_service_per_package argument allows us to define and update LVEPackage while upgrading the package. The value of this argument is a JSON array of JSON objects. That array contains all packages that the current package can be upgraded/downgraded to. Every JSON object contains the following properties:

  1. Package: Current package will be updated to this package
  2. Services: Array of services which should be updated.
    1. ServiceName: Name of services which should be updated
    2. Properties: List of properties

Enabling CloudLinux in the Hosting Control Panel

CloudLinux is not enabled by default. To enable it, proceed as follows:

    1. Locate the file: C:Program Files (x86)AtomiaHostingControlPanelbinAtomia.Web.Plugin.Domains.dll.config.
    2. Change the value of CloudLinuxEnabled to true.
<pluginSetting name="CloudLinuxEnabled" value="true" />
  1. If you want to display statistics from CloudLinux, locate the file C:Program Files (x86)AtomiaHostingControlPanelbinAtomia.Web.Plugin.UsageStats.dll.config.
  2. Change CloudLinuxEnabled to true.

Was this helpful?