20. April 2018
Nico Foerster
0

Erfolgreiche Kooperation zwischen Studenten der Hochschule Zittau/Görlitz und Saxonia Systems

Zum Abschluss des Moduls Softwareengineering im Informatikstudium an der Hochschule Zittau/Görlitz ist ein dreimonatiges Praxisprojekt vorgesehen, in dem Studenten ihre in den vergangenen Lehrveranstaltungen erworbenen Fähigkeiten unter Beweis stellen müssen. Für die Studenten am Hochschulstandort Görlitz ergibt sich der günstige Umstand, dass in der Stadt mehrere kooperationswillige IT-Firmen ansässig sind. So hat sich auch Saxonia Systems bereiterklärt, eine Gruppe von Studenten bei ihrem Praxisprojekt zu unterstützen.

Mit dem Ziel, den Studenten einen realistischen Einblick in die agile Softwareentwicklung zu gewähren, hat sich Saxonia dazu entschieden, das bewährte Vorgehensmodell Scrum anzuwenden. Dabei werden von einem Entwicklerteam unter Leitung des Scrum-Masters in Iterationen bzw. Sprints Softwareinkremente entwickelt, die dem Kunden von Beginn an einen gewissen Mehrwert bieten. Mit jedem Softwareinkrement werden neue Funktionalitäten entsprechend der Priorisierung des Kunden umgesetzt. Die Aufgaben des IT-Unternehmens bestehen darin, das Thema des Projekts vorzugeben und die Rolle des Product Owners einzunehmen. Somit repräsentiert Saxonia Systems den Kunden, der gegenüber dem Scrum-Team durch den Product Owner in Person von Nico Förster (Softwareentwickler) vertreten wurde. Das Scrum-Team setzte sich hauptsächlich aus den drei Studenten Marco Gotthans (Scrum-Master und Entwickler), Paul Bachmann und Johannes Thies (beide Softwareentwickler) zusammen, welche sich folgender Herausforderung stellten:

Es wird eine Software angefordert, die den Benutzer bei der Auswahl und Bestellung von Pizza unterstützt. Dafür sind die Speisekarten von drei Görlitzer Pizzalieferdiensten im Programm zu hinterlegen und auch Besonderheiten wie Pizzapakete und Rabatte zu berücksichtigen. Der Benutzer hat die Möglichkeit, die Anzahl an Personen und die durchschnittlich verspeiste Pizzamenge anzugeben und erhält anhand dieser Eingaben eine optimale Pizzabestellung (bestes Preis-Leistungsverhältnis) zu jeder der drei Pizzerien ausgegeben. Da diese Bestellung zwar den Pizzabedarf deckt, jedoch unter Umständen wenig abwechslungsreich ist, soll der Benutzer die Möglichkeit haben, das Ergebnis durchzuwürfeln. Dadurch werden zufällig unterschiedliche Pizzen ausgewählt, so dass die Bestellung immer noch den Bedarf deckt, jedoch teurer ausfallen kann. Die Software soll auch einen Maximalbetrag berücksichtigen können, um ein gewisses Budget nicht zu überschreiten. Die letzte Anforderung bestand darin, durchgeführte Bestellungen speichern zu können, um sie später z.B. für Abrechnungszwecke erneut aufrufen zu können.
Bei der Auswahl der Technologien wurde den Studenten freie Wahl gelassen, so dass sie sich für eine Spring Applikation mit Webfrontend entschieden. Es wurde folgender Technologiestack verwendet: Java, Spring Boot, Hibernate, H2- und MySQL-Datenbank, Thymeleaf, Lombok, HTML, JavaScript.

Bereits am Ende der ersten Iteration konnte das Team dem Product Owner ein überraschend umfangreiches Softwareprodukt präsentieren. Die Optik des Webfrontends hat direkt überzeugt, da sie sich am Design der Saxonia Webseite orientiert. Nach der Abnahme des Inkrements durch den Product Owner wurden durch selbigen die zu realisierenden Anforderungen für das nächste Softwareinkrement vorgestellt. Aufgetretene Fragen wurden gemeinsam geklärt, Probleme und Vorgehensweisen diskutiert. Bei der im Anschluss stattfindenden Retrospektive erhielt das Scrum-Team wertvolle Unterstützung vom Saxonia Mitarbeiter Michael Klose (Softwareentwickler), welcher durch jahrelange Projekterfahrung und die Vorstellung verschiedener Varianten der Scrum-Retrospektive das Praxisprojekt bereicherte.

