I'm getting my feet wet with Kubernetes, and I'm using AKS and Docker Hub. I have a REST application set up through Docker Compose that consists of nine different microservices talking with each other. Now I'm trying to deploy this to AKS, because in terms of going from Docker Compose to Kubernetes, there doesn't seem to be a straightforward way to connect the services through a single Minikube instance.
That said, I need the services to be able to call each other through REST, which led me to trying to get static IPs set up on AKS. (By now, I could've overcomplicated things, but am still getting my feet wet.) That led me to these two commands:
1. az network public-ip create --resource-group <resourceGroup> --name <sameAsValueOf_resourceGroup>
--allocation-method static
2. az network public-ip list --resource-group <resourceGroup> --query [0].ipAddress --output tsv
Supposedly, the list
command should return the same thing as the create
command, but in my case, it doesn't. For example, create
might show 10.x.x.x
as the value of publicIp.ipAddress
, but immediately thereafter, list
might return 52.y.y.y
.
This is totally inconsistent with Microsoft's documentation, and when I try to include either IP in my k8s yaml as follows, it leads to EXTERNAL-IP
getting stuck at <Pending>
:
apiVersion: v1
kind: Service
metadata:
name: warehouse-microservice
spec:
type: LoadBalancer
loadBalancerIP: 10.x.x.x
ports:
- port: 80
selector:
app: warehouse-microservice
In the above yaml, including spec.ports[0].nodePort
apparently breaks things altogether. However if I take out spec.loadBalancerIP
and then add spec.ports[0].nodePort
, everything suddenly works fine, and I can access the service through an external IP; it's just that the IP is randomly chosen.
So my question is: Why would create
and list
show two different IPs, despite MS's documentation, and how can I get it to work well enough to assign a static external IP?
When creating a new AKS cluster, behind the scenes multiple network resources created ( inside MC_${RESOURCE_GROUP_NAME}${CLUSTER_NAME}${LOCATION}
resource group). One of the resources is a static public IP (similar to the one you create using the Azure CLI command). You can find this static IP inside MC resource group => Load balancer => Frontend IP configuration
.
The issue is with az network public-ip list --resource-group <resourceGroup> --query [0].ipAddress --output tsv
command.
this command returns the first Static Ip under a given resource group. since the --query
pointing to the first object inside the array - [0].ipAddress
you always get the same IP address, which is the IP address that created automatically.
But, Even if you chose the right IP you still face an issue (< pending >) since the documentation mentions that - When multiple addresses are configured on the Azure Load Balancer, egress uses the first IP on that load balancer (Frontend IP Configuration)
.
Therefore, we must use the first static IP created automatically when creating the cluster.
End to end solution that worked for me:
EGRESS_IP=$(az network public-ip list --resource-group MC_${RESOURCE_GROUP_NAME}_${CLUSTER_NAME}_${LOCATION} --query '[0].ipAddress' --output tsv)
echo The egress ip address is: $EGRESS_IP
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: azure-egress
namespace: ${NAMESPACE}
spec:
loadBalancerIP: ${EGRESS_IP}
type: LoadBalancer
ports:
- port: 80
EOF
kubectl get svc -n ${NAMESPACE}
kubectl run -it --rm aks-egress-ip-check -n ${NAMESPACE}--image=debian --generator=run-pod/v1
apt-get update && \
apt-get install curl -y && \
curl -s checkip.dyndns.org