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',
|
||||
$admin_ipaddress = $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
||||
$docker_engine = 'native',
|
||||
$use_systemd = false,
|
||||
$release,
|
||||
$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_"
|
||||
fi
|
||||
|
||||
SYSTEMD="<%= @use_systemd.to_s %>"
|
||||
|
||||
IMAGE_PREFIX="fuel"
|
||||
# busybox image for storage containers
|
||||
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'])
|
||||
$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::host'] ->
|
||||
Class['nailgun::client'] ->
|
||||
Class['docker::dockerctl'] ->
|
||||
Class['docker'] ->
|
||||
Class['openstack::logrotate'] ->
|
||||
Class['nailgun::supervisor'] ->
|
||||
Class['monit'] ->
|
||||
Class['nailgun::bootstrap_cli']
|
||||
|
||||
@ -56,10 +66,11 @@ class { 'openstack::clocksync':
|
||||
}
|
||||
|
||||
class { 'docker::dockerctl':
|
||||
use_systemd => $use_systemd,
|
||||
release => $::fuel_release,
|
||||
production => $production,
|
||||
admin_ipaddress => $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
||||
docker_engine => 'native',
|
||||
docker_engine => 'native',
|
||||
}
|
||||
|
||||
class { "docker":
|
||||
@ -81,13 +92,6 @@ class { 'nailgun::client':
|
||||
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':
|
||||
settings => $::fuel_settings['BOOTSTRAP'],
|
||||
direct_repo_addresses => [ $::fuel_settings['ADMIN_NETWORK']['ipaddress'] ],
|
||||
@ -99,27 +103,42 @@ class { 'osnailyfacter::ssh':
|
||||
password_auth => 'yes',
|
||||
}
|
||||
|
||||
file { '/etc/supervisord.d':
|
||||
ensure => directory,
|
||||
}
|
||||
|
||||
class { 'docker::supervisor':
|
||||
release => $::fuel_release,
|
||||
require => File["/etc/supervisord.d/${::fuel_release}"],
|
||||
}
|
||||
|
||||
file { "/etc/supervisord.d/${::fuel_release}":
|
||||
ensure => directory,
|
||||
require => File['/etc/supervisord.d'],
|
||||
owner => root,
|
||||
group => root,
|
||||
}
|
||||
|
||||
file { '/etc/supervisord.d/current':
|
||||
ensure => link,
|
||||
target => "/etc/supervisord.d/${::fuel_release}",
|
||||
require => File["/etc/supervisord.d/${::fuel_release}"],
|
||||
replace => true,
|
||||
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':
|
||||
ensure => directory,
|
||||
}
|
||||
class { 'docker::supervisor':
|
||||
release => $::fuel_release,
|
||||
require => File["/etc/supervisord.d/${::fuel_release}"],
|
||||
}
|
||||
file { "/etc/supervisord.d/${::fuel_release}":
|
||||
ensure => directory,
|
||||
require => File['/etc/supervisord.d'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
}
|
||||
file { '/etc/supervisord.d/current':
|
||||
ensure => link,
|
||||
target => "/etc/supervisord.d/${::fuel_release}",
|
||||
require => File["/etc/supervisord.d/${::fuel_release}"],
|
||||
replace => true,
|
||||
}
|
||||
Class['openstack::logrotate'] ->
|
||||
Class['docker::supervisor'] ->
|
||||
Exec['sync_deployment_tasks']
|
||||
}
|
||||
|
||||
exec {'sync_deployment_tasks':
|
||||
@ -127,5 +146,4 @@ exec {'sync_deployment_tasks':
|
||||
path => '/usr/bin',
|
||||
tries => 12,
|
||||
try_sleep => 10,
|
||||
require => Class['nailgun::supervisor']
|
||||
}
|
||||
|
@ -68,6 +68,8 @@ case "$1" in
|
||||
else
|
||||
check_ready $container
|
||||
fi ;;
|
||||
create)
|
||||
create_container $container;;
|
||||
start)
|
||||
if [[ "$container" == 'all' ]]; then
|
||||
for service in $container_seq; do
|
||||
|
@ -17,6 +17,8 @@ if [ -z "$VERSION" ]; then
|
||||
VERSION="_VERSION_"
|
||||
fi
|
||||
|
||||
SYSTEMD="false"
|
||||
|
||||
IMAGE_PREFIX="fuel"
|
||||
# busybox image for storage containers
|
||||
BUSYBOX_IMAGE="busybox.tar.gz"
|
||||
|
@ -26,6 +26,7 @@ function show_usage {
|
||||
echo "Available commands:"
|
||||
echo " help: show this message"
|
||||
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 " start: start all Docker containers"
|
||||
echo " restart: restart one or more Docker containers"
|
||||
@ -57,7 +58,7 @@ function parse_options {
|
||||
nonopts+=("$@")
|
||||
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+=("$@")
|
||||
return
|
||||
;;
|
||||
@ -135,7 +136,12 @@ function check_ready {
|
||||
echo "checking container $1"
|
||||
|
||||
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)" ;;
|
||||
#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"
|
||||
@ -228,6 +234,30 @@ function commit_container {
|
||||
image="$IMAGE_PREFIX/$1_$VERSION"
|
||||
${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 {
|
||||
lock
|
||||
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
|
||||
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
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user