Oct 12

Your First Azure Kubernetes Service Cluster – Using .NET Core MVC Website

In this post I’m going to show you the steps I do in my conference talk “Getting Started with Azure Kubernetes Service”.

Prerequisites

To start with, you need to have a few things. If you don’t already have an Azure account look at getting some free resources at https://azure.microsoft.com/en-us/free/

I’m on a Windows 10 system with Bash enabled and Ubuntu installed. I like using WSL with Ubuntu because my target OS type for my microservices and websites run on Linux. It helps me stay sharp with Linux commands, etc.

I have .NET Core installed. Make sure you have the latest version. https://www.microsoft.com/net/download

I also have Docker for Windows so I can build the images. You’ll see this later in this post.
Other things you’ll need is the AZ CLI. Once that is installed you can execute the AZ command to install the Kubernetes CLI

az aks install-cli

Hopefully everything is installed and ready at this point. Now, from your terminal, you need to log into your Azure Subscription.
Execute the following command will give you a series of characters you use at the site https://microsoft.com/devicelogin.  If not already logged in you’ll be prompted to log into your Azure subscription. Once done your terminal will show some details of the subscription you just logged into.

az login

Build a Cluster

In my talk I mention a script that I use to create a cluster and an Azure Container Registry. I found the script some time ago and tweaked it a little. It uses AZ commands so you’ll need to make sure you’re logged into the subscription you want first. I recommend making a copy of the commands in the script, paste into a text editor, then modify to your needs. Start with the Environment Variables at the top. **Warning** It takes roughly 15 minutes and could be longer. Most of the time is taken waiting for the VM’s to be provisioned and come online. The script is located at https://gist.github.com/seanw122/e7b43b543f2a44be767739ce3866237f

Building the MVC Site

While the cluster is being created you can create the ASP.NET MVC site. On your computer create a new folder. The name of the folder will be the name of the project so chose wisely. In my example I have a simple name of proj1. Amazing name I know.
So, now I have my folder “D:/code/proj1”. In the address bar of the window click once. It should highlight the whole string. Type cmd and press Enter. You should see the Command Prompt window located at “D:/code/proj1”.
Now for some .NET Core. Type in the following command. It will create an ASP.NET MVC website using a generic template.

dotnet new mvc

After the site is created you’ll see several files. Find in the Controllers folder the file HomeController.cs. Edit that file and modify the method About:

public IActionResult About()
{
    ViewData["Message"] = "My About page. " + Environment.MachineName + ": " + Environment.OSVersion + ": " + DateTime.Now.ToString();
    return View();
}

This shows the Machine Name, OS Version, and the current date and time in UTC.
This is point out that the machine name is the name of the pod it is running on. The OS Version will prove that it’s running on Linux though it will show “UNIX” with some version. The date and time shows the page is running live.

Now create a new file name “Dockerfile” with no extension then put in the contents:

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .
RUN dotnet restore proj1.csproj
RUN dotnet build proj1.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish proj1.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "proj1.dll"]

Place this file in your proj1 folder. It needs to be there for the next command to work.

 

Docker Image

Now we’ll use Docker to build an image, tag to a different version, then push to our new Azure Container Registry.

docker build . -t myproj:v1

docker tag myproj:v1 {ACR Name}.azurecr.io/myproj:v1

docker push {ACR Name}.azurecr.io/myproj:v1

The first command builds the image. It will pull the image for .NET Core, ASP.NET Core then layer on our new MVC site.  The second command adds a tag to the image. There is only one final image. Now it has two tags. I do it this way so there is one for local and one specific to the ACR we’re pushing to.  Be sure to replace the {ACR Name} with the actual ACR Name you used in the script to create the cluster. The third command pushes the image to ACR specified in the tag.

In the case where the push tries but fails stating “Authorization Required”, use the following command to login. Be sure to use the name of the ACR you’re targeting without the curly braces.

az acr login --name {ACR Name}

 

Deploying to Cluster

By now the image should be successfully pushed to the Azure Container Registry. With you text editor create two new files and place the following contents.

First file save as <i>myproj-service.yml</i>

apiVersion: v1
kind: Service
metadata:
  name: my-project-service
spec:
  selector: 
    app: my-project-server
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: 80

And the second one as <i>myproj-deployment.yml</i>

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-project-deployment
spec:
  replicas: 3
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: my-project-server
    spec:
      containers:
        - name: my-project
          image: {ACR Name}.azurecr.io/myproj:v1
          ports:
            - containerPort: 80

 

Using the same terminal used to create the cluster we’re going to send these two files to the cluster to create a Deployment of 3 Pods that is accessible by a Service.  First you may need to navigate to the folder where you created these files. In my example I created the files in the same location as my MVC site, “D:/code/proj1”. To navigate to that location:

