Switch to using Nginx/uWSGI by default

This patch implements the use of uWSGI exclusively,
always with a web server acting as a reverse proxy.
It removes the option of using uWSGI with Apache
and mod_wsgi.

In the case of Keystone being used in a Federated
Service Provider configuration, it will use Apache
as the web server but for all other environments
it will use Nginx instead.

Change-Id: If6e95fc0d3f7d34780db1aed2b8cedca87499934
This commit is contained in:
Jesse Pretorius 2017-06-23 12:18:09 +01:00 committed by Jesse Pretorius (odyssey4me)
parent ce02e0a480
commit 84af640aa0
11 changed files with 66 additions and 63 deletions

View File

@ -172,17 +172,26 @@ keystone_service_adminurl: "{{ keystone_service_adminurl_v3 }}"
## Set this value to override the "public_endpoint" keystone.conf variable
#keystone_public_endpoint: "{{ keystone_service_publicuri }}"
# This is the web server that will handle all requests and will act as a
# reverse proxy to uWSGI. If internal TLS/SSL certificates are configured,
# they are implemented in this web server's configuration. Using a web server
# for endpoints is far better for scale and allows the use of additional
# modules to improve performance or security, leaving uWSGI to only have
# to be used for running the service.
#
# Note:
# The default is nginx, but apache will be used if Keystone is configured
# as a Federated Service provider.
# TODO (odyssey4me): Convert the SP implementation to use nginx instead
# so that we do not have to be concerned with multiple web servers.
#
keystone_web_server: "{{ (keystone_sp != {}) | ternary('apache', 'nginx') }}"
## Apache setup
keystone_apache_enabled: true
keystone_mod_wsgi_enabled: true
keystone_apache_log_level: info
keystone_apache_custom_log_format: combined
keystone_apache_servertokens: "Prod"
keystone_apache_serversignature: "Off"
keystone_wsgi_threads: 1
## Cap the maximun number of processes when a user value is unspecified.
keystone_wsgi_processes_max: 16
keystone_wsgi_processes: "{{ [[ansible_processor_vcpus|default(1), 1] | max * 2, keystone_wsgi_processes_max] | min }}"
## Apache MPM tunables
keystone_httpd_mpm_backend: event
@ -204,6 +213,10 @@ keystone_nginx_extra_conf:
- keepalive_timeout 70;
## uWSGI setup
keystone_wsgi_threads: 1
## Cap the maximun number of processes when a user value is unspecified.
keystone_wsgi_processes_max: 16
keystone_wsgi_processes: "{{ [[ansible_processor_vcpus|default(1), 1] | max * 2, keystone_wsgi_processes_max] | min }}"
keystone_wsgi_public_program_name: keystone-wsgi-public
keystone_wsgi_admin_program_name: keystone-wsgi-admin
keystone_wsgi_program_names:

View File

@ -15,7 +15,7 @@
- name: Restart web server
service:
name: "{{ (keystone_apache_enabled | bool) | ternary(keystone_system_service_name, 'nginx') }}"
name: "{{ (keystone_web_server == 'apache') | ternary(keystone_system_service_name, 'nginx') }}"
enabled: yes
state: restarted
daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}"
@ -47,8 +47,6 @@
retries: 5
delay: 2
with_items: "{{ keystone_wsgi_program_names }}"
when:
- not keystone_mod_wsgi_enabled | bool
listen: "Restart uWSGI"
# Note (odyssey4me):
@ -80,8 +78,6 @@
retries: 5
delay: 2
with_items: "{{ keystone_wsgi_program_names }}"
when:
- not keystone_mod_wsgi_enabled | bool
listen: "Restart uWSGI"
- name: Wait for uWSGI socket to be ready
@ -92,8 +88,6 @@
with_items:
- "{{ keystone_uwsgi_ports['keystone-wsgi-admin']['socket'] }}"
- "{{ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] }}"
when:
- not keystone_mod_wsgi_enabled | bool
register: _wait_check
until: _wait_check | success
retries: 5

View File

