はじめに
今回は k3os 上に DNS サーバの coredns を構築してみました。
k8s 内部で利用される文献は多かったのですが、IaaS やオンプレなど外部から使う用の DNS の文献は少なかったので。
※k3os ではなく、各種 k8s でも下記の手順で構築できる、、、はず。
環境・構築順序
相も変わらず今回もクライアント環境です
ホストOS:Windows 10 Pro
VirtualBox:6.0.8
※ネットワークはブリッジアダプターで作成しました
k3os:v0.2.0
※coredns については詳しく触れません、本家ドキュメントを参考に
※coredns は etcd + PersistentVolume で永続化もできますが、今回は簡易的なConfigmapを使ってます
構築順序は
- k3os 構築
- nginx-ingress のデプロイ
- coredns のデプロイ
です。
完成図
※ns:namespace、ds:daemonset、cm:configmap、svc:service、deploy:deployment
1. k3os 構築
自分の記事で申し訳ないのですが、以下の記事を参考に。
Rancher on k3os
※os-config でディスクインストールまでを参考に
k3os REAME 読んでみた
※Configuration を参考に今回はIPを固定化してます
2. nginx-ingress のデプロイ
下記、本家リンクを参考に進めていきます。
Installing the Ingress Controller
1.namespace と serviceaccount を作成します
yaml : https://github.com/nginxinc/kubernetes-ingress/blob/master/deployments/common/ns-and-sa.yaml
$ kubectl apply -f ns-and-sa.yaml
$ kubectl describe ns nginx-ingress
Name: nginx-ingress
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"nginx-ingress"}}
Status: Active
No resource quota.
No resource limits.
$ kubectl describe sa nginx-ingress -n nginx-ingress
Name: nginx-ingress
Namespace: nginx-ingress
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"nginx-ingress","namespace":"nginx-ingress"}}
Image pull secrets: <none>
Mountable secrets: nginx-ingress-token-xxxxx
Tokens: nginx-ingress-token-xxxxx
Events: <none>
2.デフォルト TLS 用に secret を登録します
yaml : https://github.com/nginxinc/kubernetes-ingress/blob/master/deployments/common/default-server-secret.yaml
$ kubectl apply -f default-server-secret.yaml
$ kubectl describe secret default-server-secret -n nginx-ingress
Name: default-server-secret
Namespace: nginx-ingress
Labels: <none>
Annotations:
Type: Opaque
Data
====
tls.crt: 1013 bytes
tls.key: 1679 bytes
3.nginx の設定ファイルとして configmap を作成します
※最初は空で作成します
yaml : https://github.com/nginxinc/kubernetes-ingress/blob/master/deployments/common/nginx-config.yaml
$ kubectl apply -f nginx-config.yaml
$ kubectl describe cm nginx-config -n nginx-ingress
Name: nginx-config
Namespace: nginx-ingress
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","data":null,"kind":"ConfigMap","metadata":{"annotations":{},"name":"nginx-config","namespace":"nginx-ingress"}}
Data
====
4.「1.」で作成したserviceaccount に rbac の設定を行います
yaml : https://github.com/nginxinc/kubernetes-ingress/blob/master/deployments/rbac/rbac.yaml
$ kubectl apply -f rbac.yaml
5.nginx-ingress コンテナをデプロイします
※今回は公開ポートを 53 で指定したいため、Deployment ではなく DaemonSets でデプロイします
※こちらを参考に yaml を修正しています
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
#annotations:
#prometheus.io/scrape: "true"
#prometheus.io/port: "9113"
spec:
serviceAccountName: nginx-ingress
containers:
- image: nginx/nginx-ingress:edge
imagePullPolicy: Always
name: nginx-ingress
ports:
- name: dns-tcp
containerPort: 53
hostPort: 53
protocol: TCP
- name: dns-udp
containerPort: 53
hostPort: 53
protocol: UDP
#- name: prometheus
#containerPort: 9113
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
#- -v=3 # Enables extensive logging. Useful for troubleshooting.
#- -report-ingress-status
#- -external-service=nginx-ingress
#- -enable-leader-election
#- -enable-prometheus-metrics
#- -enable-custom-resources
$ kubectl apply -f nginx-ingress.yaml
$ kubectl get all -n nginx-ingress
NAME READY STATUS RESTARTS AGE
pod/nginx-ingress-4xmht 1/1 Running 0 22m
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/nginx-ingress 1 1 1 1 1 <none> 22m
nginx-ingress のデプロイはここまでで完了です。
3. coredns のデプロイ
最後に coredns をデプロイし、名前解決できるところまで確認します。
下記、本家リンクを参考に進めていきます。
Support for TCP/UDP Load Balancing
1.coredns のデプロイ
※今回は default namespace に構築します
yaml : https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/tcp-udp/dns.yaml
※上部 configmap の行のみ以下で修正
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
data:
Corefile: |
.:53 {
forward . 8.8.8.8:53
log
}
invalid {
hosts /etc/hosts invalid {
192.168.xx.xx www.rancher.invalid
}
errors
log
}
※Corefile の中身は適宜変更してください、最低限「.:53」のセクションさえあれば名前解決はします
※invalid ドメインはテスト用の静的DNSとして登録してあります
$ kubectl apply -f dns.yaml
$ kubectl get all -n default
NAME READY STATUS RESTARTS AGE
pod/coredns-6b479dfb7f-lksjg 1/1 Running 0 17m
pod/coredns-6b479dfb7f-nf7sr 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/coredns ClusterIP 10.43.116.169 <none> 53/UDP,53/TCP 17m
service/coredns-headless ClusterIP None <none> 53/UDP,53/TCP 17m
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 42m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/coredns 2/2 2 2 17m
NAME DESIRED CURRENT READY AGE
replicaset.apps/coredns-6b479dfb7f 2 2 2 17m
2.nginx-ingress の nginx 設定を修正します
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress
data:
stream-snippets: |
upstream coredns-udp {
server coredns.default.svc.cluster.local:53;
}
server {
listen 53 udp;
proxy_pass coredns-udp;
proxy_responses 1;
}
upstream coredns-tcp {
server coredns.default.svc.cluster.local:53;
}
server {
listen 53;
proxy_pass coredns-tcp;
}
※k3s 内で coredns.default.svc.cluster.local が解決できない場合は、coredns の yaml 内で作成した service の ClusterIP を指定することで動作します
$ kubectl apply -f nginx-config.yaml
$ kubectl describe cm nginx-config -n nginx-ingress
Name: nginx-config
Namespace: nginx-ingress
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
・・・
Data
====
stream-snippets:
・・・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Updated 46s (x4 over 26m) nginx-ingress-controller Configuration from nginx-ingress/nginx-config was updated
3.名前解決できるか dnstool コンテナを立ち上げて確認します。
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
# dig で確認
# dig @<dns サーバ IP ※今回はホストの IP> <検索対象 FQDN>
dnstools# dig @192.168.xx.xx kubernetes.io
・・・
;; ANSWER SECTION:
kubernetes.io. 30 IN A 45.54.44.102
・・・
# Corefile で指定した静的DNSをひいてみる
dnstools# dig @192.168.xx.xx www.rancher.invalid
・・・
;; ANSWER SECTION:
www.rancher.invalid. 3600 IN A 192.168.xx.xx
・・・
おわりに
無事に名前解決まで確認できたでしょうか。
http/https の公開は ingress でできるのですが、他 TCP/UDP の公開時には今回のnginx-ingressも便利かと思います。