Provision AKS with internal load balancer from AMLS on Azure - azure-aks

I would like to provision an AKS cluster that is connected to a vnet and has an internal load balancer on Azure. I am using code from here that looks like this:
import azureml.core
from azureml.core.compute import AksCompute, ComputeTarget
# Verify that cluster does not exist already
try:
aks_target = AksCompute(workspace=ws, name=aks_cluster_name)
print("Found existing aks cluster")
except:
print("Creating new aks cluster")
# Subnet to use for AKS
subnet_name = "default"
# Create AKS configuration
prov_config=AksCompute.provisioning_configuration(load_balancer_type="InternalLoadBalancer")
# Set info for existing virtual network to create the cluster in
prov_config.vnet_resourcegroup_name = "myvnetresourcegroup"
prov_config.vnet_name = "myvnetname"
prov_config.service_cidr = "10.0.0.0/16"
prov_config.dns_service_ip = "10.0.0.10"
prov_config.subnet_name = subnet_name
prov_config.docker_bridge_cidr = "172.17.0.1/16"
# Create compute target
aks_target = ComputeTarget.create(workspace = ws, name = "myaks", provisioning_configuration = prov_config)
# Wait for the operation to complete
aks_target.wait_for_completion(show_output = True)
However, I get the following error
K8s failed to assign an IP for Load Balancer after waiting for an hour.
Is this because the AKS cluster does not yet have a 'network contributor' role for the vnet resource group? Is the only way to get this to work to first create AKS outside of AMLS, grant the network contributor role to the vnet resource group, then attach the AKS cluster to AMLS and configure the internal load balancer afterwards?

I was able to get this to work by first creating an AKS resource without an internal load balancer, then separately updating the load balancer following this code:
import azureml.core
from azureml.core.compute.aks import AksUpdateConfiguration
from azureml.core.compute import AksCompute
# ws = workspace object. Creation not shown in this snippet
aks_target = AksCompute(ws,"myaks")
# Change to the name of the subnet that contains AKS
subnet_name = "default"
# Update AKS configuration to use an internal load balancer
update_config = AksUpdateConfiguration(None, "InternalLoadBalancer", subnet_name)
aks_target.update(update_config)
# Wait for the operation to complete
aks_target.wait_for_completion(show_output = True)
No network contributor role was required.

Related

Azure ML Kubernetes - Private IP

I have an AKS cluster in a VNET/Subnet. My AKS is linked to AzureML.
I successfully deployed an Azure ML service to that AKS.
However, I see that the azureml-fe service is responding to a public IP and not a private IP from my VNET/Subnet.
How can I make it so my AzureML inference service is exposed with a private IP?
Maybe you need to use an internal load balancer, then it will use a private IP address. Here is the example code for Python:
from azureml.core.compute.aks import AksUpdateConfiguration
from azureml.core.compute import AksCompute, ComputeTarget
# When you create an AKS cluster, you can specify Internal Load Balancer to be created with provisioning_config object
provisioning_config = AksCompute.provisioning_configuration(load_balancer_type = 'InternalLoadBalancer')
# when you attach an AKS cluster, you can update the cluster to use internal load balancer after attach
aks_target = AksCompute(ws,"myaks")
# Change to the name of the subnet that contains AKS
subnet_name = "default"
# Update AKS configuration to use an internal load balancer
update_config = AksUpdateConfiguration(None, "InternalLoadBalancer", subnet_name)
aks_target.update(update_config)
# Wait for the operation to complete
aks_target.wait_for_completion(show_output = True)

Run a Docker container under a different service account when using Cloud Build

