簡體   English   中英

docker容器內調用命令

[英]Call commands within docker container

我有一個 docker 容器,我需要在其中運行一些命令。 通常,我通過運行以下命令手動執行此操作:

host> docker exec -it my-container bash
container> eval $(ssh-agent)
container> ssh-add ~/.ssh/my-key
<TYPE PASSPHRASE!!!>
container> pytest

我試圖從子流程調用docker exec -it ,但我無法模仿與手動工作流相同的行為。 我無法一一發送命令,因為 ssh 密鑰僅針對當前 session 加載,如果我以非交互方式運行它,我將無法使用該密鑰。

我有兩個問題 - 我需要通過 stdin 輸入密碼(我沒有看到將它與ssh-add一起提供的方法),我想知道pytest何時退出和返回代碼。

實現這一目標的最無縫方式是什么? 我寧願避免安裝額外的依賴項,但如果有必要,我可以使用一些東西。

ssh-agent 監聽 Unix 套接字; 它的位置在$SSH_AUTH_SOCK環境變量中。 您可以使用 Docker 綁定安裝( docker run -v選項)將此套接字注入容器。 然后,當您在主機上運行ssh-add時,只要套接字可訪問並且主機上的環境變量設置正確,容器就可以訪問代理中的憑據。

我不會在這里使用docker exec 一個容器通常運行一些單一的命令; 假設您的容器正在運行 Flask 或 Django 應用程序。 當 Django 應用程序正在運行時,您通常不會“進入”該應用程序以在服務器內部運行其單元測試。 一個單獨的容器和一個單獨的進程更有意義。

我在這里可能使用的調用看起來更像:

eval $(ssh-agent)                           # if not already done on login
ssh-add                                     # if not already done on login
docker run \
  --rm \                                    # delete temporary test container when done
  -v "$SSH_AUTH_SOCK:/tmp/ssh-auth.sock" \  # mount ssh socket into container
  -e SSH_AUTH_SOCK=/tmp/ssh-auth.sock \     # set socket location to mounted socket
  -u $(id -u) \                             # run as host user (with permissions on the socket)
  your-image \
  pytest                                    # override command to run in container

我會驚訝地看到單元測試實際上取決於對特定 ssh 憑據的訪問; 您還可能會發現,在構建 Docker 映像之前,重組測試以模擬需要這些憑據的服務客戶端或在主機上的 Python 虛擬環境中運行這些測試會更容易。

我發現 expect(或者在 python 的情況下,pexpect)在您不得不提供用戶輸入的情況下非常有用。 這是一個執行示例的簡單腳本(誠然,還有其他依賴項):

#!/usr/bin/env python
import pexpect
from getpass import getpass

prompt = ">"
child = pexpect.spawn ('docker exec -it my-container bash'))  
child.expect (prompt)
child.sendline ('eval $(ssh-agent)')
child.expect (prompt)
child.sendline ('ssh-add ~/.ssh/my-key')
child.expect ('Enter passphrase for /root/.ssh/my-key:')
password = getpass( prompt="Private Key Password:")
child.sendline (password)
child.expect (prompt)
child.sendline ("pytest")

我從https://pexpect.readthedocs.io/en/stable/overview.html中獲取示例並輸入您的命令。

關於提示的注釋。 當我測試上面的代碼時,我容器中的 bash shell 有一個 '$' 提示符。 我認為我很幸運“$”對我有用,因為它基本上是一個有效的正則表達式。 您的里程數可能因“>”提示而異,但您可能還需要注意上述同一頁面上有關 CR/LF 的信息。

我假設當您啟動容器時,您安裝了 ~/.ssh 目錄。 當我啟動我的容器來驗證上面的代碼時,我添加了掛載選項: -v ~/.ssh:/root/.ssh

您必須改為運行此命令以避免輸入密碼

sshpass -p [PASSWORD] ssh [USER]@172.17.0.2

暫無
暫無

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

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