Eirini: Mapping Code into Containers

By  |  0 Comments
Related Products

Share with mates and colleagues on social media

There was a number of noise lately concerning the Challenge referred to as Eirini.  I needed to dig into what this challenge was in a bit of extra element.

In case you weren’t already conscious, its aim is to permit Cloud Foundry to make use of any scheduler nevertheless it’s actually for permitting the workloads to run instantly inside Kubernetes while not having individually scheduled Diego cells to run on prime of.

There are a lot of motive that this can be a implausible change, however the before everything is that having a scheduler run inside one other scheduler is begging for complications. It really works, however there are odd edge instances that result in split-brain choices.

NOTE: There’s one other challenge (Quarks) that’s engaged on containerizing the management aircraft in a approach that all the platform is extra transportable and requiring considerably much less overhead. (As in: you may run Kubernetes, all the platform, and a few work, all in your laptop computer)


On this weblog, I need to hint some code by way of SUSE Cloud Utility Platform to see what really will get produced by Eirini. To do that, I’m going to run the pattern software and with the pattern buildpack from my final weblog. I imagine it will let me spotlight completely different facets of what’s occurring.

The Course of

Here’s a transient overview of the method that occurs once you create an software:

NOTE: That is all massively simplified and there are a lot of extra issues occurring behind the scenes.

  1. The almighty `cf push`. It uploads a zipper file the code to the api and kicks off the construct
  2. The pipeline runs the code by way of the buildpack and spits out a “droplet” together with some config about the way it ought to be began
  3. Eirini takes that droplet and builds it right into a container
  4. Pushes the container to a non-public registry
  5. Creates the suitable object definitions for Kubernetes to have the ability to run the container
  6. Tells the router what routes have been outlined and which containers are up
  7. Pipes the logging from every container again to a centralized place stream

It’s essential to notice that the objects that it creates are StatefulSets. This enables for scaling up and down in a extra environment friendly approach because the networking is thought forward of time and routing is finished by the cloud foundry router.

The Output

After deploying with cf push, I can see the app working with `cf app custom_test`

agracey@agracey-dev:~/demos/custombuildpack_sample> cf app custom_sample 
Displaying well being and standing for app custom_sample in org suse / house dev as admin... 

title:                custom_sample 
requested state:     began 
isolation section:   placeholder 
routes:              customsample.cap.susedemos.com 
final uploaded:       Fri 16 Aug 08:59:45 PDT 2019 
stack:               sle15 
buildpacks:          staticfile Zero.Zero.1 
kind:           internet 
situations:      1/1 
reminiscence utilization:   1024M 
     state     since                  cpu    reminiscence    disk      particulars 
#Zero   working   2019-08-16T15:59:49Z   Zero.Zero%   Zero of 1G   Zero of 1G

Operating `kubectl get pods –neirini` exhibits me:

agracey@agracey-dev:~> kubectl get pods -neirini 
NAME                                         READY   STATUS    RESTARTS   AGE 
custom-sample-dev-jplx6-Zero                    1/1     Operating   Zero          3m35s

If I describe this pod, I see: (considerably redacted to not expose an excessive amount of about my testbed)

agracey@agracey-dev:~> kubectl describe pod -n eirini custom-sample-dev-jplx6-Zero  
Identify:           custom-sample-dev-jplx6-Zero  
Namespace:      eirini  
Precedence:       Zero  
Node:           <redacted>  
Begin Time:     Fri, 16 Aug 2019 08:59:48 -0700  
Labels:         controller-revision-hash=custom-sample-dev-jplx6-5dcc455d45  
Annotations:    application_id: 92542a29-ff4e-47c5-9161-c4c2b5e02656  
               process_guid: 92542a29-ff4e-47c5-9161-c4c2b5e02656-7181e53b-5e40-4ad9-ac03-83b2aa5ac17a  
