diff --git a/Dockerfile b/Dockerfile index 20f4c69..4e13e3e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,19 @@ FROM alpine EXPOSE 53/tcp 53/udp -ARG NEXTDNS_VERSION +ARG NEXTDNS_VERSION=1.41.0 +# Docker variables that is automatically set by Docker's multi-arch build ARG TARGETARCH ARG TARGETPLATFORM +# example: https://github.com/nextdns/nextdns/releases/download/v1.41.0/nextdns_1.41.0_linux_amd64.tar.gz RUN case ${TARGETPLATFORM} in \ + # pi zero w, older arm devices "linux/arm/v7") TARGETARCH=armv7 ;; \ "linux/arm/v6") TARGETARCH=armv6 ;; \ + # apple m1, pi 4, pi 5, + "linux/arm64") TARGETARCH=arm64 ;; \ + # intel/amd + "linux/amd64") TARGETARCH=amd64 ;; \ esac \ && wget -O /tmp/nextdns.tar.gz https://github.com/nextdns/nextdns/releases/download/v${NEXTDNS_VERSION}/nextdns_${NEXTDNS_VERSION}_linux_$TARGETARCH.tar.gz \ && tar xf /tmp/nextdns.tar.gz -C /usr/bin nextdns \ @@ -16,3 +23,5 @@ RUN case ${TARGETPLATFORM} in \ COPY docker-entrypoint.sh / ENTRYPOINT ["/docker-entrypoint.sh"] +LABEL org.opencontainers.image.source https://github.com/tecandrew/docker-nextdns +ENV NEXTDNS_PROFILE "" diff --git a/README.md b/README.md index db3cbf0..106064a 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,10 @@ services: - "/etc/hosts:/etc/hosts:ro" ``` +## Kubernetes + +See [k8s/README.md](k8s/README.md) for an example. + ## License [WTFPL](LICENSE) for the `docker-entrypoint.sh` script, since it's rather minimal. diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 0000000..08a3df1 --- /dev/null +++ b/k8s/README.md @@ -0,0 +1,52 @@ +# NextDNS CLI for Kubernetes + +NOTE: This is a WIP. The docker-compose example was converted to Kubernetes using [kompose](https://kompose.io/). + +0. Obtain your NextDNS Profile ID(s) from the [NextDNS web interface](https://my.nextdns.io) + +1. Create a k8s secret with your NextDNS Profile configuration + + ```bash + kubectl create secret generic nextdns-profile --from-literal=profile1=1a2s3d4f --from-literal=profile2=a1s2d3f4 + ``` + +2. Deploy the NextDNS docker image from Github Container Registry + + ```bash + kubectl apply -f nextdns-deployment.yaml + # view and inspect the deployment + kubectl describe deployments nextdns + + # view and inspect the pods in deployment + kubectl get pods | grep nextdns + kubectl describe pods nextdns- + kubectl logs -f nextdns- + ``` + +3. Expose the NextDNS service ports using your k8s LoadBalancer or Ingress controller + + ```bash + kubectl apply -f nextdns-service.yaml + # view and inspect the service + k get services | grep nextdns + kubectl describe services nextdns + ``` + +4. Verify the service is working by querying the service using `nslookup` + + ```bash + # using the `EXTERNAL-IP` from the service inspection from step 3 + nslookup twitch.tv + ``` + +![](./nslookup-nextdns-logs.png) + + +# Restarting + +Delete the services first, then the reapply deployment + +```bash +kubectl delete -f nextdns-service.yaml +kubectl apply -f nextdns-deployment.yaml +``` diff --git a/k8s/docker-compose.example.yml b/k8s/docker-compose.example.yml new file mode 100644 index 0000000..018cd3f --- /dev/null +++ b/k8s/docker-compose.example.yml @@ -0,0 +1,26 @@ +version: "3" + +services: + nextdns: + container_name: "nextdns" + image: "ghcr.io/tecandrew/docker-nextdns:1.41.0" + build: + context: ../ + dockerfile: Dockerfile + restart: "always" + ports: + - "53:53/tcp" + - "53:53/udp" + environment: + NEXTDNS_PROFILE: ${NEXTDNS_PROFILE:?NEXTDNS_PROFILE must be set} + NEXTDNS_CACHE_SIZE: "10m" + NEXTDNS_REPORT_CLIENT_INFO: "true" + healthcheck: + test: [ + "CMD", "sh", "-c", + "dig +time=10 @127.0.0.1 -p $$(echo $${NEXTDNS_LISTEN:-:53} | rev | cut -d: -f1 | rev) probe-test.dns.nextdns.io" + ] + interval: "1m" + timeout: "10s" + retries: 1 + start_period: "5s" \ No newline at end of file diff --git a/k8s/nextdns-deployment.yaml b/k8s/nextdns-deployment.yaml new file mode 100644 index 0000000..016ac26 --- /dev/null +++ b/k8s/nextdns-deployment.yaml @@ -0,0 +1,64 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + kompose.cmd: kompose convert + kompose.version: 1.31.2 (HEAD) + creationTimestamp: null + labels: + io.kompose.service: nextdns + name: nextdns +spec: + replicas: 2 + selector: + matchLabels: + io.kompose.service: nextdns + strategy: {} + template: + metadata: + annotations: + kompose.cmd: kompose convert + kompose.version: 1.31.2 (HEAD) + creationTimestamp: null + labels: + io.kompose.network/docker-nextdns-default: "true" + io.kompose.service: nextdns + spec: + containers: + - name: nextdns + image: ghcr.io/tecandrew/docker-nextdns:1.41.0 + imagePullPolicy: Always + env: + - name: NEXTDNS_CACHE_SIZE + value: 128M + - name: NEXTDNS_PROFILE + valueFrom: + secretKeyRef: + name: nextdns-profile + key: profile1 + - name: NEXTDNS_REPORT_CLIENT_INFO + value: "true" + - name: NEXTDNS_MAX_INFLIGHT_REQUESTS + value: "2048" + - name: NEXTDNS_LOG_QUERIES + value: "true" + livenessProbe: + exec: + command: + - sh + - -c + - 'dig +time=10 @127.0.0.1 -p $(echo ${NEXTDNS_LISTEN:-:53} | rev | cut -d: -f1 | rev) probe-test.dns.nextdns.io' + failureThreshold: 1 + initialDelaySeconds: 5 + periodSeconds: 60 + timeoutSeconds: 10 + ports: + - containerPort: 53 + hostPort: 53 + protocol: TCP + - containerPort: 53 + hostPort: 53 + protocol: UDP + resources: {} + restartPolicy: Always +status: {} diff --git a/k8s/nextdns-service.yaml b/k8s/nextdns-service.yaml new file mode 100644 index 0000000..689f476 --- /dev/null +++ b/k8s/nextdns-service.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kompose.cmd: kompose convert + kompose.version: 1.31.2 (HEAD) + creationTimestamp: null + labels: + io.kompose.service: nextdns + name: nextdns +spec: + type: LoadBalancer + ports: + - name: "53" + port: 53 + targetPort: 53 + - name: 53-udp + port: 53 + protocol: UDP + targetPort: 53 + selector: + io.kompose.service: nextdns +status: + loadBalancer: {} diff --git a/k8s/nslookup-nextdns-logs.png b/k8s/nslookup-nextdns-logs.png new file mode 100644 index 0000000..76510c6 Binary files /dev/null and b/k8s/nslookup-nextdns-logs.png differ