はじめに

KubernetesクラスタからSSHトンネルを作りDMZを超える通信経路を作ります.

構成

接続先 - cdsl@192.168.201.8 - cdsl@192.168.201.141 - cdsl@192.168.201.220

リバースのトンネルを作成します. 実行するKubernetesクラスタのマスターノードのIPアドレス - 192.168.100.132

接続先

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
quickstart-ls-beats NodePort 10.43.135.154 5044:30732/TCP 31m

やり方

SSHトンネル用の秘密鍵生成

$ ssh-keygen -t ed25519 -C "用途: Kubernetes SSHトンネル用秘密鍵" -f ./ssh_tunnel_key

base64で秘密鍵を変換(SSHトンネルのPodに秘密鍵を持たせるため)

$ base64 -w 0 ./ssh_tunnel_key

接続先のIPアドレスの~/.ssh/authorized_keyに公開鍵を保存する. 詳しくはこちら

https://qiita.com/kentarosasaki/items/aa319e735a0b9660f1f0

任意の鍵を送ること

$ vim autossh.yaml

autossh.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ls-tunnel
  namespace: elastic-system # Namespaceを指定
spec:
  selector:
    matchLabels:
      app: ls-tunnel
  template:
    metadata:
      labels:
        app: ls-tunnel
    spec:
      containers:
        - name: autossh
          image: jnovack/autossh:2.0.1
          volumeMounts:
            - name: pem
              mountPath: "/tmp/my.pem"
              subPath: my.pem
          env:
            - name: SSH_REMOTE_USER
              value: cdsl
            - name: SSH_REMOTE_HOST
              value: "192.168.201.8" # 踏み台のhost/IP
            - name: SSH_MODE
              value: -R
            - name: SSH_REMOTE_PORT
              value: "22"
            - name: SSH_KEY_FILE
              value: "/tmp/my.pem"
            - name: SSH_TARGET_HOST
              value: "192.168.100.132" # Logstashサービスのホスト
            - name: SSH_TARGET_PORT
              value: "30600" # Logstash NodePortサービスのポート
            - name: SSH_TUNNEL_PORT
              value: "30600" # SSHトンネルのリモート側でバインドされるポート
            - name: SSH_BIND_IP
              value: "0.0.0.0" # すべてのインターフェースでリッスン
      volumes:
        - name: pem
          secret:
            defaultMode: 0400
            secretName: ls-tunnel
---
apiVersion: v1
kind: Service
metadata:
  name: ls-tunnel
  namespace: elastic-system # Namespaceを指定
spec:
  ports:
    - port: 30600
      protocol: TCP
      targetPort: 30600
  selector:
    app: ls-tunnel
---
apiVersion: v1
kind: Secret
metadata:
  name: ls-tunnel
  namespace: elastic-system # Namespaceを指定
type: Opaque
data:
  my.pem: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 踏み台のsshキー
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxには先程base64エンコードした秘密鍵を入れてください.

$ kubectl apply -f autossh.yaml

成功例のログです.

$ kubectl logs ls-tunnel-7b54995db-gqp8r -n elastic-system
jnovack/autossh v2.0.1 revision 816f453 built 2021-04-01T10:51:38Z
Agent pid 9
[WARN ] SSH_BIND_IP requires GatewayPorts configured on the server to work properly
[INFO ] Using autossh 1.4g
[INFO ] Tunneling 0.0.0.0:30600  on cdsl@192.168.201.8:22  to 192.168.100.132:30600
Identity added: (stdin) (用途: Kubernetes SSHトンネル用秘密鍵)
[INFO ] # autossh -M 0 -N -o StrictHostKeyChecking=no -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -t -t -R 0.0.0.0:30600:192.168.100.132:30600 -p 22 cdsl@192.168.201.8
Warning: Permanently added '192.168.201.8' (ECDSA) to the list of known hosts

同様にyamlファイルを作ります.

autossh-141.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ls-tunnel-141
  namespace: elastic-system
spec:
  selector:
    matchLabels:
      app: ls-tunnel-141
  template:
    metadata:
      labels:
        app: ls-tunnel-141
    spec:
      containers:
        - name: autossh
          image: jnovack/autossh:2.0.1
          volumeMounts:
            - name: pem
              mountPath: "/tmp/my.pem"
              subPath: my.pem
          env:
            - name: SSH_REMOTE_USER
              value: cdsl
            - name: SSH_REMOTE_HOST
              value: "192.168.201.141"
            - name: SSH_MODE
              value: -R
            - name: SSH_REMOTE_PORT
              value: "22"
            - name: SSH_KEY_FILE
              value: "/tmp/my.pem"
            - name: SSH_TARGET_HOST
              value: "192.168.100.132"
            - name: SSH_TARGET_PORT
              value: "30600"
            - name: SSH_TUNNEL_PORT
              value: "30600"
            - name: SSH_BIND_IP
              value: "0.0.0.0"
      volumes:
        - name: pem
          secret:
            defaultMode: 0400
            secretName: ls-tunnel
autossh-220.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ls-tunnel-220
  namespace: elastic-system
spec:
  selector:
    matchLabels:
      app: ls-tunnel-220
  template:
    metadata:
      labels:
        app: ls-tunnel-220
    spec:
      containers:
        - name: autossh
          image: jnovack/autossh:2.0.1
          volumeMounts:
            - name: pem
              mountPath: "/tmp/my.pem"
              subPath: my.pem
          env:
            - name: SSH_REMOTE_USER
              value: cdsl
            - name: SSH_REMOTE_HOST
              value: "192.168.201.220"
            - name: SSH_MODE
              value: -R
            - name: SSH_REMOTE_PORT
              value: "22"
            - name: SSH_KEY_FILE
              value: "/tmp/my.pem"
            - name: SSH_TARGET_HOST
              value: "192.168.100.132"
            - name: SSH_TARGET_PORT
              value: "30600"
            - name: SSH_TUNNEL_PORT
              value: "30600"
            - name: SSH_BIND_IP
              value: "0.0.0.0"
      volumes:
        - name: pem
          secret:
            defaultMode: 0400
            secretName: ls-tunnel

同様にapply

$ kubectl apply -f autossh-141.yaml
$ kubectl apply -f autossh-220.yaml