Containerized Software: Automatiseren

Andere delen in de serie:

In een vorige publicatie hebben we een Spring Boot-omgeving opgezet met Docker. Een probleem hierbij is dat we de Docker-hosts nog moeten configureren. Dit kunnen we natuurlijk met de hand doen, maar het is makkelijker en minder foutgevoelig als we dit doen met een automatiseringstool als Ansible.

Ansible gebruiken om Docker-hosts op te zetten

Om Ansible te installeren, voeren we yum -y install epel-release en yum -y install ansible uit (meer informatie is hier te vinden).

Om een Docker-omgeving te installeren en configureren, maken we de volgende playbooks:

  • docker_common – definieert de gebruikte variabelen en bevat bestanden en templates.
  • docker_host – zet een Docker-host op (installeert Docker en noodzakelijke python-bibliotheken zodat we Ansible’s Docker-module kunnen gebruiken).
  • docker_registry – stelt een Docker lokaal private registry in (installeert Docker en de noodzakelijke python-bibliotheken zodat we de Docker-module van Ansible kunnen gebruiken en maakt een Docker-registry container aan).
  • docker_spring_boot_example – maakt en voert de Spring Boot-container uit.

De directorystructuur voor de playbooks ziet er als volgt uit

/etc/ansible
    /roles
        /docker_common
            /files
                /certificates
                    /docker
                        /ca
                            ca.pem
                            ca-key.pem
                        /client
                            cert.pem
                            key.pem
                        /server
                            server-cert.pem
                            server-key.pem
                    /registry
                        regsitry.crt
                        registry.key
                    generate_certificates.sh
            /templates
                config_yml.j2 (configuration file for the registry)
                docker_service.j2 (systemd configuration file for docker)
            /vars
                main.yml
        /docker_host
            /tasks
                main.yml
        /docker_registry
            /tasks
                main.yml
        /docker_spring_boot_example
            /tasks
                main.yml
            /vars
                main.yml
    ansible.cfg
    docker_host.yml
    docker_registry.yml
    docker_spring_boot_example.yml
    hosts