@ -0,0 +1,10 @@
---
upgrade:
- Keystone now uses uWSGI exclusively (instead of Apache with mod_wsgi)
and has the web server acting as a reverse proxy. The default web
server is now set to Nginx instead of Apache, but Apache will
automatically used if federation is configured.
deprecations:
- The variables ``keystone_apache_enabled`` and ``keystone_mod_wsgi_enabled``
have been removed and replaced with a single variable ``keystone_web_server``
to optionally set the web server used for keystone.

View File

@ -49,7 +49,7 @@
- name: "shib2"
state: "{{ ( keystone_sp != {} ) | ternary('present', 'absent') }}"
- name: "proxy_http"
state: "{{ (keystone_mod_wsgi_enabled | bool) | ternary('absent', 'present') }}"
state: "present"
when:
- ansible_pkg_mgr == 'apt'
notify:
@ -61,7 +61,7 @@
lineinfile:
dest: '/etc/httpd/conf.modules.d/00-proxy.conf'
line: 'LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so'
state: "{{ (keystone_mod_wsgi_enabled | bool) | ternary('absent', 'present') }}"
state: "present"
when:
- ansible_pkg_mgr == 'yum'
notify:

View File

@ -49,6 +49,22 @@
- ansible_pkg_mgr == 'yum'
- keystone_sp != {}
# If the web server being removed was never installed, this task will fail when trying
# to stop/disable it. The task is therefore set to never fail.
- name: Ensure other web server is not running/enabled
service:
name: "{{ (keystone_web_server == 'nginx') | ternary(keystone_system_service_name, 'nginx') }}"
enabled: no
state: stopped
daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}"
failed_when: false
- name: Remove other web server distro packages and mod_wsgi
package:
name: "{{ ((keystone_web_server == 'nginx') | ternary(keystone_apache_distro_packages, keystone_nginx_distro_packages)) + keystone_mod_wsgi_distro_packages }}"
state: absent
autoremove: "{{ (ansible_pkg_mgr == 'apt') | ternary('yes', omit) }}"
- name: Install distro packages
package:
name: "{{ keystone_package_list }}"

View File

@ -21,15 +21,6 @@
tags:
- always
- name: Fail if incompatible configuration detected
fail:
msg: "keystone_apache_enabled must be True when keystone_mod_wsgi_enabled."
when:
- not keystone_apache_enabled | bool
- keystone_mod_wsgi_enabled | bool
tags:
- always
- name: Gather variables for each operating system
include_vars: "{{ item }}"
with_first_found:
@ -110,13 +101,11 @@
tags:
- keystone-config
- include: "keystone_{{ (keystone_apache_enabled | bool) | ternary('apache', 'nginx') }}.yml"
- include: "keystone_{{ keystone_web_server }}.yml"
tags:
- keystone-config
- include: keystone_uwsgi.yml
static: no
when: not keystone_mod_wsgi_enabled | bool
tags:
- keystone-config

View File

@ -2,14 +2,6 @@
Listen {{ keystone_service_port }}
<VirtualHost *:{{ keystone_service_port }}>
{% if keystone_mod_wsgi_enabled | bool -%}
WSGIDaemonProcess keystone-service user={{ keystone_system_user_name }} group={{ keystone_system_group_name }} processes={{ keystone_wsgi_processes }} threads={{ keystone_wsgi_threads }} display-name=%{GROUP} python-path={{ keystone_bin | dirname }}/lib/python2.7/site-packages
WSGIProcessGroup keystone-service
WSGIScriptAlias / /var/www/cgi-bin/keystone/main
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
WSGIScriptReloading Off
<IfVersion >= 2.4>
ErrorLogFormat "%{cu}t %M"
@ -66,21 +58,13 @@ Listen {{ keystone_service_port }}
Order allow,deny
allow from all
</Directory>
{% else %}
ProxyPass / uwsgi://127.0.0.1:{{ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] }}/
{% endif %}
</VirtualHost>
Listen {{ keystone_admin_port }}
<VirtualHost *:{{ keystone_admin_port }}>
{% if keystone_mod_wsgi_enabled | bool -%}
WSGIDaemonProcess keystone-admin user={{ keystone_system_user_name }} group={{ keystone_system_group_name }} processes={{ keystone_wsgi_processes }} threads={{ keystone_wsgi_threads }} display-name=%{GROUP} python-path={{ keystone_bin | dirname }}/lib/python2.7/site-packages
WSGIProcessGroup keystone-admin
WSGIScriptAlias / /var/www/cgi-bin/keystone/admin
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
WSGIScriptReloading Off
<IfVersion >= 2.4>
ErrorLogFormat "%{cu}t %M"
@ -111,11 +95,10 @@ Listen {{ keystone_admin_port }}
Order allow,deny
allow from all
</Directory>
{% else -%}
ProxyPass / uwsgi://127.0.0.1:{{ keystone_uwsgi_ports['keystone-wsgi-admin']["socket"] }}/
{% endif %}
</VirtualHost>
{% if not keystone_mod_wsgi_enabled | bool -%}
ProxyPass /identity uwsgi://127.0.0.1:{{ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] }}/
ProxyPass /identity_admin uwsgi://127.0.0.1:{{ keystone_uwsgi_ports['keystone-wsgi-admin']['socket'] }}/
{% endif %}

