coredns 설치

진웅·2025년 7월 8일

K8S Basics

목록 보기
17/39

CoreDNS 설치 가이드

1. Kubernetes 환경에서 CoreDNS 설치

1.1 기본 Kubernetes 클러스터 (kubeadm)

새 클러스터에서 CoreDNS 활성화

# kubeadm으로 클러스터 초기화 시 CoreDNS가 기본으로 설치됨
kubeadm init --pod-network-cidr=10.244.0.0/16

# CoreDNS 확인
kubectl get pods -n kube-system | grep coredns

기존 클러스터에 CoreDNS 설치

# 1. 현재 DNS 확인
kubectl get pods -n kube-system | grep -E "(coredns|kube-dns)"

# 2. CoreDNS Manifest 다운로드
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed

# 3. 클러스터 정보 확인
kubectl cluster-info

# 4. Manifest 수정 및 적용
sed -i 's/CLUSTER_DNS_IP/10.96.0.10/g' coredns.yaml.sed
sed -i 's/CLUSTER_DOMAIN/cluster.local/g' coredns.yaml.sed
kubectl apply -f coredns.yaml.sed

1.2 Helm을 사용한 설치

Helm Chart 추가 및 설치

# Helm repo 추가
helm repo add coredns https://coredns.github.io/helm
helm repo update

# 기본 설정으로 설치
helm install coredns coredns/coredns -n kube-system

# 커스텀 values로 설치
cat <<EOF > coredns-values.yaml
replicaCount: 2

image:
  repository: coredns/coredns
  tag: "1.11.1"

service:
  clusterIP: 10.96.0.10

servers:
- zones:
  - zone: .
  port: 53
  plugins:
  - name: errors
  - name: health
    configBlock: |-
      lameduck 5s
  - name: ready
  - name: kubernetes
    parameters: cluster.local in-addr.arpa ip6.arpa
    configBlock: |-
      pods insecure
      fallthrough in-addr.arpa ip6.arpa
      ttl 30
  - name: prometheus
    parameters: 0.0.0.0:9153
  - name: forward
    parameters: . /etc/resolv.conf
  - name: cache
    parameters: 30
  - name: loop
  - name: reload
  - name: loadbalance

resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi

nodeSelector: {}
tolerations: []
affinity: {}
EOF

helm install coredns coredns/coredns -n kube-system -f coredns-values.yaml

1.3 매뉴얼 YAML 설치

CoreDNS ConfigMap 생성

# coredns-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health {
            lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
            ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
            max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }

CoreDNS Deployment 생성