Mit jedem Sprint im Zweiwochenrhythmus wuchs der Funktionsumfang der Anwendung zur Zufriedenheit des Product Owners. Bei Test und Probebestellungen wurde deutlich, dass sich der ein oder andere Bug eingeschlichen hatte und das Scrum-Team selbst den Drang nach Refactorings (Verbesserung und Härtung des Programmcodes) verspürte. Fehlende Softwaretest (Unit Tests) erschwerten die Refaktorisierung und hätten bereits präventiv Bugs, vor allem in der Berechnungslogik verhindern können. Michael Klose und ich haben auf Wunsch des Teams auch ein Code-Review durchgeführt, dessen Ergebnisse dankend aufgenommen und entsprechende Verbesserungen vorgenommen wurden.

Das finale Produkt wurde sowohl bei der Abschlusspräsentation in der Hochschule Zittau/Görlitz, als auch im Rahmen eines Meetings am Standort Görlitz der Saxonia Systems vorgestellt. Die Reaktionen waren durchweg positiv und das Team hat zu Recht Lob für die gute Arbeit erhalten. Besonders wichtig ist es, dass den Studenten die Vorteile von bewährten Verfahren der Softwareentwicklung wie Scrum, Test-Driven-Development, Clean Code und Refactorings vermittelt wurden. Die intensive Betreuung durch Saxonia, die deutlich über die Anforderungen der Hochschule an das Unternehmen hinausging, hat sich am Ende bezahlt gemacht. Die Studenten haben wertvolle Praxiserfahrungen sammeln können und Saxonia hat im Gegenzug ein optisch und funktional tolles Produkt erhalten, wie die nachfolgenden Bilder beweisen.

Erfolgreiche Kooperation zwischen Studenten der Hochschule Zittau/Görlitz und Saxonia Systems!!!

 

29. Januar 2018
Sven Jänicke
0

Aktuelle Trends und Herausforderungen in der Softwareentwicklung

… das sagten die Teilnehmer der iJS und W-JAX

Dass nicht nur in Sachsen was geht, sondern vor allem auch an unserem Hauptsitz in München, zeigten Ende letzten Jahres die „International JavaScript Conference“ und die „W-JAX“. Beide Konferenzen fanden kurz nacheinander statt und lockten zahlreiche Besucher in die bayrische Landeshauptstadt.

Wie schon die S&S Media Group als Veranstalter der iJS (international JavaScript Conference) feststellt, ist „JavaScript [mittlerweile] überall: kaum ein digitales Business kann heute auf JavaScript und high-level Frameworks, wie Angular, React, oder NodeJS verzichten.“ Da wundert es kaum, dass diesem Thema auf der iJS vom 23.-27.10.2017 im Holiday Inn Munich City Centre eine eigene Konferenz mit zahlreichen Keynotes, Sessions und Power Workshops gewidmet wird. Auch die W-JAX beschäftigt sich zum Teil mit diesen Themenfeldern, bietet aber zusätzlich noch zahlreiche weitere Impulse im Bereich Enterprise-Technologie, Softwarearchitektur, Agilität & Java.

 

Wir nutzten bei beiden Konferenzen die Gelegenheit, uns intensiv mit der Community auszutauschen und hatten deswegen einige Fragen im Gepäck, die wir an die Teilnehmer der Konferenzen richteten. Insgesamt konnten wir fast 100 Umfragen durchführen, die sich in gleichen Teilen auf die beiden Veranstaltungen aufteilten. Wir danken an dieser Stelle noch einmal allen, die sich die Zeit genommen haben, sich an unserer Befragung zu beteiligen. Nur durch einen intensiven Austausch mit Partnern, Kunden und Community kann es gelingen, sich stets zu verbessern. Diesen Ansatz der kontinuierlichen Verbesserung, der auch im agilen Manifest verankert ist, verfolgen wir nicht nur in unseren Projekten, sondern leben wir auch unternehmensweit.

