Systemd units for docker containers
Make every docker container a standard systemd unit, allowing it to be managed by standard way with systemctl. Also add systemd support to dockercrl. Blueprint: master-on-centos7 Breaks: nothing Change-Id: I924534b43d083f93130d2af805609a81b302d7de
This commit is contained in:
parent
032c707ec8
commit
a18e970e1d
@ -5,6 +5,7 @@ class docker::dockerctl (
|
|||||||
$profile_dir = '/etc/profile.d',
|
$profile_dir = '/etc/profile.d',
|
||||||
$admin_ipaddress = $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
$admin_ipaddress = $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
||||||
$docker_engine = 'native',
|
$docker_engine = 'native',
|
||||||
|
$use_systemd = false,
|
||||||
$release,
|
$release,
|
||||||
$production,
|
$production,
|
||||||
) {
|
) {
|
||||||
|
53
deployment/puppet/docker/manifests/systemd.pp
Normal file
53
deployment/puppet/docker/manifests/systemd.pp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# == Class: docker::systemd
|
||||||
|
#
|
||||||
|
# Systemd units generator for docker containers
|
||||||
|
#
|
||||||
|
# === Parameters
|
||||||
|
#
|
||||||
|
# [*release*]
|
||||||
|
# (required) String. Determine MOS release.
|
||||||
|
# This release will use for correct docker container names,
|
||||||
|
# e.g. if release == '8.0' and container name is 'astute' -
|
||||||
|
# the full container name will be fuel-core-8.0-astute
|
||||||
|
#
|
||||||
|
# [*stop_timeout*]
|
||||||
|
# (required) Integer. Number of seconds to wait for the container
|
||||||
|
# to stop before killing it.
|
||||||
|
#
|
||||||
|
# [*containers*]
|
||||||
|
# (required) Array. This is an array of container names which should be start
|
||||||
|
# as systemd units.
|
||||||
|
#
|
||||||
|
# [*depends*]
|
||||||
|
# (optional) Hash. This is a hash of container dependencies.
|
||||||
|
# Key is a container name, value is a container name
|
||||||
|
# which should be started before.
|
||||||
|
#
|
||||||
|
|
||||||
|
class docker::systemd (
|
||||||
|
$release = undef,
|
||||||
|
$stop_timeout = 30,
|
||||||
|
$containers = ['astute', 'cobbler', 'keystone', 'mcollective', 'nailgun',
|
||||||
|
'nginx', 'ostf', 'postgres', 'rabbitmq', 'rsync', 'rsyslog'],
|
||||||
|
$depends = {
|
||||||
|
'astute' => 'rsync',
|
||||||
|
'cobbler' => 'nginx',
|
||||||
|
'keystone' => 'rabbitmq',
|
||||||
|
'mcollective' => 'cobbler',
|
||||||
|
'nailgun' => 'rsyslog',
|
||||||
|
'nginx' => 'ostf',
|
||||||
|
'ostf' => 'nailgun',
|
||||||
|
'rsync' => 'keystone',
|
||||||
|
'rsyslog' => 'astute',
|
||||||
|
'rabbitmq' => 'postgres'
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
# No empty release allowed
|
||||||
|
validate_string($release)
|
||||||
|
|
||||||
|
docker::systemd::config {$containers:
|
||||||
|
release => $release,
|
||||||
|
depends => $depends,
|
||||||
|
timeout => $stop_timeout}
|
||||||
|
}
|
||||||
|
|
35
deployment/puppet/docker/manifests/systemd/config.pp
Normal file
35
deployment/puppet/docker/manifests/systemd/config.pp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#
|
||||||
|
# docker::systemd::config resource deploys systemd units for fuel-related
|
||||||
|
# docker containers and enable to running a containers as a standard
|
||||||
|
# system service. This resource doesn't changes any state of a container.
|
||||||
|
|
||||||
|
# Variables:
|
||||||
|
#
|
||||||
|
# release - will use for correct docker container names
|
||||||
|
# e.g. if release == '8.0' and container name is 'astute' -
|
||||||
|
# the full container name will be fuel-core-8.0-astute
|
||||||
|
#
|
||||||
|
# depends - this is a hash which describes dependencies of containers
|
||||||
|
# Key is a container name which apply setting, value is a container name
|
||||||
|
# which should be started before.
|
||||||
|
#
|
||||||
|
# timeout - Number of seconds to wait for the container to stop before killing it.
|
||||||
|
#
|
||||||
|
|
||||||
|
define docker::systemd::config( $release, $depends, $timeout ) {
|
||||||
|
file { "/usr/lib/systemd/system/docker-${title}.service":
|
||||||
|
ensure => file,
|
||||||
|
content => template('docker/systemd/template.service.erb'),
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '0644',
|
||||||
|
notify => Service["docker-${title}"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# We use ensure => undef to prevent unnecessary start service
|
||||||
|
# because at first boot time, the container is launched by dockerctl
|
||||||
|
service { "docker-${title}":
|
||||||
|
enable => true,
|
||||||
|
ensure => undef,
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,8 @@ if [ -z "$VERSION" ]; then
|
|||||||
VERSION="_VERSION_"
|
VERSION="_VERSION_"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
SYSTEMD="<%= @use_systemd.to_s %>"
|
||||||
|
|
||||||
IMAGE_PREFIX="fuel"
|
IMAGE_PREFIX="fuel"
|
||||||
# busybox image for storage containers
|
# busybox image for storage containers
|
||||||
BUSYBOX_IMAGE="busybox.tar.gz"
|
BUSYBOX_IMAGE="busybox.tar.gz"
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Name=<%= @title %> container
|
||||||
|
Requires=docker.service
|
||||||
|
After=docker.service <% if @depends[@title] -%>docker-<%= @depends[@title] -%>.service<% end %>
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=10
|
||||||
|
StartLimitBurst=5
|
||||||
|
StartLimitInterval=60
|
||||||
|
ExecStartPre=/usr/bin/dockerctl create <%= @title %>
|
||||||
|
ExecStart=/usr/bin/docker start -a fuel-core-<%= @release %>-<%= @title %>
|
||||||
|
ExecStop=/usr/bin/docker stop -t <%= @timeout %> fuel-core-<%= @release %>-<%= @title %>
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -18,13 +18,23 @@ $admin_network = ipcalc_network_wildcard(
|
|||||||
$::fuel_settings['ADMIN_NETWORK']['netmask'])
|
$::fuel_settings['ADMIN_NETWORK']['netmask'])
|
||||||
$extra_networks = $fuel_settings['EXTRA_ADMIN_NETWORKS']
|
$extra_networks = $fuel_settings['EXTRA_ADMIN_NETWORKS']
|
||||||
|
|
||||||
|
case $::osfamily {
|
||||||
|
'RedHat': {
|
||||||
|
if $::operatingsystemmajrelease >= '7' {
|
||||||
|
$use_systemd = true
|
||||||
|
} else {
|
||||||
|
$use_systemd = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: { $use_systemd = false }
|
||||||
|
}
|
||||||
|
|
||||||
Class['nailgun::packages'] ->
|
Class['nailgun::packages'] ->
|
||||||
Class['nailgun::host'] ->
|
Class['nailgun::host'] ->
|
||||||
Class['nailgun::client'] ->
|
Class['nailgun::client'] ->
|
||||||
Class['docker::dockerctl'] ->
|
Class['docker::dockerctl'] ->
|
||||||
Class['docker'] ->
|
Class['docker'] ->
|
||||||
Class['openstack::logrotate'] ->
|
Class['openstack::logrotate'] ->
|
||||||
Class['nailgun::supervisor'] ->
|
|
||||||
Class['monit'] ->
|
Class['monit'] ->
|
||||||
Class['nailgun::bootstrap_cli']
|
Class['nailgun::bootstrap_cli']
|
||||||
|
|
||||||
@ -56,6 +66,7 @@ class { 'openstack::clocksync':
|
|||||||
}
|
}
|
||||||
|
|
||||||
class { 'docker::dockerctl':
|
class { 'docker::dockerctl':
|
||||||
|
use_systemd => $use_systemd,
|
||||||
release => $::fuel_release,
|
release => $::fuel_release,
|
||||||
production => $production,
|
production => $production,
|
||||||
admin_ipaddress => $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
admin_ipaddress => $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
||||||
@ -81,13 +92,6 @@ class { 'nailgun::client':
|
|||||||
keystone_pass => $::fuel_settings['FUEL_ACCESS']['password'],
|
keystone_pass => $::fuel_settings['FUEL_ACCESS']['password'],
|
||||||
}
|
}
|
||||||
|
|
||||||
class { 'nailgun::supervisor':
|
|
||||||
nailgun_env => false,
|
|
||||||
ostf_env => false,
|
|
||||||
require => File['/etc/supervisord.d/current', "/etc/supervisord.d/${::fuel_release}"],
|
|
||||||
conf_file => 'nailgun/supervisord.conf.base.erb',
|
|
||||||
}
|
|
||||||
|
|
||||||
class { 'nailgun::bootstrap_cli':
|
class { 'nailgun::bootstrap_cli':
|
||||||
settings => $::fuel_settings['BOOTSTRAP'],
|
settings => $::fuel_settings['BOOTSTRAP'],
|
||||||
direct_repo_addresses => [ $::fuel_settings['ADMIN_NETWORK']['ipaddress'] ],
|
direct_repo_addresses => [ $::fuel_settings['ADMIN_NETWORK']['ipaddress'] ],
|
||||||
@ -99,33 +103,47 @@ class { 'osnailyfacter::ssh':
|
|||||||
password_auth => 'yes',
|
password_auth => 'yes',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if $use_systemd {
|
||||||
|
class { 'docker::systemd':
|
||||||
|
release => $::fuel_release,
|
||||||
|
}
|
||||||
|
Class['openstack::logrotate'] ->
|
||||||
|
Class['docker::systemd'] ->
|
||||||
|
Exec['sync_deployment_tasks']
|
||||||
|
} else {
|
||||||
|
class { 'nailgun::supervisor':
|
||||||
|
nailgun_env => false,
|
||||||
|
ostf_env => false,
|
||||||
|
require => File['/etc/supervisord.d/current', "/etc/supervisord.d/${::fuel_release}"],
|
||||||
|
conf_file => 'nailgun/supervisord.conf.base.erb',
|
||||||
|
}
|
||||||
file { '/etc/supervisord.d':
|
file { '/etc/supervisord.d':
|
||||||
ensure => directory,
|
ensure => directory,
|
||||||
}
|
}
|
||||||
|
|
||||||
class { 'docker::supervisor':
|
class { 'docker::supervisor':
|
||||||
release => $::fuel_release,
|
release => $::fuel_release,
|
||||||
require => File["/etc/supervisord.d/${::fuel_release}"],
|
require => File["/etc/supervisord.d/${::fuel_release}"],
|
||||||
}
|
}
|
||||||
|
|
||||||
file { "/etc/supervisord.d/${::fuel_release}":
|
file { "/etc/supervisord.d/${::fuel_release}":
|
||||||
ensure => directory,
|
ensure => directory,
|
||||||
require => File['/etc/supervisord.d'],
|
require => File['/etc/supervisord.d'],
|
||||||
owner => root,
|
owner => 'root',
|
||||||
group => root,
|
group => 'root',
|
||||||
}
|
}
|
||||||
|
|
||||||
file { '/etc/supervisord.d/current':
|
file { '/etc/supervisord.d/current':
|
||||||
ensure => link,
|
ensure => link,
|
||||||
target => "/etc/supervisord.d/${::fuel_release}",
|
target => "/etc/supervisord.d/${::fuel_release}",
|
||||||
require => File["/etc/supervisord.d/${::fuel_release}"],
|
require => File["/etc/supervisord.d/${::fuel_release}"],
|
||||||
replace => true,
|
replace => true,
|
||||||
}
|
}
|
||||||
|
Class['openstack::logrotate'] ->
|
||||||
|
Class['docker::supervisor'] ->
|
||||||
|
Exec['sync_deployment_tasks']
|
||||||
|
}
|
||||||
|
|
||||||
exec {'sync_deployment_tasks':
|
exec {'sync_deployment_tasks':
|
||||||
command => 'fuel rel --sync-deployment-tasks --dir /etc/puppet/',
|
command => 'fuel rel --sync-deployment-tasks --dir /etc/puppet/',
|
||||||
path => '/usr/bin',
|
path => '/usr/bin',
|
||||||
tries => 12,
|
tries => 12,
|
||||||
try_sleep => 10,
|
try_sleep => 10,
|
||||||
require => Class['nailgun::supervisor']
|
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,8 @@ case "$1" in
|
|||||||
else
|
else
|
||||||
check_ready $container
|
check_ready $container
|
||||||
fi ;;
|
fi ;;
|
||||||
|
create)
|
||||||
|
create_container $container;;
|
||||||
start)
|
start)
|
||||||
if [[ "$container" == 'all' ]]; then
|
if [[ "$container" == 'all' ]]; then
|
||||||
for service in $container_seq; do
|
for service in $container_seq; do
|
||||||
|
@ -17,6 +17,8 @@ if [ -z "$VERSION" ]; then
|
|||||||
VERSION="_VERSION_"
|
VERSION="_VERSION_"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
SYSTEMD="false"
|
||||||
|
|
||||||
IMAGE_PREFIX="fuel"
|
IMAGE_PREFIX="fuel"
|
||||||
# busybox image for storage containers
|
# busybox image for storage containers
|
||||||
BUSYBOX_IMAGE="busybox.tar.gz"
|
BUSYBOX_IMAGE="busybox.tar.gz"
|
||||||
|
@ -26,6 +26,7 @@ function show_usage {
|
|||||||
echo "Available commands:"
|
echo "Available commands:"
|
||||||
echo " help: show this message"
|
echo " help: show this message"
|
||||||
echo " build: create all Docker containers"
|
echo " build: create all Docker containers"
|
||||||
|
echo " create: create container without running (or starting) it"
|
||||||
echo " list: list container short names (-l for more output)"
|
echo " list: list container short names (-l for more output)"
|
||||||
echo " start: start all Docker containers"
|
echo " start: start all Docker containers"
|
||||||
echo " restart: restart one or more Docker containers"
|
echo " restart: restart one or more Docker containers"
|
||||||
@ -57,7 +58,7 @@ function parse_options {
|
|||||||
nonopts+=("$@")
|
nonopts+=("$@")
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
help|build|start|check|list|copy|restart|stop|revert|shell|upgrade|restore|backup|destroy|logs|post_start_hooks)
|
help|build|create|start|check|list|copy|restart|stop|revert|shell|upgrade|restore|backup|destroy|logs|post_start_hooks)
|
||||||
nonopts+=("$@")
|
nonopts+=("$@")
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
@ -135,7 +136,12 @@ function check_ready {
|
|||||||
echo "checking container $1"
|
echo "checking container $1"
|
||||||
|
|
||||||
case $1 in
|
case $1 in
|
||||||
nailgun) retry_checker "shell_container nailgun supervisorctl status nailgun | grep -q RUNNING" ;;
|
nailgun) if [ "${SYSTEMD:-false}" == "true" ]; then
|
||||||
|
retry_checker "shell_container nailgun systemctl is-active nailgun"
|
||||||
|
else
|
||||||
|
retry_checker "shell_container nailgun supervisorctl status nailgun | grep -q RUNNING"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
ostf) retry_checker "egrep -q ^[2-4][0-9]? < <(curl --connect-timeout 1 -s -w '%{http_code}' http://$ADMIN_IP:8777/ostf/not_found -o /dev/null)" ;;
|
ostf) retry_checker "egrep -q ^[2-4][0-9]? < <(curl --connect-timeout 1 -s -w '%{http_code}' http://$ADMIN_IP:8777/ostf/not_found -o /dev/null)" ;;
|
||||||
#NOTICE: Cobbler console tool does not comply unix conversation: 'cobbler profile find' always return 0 as exit code
|
#NOTICE: Cobbler console tool does not comply unix conversation: 'cobbler profile find' always return 0 as exit code
|
||||||
cobbler) retry_checker "shell_container cobbler ps waux | grep -q 'cobblerd -F' && pgrep dnsmasq"
|
cobbler) retry_checker "shell_container cobbler ps waux | grep -q 'cobblerd -F' && pgrep dnsmasq"
|
||||||
@ -228,6 +234,30 @@ function commit_container {
|
|||||||
image="$IMAGE_PREFIX/$1_$VERSION"
|
image="$IMAGE_PREFIX/$1_$VERSION"
|
||||||
${DOCKER} commit $container_name $image
|
${DOCKER} commit $container_name $image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function create_container() {
|
||||||
|
# wrapper for systemd unit
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "Must specify a container name" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$1" = "all" ]; then
|
||||||
|
for container in $CONTAINER_SEQUENCE; do
|
||||||
|
create_container $container
|
||||||
|
done
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
opts="${CONTAINER_OPTIONS[$1]} ${CONTAINER_VOLUMES[$1]}"
|
||||||
|
container_name="${CONTAINER_NAMES[$1]}"
|
||||||
|
image="$IMAGE_PREFIX/$1_$VERSION"
|
||||||
|
if ! container_created $container_name; then
|
||||||
|
pre_setup_hooks $1
|
||||||
|
${DOCKER} create $opts --privileged --name=$container_name $image
|
||||||
|
post_setup_hooks $1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
function start_container {
|
function start_container {
|
||||||
lock
|
lock
|
||||||
if [ -z "$1" ]; then
|
if [ -z "$1" ]; then
|
||||||
|
@ -47,6 +47,72 @@ describe manifest do
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
let(:params) { {
|
||||||
|
:containers => ['astute',
|
||||||
|
'cobbler',
|
||||||
|
'keystone',
|
||||||
|
'mcollective',
|
||||||
|
'nailgun',
|
||||||
|
'nginx',
|
||||||
|
'ostf',
|
||||||
|
'postgres',
|
||||||
|
'rabbitmq',
|
||||||
|
'rsync',
|
||||||
|
'rsyslog']
|
||||||
|
} }
|
||||||
|
|
||||||
|
context 'running on centos 6' do
|
||||||
|
let(:facts) do
|
||||||
|
Noop.centos_facts.merge({
|
||||||
|
:operatingsystemmajrelease => '6'
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
it 'configure containers supervisor' do
|
||||||
|
release = facts[:fuel_release]
|
||||||
|
|
||||||
|
should contain_class('docker::supervisor').with({
|
||||||
|
:release => release,
|
||||||
|
:require => "File[/etc/supervisord.d/#{release}]",
|
||||||
|
})
|
||||||
|
params[:containers].each do |container|
|
||||||
|
should contain_file("/etc/supervisord.d/#{release}/#{container}.conf").with({
|
||||||
|
:owner => 'root',
|
||||||
|
:group => 'root',
|
||||||
|
:mode => '0644'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end #it do
|
||||||
|
end #context
|
||||||
|
|
||||||
|
context 'running on centos 7' do
|
||||||
|
let(:facts) do
|
||||||
|
Noop.centos_facts.merge({
|
||||||
|
:operatingsystemmajrelease => '7'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'configure containers systemd' do
|
||||||
|
release = facts[:fuel_release]
|
||||||
|
|
||||||
|
should contain_class('docker::systemd').with({
|
||||||
|
:release => release,
|
||||||
|
:containers => params[:containers]
|
||||||
|
})
|
||||||
|
params[:containers].each do |container|
|
||||||
|
should contain_file("/usr/lib/systemd/system/docker-#{container}.service").with({
|
||||||
|
:owner => 'root',
|
||||||
|
:group => 'root',
|
||||||
|
:mode => '0644',
|
||||||
|
})
|
||||||
|
should contain_service("docker-#{container}").with({
|
||||||
|
:ensure => nil, # we shouldn't start container from puppet
|
||||||
|
:enable => 'true',
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end #it do
|
||||||
|
end #context
|
||||||
|
end #shared_examples
|
||||||
|
|
||||||
test_centos manifest
|
test_centos manifest
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user