[英]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嘗試重啟。
仍然不確定為什么從未生成這些日志,但我通過任意更改部署清單中的command
和args
來發現這一點,而不是連續 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.