Posted at

coredns on k3os


はじめに

今回は 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を使ってます

構築順序は


  1. k3os 構築

  2. nginx-ingress のデプロイ

  3. coredns のデプロイ

です。


完成図

coredns01.jpg

※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 を作成します


ns-and-sa.yaml

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 を登録します


default-server-secret.yaml

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 を作成します

  ※最初は空で作成します


nginx-config.yaml

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 の設定を行います


rbac.yaml

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 を修正しています


nginx-ingress.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


nginx-ingress.yaml

$ 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 に構築します


dns.yaml

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として登録してあります



dns.yaml

$ 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 設定を修正します


nginx-config.yaml

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 を指定することで動作します


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:
・・・
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 コンテナを立ち上げて確認します。


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も便利かと思います。