Standing:         Operating  
IP:             10.Zero.Zero.169  
Managed By:  StatefulSet/custom-sample-dev-jplx6  
   Container ID:  docker://77aa1b6f293b5c49b07ab8a085de0b42a27ec8e20ba1f09f6da7a73474f5c37b  
   Picture:         registry.cap.susedemos.com/cloudfoundry/ <redacted>  
   Picture ID:      docker-pullable://registry.cap.susedemos.com/cloudfoundry/<redacted> 
   Port:          8080/TCP  
   Host Port:     Zero/TCP  
   State:          Operating  
     Began:      Fri, 16 Aug 2019 08:59:56 -0700  
   Prepared:          True  
   Restart Rely:  Zero  
     reminiscence:  1024M  
     cpu:      120m  
     reminiscence:   1024M  
   Liveness:   tcp-socket :8080 delay=0s timeout=1s interval=10s #success=1 #failure=Four  
   Readiness:  tcp-socket :8080 delay=0s timeout=1s interval=10s #success=1 #failure=1  
     START_COMMAND:            /dwelling/vcap/deps/Zero/node/bin/node app.js  
     VCAP_APP_PORT:            8080  
     HOME:                     /dwelling/vcap/app  
     CF_INSTANCE_PORTS:        ["external":8080,"internal":8080]  
     MEMORY_LIMIT:             1024m  
     PORT:                     8080  
     LANG:                     en_US.UTF-Eight  
     USER:                     vcap  
     VCAP_APPLICATION:         "cf_api":"https://api.cap.susedemos.com","limits":"fds":16384,"mem":1024,"disk":1024,"application_name":"custom_sample","application_uris":["customsample.cap.susedemos.com"],"title":"custom_sample","space_name":"dev"," 
     TMPDIR:                   /dwelling/vcap/tmp  
     CF_INSTANCE_ADDR:         Zero.Zero.Zero.Zero:8080  
     VCAP_APP_HOST:            Zero.Zero.Zero.Zero  
     PATH:                     /usr/native/bin:/usr/bin:/bin  
     CF_INSTANCE_PORT:         8080  
     POD_NAME:                 custom-sample-dev-jplx6-Zero (v1:metadata.title)  
     CF_INSTANCE_IP:            (v1:standing.podIP)  
     CF_INSTANCE_INTERNAL_IP:   (v1:standing.podIP)  
   Mounts:                     <none>  
 Sort              Standing  
 Initialized       True   
 Prepared             True   
 ContainersReady   True   
 PodScheduled      True   
Volumes:            <none>  
QoS Class:          Burstable  
Node-Selectors:     <none>  
Tolerations:        node.kubernetes.io/not-ready:NoExecute for 300s  
                   node.kubernetes.io/unreachable:NoExecute for 300s  
 Sort    Motive     Age    From                                               Message  
 ----    ------     ----   ----                                               -------  
 Regular  Scheduled  4m32s  default-scheduler                                  Efficiently assigned eirini/custom-sample-dev-jplx6-Zero to <redacted>  
 Regular  Pulling    4m31s  kubelet, <redacted>  pulling picture " <redacted> "  
 Regular  Pulled     4m24s  kubelet, <redacted>  Efficiently pulled picture "<redacted>"  
 Regular  Created    4m24s  kubelet, <redacted>  Created container  
 Regular  Began    4m24s  kubelet, <redacted>  Began container 

There are some things that we will gleam from this.

  • “ControlledBy: StatefulSet/custom-sample-dev-jplx6″ offers us the following object to have a look at
  • We will see all of the VCAP settings being handed in
  • We will see each a START_COMMAND within the atmosphere and Command within the container part
  • /dwelling/vcap/app is the working listing

Curiously, the START_COMMAND is what was output by the buildpack and Command that’s given to the pod to start out with is a layer of indirection. (TODO, asking why)

Let’s do a describe on the StatefulSet now:

agracey@agracey-dev:~> kubectl -neirini describe StatefulSet/custom-sample-dev-jplx6  
Identify:               custom-sample-dev-jplx6 
Namespace:          eirini 
CreationTimestamp:  Fri, 16 Aug 2019 08:59:48 -0700 
Selector:           guid=92542a29-ff4e-47c5-9161-c4c2b5e02656,source_type=APP,model=7181e53b-5e40-4ad9-ac03-83b2aa5ac17a 
Labels:             guid=92542a29-ff4e-47c5-9161-c4c2b5e02656 
Annotations:        application_id: 92542a29-ff4e-47c5-9161-c4c2b5e02656 
                    application_name: custom_sample 
                    application_uris: ["hostname":"customsample.cap.susedemos.com","port":8080] 
                    last_updated: 1565971171.Zero 
                    process_guid: 92542a29-ff4e-47c5-9161-c4c2b5e02656-7181e53b-5e40-4ad9-ac03-83b2aa5ac17a 
                    routes: ["hostname":"customsample.cap.susedemos.com","port":8080] 
                    space_name: dev 
                    model: 7181e53b-5e40-4ad9-ac03-83b2aa5ac17a 
