Developing in-cluster with ksync

September 30th, 2018

Continuing on the theme of technologies used by Jenkins X under the covers, this post is going to take a look at ksync. In Jenkins X, this project is used to implement the ‘DevPods‘ capability. It’s a pretty thin veneer over the top of what is provided by ksync though. As the name suggests, the project performs synchronisation, in particular, bi-directional synchronisation between a directory on your laptop and a pod in a Kubernetes cluster. The aim is to allow you to code locally in your favourite editor but run that code in-cluster where you have access to a full Kubernetes environment, including any other services you might be running.

The workflow is simple: a <code>ksync init sets up your local environment and deploys a daemon set in the cluster to get access to the file system of containers. Next, a ksync watch runs a process locally to monitor your laptop. The last step is to issue a ksync create to form a mapping between a local directory and a directory in a container (or potentially multiple containers that match the selector). And that’s all there is to it: make a change locally and it’s reflected in the container; see files written by the container appear on your local disk.

ksync is, in turn, using syncthing to perform the actual file synchronisation. In addition, it provides the option to restart the application container following a sync (for example, if the application process is not dynamically reloading modified files).

In practise, it works well and certainly supports a much more iterative development experience than you would get if you relied upon a Docker build from something like <code>draft up</code>, even assuming you had optimised your Docker build so it just needed to copy in the application files. As when running an application locally, all of this works best for interpreted languages like PHP, Python or Node. For a language like Java, you need to get the compiled application (or classes) in to the synced directory and that is unlikely to give you the same experience that you can get using an IDE capable of hot-reloading. That’s something that Microclimate looked to address…

 

draft up

September 21st, 2018

For my next few posts, I thought I’d pick on some of the technologies that Jenkins X uses under the covers. The first of these is Draft, originally from Deis but it went with them to Microsoft. Draft’s aim is to streamline the process of developing code that runs on Kubernetes. It’s evolved a bit since it was originally released: having started with a client-server architecture, it is now entirely client based. There are many good reasons for this although one of the things that differentiated Draft originally was that it didn’t need anything on the developer’s machine other than Draft itself: not even Docker.

The part of Draft that Jenkins X uses is the ability to add a Dockerfile and Helm chart to an existing project. The combination of Dockerfile and Helm chart is stored in what Draft calls a ‘pack’. On running a draft create, Draft does some nifty analysis to detect the language being used in the project in order to select the appropriate pack to use. As you and I know though, language alone is not going to tell me whether I’m, say, running an executable JAR or providing a WAR file to run on an app server. Fortunately, there’s a --pack option so I can tell Draft which pack to use. The pack mechanism is nicely extensible with the ability to specify new repositories (simply a Git repo containing a packs folder). The packs used by Jenkins X (which include one for Liberty even if it isn’t very good) can be found here. Draft is also clever enough to know that, if I already have a Dockerfile or chart, I probably don’t want the one from the pack instead.

Once I have a Dockerfile and chart, the next step is to deploy my application using draft up. Draft’s expecting to find the Kubernetes context and Helm already set-up. It’ll build the Docker image and if a registry is configured push the image there. The latter isn’t compulsory though so if I’m using Docker Desktop (the new name for Docker for Mac/Windows) or have my Docker client pointing at my Minikube Docker daemon then I can just use the image out of the cache. It will then use Helm to deploy the application, passing through overrides for image.repository and image.tag to reference the image that’s just been built (using a unique tag). It will even set up an imagePullSecret if necessary. You can use draft logs to see the output from the build and deploy.

Originally, Draft came with a ‘watch’ mode where it would attempt to detect file updates and automatically rebuild. Thankfully that now seems to have been dropped as, with a completely unoptimised build cycle, it really wasn’t practical. The Java pack is particularly bad as the provided Dockerfile doesn’t even attempt to cache the Maven dependencies. Now you simply run draft up again to trigger a rebuild (which you could hook up to your editor’s save option if you really wished).

The last part of the Draft developer experience is draft connect which pipes the logs from any deployed containers to your terminal, along with setting up port forwarding. Sensibly, it allows you configure the local ports that you want to forward to and this, along with other configuration, can be stored in a draft.toml file with your application. (The authors have to be congratulated for breaking with the current trend and using TOML rather than YAML!)

There are a few extra niceties in that you can define additional plugins (arbitrary commands that share the Draft meta-data via environment variables) and you can define tasks for a project that execute pre-up, post-deploy, and on cleanup. If, like me, you left wondering where these are documented, check out the Draft Enhancement Proposals where they were introduced.

All-in-all, there is nothing here that couldn’t be achieved here by scripting together a few standard commands but just because it’s simple, doesn’t mean that it isn’t useful. It’s one of many projects that are attempting to reduce developer friction when deploying to Kubernetes, and you can expect a few more posts covering others…

Jenkins X

September 19th, 2018

