Tuesday, July 7, 2020

Quick survey of tech supporting Cloud/Container Development

Cloud/Container development support

  1. Eclipse Codewind plugin/Project
    1. https://www.eclipse.org/codewind/
    2. Finally got this to install property after about 3+ weeks of toying with it - someones blog entry and some fortunate timing of things got me to reinstall my Docker setup without using 'snap' and also install Docker Compose. At that point, the final install setups started working. I've not spent much time yet working with this but it is on my short list of things to check out at the moment. I created a quick project and that seems to work but when trying to port my current Quarkus code over to CodeWind using the Appsody/Quarkus template template it wasn't a drop and run it result - I'll have to debug some build issue.  Maybe lombok related.
  2. Eclipse Docker plugin/tooling and Redhat Studio Docker Tooling 
    1. https://marketplace.eclipse.org/content/eclipse-docker-tooling
    2. https://tools.jboss.org/
    3. This has worked pretty well - I do like being able to do many operations directly from Eclipse (or IntelliJ with proper plugin) - and of course the command line.
  3. SpringBoot 2.3.x
    1. https://spring.io/guides/gs/spring-boot-docker/
    2. https://www.youtube.com/watch?v=1w1Jv9qssqg
    3. I'm lumping this in for the simplication of building Docker images and such.
  4. Spring Dev Tools and Eclipse
    1. https://docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/html/using-boot-devtools.html
    2.  This plus SpringBoot 2.3.x has some nice features I am starting to work with a bit.
  5. Quarkus 
    1. https://quarkus.io/get-started/
    2. This has a lot of potential.  I am able to create pretty decent services [Rest style access, JPA/Hibernate support, etc] and such like I had using SpringBoot.
    3. Development uses Eclipse and maven functionality.
    4. The startup times of plain Java (non-native build image) are still very good. The live-reload works ok in Eclipse much of the time.  I still have a lot of investigation to do
  6. GraalVM
    1. https://www.graalvm.org/getting-started/
    2. I have this here for its integration with Quarkus.  The idea of building Native apps for use in light-weight containers that are "relatively easy" to generate has a huge potential. Implementing the native app docker image was a massive resource hog (time, memory and CPU) but the initial startup time of the image was great.  This still needs a bunch of testing.
  7. MicroK8s
    1. https://microk8s.io/
    2. Works ok; hopefully my overall workflow will improve as I find ways to leveage the CodeWind, Quarkus/GraalVM, etc projects.  
    3. I am trying to work with the built-in registry to see if that helps with workflow in any way. I do wish I had created some aliases for the commands though.

  8. Lightweight Kubernetes package - k3s
    1. https://k3s.io/
    2. I've not tried it; sounds easy to use and setup.
  9. Docker Swarm mode
    1. https://docs.docker.com/engine/swarm/
    2. Not using it for the most part at home
  10. Apache Mesos / Mesophere / Marathon
    1. http://mesos.apache.org/
    2. https://d2iq.com/solutions/mesosphere
    3. https://mesosphere.github.io/marathon/
    4. I like the idea but haven't found a great use case for much self-learning on this.  All the cloud tooling seems to be pulling good ideas from each and integrating in some way with each other - over time this may have some type of usage that I can leverage but not sure yet.
  11. Lightweight Kubernetes package - Minikube
    1. https://minikube.sigs.k8s.io/docs/start/
    2. Not sure this at home at the moment.  
  12. Cloud Foundry 
    1. https://www.cloudfoundry.org/
    2. I'm now using this at home at the moment.  It was pretty easy to use at a previous job but I do question the overhead in some cases.  Appears to be finding ways to integrate with other technologies such as Kubernetes (See KubeCF project at cloud foundry site).
  13. Knative - kubernetes platform for deploying serverless workloads
    1. https://knative.dev/
    2. I've not tried it yet; Some of the various serverless technologies are slowly integrating with other stuff so it is likely I will work with it more at some point but isn't the highest on my list as of yet.  Serverless workloads have a lot of potential benefits but the cost with public cloud providers can be high depending on what you are doing.
  14. Lightweight local Kubernetes - kind
    1. https://kind.sigs.k8s.io/
    2. I've not tried it yet.  So far, I think Microk8s will fit my needs.
  15. OpenShift
    1. https://www.openshift.com/
    2. Sort of functionality layered on over Kubernetes.  Heard of stability issues from a proof of concept project at a past employer but not tried it myself.
  16. Container Runtime info
    1. https://www.inovex.de/blog/containers-docker-containerd-nabla-kata-firecracker/

Thanks for reading!
I'll update as I find new things to add/update.

Hope your day is blessed!

Scott

Saturday, July 4, 2020

Early Thoughts: Quarkus / GraalVM

