externalDNSとは?
・Ingressに紐づくドメインに外部からアクセスできるようRoute53にAレコード(ドメイン--ALB)を追加してくれる。
導入手順
作るもの
・IAMロール/IAMポリシー(PodからRoute53を操作する権限)
・ServiceAccount(Pod内からPod外のリソースにアクセスするためのロール)
・Pod(externalDNS)
前提
・Route53等でドメインが作成済であること
・Route53のホストゾーンが作成済であること
・AWS Load Balancer ControllerでIngressに紐づくALBが作成できる/されていること
手順1:IAMポリシー作成
・コマンド
aws iam create-policy --policy-name externalDNSPolicy --policy-document file://externalDNSPolicy.json
・route53を操作する権限付きのポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["route53:ChangeResourceRecordSets"],
"Resource": ["arn:aws:route53:::hostedzone/*"]
},
{
"Effect": "Allow",
"Action": ["route53:ListHostedZones", "route53:ListResourceRecordSets"],
"Resource": ["*"]
}
]
}
・作成されたことを確認
aws iam list policies
手順2:ServiceAccount&IAMロールの作成
・「eksctl create iamserviceaccount」で
①k8s内のServiceAccount
②ServiceAccountに紐づかせるIAMロール
の両方を作成できる
※注意点:name、roleName共にキャメルケースはNG。スネークケースで。
eksctl create iamserviceaccount
--cluster <★clusterName★>
--namespace kube-system
--name <★serviceaccountname★>
--role-name <★IAMロール名★>
--override-existing-serviceaccounts
--attach-policy-arn <★手順1で作成したIAMポリシーのARN★>
--approve
手順3:Pod(externalDNS)作成
・下記のYAMLでPod(externalDNS)を構築する
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
namespace: kube-system
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["extensions"]
resources: ["ingresses"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list", "watch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: <★手順2で作成したServiceAccount名★>
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: kube-system
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns-sa
containers:
- name: external-dns
image: k8s.gcr.io/external-dns/external-dns:v0.7.6
args:
- --source=service
- --source=ingress
- --domain-filter=<★ドメイン名★> # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
- --provider=aws
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
- --registry=txt
- --txt-owner-id=my-hostedzone-identifier
securityContext:
fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes and AWS token files
Ingressリソース
・[spec.rules.host]に指定されたドメインをexternalDNSが検知してRoute53にレコード追加してくれる。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hogeapp-back-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80,"HTTPS": 443}]'
alb.ingress.kubernetes.io/actions.response-404: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"404","messageBody":"not found"}}
labels:
app: nginx-ingress
spec:
rules:
- host: <★ドメイン名★>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8085