I am using Cloud Build and would like to run a Docker container under a different service account than the standard Cloud Build service account (A).
The service account I would like to use (B) is from a different project.
One way to do it would be to put the json key on Cloud Storage and then mount it in the Docker container, but I think it should be possible with IAM policies too.
My cloubuild.yaml now contains the following steps:
steps:
- name: 'gcr.io/kaniko-project/executor:v0.20.0'
args:
- --destination=gcr.io/$PROJECT_ID/namu-app:latest
- --cache=true
- --cache-ttl=168h
- name: 'docker'
args: ['run', '--network=cloudbuild', 'gcr.io/$PROJECT_ID/namu-app:latest']
The network is set so that Cloud Build service account is accessible to docker container - see https://cloud.google.com/cloud-build/docs/build-config#network.
So I think my container should have access to the Cloud Build service account.
Then I run the following code inside the Docker container:
import socket
from googleapiclient.discovery import build
from google.auth import impersonated_credentials, default
default_credentials, _ = default()
print("Token: {}".format(default_credentials.token))
play_credentials = impersonated_credentials.Credentials(
source_credentials=default_credentials,
target_principal='google-play-api#api-0000000000000000-0000000.iam.gserviceaccount.com',
target_scopes=[],
lifetime=3600)
TRACK = "internal"
PACKAGE_NAME = 'x.y.z'
APPBUNDLE_FILE = "./build/app/outputs/bundle/release/app.aab"
socket.setdefaulttimeout(300)
service = build('androidpublisher', 'v3')
edits = service.edits()
edit_id = edits.insert(body={}, packageName=PACKAGE_NAME).execute()['id']
However, this fails with:
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/androidpublisher/v3/applications/x.y.z/edits?alt=json returned "Request had insufficient authentication scopes.">
I tried several ways of assigning service account roles, but no luck so far. I thought at first that explicitly 'impersonating' credentials might not be necessary (maybe it can be implicit?).
In summary, I want service account A from project P1 to run as service account B from project P2.
Any ideas?
You might follow to alternatives to troubleshoot this issue:
Give the Cloud Build service account the same permissions that has the service account you are using to run this on your local environment.
Authenticate with a different approach using a credentials file, as shown in this code snippet:
from apiclient.discovery import build
import httplib2
from oauth2client import client
SERVICE_ACCOUNT_EMAIL = (
'ENTER_YOUR_SERVICE_ACCOUNT_EMAIL_HERE#developer.gserviceaccount.com')
# Load the key in PKCS 12 format that you downloaded from the Google APIs
# Console when you created your Service account.
f = file('key.p12', 'rb')
key = f.read()
f.close()
# Create an httplib2.Http object to handle our HTTP requests and authorize it
# with the Credentials. Note that the first parameter, service_account_name,
# is the Email address created for the Service account. It must be the email
# address associated with the key that was created.
credentials = client.SignedJwtAssertionCredentials(
SERVICE_ACCOUNT_EMAIL,
key,
scope='https://www.googleapis.com/auth/androidpublisher')
http = httplib2.Http()
http = credentials.authorize(http)
service = build('androidpublisher', 'v3', http=http)
Using gcloud you can do gcloud run services update SERVICE --service-account SERVICE_ACCOUNT_EMAIL. Documentation also says that
In order to deploy a service with a non-default service account, the
deployer must have the iam.serviceAccounts.actAs permission on the
service account being deployed.
See https://cloud.google.com/run/docs/securing/service-identity#gcloud for more details.

Access AKS API from private IP range with api-server-authorized-ip-ranges enabled

I have a VM that hosts an Azure DevOps agent. The VM does not have a public IP. I can run deployments to AKS fine without api-server-authorized-ip-ranges using kubectl apply (getting a .kube config via az).
Once I add an authorised IP range I can no longer run deployments. I can't add a private IP range as I get this exception:
--api-server-authorized-ip-ranges must be global non-reserved addresses or CIDRs
Due to various policies I am unable give my VM a public IP. Is there anyway around this?
You can't use api-server-authorized-ip-ranges option with private IPs. The IPs must be public as described here, or alternatively you can create a private AKS cluster

AKS create a Load Balancer itself. Purpose and usage of the sma ein not clear

I am working on AKS... AKS create a Load Balancer... Purpose and usage is not clear.
Searched google to understand the same. But no such detail is there.
As I said in the comment. In AKS, the nodes do not expose to the Internet, so if you need to access the application from the Internet, you must create the load balancer for your service.
Actually, the load balancer is associated with the service which listens to the deployment and the service is a unique one. The deployment will help you manage the pods, so the load balancer just needs to know the service.
You can take a look at the Kubernetes Service. And see its description in AKS here.
Update
When you create the service with a load balancer, and the AKS will create the load balancer rule for that service. The rule will name dependent on the uid of the service. See the screenshot of them:
You can use the command kubectl edit service serviceName to see the service uid.

neo4j how to config master and slave for HA?

I am trying to add HA on the same machine like in this article:
http://aws-labs.com/neo4j-high-availability-setup-tutorial/
("Alternative setup: Creating a local cluster for testing")
When I started to open all locations only :7474 opened.
:7475 and :7476 show me "This site can’t be reached".
All config files look like this:
# Name of the service
dbms.windows_service_name=neo4j
# With default configuration Neo4j only accepts local connections.
# To accept non-local connections, uncomment this line:
dbms.connectors.default_listen_address=0.0.0.0
# Reduce the default page cache memory allocation
dbms.pagecache.memory=500m
# Port to listen to for incoming backup requests.
online_backup_server = 10.234.10.94:6366
# Unique server id for this Neo4j instance
# can not be negative id and must be unique
ha.server_id = 1
# List of other known instances in this cluster
ha.initial_hosts = 10.234.10.94:5001,10.234.10.94:5002,10.234.10.94:5003
# IP and port for this instance to bind to for communicating cluster
information
# with the other neo4j instances in the cluster.
ha.cluster_server = 10.234.10.94:5001
# IP and port for this instance to bind to for communicating data with the
# other neo4j instances in the cluster.
ha.server = 10.234.10.94:6363
# HA - High Availability
# SINGLE - Single mode, default.
org.neo4j.server.database.mode=HA
# http port (for all data, administrative, and UI access)
dbms.connector.http.enabled=true
org.neo4j.server.webserver.port=7474
# https port (for all data, administrative, and UI access)
dbms.connector.https.enabled=true
org.neo4j.server.webserver.https.port=7484
And how I should config the master?

Resources