Während unsere Experten Manuel Mauky und Alexander Casall zu Themen wie „Angular-Anwendungen mit Redux“ und „Offlinefähige Desktopanwendungen mit Angular und Electron“ sprachen, wollten wir von unseren Interviewpartnern zuallererst wissen, welche Frameworks und Sprachen sie in ihren aktuellen Hauptprojekten einsetzen. Am häufigsten wurden Angular und JQuery genutzt, dicht gefolgt von JavaEE und Spring. React kam dagegen beispielsweise noch recht selten zum Einsatz. Dabei nutzten 72 von 88 Befragten JavaScript, 69 HTML und 51 Java als Programmiersprache. Ruby, Groovy und Coffeescript dagegen wurden kaum verwendet und bekamen jeweils maximal 5 Stimmen.

 

Natürlich interessierte uns nicht nur, mit welchen Technologien momentan gearbeitet wird, sondern vor allem in welche Richtung sich die Trends der Softwareentwicklung bewegen. Immer mehr Anwender von Geschäftsanwendungen erwarten moderne Webanwendungen anstelle bestehender Desktop-Software. Die Usability von Bestandssoftware trifft in Zeiten von modernen B2C-Applikationen oft nicht mehr die Erwartungshaltung der Nutzer und es werden immer mehr webbasierte Lösungen etabliert, die ihre Nutzer aktiv in der Arbeit unterstützen. Daher ist es auch nicht verwunderlich, dass 70 % der Befragten planen, in nächster Zeit mit Angular, React oder einer anderen reactiven Technologie (z.B. ReactiveX, RxJS, …) zu arbeiten. Vue.JS (14 Stimmen) und JavaFX (3 Stimmen) spielen dagegen bei den Umfrageteilnehmern nur untergeordnete Rollen.

 

Die Hälfte der Befragten konnte sich schon recht genau positionieren und hatte sich auf Angular, React oder zumindest eine reactive Technologie festgelegt. Rund 20 % dagegen waren noch indifferent und konnten sich noch nicht zwischen Angular oder einer reactiven Technologie entscheiden. Hilfestellung könnte hier die von uns evaluierte Entscheidungsmatrix bieten, die mithilfe eines Fragenkatalogs eine persönliche Technologieempfehlung gibt. Diese basiert auf den Erfahrungen unserer Webexperten.

Weiterhin entscheidend bei der Auswahl einer geeigneten Programmiersprache oder eines Frameworks ist selbstverständlich auch der Inhalt des eigentlichen Projektes. Wir fragten daher, was die Umfrageteilnehmer in ihrem Hauptprojekt tun. Der Großteil der Befragten beschäftigte sich hier mit Softwareevolutionsprojekten (61 Stimmen), dicht gefolgt von Neuentwicklungen (56 Stimmen). Rund ein Fünftel der Umfrageteilnehmer beschäftigte sich in ihrem Arbeitsalltag mit DevOps. Je nachdem, ob man eine bestehende Software wartet oder ein „grüne Wiese“-Projekt auf dem Tisch hat, sind die Spielräume bei der Auswahl der Programmiersprachen und verwendeten Tools natürlich sehr unterschiedlich breit.

 

Nachdem wir nun etwas näher herausgefunden hatten, womit die Befragten, bei denen es sich zum Großteil um Softwareentwickler verschiedenster Nationalitäten und aus unterschiedlichsten Branchen und Unternehmensgrößen handelte, wollten wir auch wissen, was sie im aktuellen Projekt am meisten behindert. An dieser Stelle gaben wir bewusst eher offene Antwortmöglichkeiten, wie „schlechter Code“ oder „schlechte Architektur“ vor, die dem Interviewteilnehmer noch Spielraum für Interpretation gaben und somit die Befragten bewusst dazu auffordern sollten, näher auf die Probleme einzugehen und gegebenenfalls einen ersten Dialog zu Problemlösung zu fördern.

Die häufigsten genannten Probleme sind der folgenden Grafik zu entnehmen. Neben den hier auftauchenden Antworten, bei denen sich „unklare Anforderungen“ nach wie vor als eines der Hauptprobleme darstellte, gab es auch einige freie Antworten. Relativ häufig wurde hier „legacy code“, „Warten auf den Auftraggeber / den Kunden“ oder „stark gewachsene und unübersichtliche Softwarearchitektur“ genannt.

 

 