De certificaten die nodig zijn voor het lokale private registry en de Docker-client-server-communicatie worden gegenereerd met behulp van het script generate_certificates.sh

    #!/bin/sh
     
    CERTIFICATE_ROOT_DIRECTORY="/etc/ansible/roles/docker_repository/files/certificates"
     
    REGISTRY_CERTIFICATE_DIRECTORY="${CERTIFICATE_ROOT_DIRECTORY}/registry"
    REGISTRY_SUBJECT="/C=NL/ST=Middleware/L=Snippets/O=Middleware Snippets/OU=Blogging/CN=docker.machine.com"
     
    CLIENT_SERVER_PASSWORD="password"
    CLIENT_SERVER_SUBJECT="/C=NL/ST=Middleware/L=Snippets/O=Middleware Snippets/OU=Blogging/CN=*.machine.com"
    CLIENT_SERVER_DOCKER_DIRECTORY="${CERTIFICATE_ROOT_DIRECTORY}/docker"
    CLIENT_SERVER_CA_DIRECTORY="${CLIENT_SERVER_DOCKER_DIRECTORY}/ca"
    CLIENT_SERVER_CLIENT_DIRECTORY="${CLIENT_SERVER_DOCKER_DIRECTORY}/client"
    CLIENT_SERVER_SERVER_DIRECTORY="${CLIENT_SERVER_DOCKER_DIRECTORY}/server"
     
    echo 'REMOVING OLD CERTIFICATES'
    rm -rf ${REGISTRY_CERTIFICATE_DIRECTORY} ${CLIENT_SERVER_DOCKER_DIRECTORY}
    mkdir -p ${REGISTRY_CERTIFICATE_DIRECTORY}
    mkdir -p ${CLIENT_SERVER_DOCKER_DIRECTORY}/{ca,client,server}
     
    echo 'GENERATING REGISTRY CERTIFCATES'
    openssl req -new -x509 -days 365 -sha256 -newkey rsa:2048 -nodes -keyout ${REGISTRY_CERTIFICATE_DIRECTORY}/registry.key -out ${REGISTRY_CERTIFICATE_DIRECTORY}/registry.crt -subj "${REGISTRY_SUBJECT}"
     
    #echo 'GENERATING CLIENT SERVER CA CERTIFICATES'
    openssl genrsa -aes256 -passout pass:${CLIENT_SERVER_PASSWORD} -out ${CLIENT_SERVER_CA_DIRECTORY}/ca-key.pem 2048
    openssl req -new -x509 -days 365 -passin pass:${CLIENT_SERVER_PASSWORD} -key ${CLIENT_SERVER_CA_DIRECTORY}/ca-key.pem -sha256 -out ${CLIENT_SERVER_CA_DIRECTORY}/ca.pem -subj "${CLIENT_SERVER_SUBJECT}"
     
    #echo 'GENERATING CLIENT SERVER SERVER CERTIFICATES'
    openssl genrsa -out ${CLIENT_SERVER_SERVER_DIRECTORY}/server-key.pem 2048
    openssl req -new -key ${CLIENT_SERVER_SERVER_DIRECTORY}/server-key.pem -sha256 -out ${CLIENT_SERVER_SERVER_DIRECTORY}/server.csr -subj "${CLIENT_SERVER_SUBJECT}"
    openssl x509 -req -days 365 -sha256 -passin pass:${CLIENT_SERVER_PASSWORD} -in ${CLIENT_SERVER_SERVER_DIRECTORY}/server.csr -CA ${CLIENT_SERVER_CA_DIRECTORY}/ca.pem -CAkey ${CLIENT_SERVER_CA_DIRECTORY}/ca-key.pem -CAcreateserial -out ${CLIENT_SERVER_SERVER_DIRECTORY}/server-cert.pem
     
    echo 'GENERATING CLIENT SERVER CLIENT CERTIFICATES'
    openssl genrsa -out ${CLIENT_SERVER_CLIENT_DIRECTORY}/key.pem 2048
    openssl req -new -key ${CLIENT_SERVER_CLIENT_DIRECTORY}/key.pem -out ${CLIENT_SERVER_CLIENT_DIRECTORY}/client.csr -subj "/CN=client"
    echo extendedKeyUsage = clientAuth > ${CLIENT_SERVER_CLIENT_DIRECTORY}/extfile.cnf
    openssl x509 -req -days 365 -sha256 -passin pass:${CLIENT_SERVER_PASSWORD} -in ${CLIENT_SERVER_CLIENT_DIRECTORY}/client.csr -CA ${CLIENT_SERVER_CA_DIRECTORY}/ca.pem -CAkey ${CLIENT_SERVER_CA_DIRECTORY}/ca-key.pem -CAcreateserial -out ${CLIENT_SERVER_CLIENT_DIRECTORY}/cert.pem -extfile ${CLIENT_SERVER_CLIENT_DIRECTORY}/extfile.cnf
     
    echo 'CHANGING PERMISSIONS'
    chmod 0400 ${REGISTRY_CERTIFICATE_DIRECTORY}/registry.key ${CLIENT_SERVER_CA_DIRECTORY}/ca-key.pem ${CLIENT_SERVER_SERVER_DIRECTORY}/server-key.pem ${CLIENT_SERVER_CLIENT_DIRECTORY}/key.pem
    chmod 0444 ${REGISTRY_CERTIFICATE_DIRECTORY}/registry.crt ${CLIENT_SERVER_CA_DIRECTORY}/ca.pem ${CLIENT_SERVER_SERVER_DIRECTORY}/server-cert.pem ${CLIENT_SERVER_CLIENT_DIRECTORY}/cert.pem
     
    echo 'REMOVING CERTIFICATE SIGNING REQUESTS'
    rm -f ${CLIENT_SERVER_SERVER_DIRECTORY}/server.csr ${CLIENT_SERVER_CLIENT_DIRECTORY}/client.csr

Merk op dat om de certificaten te vernieuwen, het script generate_certificates.sh en de Ansible-playbooks opnieuw worden uitgevoerd en het lokale private registry en de Docker-daemons opnieuw worden gestart.

De templates die worden gebruikt in de rol docker_common hebben de volgende inhoud

# config_yml.j2
version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    layerinfo: inmemory
  filesystem:
    rootdirectory: {{ registry_storage_filesystem_root_dir }}
http:
  addr: {{ registry_host }}:{{ registry_port }}
  tls:
    certificate: {{ registry_http_tls_certificate }}
    key: {{ registry_http_tls_key }}
#auth:
#  htpasswd:
#    realm: {{ registry_auth_htpass_realm }}
#    path: {{ registry_auth_htpass_path }}
 
# docker_service.j2
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket
 
[Service]
Type=notify
#ExecStart=/usr/bin/docker daemon -H fd://
ExecStart=/usr/bin/docker -d --tlsverify --tlscacert={{ docker_certs_dir }}/ca/ca.pem --tlscert={{ docker_certs_dir }}/server/server-cert.pem --tlskey={{ docker_certs_dir }}/server/server-key.pem -H={{ docker_host }}:{{ docker_port }}
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
 
[Install]
WantedBy=multi-user.target

De gebruikte variabelen worden gedefinieerd in het bestand docker_common/vars/main.yml

# /etc/ansible/roles/docker_common/vars/main.yml
 
os_docker_user:                       "root"
os_docker_group:                      "root"
 
root_dir:                             "/opt"
 
registry_base_dir:                    "{{ root_dir }}/registry"
registry_auth_dir:                    "{{ registry_base_dir }}/auth"
registry_certs_dir:                   "{{ registry_base_dir }}/certs"
registry_conf_dir:                    "{{ registry_base_dir }}/configuration"
registry_conf_file:                   "{{ registry_conf_dir }}/config.yml"
registry_data_dir:                    "{{ registry_base_dir }}/data"
 
registry_host:                        "docker.machine.com"
registry_port:                        5000
 
registry_username:                    "docker"
registry_password:                    "password"
 
registry_image_name:                  "registry:2"
 
registry_auth_htpass_dir:             "/auth"
registry_auth_htpass_path:            "{{ registry_auth_htpass_dir }}/htpasswd"
registry_auth_htpass_realm:           "basic-realm"
registry_config_yaml_dir:             "/etc/docker/registry"
registry_http_tls_certs_dir:          "/certs"
registry_http_tls_certificate:        "{{ registry_http_tls_certs_dir }}/registry.crt"
registry_http_tls_key:                "{{ registry_http_tls_certs_dir }}/registry.key"
registry_storage_filesystem_root_dir: "/var/lib/registry"
 
docker_base_dir:                      "{{ root_dir }}/docker"
docker_certs_dir:                     "{{ docker_base_dir }}/certs"
docker_custom_containers_dir:         "{{ docker_base_dir }}/custom_containers"
docker_registry_certs_dir:            "/etc/docker/certs.d/{{ registry_host }}:{{ registry_port }}"
docker_home:                          "/root/.docker"
docker_service_file:                  "/usr/lib/systemd/system/docker.service"
 
docker_host:                          "{{ ansible_fqdn }}"
docker_port:                          2376
 
docker_client_connect_string:         "--tlsverify --tlscacert={{ docker_certs_dir }}/ca/ca.pem --tlscert={{ docker_certs_dir }}/client/cert.pem --tlskey={{ docker_certs_dir }}/client/key.pem -H={{ docker_host }}:{{ docker_port }}"

Merk op dat we als directorystructuur voor Docker het volgende krijgen

/${root_dir}
    /${docker_base_dir}
        /${docker_certs_dir} (contains the certificates for client-server communication)
        /${docker_custom_containers_dir}
    /${registry_base_dir}
        /${registry_auth_dir}
        /${registry_certs_dir} (contains the certificates for the local private registry)
        /${registry_conf_dir}
        /${registry_data_dir}
            /docker/registry/v2 (generated by Docker when images are pushed to the registry)
                /blobs
                /repositories
                    /centos
                    /httpd
                    /springbootexample
/${docker_home}
/${docker_registry_certs_dir}

Registry

Om een lokaal private registry op te zetten, kunnen we het volgende gebruiken

# /etc/ansible/roles/docker_registry/tasks/main.yml
 
- name: install extra packages for enterprise linux repository configuration
  yum:
    name=epel-release
    state=present
 
# needed to install python libraries (pip)
- name: install python package manager (pip)
  yum:
    name={{ item }}
    state=present
  with_items:
    - libffi-devel
    - python-devel
    - python-pip
 
# needed for the ansible htpasswd module
- name: install python libraries
  pip:
    name={{ item }}
    state=present
  with_items:
    - bcrypt
    - passlib
 
# needed for the ansible docker module
# the ansible 1.9.2 docker module works with the docker-py version 1.2.3 (not the latest 1.3.1)
- name: install docker-py python library
  pip:
    name=docker-py
    version=1.2.3
    state=present
    
- name: create root directory
  file:
    path="{{ root_dir }}"
    state=directory
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0755
 
- name: create directories
  file:
    path={{ item }}
    state=directory
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0755
  with_items:
    - "{{ registry_base_dir }}"
    - "{{ registry_auth_dir }}"
    - "{{ registry_certs_dir }}"
    - "{{ registry_conf_dir }}"
    - "{{ registry_data_dir }}"
    - "{{ docker_base_dir }}"
    - "{{ docker_certs_dir }}"
    - "{{ docker_custom_containers_dir }}"
    - "{{ docker_registry_certs_dir }}"
    - "{{ docker_home }}"
    
- name: copy docker certificates
  copy:
    src=roles/docker_common/files/certificates/docker/
    dest="{{ docker_certs_dir }}"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0400
    
- name: copy client certificates
  copy:
    src={{ item }}
    dest="{{ docker_home }}"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0400
  with_items:
    - "roles/docker_common/files/certificates/docker/ca/ca.pem"
    - "roles/docker_common/files/certificates/docker/client/cert.pem"
    - "roles/docker_common/files/certificates/docker/client/key.pem"
 
- name: copy registry certificates
  copy:
    src=roles/docker_common/files/certificates/registry/
    dest="{{ registry_certs_dir }}"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0400
 
- name: copy registry certificate
  copy:
    src=roles/docker_common/files/certificates/registry/registry.crt
    dest="{{ docker_registry_certs_dir }}/ca.crt"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0400
 
# only bcrypt format passwords are supported by docker
- name: generate user file for basic authentication
  htpasswd: 
    path="{{ registry_auth_dir }}/htpasswd"
    crypt_scheme=bcrypt
    name="{{ registry_username }}"
    password="{{ registry_password }}"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0640
    
- name: create registry configuration file
  template:
    src=roles/docker_common/templates/config_yml.j2
    dest="{{ registry_conf_file }}"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0640
    
- name: install docker
  shell: /usr/bin/curl -sSL https://get.docker.com/ | sh
    creates="/usr/bin/docker"
  register: docker_installed
  
- name: enable and start docker service
  service:
    name=docker
    state=started
    enabled=yes
  when: docker_installed|success
  register: docker_started
  
- name: pull registry image from docker hub
  shell: /usr/bin/docker pull "{{ registry_image_name }}"
  when: docker_started|success
  register: registry_image_pulled
  changed_when: registry_image_pulled.rc != 0
  
- name: set-up docker registry
  docker:
    name: registry
    image: "{{ registry_image_name }}"
    net: host
    state: started
    restart_policy: always
    ports:
    - "{{ registry_port }}:{{ registry_port }}"
    volumes:
    - "{{ registry_auth_dir }}:{{ registry_auth_htpass_dir }}"
    - "{{ registry_certs_dir }}:{{ registry_http_tls_certs_dir }}"
    - "{{ registry_conf_dir }}:{{ registry_config_yaml_dir }}"
    - "{{ registry_data_dir }}:{{ registry_storage_filesystem_root_dir }}"
  when: docker_started|success and registry_image_pulled|success

