この記事を4行で
- おうちKubernetesのIngressリソース数が増えてきた
- LAN内端末からIngress経由でアクセスする為にhostsファイルを書いて回るのが面倒になってきた
- Kubernetes上にnsdとunboundを立ててLAN内名前解決を任せる
- 成果物manifest: https://gitlab.chatagiriii.com/open/nsd-unbound-on-k8s
おうちKubernetes作ってから1年
chatagiriです。
おうちKubernetesの構成考えて、実際に運用を始めておおよそ1年が経ちました。
(書く、書くと言いながら未だに構築手順書いてないのはごめんなさい)
運用から1年も経つと有象無象のPod達が無造作に動きっぱなしになっており、2021/12/22現在で104Pod、54Service, 20Ingressが稼働中です。
$ kubectl get pods --all-namespaces | grep -v NAMESPACE | wc -l
104
$ kubectl get svc --all-namespaces | grep -v NAMESPACE | wc -l
54
$ k get ingress --all-namespaces | grep -v NAMESPACE | wc -l
20
hostsファイル弄るの面倒...
動いているものが多いと嬉しい一方で問題が。増えたIngressの数だけ手元端末たちのhostsを編集する必要があるのです。。
自分の家には日常使いのPC2台、Androidスマホ1台、AndroidTV1台があり、Ingressを1個追加したときにはそれぞれのhostsを弄らないとLAN内名前解決が出来ないのです。
特にAndroidのhostsを弄る為には基本的にrootを取る必要があり、折角作った自宅ファイルサーバにLAN内Wi-Fi経由で入れない等の問題が出てきてしまいました。
これを機におうちDNS鯖を建て、新しくIngressリソースを入れた時には権威DNSの更新1本で全端末から名前解決できるようにする試みです。
nsdとunbound
NSDはdnsの権威DNSサーバ用のOSSで、unboundはキャッシュDNSサーバ用のOSSです。詳細はリンク先を追ってみてください。。
ここがこうなる
こう変わる、を図にしてみました。
- 前提:
- metallb導入済みKubernetes cluster
- nginx-ingress-controller導入済みKubnernetes cluster
- (「nginx-ingress-controller使ってるなら図のServiceのIP回りおかしくない?」と気づくと思いますが、例として分かりやすいように図中のIP回りは都度変更しています。)
- ご自身の環境に合わせて読み替え下さい
- びふぉー:
- 流れ
- webapp01のPod/Service(192.168.1.210)/Configmap/PVなどを作成
- webapp01.example.jp でingress リソースを作成して、外部に公開
- LAN内からもingressの名前でアクセスしたいので、各端末のhostsファイルを編集(webapp01.example.jp,192.168.1.210)
- メリットデメリット
- 新しくingressを追加したとき、各端末のhostsファイルを編集してまわる必要がある
- DNS回りが一元管理されていないので、漏れだったり、今どのレコードが有るか無いかをいちいち確認の必要がある場合がある
- 流れ
- あふたー
- 流れ
- webapp01のPod/Service(192.168.1.210)/Configmap/PVなどを作成
- webapp01.example.jp でingress リソースを作成して、外部に公開
- nsdのpodのconfigmapを編集して、 (webapp01.example.jp 192.168.1.210) のレコードを追加
- 各端末のDNSサーバの向け先をunboundに設定して、webapp01.exmaple.jpを問い合わせる
- unboundはnsdに対してwebapp01.example.jpを問い合わせ、192.168.1.210の応答を貰い、各端末に返す
- メリットデメリット
- 新しくingressを追加したとき、nsdのレコード設定を編集するだけでよい
- DNS回りが一元管理され、登録漏れや確認が楽になる
- 流れ
nsdとunboundのk8s manifestを書く
脳死でダーーッと書きます。意外とkubernetesでnsdとunboundして、manifestファイルまで公開してる人が居なかったため色々試してみましょう。
example.jpな部分を置き換えたり、DNSレコード回りはご自分の環境に合わせて変更してみてください。
また、ServiceのserviceTypeはLoadBalancerに設定していますが、ご家庭のKubernetesに乗っているものに合わせてご変更ください。
manifestファイルはこちらにも置いてあります。: https://gitlab.chatagiriii.com/open/nsd-unbound-on-k8s
---
apiVersion: v1
kind: Namespace
metadata:
name: nsd
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nsd
name: nsd
namespace: nsd
spec:
replicas: 2
selector:
matchLabels:
app: nsd
template:
metadata:
labels:
app: nsd
spec:
containers:
- image: ghcr.io/the-kube-way/nsd:latest
name: nsd
ports:
- name: udp
containerPort: 53
volumeMounts:
- name: nsd-zones
mountPath: /zones
- name: nsd-conf
mountPath: /etc/nsd/nsd.conf
subPath: nsd.conf
volumes:
- name: nsd-zones
configMap:
name: nsd-zones
items:
- key: db.example.jp
path: example.jp.zone
mode: 0644
- name: nsd-conf
configMap:
name: nsd-conf
items:
- key: nsd.conf
path: nsd.conf
mode: 0644
---
apiVersion: v1
kind: Service
metadata:
name: nsd
namespace: nsd
labels:
app: nsd
spec:
ports:
- name: dns
port: 53
protocol: UDP
selector:
app: nsd
type: LoadBalancer
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nsd-zones
namespace: nsd
data:
db.example.jp: |
$ORIGIN example.jp.
$TTL 800
; SOA
@ IN SOA ns1.example.jp. example.jp. (
1 ; Serial
3200 ; Refresh
1800 ; Retry
96000 ; Expire
86400 ) ; Minimum
; NAMESERVERS
@ IN NS ns.example.jp.
; A RECORDS
@ IN A 192.168.1.XX
k8s-master00 IN A 192.168.1.10
k8s-worker00 IN A 192.168.1.20
k8s-worker00 IN A 192.168.1.21
k8s-worker00 IN A 192.168.1.22
webapp00 IN A 192.168.1.200
webapp01 IN A 192.168.1.210
---
apiVersion: v1
kind: Namespace
metadata:
name: unbound
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: unbound
name: unbound
namespace: unbound
spec:
replicas: 2
selector:
matchLabels:
app: unbound
template:
metadata:
labels:
app: unbound
spec:
containers:
- image: mvance/unbound
name: unbound
ports:
- name: udp
containerPort: 53
volumeMounts:
- name: unbound-conf
mountPath: /opt/unbound/etc/unbound/unbound.conf
subPath: unbound.conf
volumes:
- name: unbound-conf
configMap:
name: unbound-conf
items:
- key: unbound.conf
path: unbound.conf
mode: 0644
---
apiVersion: v1
kind: Service
metadata:
name: unbound
namespace: unbound
labels:
app: unbound
spec:
ports:
- name: dns
port: 53
protocol: UDP
selector:
app: unbound
type: LoadBalancer
---
apiVersion: v1
kind: ConfigMap
metadata:
name: unbound-conf
namespace: unbound
data:
unbound.conf: |
server:
interface: 0.0.0.0
access-control: 192.168.1.0/24 allow
# pod network
access-control: 10.244.1.0/24 allow
access-control: 10.244.2.0/24 allow
access-control: 10.244.3.0/24 allow
do-not-query-localhost: no
cache-max-ttl: 10
stub-zone:
name: example.jp
stub-addr: 192.168.1.100@53
# example.jp 以外のドメインについてはgoogleに聞く
forward-zone:
name: "."
forward-addr: 8.8.8.8
forward-addr: 8.8.4.4
k8sでもdns回りを構築できました
出来るかなー?ぐらいで調べていったdns on k8sですが、案外すんなり動きました。
意外とkubernetesでnsdとunboundして、manifestファイルまで公開してる人が居なかったため、誰かのお役に立てれば嬉しいですね...