Schlussendlich wandten wir uns noch einigen Fragestellungen aus dem Bereich „Moderne Webentwicklung“ zu, um hier zu prüfen, welche Trends sich tatsächlich von der Community bestätigen lassen oder welche Themen zwar im Netz „gehypt“ werden, aber im tatsächlichen Entwickleralltag noch nicht angekommen sind. Einer dieser Trends in der IT ist beispielsweise GraphQL. Hier stellten wir erst einmal die grundsätzliche Frage, wie die Konferenzbesucher zu der Technologie standen. Lediglich ein Viertel der Befragten plante den Einsatz dieser REST-Alternative für die Zukunft oder hatte GraphQL bereits im Einsatz, während immerhin fast die Hälfte noch nie von der Technologie gehört hatten.

 

Wir wollten hier außerdem noch wissen, ob die Befragten in ihren Projekten Cloud-Technologien einsetzen. Hier war das Verhältnis der Antworten relativ ausgeglichen. 45 % der Umfrageteilnehmer bejahten hier, während die restlichen 55 % nicht, oder zumindest nicht in ihrem Hauptprojekt, mit Cloud-Technologien arbeiteten. Die zweite Frage aus diesem Themenblock war, welche Technologie die Befragten aktuell für das State-Management verwendeten. Zur Auswahl standen React/Angular (ohne Dritt-Framework für das State-Management), Redux oder MobX. Während letzteres lediglich eine Stimme bekam, setzte der Großteil der Umfrageteilnehmer (knapp 50 %) kein Drittframework ein und rund 25 % arbeiteten mit Redux, während wiederum ca. 20 % hier keine Antwort gaben, was das Ergebnis der Umfrage leider etwas verfälscht.

Sie interessieren sich für weitere Umfrageergebnisse? Dann stöbern Sie doch einfach noch ein wenig in unserem Blog, und lesen Sie, welche aktuelle Trends und Herausforderungen in der Softwareentwicklung wir auf der solutions.hamburg 2016, der OOP 2017, der WJAX 2016 oder der DWX 2017 erfragen konnten.

 

9. Oktober 2017
Hendrik Loesch
0

DWX 2017 – 100 Leute haben wir gefragt…

Wie schon in den vergangenen Jahren war die Saxonia Systems AG auch dieses Jahr wieder bei der Developer Week (DWX 2017)  in Nürnberg vertreten. So gestalteten wir das Programm aktiv mit Vorträgen und gewährten tiefe Einblicke in unseren Arbeitsalltag, sowie unsere Leistungen.

mehr

13. April 2017
Christoph Möbius
0

Launch a Kubernetes cluster on AWS with kube-up and let it autoscale

In the following we will walk through how to launch a Kubernetes (k8s) cluster on AWS using kube-up, push a Docker image to ECR, start a server in k8s based on that image, and autoscale the cluster. The kube-up scripts needs a proper GNU/Linux system to operate. Therefore, if you usually use Windows you either need a VM running GNU/Linux or Windows 10 Anniversary update with Windows Subsystem for Linux (WSL).

You need a Docker host up and running. Depending on whether you are using pure GNU/Linux, GNU/Linux in a VM, or WSL installing and using Docker differs. In the first two cases you may see here on how to install Docker. If you are using WSL then you need to install Docker in Windows (either Docker Toolbox, or – preferably – Docker CE). If you can install Docker CE then there may be a way to have a Docker host within WSL. If you can only use Docker Toolbox in Windows then, at this juncture, there is no way to have a Docker host within WSL.

In my case I use WSL and I am bound to Docker Toolbox. Thus, I need to switch between WSL and Windows at some point in order to build the docker image. If you can use a proper GNU/Linux, or have GNU/Linux running within a VM you can stay there and can ignore the [In WSL] / [In Windows] switches later on.

[In WSL & Windows]

First, we need kubectl on both, Windows and WSL. To install kubectl see

The awscli is also needed on both Windows and WSL. To install awscli see

[In WSL]

Now that kubectl and awscli are installed we can get the kube-up script. We will to some extent follow the instructions given here. However, since we need to make some adaptions to the script and its guts we will first download the script suite, but do not start the cluster immediately. Therefore

$ mkdir ~/scripts
$ cd
$ export KUBERNETES_RELEASE=v1.4.0 #later versions do not work
$ export KUBERNETES_PROVIDER=aws
$ export KUBERNETES_SKIP_CREATE_CLUSTER=true
$ wget -q -O - https://get.k8s.io >~/k8s_setup.sh && chmod +x ~/k8s_setup.sh && ~/k8s_setup.sh

This will download a lot of scripts to a folder ~/kubernetes. To use AWS as provider we need to adapt some variables. To save work later we write a helper in ~/scripts/prepare_k8s_aws.sh and put the following stuff and make sure to change the value of AWS_S3_BUCKET to something unique):