Containerization has become very important in recent years.  Starting about 4 years ago, jobs I've had went from no containerization in local data centers to running dockerized images in a cloud such as AWS or Azure. Initially this was just using docker directly on a cloud server.  Over time, the work has gradually migrated more towards Kubernetes though.

There are a lot of lessons learned and a few still being learned. One area of continued learning is in the area of cost. It is so easy to spend big $ in any cloud environment. The choices we make in the tech stack and architecrual areas has a huge impact on final costs.  

Native serverless solutions can become cost prohibitive when the call rate is extremely high. Slow virtual server startups means you must over-provision more initially to prevent lag time issues with auto-scaling. Fat dockerized images eat up memory typically requiring larger underlying hardware to provide additinal memory.  High initial docker container processing results in further over-provisioning to compensate for lag-time. Choices in runtime/language affect memory requirements as well.

With that said, I've been starting to toy with some relatively new technologies in the bits of spare time I have at home - Quarkus (https://quarkus.io/) which also integrates with GraalVM (https://www.graalvm.org/).

The ability to create an optimized container from Java microservice code which prunes out unused functionality and converts to a native application has some benefits.  The biggest touted benefit appears to be lower memory requirements for the deployed container and startup speed but I also think it might help improve security overall - needs some research.

My initial work with Quarkus (non-native, just local images) has been pretty straight forward. I am able to work with it from Eclipse without significant issues.  I wil say that memory requirments tend be excessive for the build process (especially native application image). Without limiting memory, it consumed too much and caused system instability and trying to tweak the memory setting for the build itself is a bit of art.  Here is a snipped of the out of memory failure with 5Gb dedicated.

[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Running Quarkus native-image plugin on GraalVM Version 19.3.1 CE[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep]...
[notesvc-quarkus-1.0.0-SNAPSHOT-runner:24] Exception in thread "ForkJoinPool-2-worker-9" java.lang.OutOfMemoryError: Java heap space: failed reallocation of scalar replaced objects
Fatal error: Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceError: Image build request failed with exit status 1
Once I bumped the setting in the POM file to 6Gb and reran build it succeeded.  Here is the profile that worked:

   <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>   
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemProperties>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                  </systemProperties>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <properties>
        <quarkus.package.type>native</quarkus.package.type>
        <quarkus.native.additional-build-args>-J-Xmx6G</quarkus.native.additional-build-args>
      </properties>
    </profile>

The startup time does appear significantly faster on first tests.  I'll come back and add some of those details soon (hopefully).

Hope your day is blessed!
Scott




  

Early thoughts: MicroK8s

For now, it appears that Kubernetes is the default method for orchestrating containers in many organizations. Since my software development work has revolved around enterprise cloud solutions for the last few years, I've gone through various proof of concepts using other technologies but in the end - kubernetes tends to end up as the preference by many organizations.

One area which I've not seen handled really well is the difference in working "microservices" at the individual developer level (local sandbox) vs in a shared development environment (cloud PaaS K8S). This also related to the initial bootstrapping of new services into a cloud/K8S environment. 

Having per developer resources in a cloud can be cost prohibitive at scale and sharing resources results in coordination issues or worse (for early development).  Most places don't seem to have a standard development method across the board for local development - which shows up as bugs in early deployments.  Some developers are using Docker by itself to manage private resources or some combination with that and very specific shared resources (maybe a dev DB).  Other developers might be using a Docker/K8S solution on a Mac. So far, it often seems awkward at scale with few good/standardized practices.

With that in mind, at home I started working with Microk8s (https://microk8s.io/). I'm hoping to derive some better practices/processes which can be shared. There are a few K8S solutions I could work with but MicroK8S was something I ran across pretty early on.

Overall it works ok - there are differences between PaaS cloud K8S, role your own K8S on cloud servers and using Microk8s on a single physical system but it is still very useful from both functional and learning perspectives. I did a 'snap' install of MicroK8S on Ubuntu and after a bit fiddling got it working.  I have had a few issues when trying to do an upgrade but we'll see how things work out over time - maybe I should use a different installation method.

It does consume resources but using an i7 based system with 16GB RAM, I am able to run MicroK8S, docker, Eclipse, Chrome, DBeaver and and a few dockerized contaniners (MySQL, Postgres, etc).   I'm trying to limit the addons for now to just a handful which are focused on metrics,monitoring,ingress,storage,registry, dashboard and Istio.

I should create some aliases for commands because I do find it tiresome typing "microk8s kubectl ..." or the other dozen or so commands.

It is easy to start/stop MicroK8S so if I find I need to do other work and need the resources, I can usually just stop it.

When I started to combine other tech into the stack with this; memory has become an issue.  Using Quarkus fo build native images is super resource intensive - I'm considing upgrading to 64GB ram even it I need a new system to do so. I'll leave those details for a different post though.