Replicas:           1 desired | 1 complete 
Replace Technique:    RollingUpdate 
  Partition:        824644288072 
Pods Standing:        1 Operating / Zero Ready / Zero Succeeded / Zero Failed 
Pod Template: 
  Sort    Motive            Age   From                    Message 
  ----    ------            ----  ----                    ------- 
  Regular  SuccessfulCreate  18m   statefulset-controller  create Pod custom-sample-dev-jplx6-Zero in StatefulSet custom-sample-dev-jplx6 profitable

Right here we will see that now we have just one reproduction being requested. However there’s not a lot else that we didn’t already know.

Subsequent, lets’ scale up and see what occurs.

agracey@agracey-dev:~> cf scale custom_sample -i 5 
Scaling app custom_sample in org suse / house dev as admin... 

Appeared to work, let’s take a look at our `kubectl get pods-n eirini` once more:

agracey@agracey-dev:~> kubectl get pods -neirini             
NAME                   READY   STATUS    RESTARTS   AGE 
custom-sample-dev-jplx6-Zero                    1/1     Operating   Zero          23m 
custom-sample-dev-jplx6-1                    1/1     Operating   Zero          53s 
custom-sample-dev-jplx6-2                    1/1     Operating   Zero          53s 
custom-sample-dev-jplx6-Three                    1/1     Operating   Zero          53s 
custom-sample-dev-jplx6-Four                    1/1     Operating   Zero          53s

We will see that there at the moment are 5 replicas. Describing the StatefulSet offers us what we might anticipate:

<identical as earlier than>
Replicas:           5 desired | 5 complete 
<identical as earlier than>

Now let’s log into one in all these pods and see what’s there. We will do that with

kubectl exec -it custom-sample-dev-jplx6-Zero -neirini -- /bin/bash

There are three issues to have a look at:

  • The working listing is ready to /dwelling/vcap/app/
  • The script being run on startup is /lifecycle/launch
  • The node binary is in /dwelling/vcap/deps/Zero/node/bin/

Let’s take a look at /dwelling/vcap/app:

vcap@custom-sample-dev-jplx6-Zero:/$ ls /dwelling/vcap/app/ 
app.js  operate.js  package deal.json  package-lock.json

This is identical as what we put into the working listing through the buildpack.

There are two scripts contained in the /lifecycle/ listing:

vcap@custom-sample-dev-jplx6-Zero:/$ ls /lifecycle/
launch  launcher

We will see that launch is what’s being run by the podspec above.  If we run this script manually it’ll choose up the prevailing atmosphere. It complains as a result of there’s a port collision which is predicted because the port is being taken by the actual course of that’s already working.

vcap@custom-sample-dev-jplx6-Zero:/$ /lifecycle/launch 
ARGS: [/lifecycle/launch] 
Server Listening on  8080 
      throw er; // Unhandled 'error' occasion 
Error: pay attention EADDRINUSE: deal with already in use :::8080 
    at Server.setupListenHandle [as _listen2] (web.js:1228:14) 
    at listenInCluster (web.js:1276:12) 
    at Server.pay attention (web.js:1364:7) 
    at Object.<nameless> (/dwelling/vcap/app/app.js:73:Four) 
    at Module._compile (inner/modules/cjs/loader.js:776:30) 
    at Object.Module._extensions..js (inner/modules/cjs/loader.js:787:10) 
    at Module.load (inner/modules/cjs/loader.js:643:32) 
    at Operate.Module._load (inner/modules/cjs/loader.js:556:12) 
    at Operate.Module.runMain (inner/modules/cjs/loader.js:839:10) 
    at inner/primary/run_main_module.js:17:11 
Emitted 'error' occasion at: 
    at emitErrorNT (web.js:1255:Eight) 
    at processTicksAndRejections (inner/course of/task_queues.js:74:11) 

As we will see, it merely begins the method based mostly on the atmosphere given.


To the consumer, Eirini isn’t very sophisticated. That is by design because it must be a drop in substitute for present cloud foundry deployments.

It does make some actually essential progress in direction of modernizing and minimizing the platform. It strips away a number of redundancy and potential pitfalls to offer a really highly effective system that makes your builders lives a lot simpler by shifting complexity to a spot the place it may be managed appropriately.

Share with mates and colleagues on social media

Andrew Gracey


You must be logged in to post a comment Login

Leave a Reply