View File

@ -120,7 +120,7 @@ deps =
{[testenv:ansible]deps}
setenv =
{[testenv]setenv}
ANSIBLE_PARAMETERS=-vvv -e keystone_mod_wsgi_enabled=False
ANSIBLE_PARAMETERS=-vvv -e keystone_web_server=apache
commands =
bash -c "{toxinidir}/tests/tests-repo-clone.sh"
bash -c "{toxinidir}/tests/common/test-ansible-functional.sh"
@ -131,7 +131,6 @@ deps =
{[testenv:ansible]deps}
setenv =
{[testenv]setenv}
ANSIBLE_PARAMETERS=-vvv -e keystone_apache_enabled=False -e keystone_mod_wsgi_enabled=False
commands =
bash -c "{toxinidir}/tests/tests-repo-clone.sh"
bash -c "{toxinidir}/tests/common/test-ansible-functional.sh"

View File

@ -20,7 +20,7 @@
#
keystone_package_list: |-
{% set packages = keystone_distro_packages %}
{% if keystone_apache_enabled | bool %}
{% if keystone_web_server == 'apache' %}
{% set _ = packages.extend(keystone_apache_distro_packages) %}
{% if keystone_idp != {} %}
{% set _ = packages.extend(keystone_idp_distro_packages) %}
@ -31,11 +31,6 @@ keystone_package_list: |-
{% else %}
{% set _ = packages.extend(keystone_nginx_distro_packages) %}
{% endif %}
{% if keystone_mod_wsgi_enabled | bool %}
{% set _ = packages.extend(keystone_mod_wsgi_distro_packages) %}
{% else %}
{% set _ = packages.extend(keystone_mod_proxy_uwsgi_distro_packages) %}
{% endif %}
{% if keystone_developer_mode | bool %}
{% set _ = packages.extend(keystone_developer_mode_distro_packages) %}
{% endif %}

View File

@ -33,13 +33,15 @@ keystone_apache_distro_packages:
- httpd
- httpd-tools
- mod_ssl
- mod_proxy_uwsgi
# TODO(odyssey4me):
# We can remove this in R because we only need this to
# handle upgrades from O->P in order to remove the
# package when switching to the new configuration.
keystone_mod_wsgi_distro_packages:
- mod_wsgi
keystone_mod_proxy_uwsgi_distro_packages:
- mod_proxy_uwsgi
keystone_nginx_distro_packages:
- nginx

View File

@ -32,13 +32,15 @@ keystone_distro_packages:
keystone_apache_distro_packages:
- apache2
- apache2-utils
- libapache2-mod-proxy-uwsgi
# TODO(odyssey4me):
# We can remove this in R because we only need this to
# handle upgrades from O->P in order to remove the
# package when switching to the new configuration.
keystone_mod_wsgi_distro_packages:
- libapache2-mod-wsgi
keystone_mod_proxy_uwsgi_distro_packages:
- libapache2-mod-proxy-uwsgi
keystone_nginx_distro_packages:
- nginx-full