はじめに
オンプレ Kubernetes 上で、Ingress を作成すると自動で Ingress リソースに記載した VirtualHost を DNS に登録し、名前解決ができる環境を構築した
Ingress も初めてだったため、Nginx ingress controller の導入から記載している
実行環境
Kubernetes クラスタ
kubespray で構築した オンプレ kuberntes クラスタ
Versoin: 1.16.3
詳細は下記
https://qiita.com/suzuyui/items/e7531fe5e1e84c061b23
Metallb で Laodbalancer 構築済
詳細は下記
https://qiita.com/suzuyui/items/c83554dd055ef0f4253a
Docker サーバ
coredns + etcd は今回は簡易的に Docker でのシングルで構築
kubernetes 化、クラスタ化は別途検討
OS: CentOS 8.0.1905
Docker-CE: 18.06.3-ce
docker-compose: 1.25.0
サーバIP: 192.168.129.16
※以下、この IP で記載しているので注記
DNS フォワーダ
EdgeRouter X という Vyatta ベースの OS で動作する Router で、 DNS フォワーダとしても動作させている (今回確認のデスクトップもこちらを参照させている)
今回の Ingress 用のドメインを、CoreDNS の方を参照させるように動作させる
Edgeroute-Xサイト: https://www.ui.com/edgemax/edgerouter-x/
概要説明
全体の構成概要を図示すると下記のような感じになる (オレンジ部分が今回記載箇所)
ローカルドメインには .home
を使用する
Nginx ingress controller
Kubernetes は Ingress Controller をデフォルトでは実装していないため、オンプレでの Kubernetes では追加で導入する必要がある。
また、実装によって動作も異なる。
今回は、Kubernetes リポジトリ配下の NGINX Ingress Controller を使用する。
※その他に NGINX, Inc. が公開している NGINX, NGINX Plus を利用する Contoroller もある
サイト: https://kubernetes.github.io/ingress-nginx/
Github: https://github.com/kubernetes/ingress-nginx
リソース概要
リソースの概要図を記載すると下記の通り。
IP については固定 IP をアサインしておきたかったので、その箇所だけ追記している。(赤字)
マニフェストは 2 つで下記の通り。
External-DNS, CoreDNS + Etcd
External-DNS
Ingress 等のリストを取得して、外部公開するホストを DNS へ登録してくれる。
対応している DNS は様々で、対応状況は、Google Cloud DNS
と AWS Route53
は Stable
だが、それ以外は Beta
or Alpha
となる。
※オンプレ実装可能なものは Alpha
しかない
※ 2020.03.23時点
今回は、External-DNS が対応可能な CoreDNS
を選択した。
External-DNS は実際には Etcd へ登録を実施するため、CoreDNS のバックエンドとして Etcd
を導入する。
Github: https://github.com/kubernetes-sigs/external-dns
CoreDNS + Etcd
Go で書かれた DNS で、CNCF graduated project の 1 つ。
権威サーバ、リゾルバサーバ両方として動作可能。
レコードのバックエンドとしては、Etcd
, hosts
、その他 Plugin など様々なものをとすることができる。
今回は External-DNS を使用するので、 Etcd
をバックエンドとして採用する
サイト: https://coredns.io/
Github: https://github.com/coredns/coredns
リソース・構成概要図
構成概要図は下記の通り。
- External-DNS
- kubernetes クラスタ上に構築
- CoreDNS
- Docker サーバ上に構築
設定は下記の通り 3 ファイル(赤文字)で、詳細は別途後述。
構築ステップ
次からの構築は下記ステップで記載していく。
- Nginx ingress controller / Ingress Serivce 構築
- CoreDNS(+Etcd) 構築
- External-DNS 構築
- DNSフォワーダ設定 (EdgeRouter X)
構築後に実際に Ingress を作成して、名前解決および URL アクセスも確認する。
1. Nginx ingress controller / Ingress Serivce 構築
Nginx ingress controller
公式からコントローラ用のマニフェストを落としてきて apply する。
$ curl -OL https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
$ kubectl apply -f mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created
参考: https://kubernetes.github.io/ingress-nginx/deploy/
Ingress Service
公式から ingress-nginx Service 用のマニフェストを落としてきて、IP 設定だけ追加して apply する。
$ curl -OL https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/cloud-generic.yaml
Ingress の IP を固定 IP とする場合は、1行追加する (固定 IP 不要の場合は、手を加えなくても良い)
loadBalancerIP: [固定IP]
下記は、上記の一行を追加した例。
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
externalTrafficPolicy: Local
type: LoadBalancer
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
loadBalancerIP: 192.168.131.80
---
apply する。
$ kubectl apply -f cloud-generic-ipfix.yaml
service/ingress-nginx created
nginx-ingress コントローラが稼働していることを確認する。
$ kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx
NAMESPACE NAME READY STATUS RESTARTS AGE
ingress-nginx nginx-ingress-controller-7f74f657bd-mcfdx 1/1 Running 0 44m
2. CoreDNS(+Etcd) 構築
CoreDNS と Etcd を Docker-compose で構築する。
下記は docker-compose.yml 例
コンテナイメージはどちらも公式のものを使用した。
---
version: '3.5'
services:
coredns:
container_name: coredns
image: coredns/coredns:1.6.7
restart: on-failure
ports:
- '53:53'
- '53:53/udp'
volumes:
- './config:/etc/coredns'
command: -conf /etc/coredns/Corefile
etcd:
container_name: etcd
image: quay.io/coreos/etcd:v3.4.5
ports:
- '2379:2379'
- '2380:2380'
- '4001:4001'
volumes:
- etcddata01:/etcd-data
command:
- /usr/local/bin/etcd
- --data-dir=/etcd-data
- --name=node1
- --listen-peer-urls=http://0.0.0.0:2380
- --advertise-client-urls=http://0.0.0.0:2379,http://0.0.0.0:4001
- --listen-client-urls=http://0.0.0.0:2379,http://0.0.0.0:4001
volumes:
etcddata01:
driver: local
Corefile にドメインの設定を記載する。
下記例は、ingress.home
を ingress で設定するドメイン名として記載している。
コメントしている範囲は、CoreDNS を DNS フォワーダとしても使用したい場合は、コメントを解除する。
# .:53 {
# forward . 8.8.8.8 9.9.9.9
# log
# errors
# }
ingress.home:53 {
etcd ingress.home {
path /skydns
endpoint http://192.168.129.16:2379
}
log
errors
}
docker-compose up -d で立ち上げる
# docker-compose up -d
Creating network "coredns_default" with the default driver
Creating coredns ... done
Creating etcd ... done
# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------------------------------
coredns /coredns -conf /etc/coredn ... Up 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp
etcd /usr/local/bin/etcd --data ... Up 0.0.0.0:2379->2379/tcp, 0.0.0.0:2380->2380/tcp, 0.0.0.0:4001->4001/tcp
3. External-DNS 構築
External-DNS を構築する。
下記は公式にあった Minikube での実施例で書いてあったものを一部手を加えたもの。
env:
の ETCD_URLS
には CoreDNS の Etcd の IP:Port を記載する。
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
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
containers:
- name: external-dns
image: bitnami/external-dns:latest
# image: registry.opensource.zalan.do/teapot/external-dns:latest
args:
- --source=ingress
- --provider=coredns
# - --log-level=debug # debug only
env:
- name: ETCD_URLS
value: http://192.168.129.16:2379
上記 yaml を apply する。
$ kubectl apply -f external-dns.yaml
4. DNSフォワーダ設定 (EdgeRouter X)
EdgeRouter X で DNS のフォワーディングオプションを利用して、.home
ドメインは CoreDNS サーバへフォワードする設定をする。
下記は、設定例。
set service dns forwarding name-server 8.8.8.8
set service dns forwarding name-server 8.8.8.4
set service dns forwarding options server=/home/192.168.129.16
参考: https://help.ubnt.com/hc/en-us/articles/115010913367-EdgeRouter-DNS-Forwarding-Setup-and-Options
動作確認: Ingress 作成と名前解決でのアクセス
Prometheus / Grafana / AlertManager を Ingress で公開する場合で、動作確認を実施した。
Ingress 作成
Ingress 作成例は下記の通り。
Prometheus / Grafana / AlertManager の host 登録と、host指定無しの設定を記載している。
host 指定無しは IP でのアクセスで使用できる。 (下記テストでは Grafana を指定した)
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: prometheus
namespace: monitoring
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
nginx.com/health-checks: "true"
spec:
rules:
- host: grafana.ingress.home
http:
paths:
- path: /
backend:
serviceName: grafana
servicePort: 3000
- host: alertmanager.ingress.home
http:
paths:
- path: /
backend:
serviceName: alertmanager-main
servicePort: 9093
- host: prometheus.ingress.home
http:
paths:
- path: /
backend:
serviceName: prometheus-k8s
servicePort: 9090
- http:
paths:
- path: /
backend:
serviceName: grafana
servicePort: 3000
上記の serviceName
は Service の NAME を指定している。
下記は、実施環境での Service Name での表示例。
$ kubectl get svc -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 10.233.48.158 <none> 9093/TCP 2d16h
grafana ClusterIP 10.233.55.79 <none> 3000/TCP 2d16h
prometheus-k8s ClusterIP 10.233.4.237 <none> 9090/TCP 2d16h
マニフェストを apply する。
ADDRESS
の割り当てには少し時間がかかる場合がある。
$ kubectl apply -f prometheus-ingress.yaml
ingress.networking.k8s.io/prometheus created
$ kubectl get ingress -n monitoring
NAME HOSTS ADDRESS PORTS AGE
prometheus grafana.ingress.home,alertmanager.ingress.home,prometheus.ingress.home + 1 more... 192.168.131.80 80 2m20s
アクセス確認
dig で名前解決確認 (フォワーダ経由) と、ブラウザでの URL アクセス確認を実施した。
dig
dig で問合せをして、 A レコードが返ってくることが確認できる。
※ 192.168.129.254 は EdgeRouter X の IP アドレス
$ dig -p 53 @192.168.129.254 A grafana.ingress.home +noall +answer
; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> -p 53 @192.168.129.254 A grafana.ingress.home +noall +answer
; (1 server found)
;; global options: +cmd
grafana.ingress.home. 300 IN A 192.168.131.80
$ dig -p 53 @192.168.129.254 A prometheus.ingress.home +noall +answer
; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> -p 53 @192.168.129.254 A prometheus.ingress.home +noall +answer
; (1 server found)
;; global options: +cmd
prometheus.ingress.home. 300 IN A 192.168.131.80
$ dig -p 53 @192.168.129.254 A alertmanager.ingress.home +noall +answer
; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> -p 53 @192.168.129.254 A alertmanager.ingress.home +noall +answer
; (1 server found)
;; global options: +cmd
alertmanager.ingress.home. 300 IN A 192.168.131.80
ブラウザ
各 URL をブラウザでアクセスして、正しくアクセスできることが確認できる。
http://grafana.ingress.home
でのアクセス
http://prometheus.ingress.home
でのアクセス
http://alertmanager.ingress.home
でのアクセス
おわりに
Ingress を作成すると、自動で名前解決でアクセスができる環境まで構築ができた
今後、Ingress は TLS 終端や、認証などできることは多岐に渡るので試していきたい。
また、CoreDNS / Etcd についても etcd-operator などで冗長化・Kubernetes 化も実施していきたい。