Quickstart: Complete the prerequisites to deploy a Containerized Network Function in Azure Operator Service Manager
In this Quickstart, you complete the tasks necessary prior to using the Azure Operator Service Manager (AOSM).
Prerequisites
Contact your Microsoft account team to register your Azure subscription for access to Azure Operator Service Manager (AOSM) or express your interest through the partner registration form.
Download and install Azure CLI
Use the Bash environment in the Azure cloud shell. For more information, see Start the Cloud Shell to use Bash environment in Azure Cloud Shell.
For users that prefer to run CLI reference commands locally refer to How to install the Azure CLI.
If you're running on Window or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the Azure CLI in a Docker container.
If you're using a local installation, sign into the Azure CLI using the az login
command and complete the prompts displayed in your terminal to finish authentication. For more sign-in options, refer to Sign in with Azure CLI.
Install Azure Operator Service Manager (AOSM) CLI extension
Install the Azure Operator Service Manager (AOSM) CLI extension using this command:
az extension add --name aosm
- Run
az version
to see the version and dependent libraries that are installed. - Run
az upgrade
to upgrade to the current version of Azure CLI.
Register and verify required resource providers
Before you begin using the Azure Operator Service Manager, execute the following commands to register the required resource provider. This registration process can take up to 5 minutes.
# Register Resource Provider
az provider register --namespace Microsoft.HybridNetwork
az provider register --namespace Microsoft.ContainerRegistry
Verify the registration status of the resource providers. Execute the following commands.
# Query the Resource Provider
az provider show -n Microsoft.HybridNetwork --query "{RegistrationState: registrationState, ProviderName: namespace}"
az provider show -n Microsoft.ContainerRegistry --query "{RegistrationState: registrationState, ProviderName: namespace}"
Note
It may take a few minutes for the resource provider registration to complete. Once the registration is successful, you can proceed with using the Azure Operator Service Manager (AOSM).
Requirements for Containerized Network Function (CNF)
For those utilizing Containerized Network Functions, it's essential to ensure that the following packages are installed on the machine from which you're executing the CLI:
- Install docker, refer to Install the Docker Engine.
- Install Helm, refer to Install Helm CLI.
Configure Containerized Network Function (CNF) deployment
For deployments of Containerized Network Functions (CNFs), it's crucial to have the following stored on the machine from which you're executing the CLI:
Helm Packages with Schema - These packages should be present on your local storage and referenced within the
input.json
configuration file. When following this quickstart, you download the required helm package.Creating a Sample Configuration File - Generate an example configuration file for defining a CNF deployment. Issue this command to generate an
input.json
file that you need to populate with your specific configuration.az aosm nfd generate-config --definition-type cnf
Images for your CNF - Here are the options:
- A reference to an existing Azure Container Registry that contains the images for your CNF. Currently, only one ACR and namespace are supported per CNF. The images to be copied from this ACR are populated automatically based on the helm package schema. You must have Reader/AcrPull permissions on this ACR. To use this option, fill in
source_registry
and optionallysource_registry_namespace
in the input.json file. - The image name of the source docker image from local machine. This image name is for a limited use case where the CNF only requires a single docker image that exists in the local docker repository. To use this option, fill in
source_local_docker_image
in the input.json file. Requires docker to be installed. This quickstart guides you through downloading an nginx docker image to use for this option.
- A reference to an existing Azure Container Registry that contains the images for your CNF. Currently, only one ACR and namespace are supported per CNF. The images to be copied from this ACR are populated automatically based on the helm package schema. You must have Reader/AcrPull permissions on this ACR. To use this option, fill in
Optional: Mapping File (path_to_mappings): Optionally, you can provide a file (on disk) named path_to_mappings. This file should mirror
values.yaml
, with your selected values replaced by deployment parameters. Doing so exposes them as parameters to the CNF. Or, you can leave this blank ininput.json
and the CLI generates the file. By default in this case, every value withinvalues.yaml
is exposed as a deployment parameter. Alternatively use the--interactive
CLI argument to interactively make choices. This quickstart guides you through creation of this file.
When configuring the input.json
file, ensure that you list the Helm packages in the order they should be deployed. For instance, if package "A" must be deployed before package "B," your input.json
should resemble the following structure:
"helm_packages": [
{
"name": "A",
"path_to_chart": "Path to package A",
"path_to_mappings": "Path to package A mappings",
"depends_on": [
"Names of the Helm packages this package depends on"
]
},
{
"name": "B",
"path_to_chart": "Path to package B",
"path_to_mappings": "Path to package B mappings",
"depends_on": [
"Names of the Helm packages this package depends on"
]
}
]
Following these guidelines ensures a well organized and structured approach to deploy Containerized Network Functions (CNFs) with Helm packages and associated configurations.
Download nginx image to local docker repo
For this quickstart, you download the nginx docker image to your local repository. The Azure Operator Service Manager (AOSM) Azure CLI extension pushes the image from there to the Azure Operator Service Manager (AOSM) Artifact Store ACR. The CLI extension also supports copying the image from an existing ACR. Copying the image is the expected default use-case, but it's slower for a quickstart to create an ACR to copy from so this method isn't used here.
Issue the following command: docker pull nginx:stable
Download sample Helm chart
Download the sample Helm chart from here Sample Helm chart for use with this quickstart.
Dive into Helm charts
This section introduces you to a basic Helm chart that sets up nginx and configures it to listen on a specified port. The Helm chart furnished in this section already incorporates a values.schema.json
file.
Sample values.schema.json file
{
"$schema": "http://json-schema.org/draft-07/schema",
"additionalProperties": true,
"properties": {
"affinity": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"fullnameOverride": {
"type": "string"
},
"image": {
"additionalProperties": false,
"properties": {
"pullPolicy": {
"type": "string"
},
"repository": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"type": "object"
},
"imagePullSecrets": {
"items": {
"anyOf": []
},
"type": "array"
},
"ingress": {
"additionalProperties": false,
"properties": {
"annotations": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"enabled": {
"type": "boolean"
},
"hosts": {
"items": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"host": {
"type": "string"
},
"paths": {
"items": {
"anyOf": []
},
"type": "array"
}
},
"type": "object"
}
]
},
"type": "array"
},
"tls": {
"items": {
"anyOf": []
},
"type": "array"
}
},
"type": "object"
},
"nameOverride": {
"type": "string"
},
"nodeSelector": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"podSecurityContext": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"replicaCount": {
"type": "integer"
},
"resources": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"securityContext": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"service": {
"additionalProperties": false,
"properties": {
"port": {
"type": "integer"
},
"type": {
"type": "string"
}
},
"type": "object"
},
"serviceAccount": {
"additionalProperties": false,
"properties": {
"create": {
"type": "boolean"
},
"name": {
"type": "null"
}
},
"type": "object"
},
"tolerations": {
"items": {
"anyOf": []
},
"type": "array"
}
},
"type": "object"
}
Although this article doesn't delve into the intricacies of Helm, a few elements worth highlighting include:
- Service Port Configuration: The
values.yaml
has a preset with a service port of 80.
Sample values.yaml file
# Default values for nginxdemo.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
# Repository gets overwritten by AOSM to the Artifact Store ACR, however we've hard-coded the image name and tag in deployment.yaml
repository: overwriteme
tag: stable
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: false
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name:
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: false
annotations:
{}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths: []
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources:
{}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
Port References: This port finds its use in multiple locations:
- Within
service.yaml
as{{ Values.service.port }}
- Within
Sample service.yaml file
apiVersion: v1
kind: Service
metadata:
name: {{ include "nginxdemo.fullname" . }}
labels:
{{ include "nginxdemo.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "nginxdemo.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
- In
nginx_config_map.yaml
represented as{{ Values.service.port }}
. This file corresponds to/etc/nginx/conf.d/default.conf
, with a mapping established using a config map indeployment.yaml
.
Sample nginx_config_map.yaml file
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
# This writes the nginx config file to the ConfigMap and deployment.yaml mounts it as a volume
# to the right place.
data:
default.conf: |
log_format client '$remote_addr - $remote_user $request_time $upstream_response_time '
'[$time_local] "$request" $status $body_bytes_sent $request_body "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 80;
listen {{ .Values.service.port }};
listen [::]:80;
server_name localhost;
access_log /var/log/nginx/host.access.log client;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
error_page 405 =200 $uri;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location = /cnf/test {
error_page 405 =200 $uri;
}
location = /post_thing {
# turn off logging here to avoid double logging
access_log off;
error_page 405 =200 $uri;
}
}
Deployment Configuration: The deployment.yaml
file showcases specific lines pertinent to imagePullSecrets
and image
. Be sure to observe their structured format, as Azure Operator Service Manager (AOSM) furnishes the necessary values for these fields during deployment. For more information, see Helm package requirements.
Sample deployment.yaml file
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "nginxdemo.fullname" . }}
labels:
{{ include "nginxdemo.labels" . | indent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "nginxdemo.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "nginxdemo.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
# Copied from sas
imagePullSecrets: {{ mustToPrettyJson (ternary (list ) .Values.imagePullSecrets (kindIs "invalid" .Values.imagePullSecrets)) }}
serviceAccountName: {{ template "nginxdemo.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
# Want this to evaluate to acr-name.azurecr.io/nginx:stable (or specific version)
# docker tag nginx:stable acr-name.azurecr.io/nginx:stable
# docker push acr-name.azurecr.io/nginx:stable
# Image hard coded to that put in the Artifact Store ACR for this CNF POC
image: "{{ .Values.image.repository }}/nginx:stable"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
# Gets the nginx config from the configMap - see nginx_config_map.yaml
volumeMounts:
- name: nginx-config-volume
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
volumes:
- name: nginx-config-volume
configMap:
name: nginx-config
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
Next steps
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for