Having started to get some rhythm back in to the publishing of my personal blog posts, I thought it was about time that I started posting some technical content again too. I’m having to do lots of new learning at the moment and, if nothing else, writing about it makes sure that I’ve understood it and helps me remember at least some of what I’ve learnt. As before, these posts in no way indicate the position of my employer nor, in general, should you read in to them anything about technical direction. On the whole, they are just about topics that I’ve found sufficiently interesting to write a little about. There is, I have found, no knowing what will be of interest to other people (my all-time top post relates to Remote Desktop!). From an entirely selfish perspective, I don’t care if anyone reads what I write as it’s largely the writing that gives me value!

Having said all the above, the subject of this post is Jenkins X which is very much in the domain of my new employer! When it was announced back in March, I have to admit that I was somewhat sceptical. It was clearly aiming at much the same space that we were with the dev-ops part of Microclimate. My view wasn’t helped by the fact that I couldn’t actually get it to run. It did (and still does) run best out on public cloud but I used up my free quotas on AWS and GCP a long time ago. I tried to run it on minikube and failed. It was also developed by the team behind Fabric8 which, although it showed lots of promise, was never incorporated in to any of RedHat’s commercial offerings. The same was not set to be true of Jenkins X and, six months later, my new employer has just announced that it now forms part of the CloudBees Core offering under the name of Kube CD. I’ll save details of that commercial offering for another post and restrict myself to talking about the open source Jenkins X project here.

So what exactly is Jenkins X? It enables Continuous Integration and Continuous Deployment, of applications on Kubernetes. It happens to use Jenkins as the engine to perform those actions but, at least at a first pass, that is immaterial. Around that Jenkins is wrapped lots of Kubernetes-native goodness and, most importantly, a CLI by the name of jx. Thankfully this time around the minikube experience worked for me just fine and getting up and running was as simple as:

I have to say that I’m not a big fan of ‘verb followed by noun’ when it comes to CLI arguments as, although perhaps more readable, it makes end-user discovery harder (jx create tells me about a whole long list of largely unrelated things) but thankfully just typing jx gives a reasonable overview of the main options. Beware though that the CLI is heavily overloaded: it’s not only used for initialisation, but also subsequent actions performed by the developer, and those performed by the pipeline.

Perhaps the quickest way to demonstrate the capabilities is to then use a quick start:

This allows you to select a technology stack (everything from Android to Vert.X via Rust, Rails and React!) which lays down a skeleton application on disk. It then uses Draft to add a Dockerfile and Helm chart(s). It doesn’t stop there though. It will then help you create a repo on GitHub, check your code in, set up a multi-branch pipeline on the Jenkins instance it provisioned, and set up the web hook to trigger Jenkins on subsequent updates. (Webhooks don’t tend to work too well unless your minikube is internet facing but, given a bit more time, polling does the job eventually.) The default pipeline (defined by a Jenkinsfile in your application repository) uses Skaffold to build the application Docker image and push to a registry. The Helm chart is published to the provided instance of ChartMuseum.

Jenkins X follows the GitOps model promulgated by Alexis Richardson and the team at Weaveworks. By default, it sets up two GitHub repositories that map to staging and production namespaces in the Kubernetes cluster. Additional environments can easily be defined via, you guessed it, jx create environment. These repositories make good use of ‘umbrella’ Helm charts to deploy specific versions of each of the application charts. By default, the master branch is automatically deployed to the staging environment but promotion to production is performed manually, for example:

There is also the concept of a preview environment. Typically created for reviewing a pull request, they can also be created manually via the CLI. These allow a specific version of the application to be accessed in a temporary namespace created just for that purpose. All of the Jenkins X configuration (environments, releases, …) are represented in the Kubernetes way: as Custom Resource Definitions.

There’s plenty more to say about Jenkins X but I’ll save that for another post on another day. Hopefully this has given you enough of a flavour to encourage you to download the CLI and give it a try for yourself.

Heathcote Mausoleum

September 16th, 2018

Despite having blogged about it here a week ago, I still failed miserably to sign up for any of the Heritage Open Day activities this weekend. We returned to Hursley this afternoon though for one that didn’t require booking. It’s a building that I’ve passed numerous times, generally en-route from work to the Dolphin pub in the village! It stands in the grounds of the church and is the mausoleum constructed by the Heathcote family (who built the main body of the current Hursley House) over 200 years ago.

The details indicated that it had space for 35 coffins on either side. Somehow, I had assumed that this meant it descended underground. It hadn’t occurred to me that they’d just be stacked five stories high! The plaque on the outside shown here indicates that Samuel Heathcote is buried instead in the churchyard, going to the lengths of being buried 12ft deep to ensure that no-one tried to exhume him to move him to the family mausoleum! He wasn’t the only one to prefer the ‘open air’ with eleven other members of the family being buried outside. The last ‘deposit’ in the mausoleum was in 1925 but there’s still plenty of space for more…

Hursley 10k

September 16th, 2018