cd /mnt/d/code/proj1

Now execute this command to list the files and verify the two files we’re going to send are indeed in the folder.

ls -al

Now to create the Service. Why Service first?  In our case it will obtain a public IP address and that takes a few minutes. So, we should get that started now.

kubectl create -f myproj-service.yml

With the Service creation on the way we’ll now create the Deployment and the Pods.

kubectl create -f myproj-deployment.yml

A Deployment specifies information about the Pods to be created. Behind the scenes it creates a Replica Set. In our example we have it set to 3 replicas. The Scheduler works to maintain that number of active Pods.

To see the status of our Service execute:

kubectl get service -o wide

Look for your Service listed and the associated External IP address.  It may still be <i>Pending</i> in which case just wait a minute and try again.

Once you have an External IP address copy that address and we’ll put that in a browser’s address bar. But, note the port number. In this example it’s set to 8080. So, be sure to specify that in the browser as well.

Now your new site should appear!  Click on the link at the top for About. In the text that appears you should see the machine name, OS Version, and date & time.  The machine name is the name of the Pod that is hosting that request of the web server. The OS Version will say “Unix” plus some version numbers.

 

Congrats!

You created a new Kubernetes cluster on Azure and now hosting a new ASP.NET MVC website. There’s SO much more about AKS. To get a list of links I found useful go to my other post at http://seanwhitesell.com/2018/06/23/resources-for-getting-started-with-azure-kubernetes-service-with-net-core-prometheus-and-grafana

Jul 23

Latest Kubectl – Older Cluster

I’m currently working Azure Container Service “ACS” until Azure Kubernetes Service “AKS” is available in my production data center. Why? Because if I use an Azure service in a data center but have data in another data center then I have to pay data egress charges. Anytime data comes out then you have to pay for it. So for now I’m have my ACS v1.7.7 setup.

I just configured another laptop to connect to the cluster. I installed the AZ CLI then Kubectl CLI. After making sure things were authenticated to the cluster I tried a simple command.

kubectl get pods

 

to which I received the this error message:

No resources found. Error from server (NotAcceptable): unknown (get pods)

 

I ran the command on my other working system and things are fine. The cluster responded with the list of pods I expected to see. So, what’s the problem??

That’s when I remembered that Kubernetes 1.11 just became public. The Kubectl CLI I just installed is 1.11. Apparently, it has issues with a cluster from the 1.7.7 version. Which, by the way, is the latest version you can have in ACS!

*sigh* Ok, so thankfully I was able to downgrade the Kubectl CLI to a previous version.

sudo apt-get remove kubectl

 

then

sudo apt-get update -q && \
sudo apt-get install -qy kubectl=1.10.0-00

 

I then re-authenticated to the cluster.

az acs kubernetes get-credentials --resource-group {resource group name here} --name {name of azure container service here} --ssh-key-file {path to key file here}

 

then

kubectl get pods

 

returned the list of pods expected.

Jun 23

Resources for “Getting Started with Azure Kubernetes Service with .NET Core, Prometheus, and Grafana”

Intro

This is the best post I have found for getting started with containers and running them on Azure Container Services:
Run .NET Core 2 Docker images in Kubernetes using Azure Container Service and Azure Container Registry | Pascal Naber

When you have Kubernetes (K8s) up and running you’ll want to view the Kubernetes Dashboard. I have seen many tutorials on how to get it started and the link they mention never worked for me. So, I simply do

1
kubectl proxy

It starts a proxy connection between the cluster and your localhost.

The link to view the dashboard is http://localhost:8001/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/#!/overview?namespace=default.

But notice the version is V1. There will be a time when that link will need to be updated for a newer version.

Script to create a new resource group, Azure Kubernetes Service, and Azure Container Registry https://gist.github.com/seanw122/e7b43b543f2a44be767739ce3866237f

.NET

I have way too many so I’ll show one for now.
Pro C# 7

Docker

Play with Docker Classroom
eBook – Docker in Action 2nd Ed.
A Developer’s Guide To Docker – Docker Swarm | Okta Developer
Dockerize a .NET Core application | Docker Documentation
50+ Useful Docker Tools | Caylent
Interactive Browser Based Labs, Courses & Playgrounds | Katacoda
Running Docker containers on Bash on Windows – Jayway
Introduction to containers and Docker | Microsoft Docs

Kubernetes

