簡體   English   中英

如何正確創建 sidecar 容器以在 kubernetes pod 中創建 SSH 隧道

[英]How to properly create sidecar container for creating SSH tunnel in kubernetes pod

我在 AWS 中有一個需要從 Kubernetes 連接到的數據庫,但該數據庫中的安全設置阻止了這一點。 我的解決方案是從 Kubernetes pod 內通過 SSH 隧道連接到代理,然后通過它連接到 AWS 中的數據庫。

但是,我不太確定如何在 Kubernetes 中實現這一點,因為 sidecar 容器拋出了“CrashLoopBackOff”錯誤。

我的 Dockerfile 很薄。 它是一個高山容器,除了復制處理隧道的 shell 腳本之外,實際上什么都不做。

文件

FROM alpine:3.14.0

COPY tunnel.sh /

RUN apk update && apk add curl \
    wget \
    nano \
    bash \
    ca-certificates \
    openssh-client

RUN chmod +x /tunnel.sh
RUN mkdir ~/.ssh

RUN ssh-keyscan -Ht ecdsa proxysql-sshtunnel.domain.com > ~/.ssh/known_hosts

CMD /bin/bash

隧道文件

#!/bin/bash
ssh -i /keys/sql_proxy.private -L 3306:10.0.0.229:6033 centos@proxysql-sshtunnel.domain.com -N

它們的 SSH 密鑰從 Kubernetes 中的秘密卷掛載到 pod。 我的部署如下所示:

部署.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: accounts-deployment
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: api-accounts
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    spec:
      containers:
      - image: gcr.io/xxxxxxxx/accounts:VERSION-2.0.6
        imagePullPolicy: Always
        name: accounts
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /tmp
          name: accounts-keys
          readOnly: true
        - mountPath: /var/www/html/var/spool
          name: mail-spool
      - image: gcr.io/xxxxxxxx/sql-proxy:latest
        imagePullPolicy: IfNotPresent
        name: sql-proxy
        args:
          - -c
          - /tunnel.sh
        command:
          - /bin/bash
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /keys
          name: keys-sql-proxy
          readOnly: true
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - name: accounts-keys
        secret:
          defaultMode: 420
          secretName: accounts-keys
      - name: spoonity-sql-proxy
        secret:
          defaultMode: 420
          secretName: spoonity-sql-proxy
      - emptyDir: {}
        name: mail-spool
status:

<-------相關部分在這里------->

...
- image: gcr.io/xxxxxxxx/sql-proxy:latest
  imagePullPolicy: IfNotPresent
  name: sql-proxy
  args:
    - -c
    - /tunnel.sh
  command:
    - /bin/bash
  resources: {}
  terminationMessagePath: /dev/termination-log
  terminationMessagePolicy: File
  volumeMounts:
    - mountPath: /keys
      name: keys-sql-proxy
      readOnly: true
...

我從 Kubernetes 得到的唯一日志是:“ /bin/bash: line 1: /tunnel.sh: No such file or directory

如果我嘗試使用docker run sql-proxy:latest /tunnel.sh本地運行容器,那么我會收到一個不同的錯誤,抱怨密鑰不存在(這正是我期望看到的) .

不知道這個問題出在哪里。

編輯:嘗試在本地重建容器並手動包含密鑰。 我能夠成功啟動容器。 所以看起來這絕對是一個 Kubernetes 問題,但我真的不知道為什么。

所以問題就在這里:

volumes:
      - name: accounts-keys
        secret:
          defaultMode: 420
          secretName: accounts-keys
      - name: spoonity-sql-proxy
        secret:
          defaultMode: 420 #<----------- this is wrong
          secretName: spoonity-sql-proxy

SSH 需要特定的密鑰權限才能連接。 Kubernetes 使用基於十進制的文件權限,所以這里的正確值應該是384 ,這將在 Linux 中以 0600 的適當權限掛載密鑰。

因為權限不對,腳本每次嘗試執行都會失敗退出,觸發Kubernetes嘗試重啟。

仍然不確定為什么從未生成這些日志,但我通過任意更改部署清單中的commandargs來發現這一點,而不是連續 ping localhost,這樣容器至少會啟動:

...
 - image: gcr.io/xxxxxxxxx/sql-proxy:latest
   command: ["ping"]
   args: ["127.0.0.1"]
...

然后我連接到正在運行的 pod,並嘗試手動運行 tunnel.sh 命令。 現在我可以真正了解它失敗的原因,我可以修復它。

這里的問題是您可能正在將文件復制到容器的/目錄,但是當您啟動容器時,shell 從~/目錄開始。 所以它找不到文件。

在 Dockerfile 的開頭添加 WORKDIR 語句,這將確保您在啟動容器時知道從哪里開始。

FROM alpine:3.14.0

WORKDIR /usr/src/app

COPY tunnel.sh .

RUN apk update && apk add curl \
    wget \
    nano \
    bash \
    ca-certificates \
    openssh-client

RUN chmod +x ./tunnel.sh

RUN mkdir ~/.ssh

RUN ssh-keyscan -Ht ecdsa proxysql-sshtunnel.domain.com > ~/.ssh/known_hosts

CMD /bin/bash

此外,建議將 CMD 更改為您要運行的實際命令,而不是通過 kubernetes 傳遞它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM