From Hero To Zero

DevOps at KN FreightNet

Kuehne + Nagel (AG & Co.) KG

Sascha Krueger

Developer & Software Architect

@skhome  
@sakruege

Markus Krogemann

Freelance Software Engineer

@mkrogemann
@mkrogemann

Time Travel

Organisation

software development

operations

infrastructure

handover

RFC

deployment notes

transfer server

Manual procedures

deployments

server configuration

virtual machines

Limited resources

bottlenecks

queues

waiting times

Drivers for Change

... and asking the right questions

extend product portfolio

growth

How do we raise the number of involved people without tipping on each others toes?

autonomy

How can we put the development teams in charge?

no deployment downtimes during business hours

availability

Is there ever a perfect time for a downtime?

Are our developers available at that time?

support business experiments

balance

What would be the minimal viable footprint?

How can we prepare for growth?

predictability

How do we avoid configuration drift?

delivery

How do we speed up the delivery pipeline?

Can we reduce the time a feature spends
"waiting for attention"?

Challenge accepted

Opportunity

Constraints

Solutions

vertical system decomposition

Avoid the monolith

zero downtime deployments

blue/green deployments

continuous delivery

Test Automation

Unit

Integration

Acceptance

Compatibility

Infrastructure Automation


- name: restart rabbitmq if this is a fresh install
  supervisorctl: name=freightnet-rabbitmq state=present
  supervisorctl: name=freightnet-rabbitmq state=restarted
  when: fresh_install.changed

- name: tell slave nodes to join the master node if this is a fresh install
  command: "{{ item }}"
  with_items:
    - rabbitmqctl stop_app
    - rabbitmqctl reset
    - rabbitmqctl join_cluster {{ rabbitmq_master_node_short_name }}
    - rabbitmqctl start_app
  when: fresh_install.changed and inventory_hostname != "{{ rabbitmq_master_node }}"
  environment:
      PATH: "{{ basedir }}/rabbitmq_server-{{ rabbitmq_version }}/sbin:{{ ansible_env.PATH }}"

ANSIBLE

Deployment Automation


- fail: msg="no application server group specified (variable app_server_group not set)"
  when: app_server_group is not defined

- fail: msg="no application specified (variable application not set)"
  when: application is not defined

- fail: msg="no application version specified (variable application_version not set)"
  when: application_version is not defined

- name: stop old application
  supervisorctl: name={{ application }} state=stopped
  ignore_errors: yes

- name: clean up application base directory
  file: path="{{ basedir }}/{{ application }}" state=absent

ANSIBLE

Heads up

Test your automation

Test for compatibility

Microservices are a valid approach...

...if your organisation is ready for them

From Hero To Zero