Category Archives: Work Related Stuff

AKS + Private Link Service + Private Endpoint

This walkthrough shows how to setup a Private Link Service with an AKS cluster and create a Private Endpoint in a separate Vnet.

While many tutorials might give you a full ARM template, this is designed as a walkthrough which completely uses the CLI so you can understand what’s happening at every step of the process.

It focuses on an “uninteresting” workload and uses podinfo as the sample app. This is because it’s easy to deploy and customize with a sample Helm chart.

This is inspired and leans heavily on the Azure Docs for creating a Private Link Service.

Architecture


Private Link Endpoint Service

Prerequisites

Assumptions

This walkthrough assumes you let Azure create the Vnet when creating the AKS cluster. If you manually created the Vnet, then the general steps are the same, except you must enter the AKS_MC_VNET, AKS_MC_SUBNET env vars manually.

Setup Steps

First, create a sample AKS cluster and install Podinfo on it.

# Set these values
AKS_NAME=
AKS_RG=
LOCATION=

# Create the AKS cluster
az aks create -n $AKS_NAME -g $AKS_RG

# Get the MC Resource Group
AKS_MC_RG=$(az aks show -n $AKS_NAME -g $AKS_RG | jq -r '.nodeResourceGroup')
echo $AKS_MC_RG

# Get the Vnet Name
AKS_MC_VNET=$(az network vnet list -g $AKS_MC_RG | jq -r '.[0].name')
echo $AKS_MC_VNET

AKS_MC_SUBNET=$(az network vnet subnet list -g $AKS_MC_RG --vnet-name $AKS_MC_VNET | jq -r '.[0].name')
echo $AKS_MC_SUBNET

AKS_MC_LB_INTERNAL=kubernetes-internal

AKS_MC_LB_INTERNAL_FE_CONFIG=$(az network lb rule list -g $AKS_MC_RG --lb-name=$AKS_MC_LB_INTERNAL | jq -r '.[0].frontendIpConfiguration.id')
echo $AKS_MC_LB_INTERNAL_FE_CONFIG

# Deploy a sample app using an Internal LB
helm upgrade --install --wait podinfo-internal-lb \
--set-string service.annotations."service\.beta\.kubernetes\.io\/azure-load-balancer-internal"=true \
--set service.type=LoadBalancer \
--set ui.message=podinfo-internal-lb \
podinfo/podinfo

Install Steps – Create the Private Link Service

These steps will be done in the MC_ resource group.

# Disable the private link service network policies
az network vnet subnet update \
--name $AKS_MC_SUBNET \
--resource-group $AKS_MC_RG \
--vnet-name $AKS_MC_VNET \
--disable-private-link-service-network-policies true

# Create the PLS
PLS_NAME=aks-pls
az network private-link-service create \
--resource-group $AKS_MC_RG \
--name $PLS_NAME \
--vnet-name $AKS_MC_VNET \
--subnet $AKS_MC_SUBNET \
--lb-name $AKS_MC_LB_INTERNAL \
--lb-frontend-ip-configs $AKS_MC_LB_INTERNAL_FE_CONFIG

Install Steps – Create the Private Endpoint

These steps will be done in our private-endpoint-rg resource group.

PE_RG=private-endpoint-rg
az group create \
--name $PE_RG \
--location $LOCATION

PE_VNET=pe-vnet
PE_SUBNET=pe-subnet

az network vnet create \
--resource-group $PE_RG \
--name $PE_VNET \
--address-prefixes 10.0.0.0/16 \
--subnet-name $PE_SUBNET \
--subnet-prefixes 10.0.0.0/24

# Disable the private link service network policies
az network vnet subnet update \
--name $PE_SUBNET \
--resource-group $PE_RG \
--vnet-name $PE_VNET \
--disable-private-endpoint-network-policies true

PE_CONN_NAME=pe-conn
PE_NAME=pe
az network private-endpoint create \
--connection-name $PE_CONN_NAME \
--name $PE_NAME \
--private-connection-resource-id $PLS_ID \
--resource-group $PE_RG \
--subnet $PE_SUBNET \
--manual-request false \
--vnet-name $PE_VNET

# We need the NIC ID to get the newly created Private IP
PE_NIC_ID=$(az network private-endpoint show -g $PE_RG --name $PE_NAME -o json | jq -r '.networkInterfaces[0].id')
echo $PE_NIC_ID

# Get the Private IP from the NIC
PE_IP=$(az network nic show --ids $PE_NIC_ID -o json | jq -r '.ipConfigurations[0].privateIpAddress')
echo $PE_IP

Validation Steps – Create a VM

Lastly, validate that this works by creating a VM in the Vnet with the Private Endpoint.

VM_NAME=ubuntu
az vm create \
--resource-group $PE_RG \
--name ubuntu \
--image UbuntuLTS \
--public-ip-sku Standard \
--vnet-name $PE_VNET \
--subnet $PE_SUBNET \
--admin-username $USER \
--ssh-key-values ~/.ssh/id_rsa.pub

