Several small procedures work together to create a new Azure Kubernetes cluster. Be sure to read each one carefully, as some are optional. The basic process is:
-
Satisfy the prerequisites.
-
Inspect and edit the cluster objects
Editing the objects allows you to use the optional procedures for:
- Specifying an HTTP proxy
- Configuring the cluster to use existing network infrastructure
Be sure also that you review the known limitations section
Prerequisites
- Before you begin, make sure you have created a Bootstrap cluster.
Name your cluster
-
Give your cluster a unique name suitable for your environment.
-
Set the environment variable:
export CLUSTER_NAME=azure-example
Naming Tips and Tricks
-
To create a cluster name that is unique, use the following command:
export CLUSTER_NAME=azure-example-cluster-$(LC_CTYPE=C tr -dc 'a-z0-9' </dev/urandom | fold -w 5 | head -n1) echo $CLUSTER_NAME
The output appears similar to:
azure-example-cluster-pf4a3
This command creates a unique name every time you run it, so use it carefully.
Create new Azure Kubernetes cluster objects
This procedure uses the --dry-run
and --output-yaml
flags together to create basic Azure Kubernetes cluster objects in a YAML file. This approach allows you to examine the YAML objects before creating the actual Azure Kubernetes cluster itself.
When creating the basic Azure Kubernetes cluster objects, you need to first consider whether you need to use an HTTP proxy. If you do, you need to do some additional configuration when creating the cluster objects. Consult the optional “Configure the control plane and workers to use an HTTP Proxy” section for more details.
-
Generate the basic Kubernetes cluster objects:
dkp create cluster azure --cluster-name=${CLUSTER_NAME} \ --dry-run \ --output=yaml \ > ${CLUSTER_NAME}.yaml
The output of this command is a ${CLUSTER_NAME}.yaml
file that you can examine or modify. If you use this method to create a basic cluster without HTTP proxies, skip to the heading, “Inspect or edit the cluster objects.”
(Optional) Configure the control plane and workers to use an HTTP Proxy
To configure the Control Plane and Worker nodes to use an HTTP proxy:
-
Copy the commands in the following code block to an editor and apply the list of edits that follows to customize them, then execute them from the command line:
export CONTROL_PLANE_HTTP_PROXY=http://example.org:8080 export CONTROL_PLANE_HTTPS_PROXY=http://example.org:8080 export CONTROL_PLANE_NO_PROXY="example.org,example.com,example.net,localhost,127.0.0.1,10.96.0.0/12,192.168.0.0/16,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local,.svc,.svc.cluster,.svc.cluster.local,169.254.169.254,.cloudapp.azure.com" export WORKER_HTTP_PROXY=http://example.org:8080 export WORKER_HTTPS_PROXY=http://example.org:8080 export WORKER_NO_PROXY="example.org,example.com,example.net,localhost,127.0.0.1,10.96.0.0/12,192.168.0.0/16,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local,.svc,.svc.cluster,.svc.cluster.local,169.254.169.254,.cloudapp.azure.com"
- Replace
example.org,example.com,example.net
with your internal addresses localhost
and127.0.0.1
addresses should not use the proxy10.96.0.0/12
is the default Kubernetes service subnet192.168.0.0/16
is the default Kubernetes pod subnetkubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local
is the internal Kubernetes kube-apiserver service.svc,.svc.cluster,.svc.cluster.local
is the internal Kubernetes services169.254.169.254
is the Azure metadata server.cloudapp.azure.com
allows the worker nodes to communicate directly to the kube-apiserver load balancer
- Replace
-
Copy and run the following command to create a Kubernetes cluster with HTTP proxy configured. (This step assumes you did not already create a cluster in the previous procedure.)
dkp create cluster azure --cluster-name=${CLUSTER_NAME} \ --control-plane-http-proxy="${CONTROL_PLANE_HTTP_PROXY}" \ --control-plane-https-proxy="${CONTROL_PLANE_HTTPS_PROXY}" \ --control-plane-no-proxy="${CONTROL_PLANE_NO_PROXY}" \ --worker-http-proxy="${WORKER_HTTP_PROXY}" \ --worker-https-proxy="${WORKER_HTTPS_PROXY}" \ --worker-no-proxy="${WORKER_NO_PROXY}" \ --dry-run \ --output=yaml \ > ${CLUSTER_NAME}.yaml
The output of this command is a ${CLUSTER_NAME}.yaml
file that you can examine or modify further.
Inspect or edit the cluster objects
-
Inspect or edit the cluster objects:
The objects are Custom Resources defined by Cluster API components, and they belong in three different categories:
-
Cluster
A Cluster object has references to the infrastructure-specific and control plane objects. Because this is an Azure cluster, there is an AzureCluster object that describes the infrastructure-specific cluster properties. Here, this means the Azure region, the VPC ID, subnet IDs, and security group rules required by the Pod network implementation.
-
Control Plane
A KubeadmControlPlane object describes the control plane, which is the group of machines that run the Kubernetes control plane components, which include the etcd distributed database, the API server, the core controllers, and the scheduler. The object describes the configuration for these components. The object also has a reference to an infrastructure-specific object that describes the properties of all control plane machines. Here, it references an AzureMachineTemplate object, which describes the instance type, the type of disk used, and the size of the disk, among other properties.
-
Node Pool
A Node Pool is a collection of machines with identical properties. For example, a cluster might have one Node Pool with large memory capacity, another Node Pool with GPU support. Each Node Pool is described by three objects: The MachinePool references an object that describes the configuration of Kubernetes components (for example, the kubelet) deployed on each node pool machine, and an infrastructure-specific object that describes the properties of all node pool machines. Here, it references a KubeadmConfigTemplate, and an AzureMachineTemplate object, which describes the instance type, the type of disk used, the size of the disk, among other properties.
For in-depth documentation about the objects, read Concepts in the Cluster API Book.
-
(Optional) Configure existing network infrastructure in the cluster
As part of inspecting and editing your cluster objects, you can also configure it to use existing network infrastructure. If you do not need to use an existing network infrastructure, you can skip this step.
-
Review the following AzureCluster excerpt, noting the entries under
networkSpec
for the apiServerLB, nodeOutboundLB, subnets, and vnet values:--- apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 kind: AzureCluster metadata: creationTimestamp: "2021-12-17T20:25:12Z" generation: 1 name: azure-example namespace: default uid: 64851501-f658-4b40-84a7-6a9f7c871629 spec: additionalTags: konvoy.d2iq.io_cluster-name: azure-example konvoy.d2iq.io_version: v2.1.0 azureEnvironment: AzurePublicCloud bastionSpec: {} controlPlaneEndpoint: host: "" port: 0 location: westus networkSpec: apiServerLB: frontendIPs: - name: azure-example-public-lb-frontEnd publicIP: name: pip-azure-example-apiserver idleTimeoutInMinutes: 4 name: azure-example-public-lb sku: Standard type: Public nodeOutboundLB: frontendIPs: - name: azure-example-frontEnd publicIP: name: pip-azure-example-node-outbound frontendIPsCount: 1 idleTimeoutInMinutes: 4 name: azure-example sku: Standard type: Public subnets: - cidrBlocks: - 10.0.0.0/16 name: azure-example-controlplane-subnet natGateway: ip: name: "" role: control-plane routeTable: {} securityGroup: name: azure-example-controlplane-nsg - cidrBlocks: - 10.1.0.0/16 name: azure-example-node-subnet natGateway: ip: name: "" role: node routeTable: name: azure-example-node-routetable securityGroup: name: azure-example-node-nsg vnet: cidrBlocks: - 10.0.0.0/8 name: azure-example-vnet resourceGroup: azure-example resourceGroup: azure-example
After you make and verify changes in these areas, save the file and go to the “create the actual cluster” procedure.
Create the actual Azure Kubernetes cluster
Use this procedure to create the Azure Kubernetes cluster when you finish your inspection and edits.
-
Create the cluster from the generated, and any modified, YAML objects using the command:
kubectl apply -f ${CLUSTER_NAME}.yaml
The output appears similar to:
cluster.cluster.x-k8s.io/azure-example created azurecluster.infrastructure.cluster.x-k8s.io/azure-example created kubeadmcontrolplane.controlplane.cluster.x-k8s.io/azure-example-control-plane created azuremachinetemplate.infrastructure.cluster.x-k8s.io/azure-example-control-plane created clusterresourceset.addons.cluster.x-k8s.io/calico-installation-azure-example created configmap/calico-cni-azure-example created machinedeployment.cluster.x-k8s.io/azure-example-md-0 created azuremachinetemplate.infrastructure.cluster.x-k8s.io/azure-example-md-0 created kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/azure-example-md-0 created
-
Wait for the cluster’s control-plane Status to be Ready:
kubectl wait --for=condition=ControlPlaneReady "clusters/${CLUSTER_NAME}" --timeout=20m
When the control plane status is Ready, the output is similar to:
cluster.cluster.x-k8s.io/azure-example condition met
After DKP creates the objects on the API server, the Cluster API controllers reconcile them. They create infrastructure and machines, and as they progress, they update the Status of each object.
-
Run the DKP Konvoy command to describe the current status of the cluster:
dkp describe cluster -c ${CLUSTER_NAME}
The output is similar to:
NAME READY SEVERITY REASON SINCE MESSAGE /azure-example True 6m37s ├─ClusterInfrastructure - AzureCluster/azure-example True 13m ├─ControlPlane - KubeadmControlPlane/azure-example-control-plane True 6m37s │ └─3 Machines... True 10m See azure-example-control-plane-bmc9b, azure-example-control-plane-msftd, ... └─Workers └─MachineDeployment/azure-example-md-0 True 7m58s └─4 Machines... True 8m10s See azure-example-md-0-84bd8b5f5b-b8cnq, azure-example-md-0-84bd8b5f5b-j8ldg, ...
-
As they progress, the controllers also create Events. List the Events using the command:
kubectl get events | grep ${CLUSTER_NAME}
For brevity, the example command also uses
grep
. You can use separate commands to get Events for specific objects, for example,kubectl get events --field-selector involvedObject.kind="AzureCluster"
andkubectl get events --field-selector involvedObject.kind="AzureMachine"
.The output is similar to:
15m Normal AzureClusterObjectNotFound azurecluster AzureCluster object default/azure-example not found 15m Normal AzureManagedControlPlaneObjectNotFound azuremanagedcontrolplane AzureManagedControlPlane object default/azure-example not found 15m Normal AzureClusterObjectNotFound azurecluster AzureCluster.infrastructure.cluster.x-k8s.io "azure-example" not found 8m22s Normal SuccessfulSetNodeRef machine/azure-example-control-plane-bmc9b azure-example-control-plane-fdvnm 10m Normal Machine controller dependency not yet met azuremachine/azure-example-control-plane-fdvnm Machine Controller has not yet set OwnerRef 12m Normal SuccessfulSetNodeRef machine/azure-example-control-plane-msftd azure-example-control-plane-z9q45 10m Normal SuccessfulSetNodeRef machine/azure-example-control-plane-nrvff azure-example-control-plane-vmqwx 12m Normal Machine controller dependency not yet met azuremachine/azure-example-control-plane-vmqwx Machine Controller has not yet set OwnerRef 14m Normal Machine controller dependency not yet met azuremachine/azure-example-control-plane-z9q45 Machine Controller has not yet set OwnerRef 14m Warning VMIdentityNone azuremachinetemplate/azure-example-control-plane You are using Service Principal authentication for Cloud Provider Azure which is less secure than Managed Identity. Your Service Principal credentials will be written to a file on the disk of each VM in order to be accessible by Cloud Provider. To learn more, see https://capz.sigs.k8s.io/topics/identities-use-cases.html#azure-host-identity 12m Warning ControlPlaneUnhealthy kubeadmcontrolplane/azure-example-control-plane Waiting for control plane to pass preflight checks to continue reconciliation: [machine azure-example-control-plane-msftd does not have APIServerPodHealthy condition, machine azure-example-control-plane-msftd does not have ControllerManagerPodHealthy condition, machine azure-example-control-plane-msftd does not have SchedulerPodHealthy condition, machine azure-example-control-plane-msftd does not have EtcdPodHealthy condition, machine azure-example-control-plane-msftd does not have EtcdMemberHealthy condition] 11m Warning ControlPlaneUnhealthy kubeadmcontrolplane/azure-example-control-plane Waiting for control plane to pass preflight checks to continue reconciliation: [machine azure-example-control-plane-nrvff does not have APIServerPodHealthy condition, machine azure-example-control-plane-nrvff does not have ControllerManagerPodHealthy condition, machine azure-example-control-plane-nrvff does not have SchedulerPodHealthy condition, machine azure-example-control-plane-nrvff does not have EtcdPodHealthy condition, machine azure-example-control-plane-nrvff does not have EtcdMemberHealthy condition] 9m52s Normal SuccessfulSetNodeRef machine/azure-example-md-0-84bd8b5f5b-b8cnq azure-example-md-0-bsc82 9m53s Normal SuccessfulSetNodeRef machine/azure-example-md-0-84bd8b5f5b-j8ldg azure-example-md-0-mjcbn 9m52s Normal SuccessfulSetNodeRef machine/azure-example-md-0-84bd8b5f5b-lx89f azure-example-md-0-pmq8f 10m Normal SuccessfulSetNodeRef machine/azure-example-md-0-84bd8b5f5b-pcv7q azure-example-md-0-vzprf 15m Normal SuccessfulCreate machineset/azure-example-md-0-84bd8b5f5b Created machine "azure-example-md-0-84bd8b5f5b-j8ldg" 15m Normal SuccessfulCreate machineset/azure-example-md-0-84bd8b5f5b Created machine "azure-example-md-0-84bd8b5f5b-lx89f" 15m Normal SuccessfulCreate machineset/azure-example-md-0-84bd8b5f5b Created machine "azure-example-md-0-84bd8b5f5b-pcv7q" 15m Normal SuccessfulCreate machineset/azure-example-md-0-84bd8b5f5b Created machine "azure-example-md-0-84bd8b5f5b-b8cnq" 15m Normal Machine controller dependency not yet met azuremachine/azure-example-md-0-bsc82 Machine Controller has not yet set OwnerRef 15m Normal Machine controller dependency not yet met azuremachine/azure-example-md-0-mjcbn Machine Controller has not yet set OwnerRef 15m Normal Machine controller dependency not yet met azuremachine/azure-example-md-0-pmq8f Machine Controller has not yet set OwnerRef
Known Limitations
- The Konvoy version used to create a bootstrap cluster must match the Konvoy version used to create a workload cluster.
- Konvoy supports deploying one workload cluster.
- Konvoy generates a set of objects for one Node Pool.
- Konvoy does not validate edits to cluster objects.
Next, you can Explore the New Cluster.