diff --git a/build_docker.sh b/build_docker.sh index 64409180b..27d6fc405 100755 --- a/build_docker.sh +++ b/build_docker.sh @@ -40,7 +40,9 @@ go run github.com/tailscale/mkctr \ -X tailscale.com/version.Long=${VERSION_LONG} \ -X tailscale.com/version.Short=${VERSION_SHORT} \ -X tailscale.com/version.GitCommit=${VERSION_GIT_HASH}" \ + --files="docs/k8s/run.sh:/tailscale/run.sh" \ --base="${BASE}" \ --tags="${TAGS}" \ --repos="${REPOS}" \ - --push="${PUSH}" + --push="${PUSH}" \ + /bin/sh /tailscale/run.sh diff --git a/docs/k8s/Dockerfile b/docs/k8s/Dockerfile deleted file mode 100755 index 42f9e969d..000000000 --- a/docs/k8s/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -FROM ghcr.io/tailscale/tailscale:latest -COPY run.sh /run.sh -CMD "/run.sh" diff --git a/docs/k8s/Makefile b/docs/k8s/Makefile index 580164739..6b3d8ed50 100644 --- a/docs/k8s/Makefile +++ b/docs/k8s/Makefile @@ -1,38 +1,28 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -ifndef IMAGE_TAG - $(error "IMAGE_TAG is not set") -endif - ROUTES ?= "" SA_NAME ?= tailscale KUBE_SECRET ?= tailscale -build: - @docker build . -t $(IMAGE_TAG) - -push: build - @docker push $(IMAGE_TAG) - rbac: - @sed -e "s;{{KUBE_SECRET}};$(KUBE_SECRET);g" role.yaml | kubectl apply -f - + @sed -e "s;{{TS_KUBE_SECRET}};$(TS_KUBE_SECRET);g" role.yaml | kubectl apply -f - @sed -e "s;{{SA_NAME}};$(SA_NAME);g" rolebinding.yaml | kubectl apply -f - @sed -e "s;{{SA_NAME}};$(SA_NAME);g" sa.yaml | kubectl apply -f - sidecar: @kubectl delete -f sidecar.yaml --ignore-not-found --grace-period=0 - @sed -e "s;{{KUBE_SECRET}};$(KUBE_SECRET);g" sidecar.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | sed -e "s;{{IMAGE_TAG}};$(IMAGE_TAG);g" | kubectl create -f- + @sed -e "s;{{TS_KUBE_SECRET}};$(TS_KUBE_SECRET);g" sidecar.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | kubectl create -f- userspace-sidecar: @kubectl delete -f userspace-sidecar.yaml --ignore-not-found --grace-period=0 - @sed -e "s;{{KUBE_SECRET}};$(KUBE_SECRET);g" userspace-sidecar.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | sed -e "s;{{IMAGE_TAG}};$(IMAGE_TAG);g" | kubectl create -f- + @sed -e "s;{{TS_KUBE_SECRET}};$(TS_KUBE_SECRET);g" userspace-sidecar.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | kubectl create -f- proxy: - @kubectl delete -f proxy.yaml --ignore-not-found --grace-period=0 - @sed -e "s;{{KUBE_SECRET}};$(KUBE_SECRET);g" proxy.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | sed -e "s;{{IMAGE_TAG}};$(IMAGE_TAG);g" | sed -e "s;{{DEST_IP}};$(DEST_IP);g" | kubectl create -f- + kubectl delete -f proxy.yaml --ignore-not-found --grace-period=0 + sed -e "s;{{TS_KUBE_SECRET}};$(TS_KUBE_SECRET);g" proxy.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | sed -e "s;{{TS_DEST_IP}};$(TS_DEST_IP);g" | kubectl create -f- subnet-router: @kubectl delete -f subnet.yaml --ignore-not-found --grace-period=0 - @sed -e "s;{{KUBE_SECRET}};$(KUBE_SECRET);g" subnet.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | sed -e "s;{{IMAGE_TAG}};$(IMAGE_TAG);g" | sed -e "s;{{ROUTES}};$(ROUTES);g" | kubectl create -f- + @sed -e "s;{{TS_KUBE_SECRET}};$(TS_KUBE_SECRET);g" subnet.yaml | sed -e "s;{{SA_NAME}};$(SA_NAME);g" | sed -e "s;{{TS_ROUTES}};$(TS_ROUTES);g" | kubectl create -f- diff --git a/docs/k8s/README.md b/docs/k8s/README.md index 774478c3e..8fd48c4eb 100644 --- a/docs/k8s/README.md +++ b/docs/k8s/README.md @@ -15,19 +15,12 @@ There are quite a few ways of running Tailscale inside a Kubernetes Cluster, som AUTH_KEY: tskey-... ``` -1. Build and push the container - - ```bash - export IMAGE_TAG=tailscale-k8s:latest - make push - ``` - 1. Tailscale (v1.16+) supports storing state inside a Kubernetes Secret. Configure RBAC to allow the Tailscale pod to read/write the `tailscale` secret. ```bash export SA_NAME=tailscale - export KUBE_SECRET=tailscale-auth + export TS_KUBE_SECRET=tailscale-auth make rbac ``` @@ -82,11 +75,11 @@ Running a Tailscale proxy allows you to provide inbound connectivity to a Kubern ```bash kubectl create deployment nginx --image nginx kubectl expose deployment nginx --port 80 - export DEST_IP="$(kubectl get svc nginx -o=jsonpath='{.spec.clusterIP}')" + export TS_DEST_IP="$(kubectl get svc nginx -o=jsonpath='{.spec.clusterIP}')" ``` **Using an existing service** ```bash - export DEST_IP="$(kubectl get svc -o=jsonpath='{.spec.clusterIP}')" + export TS_DEST_IP="$(kubectl get svc -o=jsonpath='{.spec.clusterIP}')" ``` 1. Deploy the proxy pod @@ -114,12 +107,12 @@ Running a Tailscale proxy allows you to provide inbound connectivity to a Kubern Running a Tailscale [subnet router](https://tailscale.com/kb/1019/subnets/) allows you to access the entire Kubernetes cluster network (assuming NetworkPolicies allow) over Tailscale. -1. Identify the Pod/Service CIDRs that cover your Kubernetes cluster. These will vary depending on [which CNI](https://kubernetes.io/docs/concepts/cluster-administration/networking/) you are using and on the Cloud Provider you are using. Add these to the `ROUTES` variable as comma-separated values. +1. Identify the Pod/Service CIDRs that cover your Kubernetes cluster. These will vary depending on [which CNI](https://kubernetes.io/docs/concepts/cluster-administration/networking/) you are using and on the Cloud Provider you are using. Add these to the `TS_ROUTES` variable as comma-separated values. ```bash SERVICE_CIDR=10.20.0.0/16 POD_CIDR=10.42.0.0/15 - export ROUTES=$SERVICE_CIDR,$POD_CIDR + export TS_ROUTES=$SERVICE_CIDR,$POD_CIDR ``` 1. Deploy the subnet-router pod. diff --git a/docs/k8s/proxy.yaml b/docs/k8s/proxy.yaml index 3ee59f95d..cccb8edef 100644 --- a/docs/k8s/proxy.yaml +++ b/docs/k8s/proxy.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. apiVersion: v1 @@ -26,21 +26,21 @@ spec: containers: - name: tailscale imagePullPolicy: Always - image: "{{IMAGE_TAG}}" + image: "ghcr.io/tailscale/tailscale:latest" env: # Store the state in a k8s secret - - name: KUBE_SECRET - value: "{{KUBE_SECRET}}" - - name: USERSPACE + - name: TS_KUBE_SECRET + value: "{{TS_KUBE_SECRET}}" + - name: TS_USERSPACE value: "false" - - name: AUTH_KEY + - name: TS_AUTH_KEY valueFrom: secretKeyRef: name: tailscale-auth key: AUTH_KEY optional: true - - name: DEST_IP - value: "{{DEST_IP}}" + - name: TS_DEST_IP + value: "{{TS_DEST_IP}}" securityContext: capabilities: add: diff --git a/docs/k8s/role.yaml b/docs/k8s/role.yaml index cc79ae4be..3de458edd 100644 --- a/docs/k8s/role.yaml +++ b/docs/k8s/role.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. apiVersion: rbac.authorization.k8s.io/v1 @@ -11,6 +11,6 @@ rules: # Create can not be restricted to a resource name. verbs: ["create"] - apiGroups: [""] # "" indicates the core API group - resourceNames: ["{{KUBE_SECRET}}"] + resourceNames: ["{{TS_KUBE_SECRET}}"] resources: ["secrets"] verbs: ["get", "update"] diff --git a/docs/k8s/run.sh b/docs/k8s/run.sh index f50a86e75..4e5686da6 100755 --- a/docs/k8s/run.sh +++ b/docs/k8s/run.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. @@ -6,19 +6,29 @@ export PATH=$PATH:/tailscale/bin -AUTH_KEY="${AUTH_KEY:-}" -ROUTES="${ROUTES:-}" -DEST_IP="${DEST_IP:-}" -EXTRA_ARGS="${EXTRA_ARGS:-}" -USERSPACE="${USERSPACE:-true}" -KUBE_SECRET="${KUBE_SECRET:-tailscale}" +TS_AUTH_KEY="${TS_AUTH_KEY:-}" +TS_ROUTES="${TS_ROUTES:-}" +TS_DEST_IP="${TS_DEST_IP:-}" +TS_EXTRA_ARGS="${TS_EXTRA_ARGS:-}" +TS_USERSPACE="${TS_USERSPACE:-true}" +TS_STATE_DIR="${TS_STATE_DIR:-}" +TS_ACCEPT_DNS="${TS_ACCEPT_DNS:-false}" +TS_KUBE_SECRET="${TS_KUBE_SECRET:-tailscale}" set -e -TAILSCALED_ARGS="--state=kube:${KUBE_SECRET} --socket=/tmp/tailscaled.sock" +TAILSCALED_ARGS="--socket=/tmp/tailscaled.sock" -if [[ "${USERSPACE}" == "true" ]]; then - if [[ ! -z "${DEST_IP}" ]]; then +if [[ ! -z "${KUBERNETES_SERVICE_HOST}" ]]; then + TAILSCALED_ARGS="${TAILSCALED_ARGS} --state=kube:${TS_KUBE_SECRET}" +elif [[ ! -z "${TS_STATE_DIR}" ]]; then + TAILSCALED_ARGS="${TAILSCALED_ARGS} --statedir=${TS_STATE_DIR}" +else + TAILSCALED_ARGS="${TAILSCALED_ARGS} --state=mem:" +fi + +if [[ "${TS_USERSPACE}" == "true" ]]; then + if [[ ! -z "${TS_DEST_IP}" ]]; then echo "IP forwarding is not supported in userspace mode" exit 1 fi @@ -37,23 +47,23 @@ echo "Starting tailscaled" tailscaled ${TAILSCALED_ARGS} & PID=$! -UP_ARGS="--accept-dns=false" -if [[ ! -z "${ROUTES}" ]]; then - UP_ARGS="--advertise-routes=${ROUTES} ${UP_ARGS}" +UP_ARGS="--accept-dns=${TS_ACCEPT_DNS}" +if [[ ! -z "${TS_ROUTES}" ]]; then + UP_ARGS="--advertise-routes=${TS_ROUTES} ${UP_ARGS}" fi -if [[ ! -z "${AUTH_KEY}" ]]; then - UP_ARGS="--authkey=${AUTH_KEY} ${UP_ARGS}" +if [[ ! -z "${TS_AUTH_KEY}" ]]; then + UP_ARGS="--authkey=${TS_AUTH_KEY} ${UP_ARGS}" fi -if [[ ! -z "${EXTRA_ARGS}" ]]; then - UP_ARGS="${UP_ARGS} ${EXTRA_ARGS:-}" +if [[ ! -z "${TS_EXTRA_ARGS}" ]]; then + UP_ARGS="${UP_ARGS} ${TS_EXTRA_ARGS:-}" fi echo "Running tailscale up" tailscale --socket=/tmp/tailscaled.sock up ${UP_ARGS} -if [[ ! -z "${DEST_IP}" ]]; then +if [[ ! -z "${TS_DEST_IP}" ]]; then echo "Adding iptables rule for DNAT" - iptables -t nat -I PREROUTING -d "$(tailscale --socket=/tmp/tailscaled.sock ip -4)" -j DNAT --to-destination "${DEST_IP}" + iptables -t nat -I PREROUTING -d "$(tailscale --socket=/tmp/tailscaled.sock ip -4)" -j DNAT --to-destination "${TS_DEST_IP}" fi wait ${PID} diff --git a/docs/k8s/sa.yaml b/docs/k8s/sa.yaml index 5bfa2dbfc..1be5a97b9 100644 --- a/docs/k8s/sa.yaml +++ b/docs/k8s/sa.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. apiVersion: v1 diff --git a/docs/k8s/sidecar.yaml b/docs/k8s/sidecar.yaml index 98e60c22c..24ce87f0d 100644 --- a/docs/k8s/sidecar.yaml +++ b/docs/k8s/sidecar.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. apiVersion: v1 @@ -12,14 +12,14 @@ spec: image: nginx - name: ts-sidecar imagePullPolicy: Always - image: "{{IMAGE_TAG}}" + image: "ghcr.io/tailscale/tailscale:latest" env: # Store the state in a k8s secret - - name: KUBE_SECRET - value: "{{KUBE_SECRET}}" - - name: USERSPACE + - name: TS_KUBE_SECRET + value: "{{TS_KUBE_SECRET}}" + - name: TS_USERSPACE value: "false" - - name: AUTH_KEY + - name: TS_AUTH_KEY valueFrom: secretKeyRef: name: tailscale-auth diff --git a/docs/k8s/subnet.yaml b/docs/k8s/subnet.yaml index eaf5820cd..428c255bc 100644 --- a/docs/k8s/subnet.yaml +++ b/docs/k8s/subnet.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. apiVersion: v1 @@ -12,21 +12,21 @@ spec: containers: - name: tailscale imagePullPolicy: Always - image: "{{IMAGE_TAG}}" + image: "ghcr.io/tailscale/tailscale:latest" env: # Store the state in a k8s secret - - name: KUBE_SECRET - value: "{{KUBE_SECRET}}" - - name: USERSPACE + - name: TS_KUBE_SECRET + value: "{{TS_KUBE_SECRET}}" + - name: TS_USERSPACE value: "true" - - name: AUTH_KEY + - name: TS_AUTH_KEY valueFrom: secretKeyRef: name: tailscale-auth key: AUTH_KEY optional: true - - name: ROUTES - value: "{{ROUTES}}" + - name: TS_ROUTES + value: "{{TS_ROUTES}}" securityContext: runAsUser: 1000 runAsGroup: 1000 diff --git a/docs/k8s/userspace-sidecar.yaml b/docs/k8s/userspace-sidecar.yaml index 8b1ebed7d..3a534a930 100644 --- a/docs/k8s/userspace-sidecar.yaml +++ b/docs/k8s/userspace-sidecar.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. apiVersion: v1 @@ -12,17 +12,17 @@ spec: image: nginx - name: ts-sidecar imagePullPolicy: Always - image: "{{IMAGE_TAG}}" + image: "ghcr.io/tailscale/tailscale:latest" securityContext: runAsUser: 1000 runAsGroup: 1000 env: # Store the state in a k8s secret - - name: KUBE_SECRET - value: "{{KUBE_SECRET}}" - - name: USERSPACE + - name: TS_KUBE_SECRET + value: "{{TS_KUBE_SECRET}}" + - name: TS_USERSPACE value: "true" - - name: AUTH_KEY + - name: TS_AUTH_KEY valueFrom: secretKeyRef: name: tailscale-auth