VM_PIP=$(az vm list-ip-addresses -g $PE_RG -n $VM_NAME | jq -r '.[0].virtualMachine.network.publicIpAddresses[0].ipAddress')
echo $VM_PIP

# SSH into the host
ssh $VM_IP

$ curl COPY_THE_VALUE_FROM_PE_IP:9898

# The output should look like:
$ curl 10.0.0.5:9898
{
"hostname": "podinfo-6ff68cbf88-cxcvv",
"version": "6.0.3",
"revision": "",
"color": "#34577c",
"logo": "https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif",
"message": "podinfo-internal-lb",
"goos": "linux",
"goarch": "amd64",
"runtime": "go1.16.9",
"num_goroutine": "9",
"num_cpu": "2"
}

Multiple PLS/PE

To test a specific use case, I wanted to create multiple PLS and PE’s. This set of instructions lets you easily loop through and create multiple instances.

# podinfo requires a high numbered port, eg 9000+

SUFFIX=9000
helm upgrade --install --wait podinfo-$SUFFIX \
--set-string service.annotations."service\.beta\.kubernetes\.io\/azure-load-balancer-internal"=true \
--set service.type=LoadBalancer \
--set service.httpPort=$SUFFIX \
--set service.externalPort=$SUFFIX \
--set ui.message=podinfo-$SUFFIX \
podinfo/podinfo

# This might be easier to hard-code
AKS_MC_LB_INTERNAL_FE_CONFIG=$(az network lb rule list -g $AKS_MC_RG --lb-name=$AKS_MC_LB_INTERNAL -o json | jq -r ".[] | select( .backendPort == $SUFFIX) | .frontendIpConfiguration.id")
echo $AKS_MC_LB_INTERNAL_FE_CONFIG

PLS_NAME=aks-pls-$SUFFIX
PE_CONN_NAME=pe-conn-$SUFFIX
PE_NAME=pe-$SUFFIX

az network private-link-service create \
--resource-group $AKS_MC_RG \
--name $PLS_NAME \
--vnet-name $AKS_MC_VNET \
--subnet $AKS_MC_SUBNET \
--lb-name $AKS_MC_LB_INTERNAL \
--lb-frontend-ip-configs $AKS_MC_LB_INTERNAL_FE_CONFIG

PLS_ID=$(az network private-link-service show \
--name $PLS_NAME \
--resource-group $AKS_MC_RG \
--query id \
--output tsv)
echo $PLS_ID

az network private-endpoint create \
--connection-name $PE_CONN_NAME \
--name $PE_NAME \
--private-connection-resource-id $PLS_ID \
--resource-group $PE_RG \
--subnet $PE_SUBNET \
--manual-request false \
--vnet-name $PE_VNET

PE_NIC_ID=$(az network private-endpoint show -g $PE_RG --name $PE_NAME -o json | jq -r '.networkInterfaces[0].id')
echo $PE_NIC_ID

PE_IP=$(az network nic show --ids $PE_NIC_ID -o json | jq -r '.ipConfigurations[0].privateIpAddress')
echo $PE_IP

echo "From your Private Endpoint VM run: curl $PE_IP:$SUFFIX"

I created this article to help myself (and hopefully you!) to clearly understand all of the resources and how they interact to create a Private Link Service and Private Endpoint fronting a private service inside an AKS cluster. This has been highly enlightening for me and I hope it has for you too.

Urinal Noise

Coming from a guy who has a national reputation for licking people, one can imagine that it would take something fierce to really gross me out.

I also live pretty much an open book life, but there are some times that are sacred to me. Namely, when I’m releaving my bodily needs. I think that those are times that should be done behind closed doors and with no one else observing or even being aware. (I’ll admit that I’ve done my buisness while on the phone before, but it’s one of those things that I feel really guilty about and made sure that I was on mute during those un/comforting times. So, that makes it ok.)

Therefore, I was surprised when I walked into the work bathroom to find someone giving directions while operating “hands-free”. I then took it upon myself to ensure that his compantion was quite aware of his social faux pas (pis?). No hitting the back wall, I was aiming for the water, baby. I was somehow able to fill the entire bathroom with that famous sound and could tell that I made my urinal-neighbor quite shifty as he obviously was trying to quicken his own process. But these are things you really can’t rush. No really.

When he finally left (I forget if he washed afterwards), I felt somewhat guilty, but even more embarassed when I noticed I was laughing all by myself at a urinal. Great story for the next guy.

— Snoopykiss wants a mini. Cooper that is.

When w00t! goes wrong

One of my small pleasures in life is the art of subtle humor. My friend Matt Mussleman is the supreme king of such humor. I, on the other hand, tend to keep it to myself and many times too obscure or bizarre. For example, one of the servers I created at work is named Tatu, also one of the tools I wrote generates logs named TPS reports. I bond instantly to anyone to pick up on it.