Merk op dat we een specifieke versie van docker-py gebruiken.

Host

Om Docker-hosts op te zetten, kunnen we het volgende gebruiken

# /etc/ansible/roles/docker_host/tasks/main.yml
 
- name: install extra packages for enterprise linux repository configuration
  yum:
    name=epel-release
    state=present
 
# needed to install python libraries (pip: https://pip.pypa.io/en/stable/)
- name: install python package manager (pip)
  yum:
    name={{ item }}
    state=present
  with_items:
    - libffi-devel
    - python-devel
    - python-pip
    
#- name: upgrade python package manager
#  shell: /usr/bin/pip install --upgrade pip
 
# needed for the ansible htpasswd module (http://docs.ansible.com/ansible/htpasswd_module.html)    
- name: install python libraries
  pip:
    name={{ item }}
    state=present
  with_items:
    - bcrypt
    - passlib
 
# needed for the ansible docker module (http://docs.ansible.com/ansible/docker_module.html)
# the ansible 1.9.2 docker module works with the docker-py version 1.2.3 (not 1.3.1)
- name: install docker-py python library
  pip:
    name=docker-py
    version=1.2.3
    state=present
    
- name: create root directory
  file:
    path="{{ root_dir }}"
    state=directory
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0755
 
- name: create directories
  file:
    path={{ item }}
    state=directory
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0755
  with_items:
    - "{{ docker_certs_dir }}"
    - "{{ docker_registry_certs_dir }}"
    
- name: copy docker certificates
  copy:
    src=roles/docker_common/files/certificates/docker/
    dest="{{ docker_certs_dir }}"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0400
    
- name: copy registry certificate
  copy:
    src=roles/docker_common/files/certificates/registry/registry.crt
    dest="{{ docker_registry_certs_dir }}/ca.crt"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0400
 
- name: install docker
  shell: /usr/bin/curl -sSL https://get.docker.com/ | sh
    creates="/usr/bin/docker"
  register: docker_installed
 
- name: edit docker service file
  template:
    src=roles/docker_common/templates/docker_service.j2
    dest="{{ docker_service_file }}"
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0640
  when: docker_installed|success
  
- name: enable and start docker service
  service:
    name=docker
    state=started
    enabled=yes
  when: docker_installed|success
  register: docker_started

Spring Boot

Om een Docker-container voor de Spring Boot applicatie te maken en uit te voeren, kunnen we het volgende gebruiken

# /etc/ansible/roles/docker_spring_boot_example/tasks/main.yml
 
- name: pull spring boot image from local private registry
  shell: /usr/bin/docker {{ docker_client_connect_string }} pull {{ registry_host }}:{{ registry_port }}/{{ docker_image_name }}:{{ docker_image_version }}
  register: spring_boot_image_pulled
  changed_when: spring_boot_image_pulled.rc != 0
  
- name: create volume directories
  file:
    path="{{ item }}"
    state=directory
    owner="{{ os_docker_user }}"
    group="{{ os_docker_group }}"
    mode=0755
  with_items:
    - "{{ spring_boot_volume_temp }}"
  when: spring_boot_image_pulled|success
  
- name: create spring boot container
  docker:
    name: "{{ docker_container_name }}"
    image: "{{ registry_host }}:{{ registry_port }}/{{ docker_image_name }}:{{ docker_image_version }}"
    net: host
    state: started
    docker_url: "https://{{ docker_host }}:{{ docker_port }}"
    use_tls: encrypt
    tls_ca_cert: "{{ docker_certs_dir }}/ca/ca.pem"
    tls_client_cert: "{{ docker_certs_dir }}/client/cert.pem"
    tls_client_key: "{{ docker_certs_dir }}/client/key.pem"
    tls_hostname: "{{ docker_host }}"
    ports:
    - "{{ spring_boot_server_port }}:{{ spring_boot_server_port }}"
    - "{{ spring_boot_jmx_port }}:{{ spring_boot_jmx_port }}"
    volumes:
    - "{{ spring_boot_volume_temp }}:{{ spring_boot_volume_temp }}"
    registry: "https://{{ registry_host }}:{{ registry_port }}"
  when: spring_boot_image_pulled|success