# coredns-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/name: "CoreDNS"
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  selector:
    matchLabels:
      k8s-app: kube-dns
  template:
    metadata:
      labels:
        k8s-app: kube-dns
    spec:
      priorityClassName: system-cluster-critical
      serviceAccountName: coredns
      tolerations:
        - key: "CriticalAddonsOnly"
          operator: "Equal"
          value: "true"
        - key: node-role.kubernetes.io/control-plane
          operator: Exists
          effect: NoSchedule
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule
      nodeSelector:
        kubernetes.io/os: linux
      affinity:
         podAntiAffinity:
           preferredDuringSchedulingIgnoredDuringExecution:
           - weight: 100
             podAffinityTerm:
               labelSelector:
                 matchExpressions:
                   - key: k8s-app
                     operator: In
                     values: ["kube-dns"]
               topologyKey: kubernetes.io/hostname
      containers:
      - name: coredns
        image: coredns/coredns:1.11.1
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            memory: 170Mi
          requests:
            cpu: 100m
            memory: 70Mi
        args: [ "-conf", "/etc/coredns/Corefile" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
          readOnly: true
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - all
          readOnlyRootFilesystem: true
      dnsPolicy: Default
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile

CoreDNS Service 생성

# coredns-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  annotations:
    prometheus.io/port: "9153"
    prometheus.io/scrape: "true"
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.96.0.10
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
  - name: metrics
    port: 9153
    protocol: TCP

RBAC 설정

# coredns-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: coredns
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:coredns
rules:
  - apiGroups:
    - ""
    resources:
    - endpoints
    - services
    - pods
    - namespaces
    verbs:
    - list
    - watch
  - apiGroups:
    - discovery.k8s.io
    resources:
    - endpointslices
    verbs:
    - list
    - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:coredns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:coredns
subjects:
- kind: ServiceAccount
  name: coredns
  namespace: kube-system

전체 설치 실행

# 모든 매니페스트 적용
kubectl apply -f coredns-rbac.yaml
kubectl apply -f coredns-configmap.yaml
kubectl apply -f coredns-service.yaml
kubectl apply -f coredns-deployment.yaml

2. 독립형 서버에서 CoreDNS 설치

2.1 바이너리 설치 (Linux)

다운로드 및 설치

# 최신 버전 확인
COREDNS_VERSION=$(curl -s https://api.github.com/repos/coredns/coredns/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')

# 바이너리 다운로드
wget https://github.com/coredns/coredns/releases/download/${COREDNS_VERSION}/coredns_${COREDNS_VERSION#v}_linux_amd64.tgz

# 압축 해제 및 설치
tar -xzf coredns_${COREDNS_VERSION#v}_linux_amd64.tgz
sudo mv coredns /usr/local/bin/
sudo chmod +x /usr/local/bin/coredns

# 버전 확인
coredns -version

설정 파일 생성

# /etc/coredns/Corefile 생성
sudo mkdir -p /etc/coredns
sudo tee /etc/coredns/Corefile <<EOF
.:53 {
    errors
    health
    ready
    forward . 8.8.8.8 9.9.9.9
    cache 30
    loop
    reload
    log
}
EOF

systemd 서비스 설정

# CoreDNS 사용자 생성
sudo useradd --system --home /var/lib/coredns --shell /bin/false coredns
sudo mkdir -p /var/lib/coredns
sudo chown coredns:coredns /var/lib/coredns

# systemd 서비스 파일 생성
sudo tee /etc/systemd/system/coredns.service <<EOF
[Unit]
Description=CoreDNS DNS server
Documentation=https://coredns.io
After=network.target

[Service]
PermissionsStartOnly=true
LimitNOFILE=1048576
LimitNPROC=1048576
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
User=coredns
WorkingDirectory=/var/lib/coredns
ExecStart=/usr/local/bin/coredns -conf=/etc/coredns/Corefile
ExecReload=/bin/kill -SIGUSR1 \$MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

# 서비스 시작 및 활성화
sudo systemctl daemon-reload
sudo systemctl enable coredns
sudo systemctl start coredns
sudo systemctl status coredns

2.2 Docker를 사용한 설치

Docker Compose 설정

# docker-compose.yml
version: '3.8'

services:
  coredns:
    image: coredns/coredns:1.11.1
    container_name: coredns
    restart: unless-stopped
    ports:
      - "53:53/udp"
      - "53:53/tcp"
      - "9153:9153/tcp"  # metrics
    volumes:
      - ./Corefile:/etc/coredns/Corefile:ro
    command: ["-conf", "/etc/coredns/Corefile"]
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp

Corefile 설정

# Corefile 생성
cat <<EOF > Corefile
.:53 {
    errors
    health {
        lameduck 5s
    }
    ready
    forward . 8.8.8.8 8.8.4.4 {
        max_concurrent 1000
    }
    cache 30
    loop
    reload
    log
    prometheus :9153
}

# 특정 도메인 설정
example.com:53 {
    file /etc/coredns/db.example.com
    log
    errors
}
EOF

# 실행
docker-compose up -d

3. 설치 후 검증 및 테스트

3.1 기본 검증

# CoreDNS Pod/Container 상태 확인
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 또는 독립형의 경우
sudo systemctl status coredns
docker ps | grep coredns

# DNS 서비스 확인
kubectl get svc -n kube-system kube-dns
nslookup kubernetes.default.svc.cluster.local 10.96.0.10

3.2 DNS 해결 테스트

# 클러스터 내 DNS 테스트
kubectl run dns-test --image=busybox:1.28 --rm -it --restart=Never -- nslookup kubernetes.default

# 외부 DNS 테스트
kubectl run dns-test --image=busybox:1.28 --rm -it --restart=Never -- nslookup google.com

# 독립형 서버에서 테스트
dig @localhost google.com
nslookup google.com localhost

3.3 메트릭 확인

# CoreDNS 메트릭 확인 (Kubernetes)
kubectl port-forward -n kube-system svc/kube-dns 9153:9153
curl http://localhost:9153/metrics

# 독립형에서 메트릭 확인
curl http://localhost:9153/metrics

4. 고급 설정 및 최적화

4.1 성능 튜닝

# 고성능 Corefile 설정
.:53 {
    errors
    health {
        lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    prometheus :9153
    forward . /etc/resolv.conf {
        max_concurrent 1000
        prefer_udp
    }
    cache {
        success 9984 30
        denial 9984 5
    }
    loop
    reload
    loadbalance
}

4.2 로깅 설정

# 상세 로깅 Corefile
.:53 {
    log {
        class denial error
    }
    errors
    health
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    forward . 8.8.8.8 8.8.4.4
    cache 30
    reload
}

5. 문제 해결

5.1 일반적인 문제

# Core
profile
bytebliss

0개의 댓글