Update 17th April 2018 - all parts are now available:
If you happen to find yourself about to build a new application, and you bump into an architect they will tell you that it's very important that it needs to support a "microservices architecture". (This will of course happen before considering if it really should be built that way.)
If you ask what tools you need to utilize to achieve this state of bliss you shouldn't be very surprised if the name Kubernetes is uttered. (It is after all almost the de facto standard for orchestrating containers these days.) It's usually shortened to k8s so I'm probably going to switch between the two terms going forward.
If you ask around how to build a Kubernetes cluster you will get a couple of different answers. If one of them involves Azure it's possible that AKS (Azure Kubernetes Service) is mentioned, or managed Kubernetes as it's also known. Being managed it takes away some of the grunt work involved with setting up the cluster from scratch and keep it running. Confusingly enough there is a service called ACS (Azure Container Service) which supports a number of orchestrators, including Kubernetes, and ACS-AKS which is specific to Kubernetes.
Wait a minute, isn't the Microsoft answer to this something called Service Fabric? Yes, that is also an option. I wouldn't call it a direct competitor to Kubernetes though. It handles more of what is required for a microservices architecture, but to take full advantage of it you might find yourself needing to write the code itself differently. This post isn't an evaluation of which of these are better suited for a given scenario; I happen to have defined that the learning point today is the Kubernetes stack 🙂
If you want more on the theory behind microservices Gaurav is running a separate series that I can recommend:
Enough with the pre-amble. For some reason you have landed on wanting to use AKS, and you're wondering where to start. If you want to really learn the ins and outs of Kubernetes you can go through "Kubernetes The Hard Way on Azure" (https://github.com/ivanfioravanti/kubernetes-the-hard-way-on-azure) - impressive guide, but kind of a good example of why you would want to go the managed way as well 🙂
So, you hit the official documentation as well as the search engines, and you start finding yourself more confused by the minute. While individual docs can be good, they often focus on a very specific part, and sometimes it feels like there's something missing for completing the picture. The cloud is supposed to be easy isn't it? Yes, but it turns out there are a lot of moving parts involved in getting this to actually work. I'm not going to try to cover everything in detail, but I will attempt to get as much as possible up and running on the Microsoft stack of services.
Here's the high level agenda of what we want to cover:
- Building a sample app in Visual Studio locally.
- Dockerize it locally.
- Check the code into a repository that also handles Continuous Integration (CI) and Continuous Delivery (CD).
- Push images into a container registry.
- Pulling above images into an AKS cluster.
- Expose the services outside the cluster.
- Automating DNS.
- Automating SSL/TLS.
This is about how you get your code from your IDE to a production-ish state. ("ish" because you might want to bolt on some extra things around availability and scale if you're making money from your code.) The developer "inner loop"; what you do before you push to prod is not covered extensively here.
There are a number of ways you can architect and implement a Kubernetes cluster, so this isn't the ultimate or necessarily best approach for you. It is however an approach that should bring you to a working setup, and give you an understanding of the basics of using Kubernetes for your microservices.
Building a web app
Since this isn't about how to build a web app in general you can technically just step through a wizard in Visual Studio to get a hello world type app. I will be using my API-Playground app, and since it is available on GitHub you can follow along and use that too if you like:
Before we move things to the cloud you should make sure that this actually builds and runs locally. (Restore packages, build, and F5.)
If things build as expected, and you can actually test things on localhost, you will want to add Docker support. If you don't have it up and running already I recommend downloading Docker for Windows, and installing it. You need Windows 10, and you need virtualization support in your CPU for enabling Hyper-V. (If you don't have this you can still follow along; you're just not able to test the image locally.)
Stable vs Edge
There are two types of builds of Docker; the Stable and the Edge (beta). If you run the standard builds of Windows 10 you can choose to with Stable. However I have found that if you run Windows Insider builds things occasionally breaks, and when the fix arrives it comes to the Edge release first. So with beta Windows go for beta Docker 🙂 (Edge can of course be installed on regular Windows builds too.)
Setting up Visual Studio Team Services (VSTS)
Visual Studio supports a number of options for deploying code directly from your laptop to a hosted environment, be it on-premises or cloud. However even for your hobby projects it is easier to check code into a repository and handle things from there. Why am I not using GitHub in this article? I use GitHub for a lot of my personal code, but VSTS offers some integration points to Azure that GitHub doesn't. (If you like you can use GitHub for the source, and just use VSTS for CI/CD, but let's not complicate the scenario further here.)
I will assume that you already have an account for VSTS; there's no cost for your one-man personal projects, and since they are private there's less risk of messing up with secrets and stuff. (Which is nice compared to GitHub where only public repos are free.) If you use the same account for signing in to VSTS, and Azure, that will simplify things later on.
There are different approaches for the initial setup depending on whether you're starting from scratch or not, but I will check in what we already have. (I did not clone my own repo, and just downloaded and extracted the .zip file which means it is not a repo yet.)
Go to the command line and do a git init in the root directory.
There's things that could differ in my setup, and what you have running on your computer, so I can't really guarantee things will be 100 percent like the above. Maybe you didn't install Git when installing Visual Studio, maybe you haven't logged in to Visual Studio with the same account as VSTS. I'm just hoping the above process is clear enough that you might sort out minor snags on your own 🙂 (That's promising for a tutorial/walkthrough I guess.)
Ok, so if everything went to plan we have code locally, and we have code in the cloud. This is a good start.
Now you can add Docker support for the project. Right-click the project in Visual Studio (API-Playground)->Add->Docker Support
To verify that all is good on your devbox you should try out the F5 experience. By default you're probably deploying to IIS Express, and this should now have changed to Docker as the deploy target. (The default image should contain the necessary pieces to host web components.)
This doesn't technically mean we have built a microservice yet. What we have is a monolithic app that has been primed for promotion to a microservice when the time is right.
Let's pause for a moment here. (And forgive me if this is basic stuff you are already familiar with.) This image is a basic building block for proceeding. If I move this code to a different computer where Docker is installed I can have this up and running in a matter of minutes. (Visual Studio isn't needed either.) So it means we have removed the "it works on my machine" hurdle often preventing mass deployment. (Realistically there are still things that might trip you up, like a proxy component on the network level, different Docker version on the host, well - you catch my drift. But in general you now have a module that can be moved across environments.)
If you start splitting up your code into different images you could have www.contoso.com in one, and api.contoso.com in another. This leads you to setting up a shared Docker host that developers push images to, and you can replace the www part without affecting the api part. This is great for separating components, but you will run into new challenges.
Host goes down => services go down.
Service A needs to communicate with Service B => how do they do that?
Who takes ownership of the Docker host, opening firewall ports, mapping DNS and the like => developers, or operations?
Dockerfiles just describe one individual service, and if you have 5 services you have 5 Dockerfiles to maintain. Docker provides another abstraction layer where you define docker-compose files which describe relationships between containers. We will use these in our further setup. The new concern is that while managing 10 monolithic services can be daunting, managing 100 microservices isn't necessarily less work. Which is why you need something to "herd" your services. We often refer to this as an orchestrator, and k8s is just one of several options. At the risk of repeating myself; we have already decided that AKS is our choice for this purpose so we're still not comparing orchestrators, or different Kubernetes configurations 🙂
Make sure you save your code, and check it in to VSTS.
I think that rounds up this initial part of our exploration. So tune in to the next installment - same bat time, same bat channel, for more microservice goodness.