mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 01:26:59 +02:00
Azure tutorial refresh
This commit is contained in:
parent
eb25614b78
commit
2eb88c266b
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# Setting up ExternalDNS for Services on Azure
|
# Setting up ExternalDNS for Services on Azure
|
||||||
|
|
||||||
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on Azure.
|
This tutorial describes how to setup ExternalDNS for [Azure DNS](https://azure.microsoft.com/services/dns/) with [Azure Kubernetes Service](https://docs.microsoft.com/azure/aks/).
|
||||||
|
|
||||||
Make sure to use **>=0.11.0** version of ExternalDNS for this tutorial.
|
Make sure to use **>=0.11.0** version of ExternalDNS for this tutorial.
|
||||||
|
|
||||||
@ -14,33 +14,27 @@ are being run on an orchestration node.
|
|||||||
The Azure provider for ExternalDNS will find suitable zones for domains it manages; it will
|
The Azure provider for ExternalDNS will find suitable zones for domains it manages; it will
|
||||||
not automatically create zones.
|
not automatically create zones.
|
||||||
|
|
||||||
For this tutorial, we will create a Azure resource group named 'externaldns' that can easily be deleted later:
|
For this tutorial, we will create a Azure resource group named `MyDnsResourceGroup` that can easily be deleted later:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ az group create -n externaldns -l eastus
|
$ az group create --name "MyDnsResourceGroup" --location "eastus"
|
||||||
```
|
```
|
||||||
|
|
||||||
Substitute a more suitable location for the resource group if desired.
|
Substitute a more suitable location for the resource group if desired.
|
||||||
|
|
||||||
Next, create a Azure DNS zone for "example.com":
|
Next, create a Azure DNS zone for `example.com`:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ az network dns zone create -g externaldns -n example.com
|
$ az network dns zone create --resource-group "MyDnsResourceGroup" --name "example.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
Substitute a domain you own for "example.com" if desired.
|
Substitute a domain you own for `example.com` if desired.
|
||||||
|
|
||||||
If using your own domain that was registered with a third-party domain registrar, you should point your domain's
|
If using your own domain that was registered with a third-party domain registrar, you should point your domain's name servers to the values in the `nameServers` field from the JSON data returned by the `az network dns zone create` command. Please consult your registrar's documentation on how to do that.
|
||||||
name servers to the values in the `nameServers` field from the JSON data returned by the `az network dns zone create` command.
|
|
||||||
Please consult your registrar's documentation on how to do that.
|
|
||||||
|
|
||||||
## Permissions to modify DNS zone
|
## Configuration File
|
||||||
External-DNS needs permissions to make changes in the Azure DNS server. These permissions are defined in a Service Principal that should be made available to External-DNS as a configuration file.
|
|
||||||
|
|
||||||
The Azure DNS provider expects, by default, that the configuration file is at `/etc/kubernetes/azure.json`. This can be overridden with the `--azure-config-file` option when starting ExternalDNS.
|
The azure provider will reference a configuration file called `azure.json`. The preferred way to inject the configuration file is by using a Kubernetes secret. The secret should contain an object named `azure.json` with content similar to this:
|
||||||
|
|
||||||
### Creating configuration file
|
|
||||||
The preferred way to inject the configuration file is by using a Kubernetes secret. The secret should contain an object named azure.json with content similar to this:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -52,93 +46,91 @@ The preferred way to inject the configuration file is by using a Kubernetes secr
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can find the `tenantId` by running `az account show --query "tenantId"` or by selecting Azure Active Directory in the Azure Portal and checking the _Directory ID_ under Properties.
|
The following fields are used:
|
||||||
|
|
||||||
You can find the `subscriptionId` by running `az account show --query "id"` or by selecting Subscriptions in the Azure Portal.
|
* `tenantId` (**required**) - run `az account show --query "tenantId"` or by selecting Azure Active Directory in the Azure Portal and checking the _Directory ID_ under Properties.
|
||||||
|
* `subscriptionId` (**required**) - run `az account show --query "id"` or by selecting Subscriptions in the Azure Portal.
|
||||||
|
* `resourceGroup` (**required**) is the Resource Group created in a previous step that contains the Azure DNS Zone.
|
||||||
|
* `aadClientID` and `aaClientSecret` are associated with the Service Principal. This only used with Service Principal method documented in the next section.
|
||||||
|
* `useManagedIdentityExtension` - this is set to `true` if you use either AKS Kubelet Identity or AAD Pod Identities methods documented in the next section.
|
||||||
|
* `userAssignedIdentityID` - this contains the client id from the Managed identitty when using the AAD Pod Identities method documented in the next setion.
|
||||||
|
|
||||||
The `resourceGroup` is the Resource Group created in a previous step.
|
The Azure DNS provider expects, by default, that the configuration file is at `/etc/kubernetes/azure.json`. This can be overridden with the `--azure-config-file` option when starting ExternalDNS.
|
||||||
|
|
||||||
The `aadClientID` and `aaClientSecret` are associated with the Service Principal, that you need to create next.
|
## Permissions to modify DNS zone
|
||||||
|
|
||||||
### Creating service principal
|
ExternalDNS needs permissions to make changes to the Azure DNS zone. There are three ways configure the access needed:
|
||||||
A Service Principal with a minimum access level of `DNS Zone Contributor` or `Contributor` to the DNS zone(s) and `Reader` to the resource group containing the Azure DNS zone(s) is necessary for ExternalDNS to be able to edit DNS records. However, other more permissive access levels will work too (e.g. `Contributor` to the resource group or the whole subscription).
|
|
||||||
|
|
||||||
This is an Azure CLI example on how to query the Azure API for the information required for the Resource Group and DNS zone you would have already created in previous steps.
|
- [Service Principal](#service-principal)
|
||||||
|
- [Managed Identity Using AKS Kubelet Identity](#managed-identity-using-aks-kubelet-identity)
|
||||||
|
- [Managed Identity Using AAD Pod Identities](#managed-identity-using-aad-pod-identities)
|
||||||
|
|
||||||
``` bash
|
### Service Principal
|
||||||
> az login
|
|
||||||
```
|
|
||||||
|
|
||||||
Find the relevant subscription and make sure it is selected (the same subscriptionId should be set into azure.json)
|
These permissions are defined in a Service Principal that should be made available to ExternalDNS as a configuration file `azure.json`.
|
||||||
|
|
||||||
``` bash
|
#### Creating service principal
|
||||||
> az account list
|
|
||||||
{
|
|
||||||
"cloudName": "AzureCloud",
|
|
||||||
"id": "<subscriptionId GUID>",
|
|
||||||
"isDefault": false,
|
|
||||||
"name": "My Subscription",
|
|
||||||
"state": "Enabled",
|
|
||||||
"tenantId": "AzureAD tenant ID",
|
|
||||||
"user": {
|
|
||||||
"name": "name",
|
|
||||||
"type": "user"
|
|
||||||
}
|
|
||||||
|
|
||||||
# select the subscription
|
A Service Principal with a minimum access level of `DNS Zone Contributor` or `Contributor` to the DNS zone(s) and `Reader` to the resource group containing the Azure DNS zone(s) is necessary for ExternalDNS to be able to edit DNS records. However, other more permissive access levels will work too (e.g. `Contributor` to the resource group or the whole subscription).
|
||||||
> az account set -s <subscriptionId GUID>
|
|
||||||
...
|
|
||||||
```
|
|
||||||
Create the service principal
|
|
||||||
|
|
||||||
``` bash
|
This is an Azure CLI example on how to query the Azure API for the information required for the Resource Group and DNS zone you would have already created in previous steps (requires `azure-cli` and `jq`)
|
||||||
> az ad sp create-for-rbac -n ExternalDnsServicePrincipal
|
|
||||||
{
|
```bash
|
||||||
"appId": "appId GUID", --> aadClientId value
|
$ EXTERNALDNS_NEW_SP_NAME="ExternalDnsServicePrincipal" # name of the service principal
|
||||||
...
|
$ AZURE_DNS_ZONE_RESOURCE_GROUP="MyDnsResourceGroup" # name of resource group where dns zone is hosted
|
||||||
"password": "password", --> aadClientSecret value
|
$ AZURE_DNS_ZONE="example.com" # DNS zone name like example.com or sub.example.com
|
||||||
"tenant": "AzureAD Tenant Id" --> tenantId value
|
|
||||||
}
|
# Create the service principal
|
||||||
|
$ DNS_SP=$(az ad sp create-for-rbac --name $EXTERNALDNS_NEW_SP_NAME)
|
||||||
|
$ EXTERNALDNS_SP_APP_ID=$(echo $DNS_SP | jq -r '.appId')
|
||||||
|
$ EXTERNALDNS_SP_PASSWORD=$(echo $DNS_SP | jq -r '.password')
|
||||||
```
|
```
|
||||||
|
|
||||||
Assign the rights for the service principal
|
Assign the rights for the service principal
|
||||||
|
|
||||||
```
|
```bash
|
||||||
# find out the resource ids of the resource group where the dns zone is deployed, and the dns zone itself
|
# fetch DNS id used to grant access to the service principal
|
||||||
> az group show --name externaldns
|
DNS_ID=$(az network dns zone show --name $AZURE_DNS_ZONE \
|
||||||
{
|
--resource-group $AZURE_DNS_ZONE_RESOURCE_GROUP --query "id" --output tsv)
|
||||||
"id": "/subscriptions/id/resourceGroups/externaldns",
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
> az network dns zone show --name example.com -g externaldns
|
|
||||||
{
|
|
||||||
"id": "/subscriptions/.../resourceGroups/externaldns/providers/Microsoft.Network/dnszones/example.com",
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
```
|
|
||||||
# assign the rights to the created service principal, using the resource ids from previous step
|
|
||||||
|
|
||||||
# 1. as a reader to the resource group
|
# 1. as a reader to the resource group
|
||||||
> az role assignment create --role "Reader" --assignee <appId GUID> --scope <resource group resource id>
|
$ az role assignment create --role "Reader" --assignee $EXTERNALDNS_SP_APP_ID --scope $DNS_ID
|
||||||
|
|
||||||
# 2. as a contributor to DNS Zone itself
|
# 2. as a contributor to DNS Zone itself
|
||||||
> az role assignment create --role "Contributor" --assignee <appId GUID> --scope <dns zone resource id>
|
$ az role assignment create --role "Contributor" --assignee $EXTERNALDNS_SP_APP_ID --scope $DNS_ID
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you can create a file named 'azure.json' with values gathered above and with the structure of the example above. Use this file to create a Kubernetes secret:
|
#### Creating a configuration file for the service principal
|
||||||
|
|
||||||
```
|
Create the file `azure.json` with values gather from previous steps.
|
||||||
$ kubectl create secret generic azure-config-file --from-file=/local/path/to/azure.json
|
|
||||||
|
```bash
|
||||||
|
cat <<-EOF > /local/path/to/azure.json
|
||||||
|
{
|
||||||
|
"tenantId": "$(az account show --query tenantId -o tsv)",
|
||||||
|
"subscriptionId": "$(az account show --query id -o tsv)",
|
||||||
|
"resourceGroup": "$AZURE_DNS_ZONE_RESOURCE_GROUP",
|
||||||
|
"aadClientId": "$EXTERNALDNS_SP_APP_ID",
|
||||||
|
"aadClientSecret": "$EXTERNALDNS_SP_PASSWORD"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
### Azure Managed Service Identity (MSI)
|
Use this file to create a Kubernetes secret:
|
||||||
|
|
||||||
If [Azure Managed Service Identity (MSI)](https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview) is enabled for virtual machines, then there is no need to create separate service principal. Note that when granting access the kubeletidentity must be used, not the MSI used for the cluster (it usually has a name in the format <Clustername>-<agentpool>).
|
```bash
|
||||||
|
$ kubectl create secret generic azure-config-file --namespace "default" --from-file /local/path/to/azure.json
|
||||||
|
```
|
||||||
|
|
||||||
The contents of `azure.json` should be similar to this:
|
### Managed Identity using AKS Kubelet identity
|
||||||
|
|
||||||
|
The [managed identity](https://docs.microsoft.com//azure/active-directory/managed-identities-azure-resources/overview) that is assigned to the underlying node pool in the AKS cluster can be given permissions to access Azure DNS. Managed identities are essentially a service principal whose lifecycle is managed, such as deleting the AKS will also delete the service principals associating with AKS. The managed identity associated with the AKS Kubenetes node pool is called Kubelet identity.
|
||||||
|
|
||||||
|
The managed identites were previously called MSI (Managed Service Identity) and are enabled by default when creating an AKS cluster.
|
||||||
|
|
||||||
|
Note that permissions granted to this identity will be accessible to all containers running inside the Kubernetes cluster, not just the ExternalDNS container(s).
|
||||||
|
|
||||||
|
For the managed identity, the contents of `azure.json` should be similar to this:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -149,17 +141,179 @@ The contents of `azure.json` should be similar to this:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
*NOTE:* If there are multiple user assigned identitys available add "userAssignedIdentityID": "<id>" to the json
|
## Fetching the Kubelet identity
|
||||||
|
|
||||||
If you have all the information necessary: create a file called azure.json containing the json structure above and substitute the values. Otherwise create a service principal as previously shown before creating the Kubernetes secret.
|
For this process, you will need to get the kublet identity:
|
||||||
|
|
||||||
Then add the secret to the Kubernetes cluster before continuing:
|
```bash
|
||||||
|
$ PRINCIPAL_ID=$(az aks show --resource-group $CLUSTER_GROUP --name $CLUSTERNAME \
|
||||||
|
--query "identityProfile.kubeletidentity.objectId" --output tsv)
|
||||||
```
|
```
|
||||||
kubectl create secret generic azure-config-file --from-file=azure.json
|
Grant access to Azure DNS zone to the kublet identity:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ AZURE_DNS_ZONE="example.com" # DNS zone name like example.com or sub.example.com
|
||||||
|
$ AZURE_DNS_ZONE_RESOURCE_GROUP="MyDnsResourceGroup" # resource group where DNS zone is hosted
|
||||||
|
|
||||||
|
# fetch DNS id used to grant access to the kublet identity
|
||||||
|
$ DNS_ID=$(az network dns zone show --name $AZURE_DNS_ZONE \
|
||||||
|
--resource-group $AZURE_DNS_ZONE_RESOURCE_GROUP --query "id" --output tsv)
|
||||||
|
|
||||||
|
$ az role assignment create --role "DNS Zone Contributor" --assignee $PRINCIPAL_ID --scope $DNS_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Creating a configuration file for the kubelet identity
|
||||||
|
|
||||||
## Deploy ExternalDNS
|
Create the file `azure.json` with values gather from previous steps.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<-EOF > /local/path/to/azure.json
|
||||||
|
{
|
||||||
|
"tenantId": "$(az account show --query tenantId -o tsv)",
|
||||||
|
"subscriptionId": "$(az account show --query id -o tsv)",
|
||||||
|
"resourceGroup": "$AZURE_DNS_ZONE_RESOURCE_GROUP",
|
||||||
|
"useManagedIdentityExtension": true
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the `azure.json` file to create a Kubernetes secret:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl create secret generic azure-config-file --namespace "default" --from-file /local/path/to/azure.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Managed Identity Using AAD Pod Identities
|
||||||
|
|
||||||
|
For this process, we will create [managed identity](https://docs.microsoft.com//azure/active-directory/managed-identities-azure-resources/overview) that will be explicitly used by the ExternalDNS container. This process is similar to Kubelet identity except that this managed identity is not associated with the Kubernetes node pool, but rather associated with explicit ExternalDNS containers.
|
||||||
|
|
||||||
|
#### Enable the AAD Pod Identities feature
|
||||||
|
|
||||||
|
For this solution, [AAD Pod Identities](https://docs.microsoft.com/azure/aks/use-azure-ad-pod-identity) preview feature can be enabled. The commands below should do the trick to enable this feature:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ az feature register --name EnablePodIdentityPreview --namespace Microsoft.ContainerService
|
||||||
|
$ az feature register --name AutoUpgradePreview --namespace Microsoft.ContainerService
|
||||||
|
$ az extension add --name aks-preview
|
||||||
|
$ az extension update --name aks-preview
|
||||||
|
$ az provider register --namespace Microsoft.ContainerService
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Deploy the AAD Pod Identities service
|
||||||
|
|
||||||
|
Once enabled, you can update your cluster and install needed services for the [AAD Pod Identities](https://docs.microsoft.com/azure/aks/use-azure-ad-pod-identity) feature.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ AZURE_AKS_RESOURCE_GROUP="my-aks-cluster-group" # name of resource group where aks cluster was created
|
||||||
|
$ AZURE_AKS_CLUSTER_NAME="my-aks-cluster" # name of aks cluster previously created
|
||||||
|
|
||||||
|
$ az aks update --resource-group ${AZURE_AKS_RESOURCE_GROUP} --name ${AZURE_AKS_CLUSTER_NAME} --enable-pod-identity
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that, if you use the default network plugin `kubenet`, then you need to add the command line option `--enable-pod-identity-with-kubenet` to the above command.
|
||||||
|
|
||||||
|
#### Creating the managed identity
|
||||||
|
|
||||||
|
After this process is finished, create a managed identity.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ IDENTITY_RESOURCE_GROUP=$AZURE_AKS_RESOURCE_GROUP # custom group or reuse AKS group
|
||||||
|
$ IDENTITY_NAME="example-com-identity"
|
||||||
|
|
||||||
|
# create a managed identity
|
||||||
|
$ az identity create --resource-group "${IDENTITY_RESOURCE_GROUP}" --name "${IDENTITY_NAME}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Grant access to Azure DNS zone to the managed identity.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ AZURE_DNS_ZONE_RESOURCE_GROUP="MyDnsResourceGroup" # name of resource group where dns zone is hosted
|
||||||
|
$ AZURE_DNS_ZONE="example.com" # DNS zone name like example.com or sub.example.com
|
||||||
|
|
||||||
|
# fetch identity client id from managed identity created earlier
|
||||||
|
$ IDENTITY_CLIENT_ID=$(az identity show --resource-group "${IDENTITY_RESOURCE_GROUP}" \
|
||||||
|
--name "${IDENTITY_NAME}" --query "clientId" --output tsv)
|
||||||
|
# fetch DNS id used to grant access to the managed identity
|
||||||
|
$ DNS_ID=$(az network dns zone show --name "${AZURE_DNS_ZONE}" \
|
||||||
|
--resource-group "${AZURE_DNS_ZONE_RESOURCE_GROUP}" --query "id" --output tsv)
|
||||||
|
|
||||||
|
$ az role assignment create --role "DNS Zone Contributor" \
|
||||||
|
--assignee "${IDENTITY_CLIENT_ID}" --scope "${DNS_ID}"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Creating a configuration file for the managed identity
|
||||||
|
|
||||||
|
Create the file `azure.json` with the values from previous steps:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<-EOF > /local/path/to/azure.json
|
||||||
|
{
|
||||||
|
"tenantId": "$(az account show --query tenantId -o tsv)",
|
||||||
|
"subscriptionId": "$(az account show --query id -o tsv)",
|
||||||
|
"resourceGroup": "$AZURE_DNS_ZONE_RESOURCE_GROUP",
|
||||||
|
"useManagedIdentityExtension": true,
|
||||||
|
"userAssignedIdentityID": "$IDENTITY_CLIENT_ID"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the `azure.json` file to create a Kubernetes secret:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl create secret generic azure-config-file --namespace "default" --from-file /local/path/to/azure.json
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Creating a Azure identity binding
|
||||||
|
|
||||||
|
A binding between the managed identity and the External DNS pods needs to be setup by creating `AzureIdentity` and `AzureIdentityBinding` resources. This will allow appropriately labeled ExternalDNS pods to authenticate using the managed identity. When AAD Pod Identity feature is enabled from previous steps above, the `az aks pod-identity add` can be used to create these resources:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ IDENTITY_RESOURCE_ID=$(az identity show --resource-group ${IDENTITY_RESOURCE_GROUP} \
|
||||||
|
--name ${IDENTITY_NAME} --query id --output tsv)
|
||||||
|
|
||||||
|
$ az aks pod-identity add --resource-group ${AZURE_AKS_RESOURCE_GROUP} \
|
||||||
|
--cluster-name ${AZURE_AKS_CLUSTER_NAME} --namespace "default" \
|
||||||
|
--name "external-dns" --identity-resource-id ${IDENTITY_RESOURCE_ID}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will add something similar to the following resouces:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: aadpodidentity.k8s.io/v1
|
||||||
|
kind: AzureIdentity
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
addonmanager.kubernetes.io/mode: Reconcile
|
||||||
|
kubernetes.azure.com/managedby: aks
|
||||||
|
name: external-dns
|
||||||
|
spec:
|
||||||
|
clientID: $IDENTITY_CLIENT_ID
|
||||||
|
resourceID: $IDENTITY_RESOURCE_ID
|
||||||
|
type: 0
|
||||||
|
---
|
||||||
|
apiVersion: aadpodidentity.k8s.io/v1
|
||||||
|
kind: AzureIdentityBinding
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
labels:
|
||||||
|
addonmanager.kubernetes.io/mode: Reconcile
|
||||||
|
kubernetes.azure.com/managedby: aks
|
||||||
|
name: external-dns-binding
|
||||||
|
spec:
|
||||||
|
azureIdentity: external-dns
|
||||||
|
selector: external-dns
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Update ExternalDNS labels
|
||||||
|
|
||||||
|
When deploying ExternalDNS, you want to make sure that deployed pod(s) will have the label `aadpodidbinding: external-dns` to enable AAD Pod Identities. You can patch an existing deployment of External DNS with this command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl patch deployment external-dns --namespace "default" --patch \
|
||||||
|
'{"spec": {"template": {"metadata": {"labels": {"aadpodidbinding": "external-dns"}}}}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ingress used with ExternalDNS
|
||||||
|
|
||||||
This deployment assumes that you will be using nginx-ingress. When using nginx-ingress do not deploy it as a Daemon Set. This causes nginx-ingress to write the Cluster IP of the backend pods in the ingress status.loadbalancer.ip property which then has external-dns write the Cluster IP(s) in DNS vs. the nginx-ingress service external IP.
|
This deployment assumes that you will be using nginx-ingress. When using nginx-ingress do not deploy it as a Daemon Set. This causes nginx-ingress to write the Cluster IP of the backend pods in the ingress status.loadbalancer.ip property which then has external-dns write the Cluster IP(s) in DNS vs. the nginx-ingress service external IP.
|
||||||
|
|
||||||
@ -171,8 +325,11 @@ Ensure that your nginx-ingress deployment has the following arg: added to it:
|
|||||||
|
|
||||||
For more details see here: [nginx-ingress external-dns](https://github.com/kubernetes-sigs/external-dns/blob/HEAD/docs/faq.md#why-is-externaldns-only-adding-a-single-ip-address-in-route-53-on-aws-when-using-the-nginx-ingress-controller-how-do-i-get-it-to-use-the-fqdn-of-the-elb-assigned-to-my-nginx-ingress-controller-service-instead)
|
For more details see here: [nginx-ingress external-dns](https://github.com/kubernetes-sigs/external-dns/blob/HEAD/docs/faq.md#why-is-externaldns-only-adding-a-single-ip-address-in-route-53-on-aws-when-using-the-nginx-ingress-controller-how-do-i-get-it-to-use-the-fqdn-of-the-elb-assigned-to-my-nginx-ingress-controller-service-instead)
|
||||||
|
|
||||||
Connect your `kubectl` client to the cluster you want to test ExternalDNS with.
|
## Deploy ExternalDNS
|
||||||
Then apply one of the following manifests file to deploy ExternalDNS.
|
|
||||||
|
Connect your `kubectl` client to the cluster you want to test ExternalDNS with. Then apply one of the following manifests file to deploy ExternalDNS.
|
||||||
|
|
||||||
|
The deployment assumes that ExternalDNS will be installed into the `default` namespace. If this namespace is different, the `ClusterRoleBinding` will need to be updated to reflect the desired alternative namespace, such as `external-dns`, `kube-addons`, etc.
|
||||||
|
|
||||||
### Manifest (for clusters without RBAC enabled)
|
### Manifest (for clusters without RBAC enabled)
|
||||||
```yaml
|
```yaml
|
||||||
@ -208,12 +365,10 @@ spec:
|
|||||||
- name: azure-config-file
|
- name: azure-config-file
|
||||||
secret:
|
secret:
|
||||||
secretName: azure-config-file
|
secretName: azure-config-file
|
||||||
items:
|
|
||||||
- key: azure.json
|
|
||||||
path: azure.json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Manifest (for clusters with RBAC enabled, cluster access)
|
### Manifest (for clusters with RBAC enabled, cluster access)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ServiceAccount
|
kind: ServiceAccount
|
||||||
@ -225,18 +380,12 @@ kind: ClusterRole
|
|||||||
metadata:
|
metadata:
|
||||||
name: external-dns
|
name: external-dns
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: ['']
|
- apiGroups: [""]
|
||||||
resources: ['endpoints', 'pods', 'services']
|
resources: ["services","endpoints","pods", "nodes"]
|
||||||
verbs: ['get', 'watch', 'list']
|
verbs: ["get","watch","list"]
|
||||||
- apiGroups: ['extensions']
|
- apiGroups: ["extensions","networking.k8s.io"]
|
||||||
resources: ['ingresses']
|
|
||||||
verbs: ['get', 'watch', 'list']
|
|
||||||
- apiGroups: ["networking.k8s.io"]
|
|
||||||
resources: ["ingresses"]
|
resources: ["ingresses"]
|
||||||
verbs: ["get","watch","list"]
|
verbs: ["get","watch","list"]
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["nodes"]
|
|
||||||
verbs: ["watch", "list"]
|
|
||||||
---
|
---
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRoleBinding
|
kind: ClusterRoleBinding
|
||||||
@ -247,9 +396,9 @@ roleRef:
|
|||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
name: external-dns
|
name: external-dns
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: external-dns
|
name: external-dns
|
||||||
namespace: default
|
namespace: default
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@ -268,26 +417,23 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
serviceAccountName: external-dns
|
serviceAccountName: external-dns
|
||||||
containers:
|
containers:
|
||||||
- name: external-dns
|
- name: external-dns
|
||||||
image: k8s.gcr.io/external-dns/external-dns:v0.8.0
|
image: k8s.gcr.io/external-dns/external-dns:v0.11.0
|
||||||
args:
|
args:
|
||||||
- --source=service
|
- --source=service
|
||||||
- --source=ingress
|
- --source=ingress
|
||||||
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
|
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
|
||||||
- --provider=azure
|
- --provider=azure
|
||||||
- --azure-resource-group=externaldns # (optional) use the DNS zones from the tutorial's resource group
|
- --azure-resource-group=externaldns # (optional) use the DNS zones from the tutorial's resource group
|
||||||
- --txt-prefix=externaldns-
|
- --txt-prefix=externaldns-
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: azure-config-file
|
- name: azure-config-file
|
||||||
mountPath: /etc/kubernetes
|
mountPath: /etc/kubernetes
|
||||||
readOnly: true
|
readOnly: true
|
||||||
volumes:
|
volumes:
|
||||||
- name: azure-config-file
|
- name: azure-config-file
|
||||||
secret:
|
secret:
|
||||||
secretName: azure-config-file
|
secretName: azure-config-file
|
||||||
items:
|
|
||||||
- key: azure.json
|
|
||||||
path: azure.json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Manifest (for clusters with RBAC enabled, namespace access)
|
### Manifest (for clusters with RBAC enabled, namespace access)
|
||||||
@ -306,12 +452,12 @@ kind: Role
|
|||||||
metadata:
|
metadata:
|
||||||
name: external-dns
|
name: external-dns
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["services","endpoints","pods"]
|
resources: ["services","endpoints","pods"]
|
||||||
verbs: ["get","watch","list"]
|
verbs: ["get","watch","list"]
|
||||||
- apiGroups: ["extensions","networking.k8s.io"]
|
- apiGroups: ["extensions","networking.k8s.io"]
|
||||||
resources: ["ingresses"]
|
resources: ["ingresses"]
|
||||||
verbs: ["get","watch","list"]
|
verbs: ["get","watch","list"]
|
||||||
---
|
---
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
@ -322,8 +468,8 @@ roleRef:
|
|||||||
kind: Role
|
kind: Role
|
||||||
name: external-dns
|
name: external-dns
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: external-dns
|
name: external-dns
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@ -342,36 +488,33 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
serviceAccountName: external-dns
|
serviceAccountName: external-dns
|
||||||
containers:
|
containers:
|
||||||
- name: external-dns
|
- name: external-dns
|
||||||
image: k8s.gcr.io/external-dns/external-dns:v0.8.0
|
image: k8s.gcr.io/external-dns/external-dns:v0.11.0
|
||||||
args:
|
args:
|
||||||
- --source=service
|
- --source=service
|
||||||
- --source=ingress
|
- --source=ingress
|
||||||
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
|
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
|
||||||
- --provider=azure
|
- --provider=azure
|
||||||
- --azure-resource-group=externaldns # (optional) use the DNS zones from the tutorial's resource group
|
- --azure-resource-group=externaldns # (optional) use the DNS zones from the tutorial's resource group
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: azure-config-file
|
- name: azure-config-file
|
||||||
mountPath: /etc/kubernetes
|
mountPath: /etc/kubernetes
|
||||||
readOnly: true
|
readOnly: true
|
||||||
volumes:
|
volumes:
|
||||||
- name: azure-config-file
|
- name: azure-config-file
|
||||||
secret:
|
secret:
|
||||||
secretName: azure-config-file
|
secretName: azure-config-file
|
||||||
items:
|
|
||||||
- key: azure.json
|
|
||||||
path: azure.json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the deployment for ExternalDNS:
|
Create the deployment for ExternalDNS:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ kubectl create -f externaldns.yaml
|
$ kubectl create --namespace "default" --filename externaldns.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deploying an Nginx Service
|
## Deploying an Nginx Service
|
||||||
|
|
||||||
Create a service file called 'nginx.yaml' with the following contents:
|
Create a file called `nginx.yaml` with the following contents:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
@ -388,10 +531,10 @@ spec:
|
|||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: nginx
|
- image: nginx
|
||||||
name: nginx
|
name: nginx
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
@ -399,9 +542,9 @@ metadata:
|
|||||||
name: nginx-svc
|
name: nginx-svc
|
||||||
spec:
|
spec:
|
||||||
ports:
|
ports:
|
||||||
- port: 80
|
- port: 80
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
targetPort: 80
|
targetPort: 80
|
||||||
selector:
|
selector:
|
||||||
app: nginx
|
app: nginx
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
@ -415,31 +558,34 @@ metadata:
|
|||||||
kubernetes.io/ingress.class: nginx
|
kubernetes.io/ingress.class: nginx
|
||||||
spec:
|
spec:
|
||||||
rules:
|
rules:
|
||||||
- host: server.example.com
|
- host: server.devopsstudio.org
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- backend:
|
- path: /
|
||||||
serviceName: nginx-svc
|
pathType: Prefix
|
||||||
servicePort: 80
|
backend:
|
||||||
path: /
|
service:
|
||||||
|
name: nginx-svc
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
```
|
```
|
||||||
|
|
||||||
When using external-dns with ingress objects it will automatically create DNS records based on host names specified in ingress objects that match the domain-filter argument in the external-dns deployment manifest. When those host names are removed or renamed the corresponding DNS records are also altered.
|
When using ExternalDNS with `ingress` objects it will automatically create DNS records based on host names specified in ingress objects that match the domain-filter argument in the external-dns deployment manifest. When those host names are removed or renamed the corresponding DNS records are also altered.
|
||||||
|
|
||||||
Create the deployment, service and ingress object:
|
Create the deployment, service and ingress object:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ kubectl create -f nginx.yaml
|
$ kubectl create --namespace "default" --filename nginx.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Since your external IP would have already been assigned to the nginx-ingress service, the DNS records pointing to the IP of the nginx-ingress service should be created within a minute.
|
Since your external IP would have already been assigned to the nginx-ingress service, the DNS records pointing to the IP of the nginx-ingress service should be created within a minute.
|
||||||
|
|
||||||
## Verifying Azure DNS records
|
## Verifying Azure DNS records
|
||||||
|
|
||||||
Run the following command to view the A records for your Azure DNS zone:
|
Run the following command to view the A records for your Azure DNS zone:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ az network dns record-set a list -g externaldns -z example.com
|
$ az network dns record-set a list --resource-group "MyDnsResourceGroup" --zone-name example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
Substitute the zone for the one created above if a different domain was used.
|
Substitute the zone for the one created above if a different domain was used.
|
||||||
@ -451,6 +597,6 @@ This should show the external IP address of the service as the A record for your
|
|||||||
Now that we have verified that ExternalDNS will automatically manage Azure DNS records, we can delete the tutorial's
|
Now that we have verified that ExternalDNS will automatically manage Azure DNS records, we can delete the tutorial's
|
||||||
resource group:
|
resource group:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ az group delete -n externaldns
|
$ az group delete --name "MyDnsResourceGroup"
|
||||||
```
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user