eBook – Kubernetes in Action
kubernetes/autoscaler: Autoscaling components for Kubernetes
brendandburns/k8s-playbooks: Some ansible playbooks for managing my k8s cluster(s)
Web UI (Dashboard) | Kubernetes
Watching auto-recovery
Azure: “Kubernetes the Easy Way” Managed Kubernetes on Azure AKS | E101 – YouTube
Kubernetes Co Founder Brendan Burns Orchestration is Becoming a Commodity – YouTube
Scaling Docker Containers using Kubernetes and Azure Container Service – Ben Hall – YouTube
Workloads – Kubernetes Dashboard
Ben Hall’s Blog – I don’t know darling, I’m doing my work
az acs kubernetes | Microsoft Docs
Introducing Play with Kubernetes – Docker Blog
Kubernetes Security: from Image Hygiene to Network Policies // Speaker Deck
Overview – Kubernetes Dashboard

Azure Container Services

Azure Region Availability
Azure Container Service – How to change your public key | Azure Container Service | Channel 9
Building Microservices with AKS and VSTS – Part 1 – Azure Development Community
Building Microservices with AKS and VSTS – Part 2 – Azure Development Community
Building Microservices with AKS and VSTS – Part 3 – Azure Development Community
A Closer Look at Microsoft Azure’s Managed Kubernetes Service – The New Stack
Introducing AKS (managed Kubernetes) and Azure Container Registry improvements | Blog | Microsoft Azure
SSH into Azure Container Service (AKS) cluster nodes | Microsoft Docs
Frequently asked questions for Azure Container Service | Microsoft Docs
Your very own private Docker registry for Kubernetes cluster on Azure (ACR)
Service principal for Azure Kubernetes cluster | Microsoft Docs
SSH keys on Windows for Kubernetes with Azure Container Service (ACS) | Pascal Naber
Setting up a Kubernetes cluster with Azure Container Service: Terraform, Azure Resource Manager, CLI
Manage Azure Kubernetes cluster with web UI | Microsoft Docs
Manage Azure Container Services cluster with web UI | Microsoft Docs

Prometheus

How to Setup Prometheus Monitoring On Kubernetes Cluster [Tutorial]
A monitoring solution for Docker hosts, containers and containerized services

Grafana

https://grafana.com
Monitor Azure services and applications using Grafana | Microsoft Docs

Jun 23

Dockerizing an Existing App

I have been playing with Docker for a bit now and have always started play apps with Docker enabled. I decided to Dockerize an existing app. Ok, so, Right-click on project, select Add, then Docker Support. Ok great, there’s my additional project in the solution for Docker-Compose. I then decide to start debugger with Docker environment as primary. It fails to build. That’s strange. So, I do a Clean and Rebuild. Same issue. Docker-compose is complaining about a npm package that is not even in my project but in another app altogether! Sheesh!

When you Dockerize your app, select that project and then Show All Files. What I found is that the Docker-Compose files are in the parent folder of my application. It now sees and attempts to use ALL projects in the sub-folders from that point.

Simple solution; copy the solution file, Docker-compose files, and my application folder to a new parent folder. Now it only has my application(s) and Docker-Compose.

Aug 05

Speaker Confession

@geekygirlsarah helped start a trend called #speakerconfessions. I just submitted mine.

In 2016 at Tulsa TechFest I gave two talks back to back right after lunch. I was congested at lunch so I took an antihistamine and drank a bottle of water. During my talks I always drink water. So,during my first talk I drank another bottle of water. Then, in between sessions, I went to the bathroom. Well, 20 minutes into my 2nd talk I had to leave to pee again!

Aug 05

KCDC 2017 – Intro to OAuth2

On Aug 5th I had the pleasure of giving my Intro to OAuth 2 talk at KCDC 2017, {speaker}. As promised I’m including here the related information. The talk was a general overview of what OAuth is and an example of an “Authorization Flow”. In upcoming posts I’ll go over OAuth in bit more detail.

The talk was from the perspective of the Application and of the User. This post does not go over how to be an OAuth provider.

To get started creating your own application with Google:
1. Create the application
2. Google OAuth Details
3. Google Scopes

Spotify:
Beginning Tutorial

Recommended Blogs:
Aaron Parecki
Digital Ocean

Recommended Books:
OAuth 2 in Action
Mastering OAuth 2

My slide deck:
OAuth 2 Slide Deck

Code samples ASAP

Feb 27

Do it Right Now or Do it Right, Now?

“Do you solemnly swear to tell the truth, the whole truth, and nothing but the truth, so help you God?” Those can be scary words. When you hear those words you’re likely on the witness stand. The real problem is when it is YOU that is being sued. Incompetence on your part has lead to a bug. A bug that in turn lost millions of dollars for your employer or a client. Or far worse, that bug lead to the death of an occupant of a vehicle. “Do it right now” versus “do it right, now” having vastly different implications. As professionals it is our duty to apply the quality in our craftsmanship so the highest quality output is obtained. But, to do so comes at a cost. It takes a lot of extra time, effort, and forethought to have that quality. Generally deadlines are set for us and we feel that line cannot move.