It was Christine’s turn to run the Hursley 10k this year so the rest of us went along to spectate (Emma is always keen when there’s prospect of a cake stall!). There was lots of Eastleigh Running Club orange out for us to cheer on. As you’d expect given the location, there were also a few IBMers although, looking at the results, I also failed to spot many I should have seen.

On Christine’s return, I raced off for a quick run (a chance to knock out the September Challenge). It took longer than I anticipated but I made it back just in time to see Duncan cross the line in the KS2 race. He seemed pleased with his run. It’s just a shame that it’s another four years before Emma is allowed to take part in any of the races again.

More photos on Flickr.

Bursledon Bricks and Mill

September 9th, 2018

As part of this year’s Heritage Open Days we went along to Bursledon Brickworks (actually on the Swanwick side of the river for the pedants). We started with a ride on the narrow gauge railway although the particular specimen on show today wasn’t anything to write home about. We then went in search of one of the ‘heritage’ buses that was meant to be running to the windmill. There were several buses parked up in the courtyard but none moving and when I was asked whether I was ‘interested in buses’ we retreated to the brickworks itself.

The museum itself is quite well done, at least in parts (it has had significant lottery money spent on it). The site was still operational until the early seventies when it was cleaved in two by the M27. The steam workings are still operational although not making bricks (and the steam was being generated by a very modern looking boiler). Following on from my earlier rant, the children were given a quiz that required them to actually read the signs AND we didn’t have to pay for a pencil (I’m looking at you English Heritage!). The prize was a few old pennies to spend in the arcade which they enjoye. There was also an interesting display on the brickworks’ predecessor in Chandler’s Ford.

We tried to get on the one o’clock bus to Bursledon Windmill but it was already full. This gave the children a chance to make clay bricks by hand though. They brought them home although they’ll take 2-3 weeks to fully dry out. After a spot of lunch we made it on the two o’clock bus (just) but when we arrived at the windmill we were told that the tours were full for the rest of the day. We took a quick look round outside and then got another bus back to the car. We’ll have to decide whether to return another weekend to (pay and) see inside.

All in all, it was a reasonable way to spend a few hours and, given both sites are staffed by volunteers, one shouldn’t grumble too much about the lack of organisation. If you’re at a loose end next weekend then there are lots more attractions open across the UK and, if you’re local, particularly in the Winchester area.

Double Celebration Weekend

September 2nd, 2018

This weekend we were signed up for a double-header of orienteering. On Saturday it was the British Sprint Champs at Bath University. We were there early as Christine’s parents were running the local parkrun and returning the children to us beforehand. The first-class sports facilities at the University made an excellent assembly area for the event. We had mixed fortunes in the heats. Christine and I made it through to the A finals but both the children were disqualified for wrong controls (it was a tricky area to plan easy courses on). Christine was fourth in her final and Duncan managed a first in his B final. I faired less well making one bad route choice through the multi-level section and losing my head completely on a later leg.

We spent the night in Glastonbury and had a nice dinner out at Tamburino’s in Street. On Sunday it was the Middle Distance Champs at Stock Hill near Wells. Despite a panic whilst we tried to find where Duncan’s SI card had ended up (down the back of his car seat!) we arrived in plenty of time for Christine’s start. Duncan had a good run on M10, finishing 7th. Emma was 8th on W12 although in a smaller field. She made a 10 minute error on one control though on what looked like a tricky orange course. I also managed 8th place despite making several blunders – not surprising given that I wasn’t really reading any of the contour detail on the map!

Christine had the start performance: a place on the podium and a silver medal. And the double celebration? It was also our wedding anniversary!

(Sprint photos courtesy of Gerry Ashton.)

Not so sunny Severn Half

August 29th, 2018

On Sunday both Christine and I lined up at the start of the Severn Bridge Half Marathon in the pouring rain. We had free entries as a consequence of Christine’s parents helping and neither of us had done anything in the way of preparation. In my case, I’d also had some stomach bug for the proceeding three days. As a consequence, I really had no idea how I’d do, or even whether I’d finish.

The race starts at the Welsh end of the bridge, heads over to England where it does a loop in the country lanes before returning back over the bridge. I felt okay at the start and my pace was forced a little by a feeling that I should be ahead of the guy pushing the running buggy (although he was aiming for under 90 mins). I fell in behind a runner from the local club who, it seemed, was aiming for negative splits as the pace picked up when we passed through the halfway point.

That said, when we arrived at the bridge again, I was still feeling pretty good and left him behind as I realised that I might just be able to make it back in under 1:25. As the results show, clock time was 1:24:54 with three seconds less on the chip. Not a PB by any means but still much better than I was expecting when I set off. Christine was also pleased with her time having come in well under 1:45. Comparing with her medal from last year, someone appears to have added a sun above the bridge this year – something we certainly didn’t see all day! The children seemed to have enjoyed their time on banana duty though despite getting soaked through their waterproofs!