Ansible inventory

Ansible werkt tegelijkertijd tegen meerdere systemen in de infrastructuur. Het doet dit door delen van systemen te selecteren die worden vermeld in het inventory-bestand van Ansible, dat standaard wordt opgeslagen op de locatie /etc/ansible/hosts, bijvoorbeeld

[docker_registry]
docker.machine.com
 
[docker_host]
springboot1.machine.com
springboot2.machine.com
 
[spring_boot_example]
springboot1.machine.com
springboot2.machine.com

Met de inventory op zijn plaats, kunnen we de playbooks uitvoeren.

Om dingen eenvoudig maken (maar niet eenvoudiger) kunnen we ook Docker vergeten, en gewoon Ansible gebruiken om een Spring Boot-omgeving op te zetten.

Ansible gebruiken om een Spring Boot-omgeving op te zetten

Om dingen gemakkelijker te maken, waarom zouden we de omgeving niet inrichten zonder Docker. Met Spring Boot hoeven we alleen Java Virtual Machines te starten, wat kan worden gedaan door het gebruik van bijvoorbeeld systemd.

Om de omgeving te installeren en configureren, kunnen we denken aan de volgende playbooks

  • spring_boot_common – maakt de spring boot runtime directory-structuur, kopieert de benodigde spring boot modules, en installeert de Java Virtual Machine.
  • spring_boot_config_host – configureert de (Linux) hosts.
  • spring_boot_example – kopieert het jar-bestand van de applicatie en maakt en start een systemd-service voor de applicatie.
  • spring_boot_repository – definieert variabelen, en bevat bestanden en templates.

Om de benodigde Spring Boot-runtime-componenten in te stellen, kunnen we het volgende gebruiken

# /etc/ansible/roles/spring_boot_common/tasks/main.yml
    
- name: create homes
  file:
    path={{ item }}
    state=directory
    owner={{ java_user }}
    group={{ java_group }}
    mode=0755
  with_items:
    - "{{ pivotal_home }}"
    - "{{ oracle_home }}"
    - "{{ scripts_home }}"
    - "{{ java_home }}"
    - "{{ modules_home }}"
    - "{{ applications_home }}"
 
- name: copy spring boot modules
  copy:
    src=roles/spring_boot_repository/files/spring_boot_modules/
    dest={{ modules_home }}
    owner={{ java_user }}
    group={{ java_group }}
    mode=0644
    
- name: install java virtual machine
  shell: /bin/su - "{{ java_user }}" -c "/bin/tar xzf {{ jvm_installer }} -C {{ oracle_home }}"
    creates="{{ java_executable }}"
  register: jvm_installed
  
- name: set entropy gathering device
  replace:
    dest="{{ java_security }}"
    regexp='^securerandom\.source=file:/dev/random'
    replace="securerandom.source={{ secure_random_source }}"
  when: jvm_installed|success

Om onze applicatie op te zetten, kunnen we het volgende gebruiken

# /etc/ansible/roles/spring_boot_example/tasks/main.yml
 
- name: create application homes
  file:
    path={{ item }}
    state=directory
    owner={{ java_user }}
    group={{ java_group }}
    mode=0755
  with_items:
    - "{{ application_home }}"
    - "{{ application_log_home }}"
    
- name: copy spring boot application
  copy:
    src=roles/spring_boot_example/files/{{ application_name }}.jar
    dest={{ application_home }}
    owner={{ java_user }}
    group={{ java_group }}
    mode=0644
    
- name: create script
  template:
    src=roles/spring_boot_example/templates/{{ application_name }}_sh.j2 
    dest="{{ exec_start_service_script }}"
    owner={{ java_user }}
    group={{ java_group }}
    mode=0744
  when: ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7'
    
- name: create systemd script
  template:
    src=roles/spring_boot_example/templates/{{ application_name }}_service.j2 
    dest="{{ systemd_service_script }}"
    owner='root'
    group='root'
    mode=0644
  when: ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7'
 
