k3sは簡単にkubernetesクラスタを構築できて便利ですが、デフォルトの構成では自前のロードバランサーであるservicelb(中身はklipper-lbという1ファイルのshellスクリプト)がアクセス元のIPアドレスを喪失してしまうので、バックエンドからこれを知るのが困難です。
これはきっと外部のCloud LBがフロントに立つ事を想定して、そちらがhttp/httpsなトラフィックにX-Forwarded-For
やX-Real-IP
を付加する事を期待しているからでしょう。
しかしせっかく簡単に作れるクラスタなので、外部LBに依存させず独立した構成にしたかったのでその方法をまとめました。
まず普通に デフォルト設定でk3sクラスタを構築します。--disable=servicelb
オプションを指定しても良いですが、これは後から削除もできます。
次にserverを担当しているホストにログインして /var/lib/rancher/k3s/server/manifests/traefik.yaml
の中身を以下のように書き換えます。ファイルを書き換えると自動的に helm-installer が設定を反映させようと動き出すので注意してください。
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: traefik-crd
namespace: kube-system
spec:
chart: https://%{KUBERNETES_API}%/static/charts/traefik-crd-25.0.3+up25.0.0.tgz
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: traefik
namespace: kube-system
spec:
chart: https://%{KUBERNETES_API}%/static/charts/traefik-25.0.3+up25.0.0.tgz
set:
global.systemDefaultRegistry: ""
valuesContent: |-
additionalArguments:
- "--log.level=INFO"
- "--entrypoints.web.address=:80/tcp"
- "--entrypoints.websecure.address=:443/tcp"
deployment:
podAnnotations:
prometheus.io/port: "8082"
prometheus.io/scrape: "true"
kind: DaemonSet
providers:
kubernetesIngress:
publishedService:
enabled: true
priorityClassName: "system-cluster-critical"
image:
repository: "rancher/mirrored-library-traefik"
tag: "2.10.7"
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
service:
enable: false
securityContext:
capabilities:
add:
- NET_BIND_SERVICE
runAsNonRoot: false
runAsUser: 0
hostNetwork: true
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
ports:
web:
port: 80
expose: true
protocol: TCP
exposePort: 80
websecure:
port: 443
expose: true
protocol: TCP
exposePort: 443
tls:
enable: true
metrics:
port: 9100
expose: true
protocol: TCP
exposePort: 9100
traefik:
port: 9000
expose: true
protocol: TCP
exposePort: 9000
これによって helm-installer は traefik
を DaemonSetとして配備しようとしますが、すでに servicelbが起動してポート80と443を使っているのでこの処理はPendingになります。
そこで kube-system名前空間にある先住DaemonSetを削除します
kubectl delete -n kube-system daemonset svclb-traefik-84aa502b
あとは勝手にtraefikのDaemonSetの配備が完了して外部からのアクセスを受け付け、独自に X-Forwarded-For
やX-Real-IP
をつけてくれます。