Ok, the client set the deadline. It is a nearly impossible deadline. You and your team work furiously day and night to reach that deadline. In the end there are of course bugs. Processes and/or requirements have changed during the development cycle. Not enough checks and balances were done along the way. And finally a sub-par solution is presented to the client. Who’s responsible for the defects? Who’s responsible for the money and/or people hurt over time? Why was the client not told what they require could not be obtained by that deadline?

“Your honor I was merely obeying orders.” Following orders does not always save your tail. Ultimately we programmers, we professionals, we so called experts have the right to say NO. Yes the client dictated the deadline. But, what if you lost that client and the project went to someone else? Then it is not you on the witness stand trying to defend your actions by blaming the orders given. Sometimes the best outcome for us it to lose a client or a job where the best quality was not possible to apply.

I believe it will happen one day when programming professionals will be required to have some form of certification much like nursing or a physician. It will include a state level board exam. It will cost thousands. And it will cause the price of development to sky-rocket. That is not a favorable outcome.

It is impossible for us programmers to know everything. But, that is not a requirement. We are, however, required to do our best. Sometimes telling our managers and/or clients NO is the best answer. Sometimes a little loss helps us keep our head up high in our efforts to strive for quality in ourselves and in our craftsmanship.

So, are you going to do it right now OR are you going to do it “right”, now?

Nov 30

Willingness to be Wrong

In user group meetings I sometimes ask questions of which I already know the answer. I do this because I know there are a few attendees that are either intimidated by crowds and/or may have a pier/coworker in the audience and they don’t want to appear as stupid. I don’t mind asking those questions on their behalf. However, there are also times when I’m wrong in my understandings or assumptions. Anymore I don’t mind being wrong for the sake of learning. It’s also helpful when I’m wrong that others learn at the same time.

The willingness to be wrong allows us to be humble and thus open to learn. If I continue to fight for my (wrong) assumptions then I’m not learning. I’m only making it harder on myself and anyone willing to help teach me. “Is this the hill you want to die on?” That’s a great question I need to be reminded of often. We grow more and faster when we put aside our misunderstandings, humble ourselves, and listen.

There’s a phrase in martial arts called “Empty the Cup”. In order for us to learn we first must set aside what we know (or think we know) to allow new knowledge to come in. It stops us from making snap judgments and jumping ahead. I know for myself it’s easier to teach a student willing to listen and simply do what is asked of them. I teach programming and also self-defense. I see the different types of students. Regardless of age it’s easy to identify the students who want to learn versus those who are required to attend. I’ve seen young students in self-defense more eager to learn new things. I’ve also seen adult students who couldn’t empty the cup and learn new programming lessons. Age does not mean you are wiser. It means you have had more opportunities to grow.

Though I’m a teacher I’m also a student. I too must be reminded to empty the cup, breathe, and learn. But it starts with a willingness to be wrong. Don’t allow yourself to believe being wrong is a bad thing. Learning from your mistakes and those of others is a great gift.

http://thecodelesscode.com/case/100

Sep 23

Try it Another Way

How many ways can you reverse a string? An issue exists where the remaining solution is the first one made that works. This is rarely the right way to write code. We write code to solve problems. Just because a method is written and works does not mean it was the best way to solve the problem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private string Reverse1(string value)
{
    string newValue = "";
    for (int i = value.Length-1; i >= 0; i--)
    {
        newValue += value[i];
    }
    return newValue;
}
 
private string Reverse2(string value)
{
    if (string.IsNullOrWhiteSpace(value)) return "";
    var newValue = value.Substring(0, value.Length - 1);
    return value[value.Length - 1] + Reverse2(newValue);
}
 
private string Reverse3(string value)
{
    return new string(value.Reverse().ToArray());
}

I’m using these simple methods to reverse a string to show a point. These are not the only ways to reverse a string. The point is that are other ways. When a solution is made try rewriting it. Challenge yourself for other ways to solve it. What are better ways that use different techniques and/or more efficient. Perhaps a new Dependency Injection tool should be evaluated or learned. Perhaps your solution should make use of multi-threading. Don’t just stop with the first solution to the problem but instead master it.

Aug 07

Tulsa TechFest 2016

Had a great time at Tulsa TechFest 2016 this year. I gave two talks; “Converting Crap Code to a Better Design” and “A Look at the Plug-In Architecture”;  I had over 40 people in the converting crap code session. We went further than I planned and went into the next phase of the project and talked about plug-ins. So, on the plug-in talk I only had about 20 people. That’s OK. In the plug-in talk I showed “Poor Man’s IoC” and MEF to find classes that implement a specific interface. Then I showed a very brief example of Autofac using dotnetfiddle.

 

Older posts «

hublot replica | replica watches | cartier replica sale | breitling replica sale