- name: enable and start application service
  service:
    name={{ application_name }}
    state=started
    enabled=yes
  register: application_started

waarin we gebruik gemaakt hebben van de volgende templates

# spring_boot_example_sh.j2
#!/bin/sh
 
JAVA_HOME="{{ java_home }}"
 
SERVER_MEM_ARGS="{{ server_mem_args }}"
THROUGHPUT_GARBAGE_COLLECTOR_ARGS="{{ throughput_garbage_collector_args }}"
PAUSETIME_GARBAGE_COLLECTOR_ARGS="{{ pausetime_garbage_collector_args }}"
MONITORING_ARGS="{{ monitoring_args }}"
SPRING_BOOT_ARGS="{{ spring_boot_args }}"
 
USER_MEM_ARGS="${SERVER_MEM_ARGS} ${PAUSETIME_GARBAGE_COLLECTOR_ARGS} ${MONITORING_ARGS} ${SPRING_BOOT_ARGS}"
MODULES="{{ modules_home }}/*:{{ application_home }}/{{ application_name }}.jar"
 
${JAVA_HOME}/bin/java ${USER_MEM_ARGS} -classpath ${MODULES} {{ application_class_name }}
 
# spring_boot_example_service.j2
[Unit]
Description=Spring Boot Example application
After=network.target
 
[Service]
User={{ java_user }}
Group={{ java_group }}
Type=simple
ExecStart={{ exec_start_service_script }} >/dev/null 2>/dev/null &
Restart=on-failure
RestartSec=1
 
[Install]
WantedBy=default.target

Als we de playbooks draaien hebben we het volgende

# run the playbooks
[root@docker ansible]# ansible-playbook spring_boot_example.yml
 
PLAY [spring_boot_example] ****************************************************
...
 
[root@docker ansible]# ansible-playbook spring_boot_http_server.yml
 
PLAY [spring_boot_http_server] ************************************************
...
 
# check the set-up
[root@springboot1 ~]# ps -ef|grep [j]ava
duke       1296   1287  0 10:40 ?        00:01:08 /u01/app/oracle/jdk8/bin/java -Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dserver.port=8001 -Dserver.address=springboot1.machine.com -Dlogging.path=/u01/app/pivotal/applications/spring_boot_example/logs -classpath /u01/app/pivotal/modules/*:/u01/app/pivotal/applications/spring_boot_example/spring_boot_example.jar Example
 
[root@springboot1 ~]# netstat -anp|grep 1296
tcp6       0      0 :::45032                :::*                    LISTEN      1296/java
tcp6       0      0 :::9999                 :::*                    LISTEN      1296/java
tcp6       0      0 :::57523                :::*                    LISTEN      1296/java
tcp6       0      0 192.168.101.220:8001    :::*                    LISTEN      1296/java
unix  2      [ ]         STREAM     CONNECTED     18812    1296/java
 
[root@springboot2 ~]# ps -ef|grep [j]ava
duke       1296   1286  0 10:40 ?        00:01:17 /u01/app/oracle/jdk8/bin/java -Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dserver.port=8001 -Dserver.address=springboot2.machine.com -Dlogging.path=/u01/app/pivotal/applications/spring_boot_example/logs -classpath /u01/app/pivotal/modules/*:/u01/app/pivotal/applications/spring_boot_example/spring_boot_example.jar Example
 
[root@springboot2 ~]# netstat -anp|grep 1296
tcp6       0      0 :::58380                :::*                    LISTEN      1296/java
tcp6       0      0 :::9999                 :::*                    LISTEN      1296/java
tcp6       0      0 :::52789                :::*                    LISTEN      1296/java
tcp6       0      0 192.168.101.230:8001    :::*                    LISTEN      1296/java
unix  2      [ ]         STREAM     CONNECTED     19520    1296/java

“Everything should be as simple as it can be, but not simpler.” – a scientist’s (Albert Einstein) defense of art and knowledge – of lightness, completeness and accuracy.

Scroll to Top