I’ve decided to name my latest server “w00t”, my new desktop will be “yarr” and I’ve already got a “pago”. Unfortunately, as I write this, I’m at work fighting with Yarr and w00t. Thus producing a bunch of other four letter word exclamiations, but thankfully, most everyone is either gone or doesn’t speak English and is using a vacuum cleaner.

On a side note, the last time I really heard anything from the Aforementioned Brooke was right after she posted a comment on my site. Maybe I’ll hear from here again. 🙂

5 Years already?!

Didn’t I move to Dallas just a few weeks ago?Didn’t I start working for Nortel the day after that?
Didn’t I just buy my house?!
Then what the heck is this email saying that I’m getting a gift for my 5 years of employment?!!!


Hopefully, that doesn’t mean that I’m getting old.  Because that would probably require me settling down, getting married, having little rugrats, and being “responsible.”  I’ve successfully avoided all of that so far, and I plan on continuing to do so.


I plan on having a small taste of this whole, “family” thing coming soon as my house will soon have it’s “maximum family stability factor” tested when Melissa stays here for a few days before heading back to Maryland, and my mom and dad come to visit and bring my two nephews, Charles and Evan.  Yes, I will be good to see all of them; however, I’m not sure how high my “family tolerance” meter goes to.  I bet that it’ll be pushed to 11.


The Utah Swing Exchange is getting more and more on my mind as the time nears.  Yea!  I used to think that I would get some of my best new pics at Utah, but I’m starting to think that the prize winners can be the expressions I get when I tell them that I’m going to Utah to dance. 


“You’re going to Utah…to dance?!  They have music over there?””You mean, you don’t know these people and you’re going to stay with them?”


I should have my pics from my second trip to the Scar. Renaissance Faire up soon.  Word to the wise:  Don’t go when raining.  Blah.

Lindy Gras a cometh

For those still not aware of my new habit of going to Lindy Exchanges, get used to me mentioning them.  I should be hitting quite a few this year.  The latest one which I am preparing myself for tonight is Lindy Gras, hosted in one of my old neigborhoods of New Orleans.


Most of the dances will be right by alma-mater, Tulane.  I’m really looking forward to it.  Although the drive (Yes, I’m driving there instead of flying), will be quite an 8 hour hike which I’m not looking forward to.  Thankfully, I’ve got Greg to keep me busy. Plus, I just found all of my missing MP3 CD’s!  Yea!  Each CD is about 11 hours of music, so we’ll never run out of music.  Yarrr!


I’m also planning another trip down to New Orleans in two weekends for the classic celebration of Mardi Gras.  This time, George, Lee, Michael and I are planning to make the journey.  I’m not sure how that will turn out since George is our more “pure” friend joining us.  I wonder how his brain will handle the massive visual breast intake.  Will it fry his brain?  Or will Pat O’s do it first?


Planning a trip to New Orleans always concerns me.  Living there for 4 years and hearing about your friends getting mugged, I’m always the cautious one, watching my step.  I hope that this will be a safe time for me and my fellow Lindy Hoppers.  May God keep us safe.  Especially through this time of international tension.  I hope that no crazy guy decides to bomb New Orleans while we’re there.  Pray for a safe trip for me.


Dancing like there’s no tomorrow,Moi.


P.S.  I also have the pictures from Matt Weyandt’s 80’s B-day party up.  It was a total blast, dude.  Complete with Rubix Cube cake and almost working Atari’s.

Those Special Words that Mean So Much

In this society of uncertainty and insecurity of ones future, there are always those little things that managers can say to you that have you realize that they’re not going to lay you off anytime soon. Today, I heard those special words…

Working in Nortel’s 3rd Generation Wireless Department (3G/UMTS/Wireless Data), I’m developing this script which will be able to configure their servers automatically in a matter of minutes. You see this, is a big deal, because many times, it takes people hours if not days to configure their switch properly. So, needless to say, this is a BIG deal. And I’m the brains behind the operation there.

Anywho, I’m doing all of my development on this separate workstation I have in my cube. And everything pretty much resides on it. I was talking to my manager today about future roles for me and he said that he wanted documentation of everything, because “If you were to die tomorrow, we’d be screwed.” (If you haven’t caught on by now, those are the Special Words I was referring to earlier.)

Some people might think that’s morbid. Some people might think that means I’ve got more work to do. Some people might get a power trip from that…but Me…I think that’s AWESOME! (Ok, maybe I enjoy the power trip a tad, but that’s ok.) You see, I have now proven my value to the company, and future productivity now is vested in my staying with Nortel. Now yes, I know that once I’m done with this project, that I can be canned, but I’ve also got a few ideas up my sleeve that I can prevent to management for future job security. 🙂

Feeling good about myself and looking forward to the Studio 54 party on Friday-Me.