# edit to your liking
# and particularly CHANGE the value of AWS_S3_BUCKET
export KUBERNETES_PROVIDER=aws
echo "setting KUBERNETES_PROVIDER=$KUBERNETES_PROVIDER"
export KUBE_AWS_ZONE=eu-central-1a
echo "setting KUBE_AWS_ZONE=$KUBE_AWS_ZONE"
export NUM_NODES=2
echo "setting NUM_NODES=$NUM_NODES"
export NUM_NODES_MIN=2   # needed for autoscaling
echo "setting NUM_NODES_MIN=$NUM_NODES_MIN"
export NUM_NODES_MAX=5   # needed for autoscaling
echo "setting NUM_NODES_MIN=$NUM_NODES_MAX"
export MASTER_SIZE=m3.medium
echo "setting MASTER_SIZE=$MASTER_SIZE"
export NODE_SIZE=m3.medium
echo "setting NODE_SIZE=$NODE_SIZE"
export AWS_S3_REGION=eu-central-1
echo "setting AWS_S3_REGION=$AWS_S3_REGION"
export AWS_S3_BUCKET=yourProjectUniqueName-kubernetes-artifacts
echo "setting AWS_S3_BUCKET=$AWS_S3_BUCKET"
export KUBE_AWS_INSTANCE_PREFIX=k8s
echo "setting KUBE_AWS_INSTANCE_PREFIX=$KUBE_AWS_INSTANCE_PREFIX"

To make kube-up actually using these variables we do

$ sed -i '2i. ~/scripts/prepare_k8s_aws.sh' ~/k8s_setup.sh
$ sed -i '2i. ~/scripts/prepare_k8s_aws.sh' ~/kubernetes/cluster/kube-down.sh
$ sed '/--vpc-zone-identifier/i\      --min-size ${NUM_NODES_MIN} \\' -i \
  ~/kubernetes/cluster/aws/util.sh
$ sed '/--vpc-zone-identifier/i\      --max-size ${NUM_NODES_MAX} \\' -i \
  ~/kubernetes/cluster/aws/util.sh

To enable autoscaling later, we need the IAM role that is assigned to the minions during cluster startup to have some more permissons. Edit a file e.g. ~/as_policy.json and insert the following content (be sure to have no empty lines in the file):

{
    "Effect": "Allow",
    "Action": [
        "autoscaling:DescribeAutoScalingGroups",
        "autoscaling:DescribeAutoScalingInstances",
        "autoscaling:SetDesiredCapacity",
        "autoscaling:TerminateInstanceInAutoScalingGroup"
    ],
    "Resource": "*"
}

Then add the content to the policy template:

$ cd ~ # or change to the directory where as_policy.json resides
$ sed -i '43s|}|},|' ~/kubernetes/cluster/aws/templates/iam/kubernetes-minion-policy.json
$ sed -i -e '43r as_policy.json' ~/kubernetes/cluster/aws/templates/iam/kubernetes-minion-policy.json

Now we are ready to start the cluster:

$ unset KUBERNETES_SKIP_CREATE_CLUSTER
$ ~/k8s_setup.sh

Answer Y to the question, i.e. keep the ~/kubernetes directory, since otherwise all your previous changes will be lost. If anything fails during the process and you need to start over you need to run

$ ~/kubernetes/cluster/kube-down.sh

first.

The cluster setup will take up to ten minutes. In the meantime, we will implement a Hello-World service that we will use later on to hog the pod’s CPU capacity and trigger a scale-out. Take e.g. the Getting-Started Actuator Service as described here. Clone the project from here and change into gs-actuator-service/complete. In src/main/java/hello/Greeting.java add the following methods

private int ackermann(int n, int m) {
    if (n == 0) return m + 1;
    if (m == 0) return ackermann(n - 1, 1);
    return ackermann(n - 1, ackermann(n, m - 1));
}


private void hogCPU() {
    ExecutorService executor = Executors.newWorkStealingPool();

    List<Callable<Integer>> callables = Collections.nCopies(35, () -> ackermann(3, 11));

    try {
        executor.invokeAll(callables)
                .stream()
                .map(future -> {
                    try {
                        return future.get();
                    }
                    catch (Exception e) {
                        throw new IllegalStateException(e);
                    }
                })
                .forEach(System.out::println);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

and call hogCPU() in the last line of the constructor. You may reduce (or increase) the number of parallel processes depending on the instance type you chose in NODE_SIZE above. In our case, NODE_SIZE is m3.medium which has one virtual CPU. You also need to import the following packages:

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

To build Docker images for this project one may use the fabric8 maven plugin. See here on how to install it. (At the time of writing the latest version is 3.2.7 rather than 3.2.28.). Since I cannot have a Docker host within WSL I need to switch to Windows for building the image. This has one more implication: Since I start the cluster within WSL all configuration that is generated by kube-up will be written to ~/.kube/config within WSL. However, I need that configuration in Windows as well in order to use kubectl properly. So, after the cluster has been brought up successfully, I copy the generated kubectl config from WSL to Windows:

$ cp ~/.kube/config /mnt/c/Users/<yourUserName>/.kube/config

Also, after the cluster has been brought up a few URIs will be printed to the terminal. Find the URI for Kubernetes-dashboard and open it in a browser. You will get an SSL warning. After you accepted the warning you will be presented a login form. To login change back to the terminal and type

$ CTX=$(kubectl config view | grep current-context | sed 's|current-context: ||')
$ kubectl config view | grep -A2 $CTX-basic-auth | grep password | \
  sed 's| *password: ||'

This will print the password. The username is always admin. After logging in to the dashboard navigate to Workloads->Deployments and then change back to the terminal.

[In Windows]

Remember that I only need to switch to Windows since I am bound to Docker Toolbox for technical reasons. I start Docker Toolbox and use the provided shell.

Change to the Hello-World project and build it using fabric8:

$ cd ~/path/to/gs-actuator-service/complete
$ mvn clean package fabric8:build

You can check the image that has been created using

$ docker images

In our case there should be an output similar to

REPOSITORY                              TAG                IMAGE ID            CREATED             SIZE
springframework/gs-actuator-service     0.1.0              e3b475c4e906        17 hours ago        112.3 MB

Since we want to use Amazon’s Elastic Container Registry (ECR) to store our image we need to tag the image accordingly. First, you should create a repository for the project:

$ ECR_ID=$(aws ecr create-repository --repository-name hellorepo --query repository.registryId --output text)

Then we tag the image:

$ docker tag springframework/gs-actuator-service:0.1.0 \
  ${ECR_ID}.dkr.ecr.eu-central-1.amazonaws.com/hellorepo:0.1.0

To actually upload the image to ECR we need Docker to authenticate against ECR. As described here this _shall_ be (it’s NOT) as simple as

$ $(aws ecr get-login)

However, the login command that is returned by the awscli is, at this junction, indeed wrong: The repository URI contains an https:// which will later lead to a message that there is „no such repository“ if you try to push the image with Docker. (This was a thing that drove me nuts for an entire day until I figured out what was actually going wrong). See on stackoverflow for the solution. Be sure to have GnuWin32 installed in Windows at this point. The „correct“ way to authenticate Docker against ECR is then

$ $(aws ecr get-login | sed 's|https://||' | sed 's|-e none ||')

Now push the image to ECR:

$ docker push ${ECR_ID}.dkr.ecr.eu-central-1.amazonaws.com/hellorepo:0.1.0

At this point we could make a deployment and expose it as a service. But we want to demonstrate autoscaling. In order to make that work we need to understand two things: (1) Deployments (and thus pods) can have explicit resource requirements. If there are no nodes available in the k8s cluster that could fulfil these requirements, a new node (i.e. a minion, i.e. an EC2 instance) would need to be instantiated. (2) This horizontal autoscaling for nodes is not yet built-in to kubernetes for AWS. But there is a cluster autoscaler available as deployment.

So we edit a file ~/autoscaler.yml with the following content:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: cluster-autoscaler
  labels:
    app: cluster-autoscaler
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cluster-autoscaler
  template:
    metadata:
      labels:
        app: cluster-autoscaler
    spec:
      containers:
        - image: gcr.io/google_containers/cluster-autoscaler:v0.4.0
          name: cluster-autoscaler
          resources:
            limits:
              cpu: 100m
              memory: 300Mi
            requests:
              cpu: 100m
              memory: 300Mi
          command:
            - ./cluster-autoscaler
            - --v=4
            - --cloud-provider=aws
            - --skip-nodes-with-local-storage=false
            - --scale-down-delay=10m
            - --nodes=2:5:k8s-minion-group-eu-central-1a
          env:
            - name: AWS_REGION
              value: eu-central-1
          volumeMounts:
            - name: ssl-certs
              mountPath: /etc/ssl/certs/ca-certificates.crt
              readOnly: true
          imagePullPolicy: "Always"
      volumes:
        - name: ssl-certs
          hostPath:
            path: "/etc/ssl/certs/ca-certificates.crt"

This configuration will scale the minions in the autoscaling group k8s-minion-group-eu-central-1a between 2 and 5 nodes. And it will take a node out of the cluster after it has been underutlized for 10 minutes.  Be sure to edit the value of AWS_REGION (in the example above eu-central-1), and the autoscaling group name (in the above example k8s-minion-group-eu-central-1a) to fit your config. The name of your autoscaling group name can be determined using

$ aws autoscaling describe-auto-scaling-groups \
  --query AutoScalingGroups[].AutoScalingGroupName --output text

Deploy the cluster autoscaler:

$ kubectl create -f ~/autoscaler.yml

You can check the successful deployment in the Kubernetes-dashboard: refresh the Deployments page; the autoscaling deployment should be visible.

Now we can deploy the image to the k8s cluster:

$ kubectl run gs-actuator \
  --image ${ECR_ID}.dkr.ecr.eu-central-1.amazonaws.com/hellorepo:0.1.0 \
  --requests='cpu=700m,memory=150Mi' \
  --limits='cpu=900m,memory=200Mi'

The requests and limits parameters are essential to trigger the autoscaling: We state that the deployment needs a pod with (at least) 70% CPU time and 150 MiB memory available. If you refresh the Deployments page you will see an error message that no node has enough capacity to take the pod. In the background it will launch a new EC2 instance and after ca. 6 minutes the new node will be available and the pod gets deployed on that node. Wait until the deployment is successful. It should not take longer than two more minutes, but depending on how fast AWS initializes the instance it can take up to 10 minutes in total.

Now let’s start a service of the gs-actuator deployment and make port 9000 available to the public (check that this meets the server.port in the application.properties of gs-actuator):

$ kubectl expose deployment gs-actuator --type=LoadBalancer --port=9000

This will start an Elastic Load Balancer (ELB) and you get the public DNS name with

$ ELB_DNS_NAME=$(aws elb describe-load-balancers \
  --query LoadBalancerDescriptions[0].DNSName --output text) && \
  echo $ELB_DNS_NAME

It may take a while until the DNS name can be resolved.

The last step for full autoscaling is to enable Horizontal Pod Autoscaling (HPA) within the cluster:

$ kubectl autoscale deployment gs-actuator --min=1 --max=3 --cpu-percent=80

 This will run at least one pod and at most three pods where a new pod gets launched as soon the (average) CPU utilization of the already running pods exceeds 80%.

Now generate a request for the service:

$ curl http://${ELB_DNS_NAME}:9000/hello-world

This will utilize the pod’s CPU fully for more than a minute which should then trigger the HPA. (If the service responds earlier in your case you may need to fire more requests in parallel or consider to adapt Greetings.hogCPU() to start more parallel processes.) This will start a new pod which – due to the specified resource requirements – will trigger a scale out at the nodes. Watch the kubernetes Dashboard Workloads -> Pods and Admin -> Nodes. A new pod will be created that does not fit in any node. Eventually (after 2 minutes or so), a new node will appear.

Let the service rest. HPA will eventually remove the pod. 10 minutes later the cluster autoscaler will remove the additional node.

To clean up run

$ ~/kubernetes/cluster/kube-down.sh

Remove the registry in ECR:

$ aws ecr delete-repository --repository-name hellorepo --force

Optionally, you may remove the S3 bucket. Do NOT use this if you have other buckets than the one created using the kube-up script): Be CAREFUL and double check. To be safe use the values you have set for AWS_S3_REGION and AWS_S3_BUCKET in ~/scripts/prepare_k8s_aws.sh. (You cannot plainly use $AWS_S3_REGION and $AWS_S3_BUCKET since these variables were set in a subprocess and are not known to the parent process: i.e. the child Bash that actually executes k8s_setup.sh cannot set variables in the parent Bash which called k8s_setup.sh)

$ S3_BUCKET=$(aws --region eu-central-1 s3api list-buckets --query Buckets[].Name --output text)
$ aws s3 rm s3://$S3_BUCKET --recursive # only deletes content but not bucket itself
$ aws s3api delete-bucket --bucket $S3_BUCKET

This concludes our walkthrough. You

  • started a kubernetes cluster on AWS
  • set up kubernetes for autoscaling
  • built a Docker image and pushed it to ECR
  • let kubernetes use the image to start a deployment
  • exposed the deployment as a service
  • generated requests to the service in order to trigger autoscaling
  • let the cluster scale-out and scale-in
  • teared down the cluster
  • cleaned up after you

I am eager to get your comments how this was helpful to you or receive your questions.

10. April 2017
Leo Lindhorst
0

Building Cross Platform Desktop Apps with Angular and Electron

angular-2-electron-saxonia-systems

The rapid development in the world of web technologies, especially in SPA frameworks like Angular and React, empowers developers to build enterprise scale, platform independent applications with a flexible and vivid technology stack. Although these applications can fulfill numerous use cases they may fall short in others because of the limitations web applications have. Especially the limited environment integration and system access capabilities make some kinds of applications impossible (e.g. missing file system access) or hurt the user experience (e.g. no offline usage, no integration into application menu or task bar in most cases).

mehr

6. April 2017
Niels Brestrich
0

Protractor – Automatisiert Testen mit Angular

Kritische Fehler, die erst im Rahmen des Live-Betriebes öffentlich werden, stellen ein großes finanzielles Risiko und nicht zuletzt eine negative Werbung für ein Produkt und die beteiligten Unternehmen dar. Deshalb ist das Thema Test in der modernen Softwareentwicklung ein grundlegender und integraler Bestandteil. Durch eine hohe Testabdeckung und der zeitnahen Rückmeldung der Testergebnisse lässt sich die Qualität und Reife des Produktes ausreichend genau nachweisen und bestätigen.

mehr

20. März 2017
Leroy Buchholz
0

Wirklich perfekte full-size Hintergrundbilder im Web

Ein full-size Hintergrundbild mit CSS3 zu setzen, ist doch kein Problem, oder? Im Internet finden sich viele Lösungen. Die funktionieren auf den ersten Blick auch ganz gut, aber schaut man etwas genauer hin, wird man häufig enttäuscht. Sollte man ein 2 MB großes Bild an mobile Geräte mit 3G ausliefern? Wohl eher nicht. Werden mobile Browser auch unterstützt? Dazu findet man häufig keine Angaben und bei einem eigenen Test fällt die Standardlösung durch. Also stellt sich zunächst die Frage: Was macht ein gutes full-size Hintergrundbild aus?

mehr

15. März 2017
Stefan Bley
0

How to build your Angular project on Travis CI

Recently, I created an Angular App with current Angular CLI 1.0.0-rc.0 using Yarn instead of NPM. When I pushed some code to the GitHub repo and opened a pull request for my teammates to review, an information box popped up on GitHub suggesting to connect to a GitHub Integrations tool. Then with every push or pull request the app is built and tested by the integration tool, allowing for a quick feedback about whether it is safe to integrate the code. Let’s give it a try, I thought and decided to go with Travis CI. An hour later I had everything up and running. Here is what you need to do:
mehr

10. März 2017
Denny Israel
0

React + Redux + HATEOAS

When developing a web application with ReactJS it is often a good idea to use it in combination with the Redux architecture. This gives us good and precise control about the application state and all actions that change the state. All view changes must be executed as actions on the redux store and thus the central application state. When dealing with a RESTful backend we have to cope with asynchronous requests and thus have to deal with long running requests, error responses, missing data. Furthermore when the backend uses HATEOAS we have to deal with getting and managing the necessary request links. mehr

6. März 2017
Matthias Baumgart
0

Using a HAL hypermedia API in an Angular App

Modern APIs are often realized in a RESTful way. Besides being stateless and using the correct HTTP verbs for specific actions, REST does not specify the response of a request. Hypermedia Formats are trying to overcome this issue by providing a discoverable API. Hypermedia Application Language is one format and abbreviates as HAL.

HAL is a set of conventions expressing hyperlinks in either JSON or XML. Resources returned by a HAL API contain a _links element hosting a self link and a link to resources. This makes HAL APIs discoverable as it is possible to navigate from one resource to another via the links provided within the resources knowing only a single entry point. This article describes how to use HAL hypermedia APIs in Angular.

mehr