Skip to content
This repository has been archived by the owner on Oct 24, 2023. It is now read-only.

feat: azure arc addon #3634

Merged
merged 12 commits into from Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 0 additions & 58 deletions docs/design/get-logs.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/topics/clusterdefinitions.md
Expand Up @@ -128,6 +128,7 @@ $ aks-engine get-versions
| [cilium](https://docs.cilium.io/en/v1.4/kubernetes/policy/#ciliumnetworkpolicy) | true if networkPolicy is "cilium"; currently validated against Kubernetes v1.13, v1.14, and v1.15 | 0 | A NetworkPolicy CRD implementation by the Cilium project (currently supports v1.4) |
| [flannel](https://coreos.com/flannel/docs/0.8.0/index.html) | false | 0 | An addon that delivers flannel: a virtual network that gives a subnet to each host for use with container runtimes. If `networkPlugin` is set to `"flannel"` this addon will be enabled automatically. Not compatible with any other `networkPlugin` or `networkPolicy`. |
| [csi-secrets-store](../../examples/addons/csi-secrets-store/README.md) | true (for 1.16+ clusters) | as many as linux agent nodes | Integrates secrets stores (Azure keyvault) via a [Container Storage Interface (CSI)](https://kubernetes-csi.github.io/docs/) volume. |
| [azure-arc-onboarding](../../examples/addons/azure-arc-onboarding/README.md) | false | 7 | Attaches the cluster to Azure Arc enabled Kubernetes. |

To give a bit more info on the `addons` property: We've tried to expose the basic bits of data that allow useful configuration of these cluster features. Here are some example usage patterns that will unpack what `addons` provide:

Expand Down
104 changes: 104 additions & 0 deletions examples/addons/azure-arc-onboarding/README.md
@@ -0,0 +1,104 @@
# Azure Arc enabled Kubernetes

You can attach and configure Kubernetes clusters by using [Azure Arc enabled Kubernetes](https://docs.microsoft.com/azure/azure-arc/kubernetes/overview).
When a Kubernetes cluster is attached to Azure Arc, it will appear in the Azure portal. It will have an Azure Resource Manager ID and a managed identity.
Clusters are attached to standard Azure subscriptions, are located in a resource group, and can receive tags just like any other Azure resource.

To connect a Kubernetes cluster to Azure, the cluster administrator needs to deploy agents. These agents run in a Kubernetes namespace named `azure-arc` and are standard Kubernetes deployments. The agents are responsible for connectivity to Azure, collecting Azure Arc logs and metrics, and watching for configuration requests.

You can deploy the Azure Arc agents either as part of the cluster creation process (by including the `azure-arc-onboarding` addon spec in your input `apimodel.json`) or manually using [azure-cli](https://docs.microsoft.com/en-us/azure/azure-arc/kubernetes/connect-cluster).

## Azure Arc enabled Kubernetes Addon

The `azure-arc-onboarding` addon creates a Kubernetes job (in namespace `azure-arc-onboarding`) in charge of deploying the Azure Arc agents.
The following information is required in order to successfully onboard the new cluster.

| Name | Required | Description |
| ---------------- | -------- | -------------------------------------------------------------------------------------- |
| location | yes | Azure region where the `connectedCluster` ARM resource will be created |
| subscriptionID | yes | Subscription ID where the `connectedCluster` ARM resource will be created |
| tenantID | yes | Tenant ID that owns the specified Subscription |
| resourceGroup | yes | Existing resource group name where the `connectedCluster` ARM resource will be created |
| clusterName | yes | Unique cluster friendly name |
| clientID | yes | Service principal ID with permissions to create resources in target subscription/group |
| clientSecret | yes | Service principal secret |

Example:

```json
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's enclose this example JSON in something like this:

{
  ...
  "properties": {
    "orchestratorProfile": {
      "kubernetesConfig": {
        "addons": [
          ...,
          <your example addons configuration here>,
          ...
        ]
      }
    },
    ...
}

"apiVersion": "vlabs",
"properties": {
"orchestratorProfile": {
"kubernetesConfig": {
"addons": [
{
"name": "azure-arc-onboarding",
"enabled": true,
"config": {
"tenantID": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"subscriptionID": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"resourceGroup": "connectedClusters",
"clusterName": "clusterName",
"clientID": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"clientSecret": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"location": "eastus"
}
}
]
}
},
}
}
```

### Validation / Troubleshooting

To make sure that the onboarding process succeded, you can either look for the new `connectedCluster` resource in the Azure portal
(ARM ID: `/subscriptions/{subscriptionID}/resourceGroups/{resourceGroup}/providers/Microsoft.Kubernetes/connectedClusters/{clusterName}`)
or check the status of the agent pods in the `azure-arc` namespace.

```bash
kubectl get pods -n azure-arc
```

If you notice something wrong, the first troubleshooting step would be to inspect the logs produced by the onboarding process

```bash
kubectl logs -l job-name=azure-arc-onboarding -n azure-arc-onboarding
```

#### Frequent issues

Potential issues you may find by inspecting the job logs include:

- Target resource group does not exit
- Cluster name is not unique
- Invalid service principal credentials
- Service principal does not have enough permissions to create resources in target subscription or resource group
- Azure Arc is not available in the desired Azure region

### Clean up

You are free to delete the resources created in namespace `azure-arc` created by job `azure-arc-onboarding`.

However, you won't be able to permanently delete the resources created in namespace `azure-arc-onboarding`
until file `arc-onboarding.yaml` is moved out of directory `/etc/kubernetes/addons` (control plane nodes' file system)
as `addon-manager` will re-create the resources in namespace `azure-arc-onboarding`.

### Addon Reconfiguration

There are two different ways to reconfigure the `azure-arc-onboarding` addon the cluster is deployed.

The safer and recommended approach is to update, on every control plane node,
the secret resource declared in the addon manifest (`/etc/kubernetes/addons/arc-onboarding.yaml`)
and re-trigger the onboarding process by deleting the `azure-arc-onboarding` namespace.

A faster and more fragile alternative is to edit the secret using kubectl
(`kubectl edit secret azure-arc-onboarding -n azure-arc-onboarding`) and
and re-trigger the onboarding process by deleting the onboarding job
(`kubectl delete job azure-arc-onboarding -n azure-arc-onboarding`).
Keep in mind that your changes will be lost if the secret resource is deleted at any point in the future
as `addon-manager` will recreate it using the data in `arc-onboarding.yaml`.

More information on how to edit a Kubernetes secret can be found [here](https://kubernetes.io/docs/concepts/configuration/secret/#creating-a-secret-manually).
50 changes: 50 additions & 0 deletions examples/addons/azure-arc-onboarding/kubernetes-arc.json
@@ -0,0 +1,50 @@
{
"apiVersion": "vlabs",
"properties": {
"orchestratorProfile": {
"orchestratorType": "Kubernetes",
"kubernetesConfig": {
"useManagedIdentity": true,
"addons": [
{
"name": "azure-arc-onboarding",
"enabled": true,
"config": {
"tenantID": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"subscriptionID": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"resourceGroup": "connectedClusters",
"clusterName": "clusterName",
"clientID": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"clientSecret": "88e66958-71dd-48b9-8fed-99e13b5c0a59",
"location": "eastus"
}
}
]
}
},
"masterProfile": {
"count": 1,
"dnsPrefix": "",
"vmSize": "Standard_DS2_v2"
},
"agentPoolProfiles": [
{
"name": "agentpool",
"count": 1,
"vmSize": "Standard_DS2_v2",
"availabilityProfile": "VirtualMachineScaleSets",
"storageProfile": "ManagedDisks"
}
],
"linuxProfile": {
"adminUsername": "azureuser",
"ssh": {
"publicKeys": [
{
"keyData": ""
}
]
}
}
}
}
102 changes: 102 additions & 0 deletions parts/k8s/addons/arc-onboarding.yaml
@@ -0,0 +1,102 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: azure-arc-onboarding
labels:
addonmanager.kubernetes.io/mode: "EnsureExists"
---
apiVersion: v1
kind: Secret
metadata:
name: azure-arc-onboarding
namespace: azure-arc-onboarding
labels:
addonmanager.kubernetes.io/mode: "EnsureExists"
data:
TENANT_ID: {{ContainerConfigBase64 "tenantID"}}
SUBSCRIPTION_ID: {{ContainerConfigBase64 "subscriptionID"}}
RESOURCE_GROUP: {{ContainerConfigBase64 "resourceGroup"}}
CONNECTED_CLUSTER: {{ContainerConfigBase64 "clusterName"}}
LOCATION: {{ContainerConfigBase64 "location"}}
CLIENT_ID: {{ContainerConfigBase64 "clientID"}}
CLIENT_SECRET: {{ContainerConfigBase64 "clientSecret"}}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: azure-arc-onboarding
namespace: azure-arc-onboarding
labels:
addonmanager.kubernetes.io/mode: "EnsureExists"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: azure-arc-onboarding
labels:
addonmanager.kubernetes.io/mode: "EnsureExists"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: azure-arc-onboarding
namespace: azure-arc-onboarding
---
apiVersion: batch/v1
kind: Job
metadata:
name: azure-arc-onboarding
namespace: azure-arc-onboarding
labels:
addonmanager.kubernetes.io/mode: "EnsureExists"
spec:
template:
spec:
serviceAccountName: azure-arc-onboarding
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: azure-arc-onboarding
image: {{ContainerImage "azure-arc-onboarding"}}
env:
- name: TENANT_ID
valueFrom:
secretKeyRef:
name: azure-arc-onboarding
key: TENANT_ID
- name: SUBSCRIPTION_ID
valueFrom:
secretKeyRef:
name: azure-arc-onboarding
key: SUBSCRIPTION_ID
- name: RESOURCE_GROUP
valueFrom:
secretKeyRef:
name: azure-arc-onboarding
key: RESOURCE_GROUP
- name: CONNECTED_CLUSTER
valueFrom:
secretKeyRef:
name: azure-arc-onboarding
key: CONNECTED_CLUSTER
- name: LOCATION
valueFrom:
secretKeyRef:
name: azure-arc-onboarding
key: LOCATION
- name: CLIENT_ID
valueFrom:
secretKeyRef:
name: azure-arc-onboarding
key: CLIENT_ID
- name: CLIENT_SECRET
valueFrom:
secretKeyRef:
name: azure-arc-onboarding
key: CLIENT_SECRET
restartPolicy: Never
backoffLimit: 4
12 changes: 12 additions & 0 deletions pkg/api/addons.go
Expand Up @@ -877,6 +877,17 @@ func (cs *ContainerService) setAddonsConfig(isUpgrade bool) {
},
}

defaultAzureArcOnboardingAddonsConfig := KubernetesAddon{
Name: common.AzureArcOnboardingAddonName,
Enabled: to.BoolPtr(DefaultAzureArcOnboardingAddonEnabled),
Containers: []KubernetesContainerSpec{
{
Name: common.AzureArcOnboardingAddonName,
Image: k8sComponents[common.AzureArcOnboardingAddonName],
},
},
}

// Allow folks to simply enable kube-dns at cluster creation time without also requiring that coredns be explicitly disabled
if !isUpgrade && o.KubernetesConfig.IsAddonEnabled(common.KubeDNSAddonName) {
defaultCorednsAddonsConfig.Enabled = to.BoolPtr(false)
Expand Down Expand Up @@ -917,6 +928,7 @@ func (cs *ContainerService) setAddonsConfig(isUpgrade bool) {
defaultFlannelAddonsConfig,
defaultScheduledMaintenanceAddonsConfig,
defaultSecretsStoreCSIDriverAddonsConfig,
defaultAzureArcOnboardingAddonsConfig,
}
// Add default addons specification, if no user-provided spec exists
if o.KubernetesConfig.Addons == nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/common/const.go
Expand Up @@ -286,6 +286,8 @@ const (
CSISecretsStoreDriverContainerName = "secrets-store"
// CSISecretsStoreProviderAzureContainerName is the name of the provider-azure-installer container in csi-secrets-store addon
CSISecretsStoreProviderAzureContainerName = "provider-azure-installer"
// ArcAddonName is the name of the arc addon
AzureArcOnboardingAddonName = "azure-arc-onboarding"
)

// Component name consts
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/const.go
Expand Up @@ -186,6 +186,8 @@ const (
DefaultContainerMonitoringAddonEnabled = false
// DefaultIPMasqAgentAddonEnabled enables the ip-masq-agent addon
DefaultIPMasqAgentAddonEnabled = true
// DefaultArcAddonEnabled determines the aks-engine provided default for enabling arc addon
DefaultAzureArcOnboardingAddonEnabled = false
// DefaultPrivateClusterEnabled determines the aks-engine provided default for enabling kubernetes Private Cluster
DefaultPrivateClusterEnabled = false
// DefaultPrivateClusterHostsConfigAgentEnabled enables the hosts config agent for private cluster
Expand Down