我需要实现虚拟服务器启动过程,其中一个过程需要在新启动的实例中生成的ssh密钥添加到部署服务器" authorized_keys"文件。
为了做到这一点,我创建了一个简单的烧瓶应用程序,它将在部署服务器中侦听传入的get请求,其中ip和实例的端口号将其密钥添加到authorized_keys。
以下是部署服务器上的烧瓶应用程序:
from flask import Flask, render_template
import requests
import os
from time import sleep
app = Flask(__name__)
#Get the ip and port number from the newly launched port
@app.route('/<ip_addr>/<port>')
def get_ip_port(ip_addr, port):
#rmt_response = requests.get('http://%s:%s/id_rsa.pub' % (ip_addr, port))
rmt_response = requests.get('http://127.0.1.1:9090/id_rsa.pub', timeout=1)
#sleep(5)
if rmt_response.status_code == 200:
auth_file = open("authorized_keys", "a")
auth_file.write(rmt_response.content)
return render_template('layout.html', ip_addr=ip_addr, port=port, \
srvrsp=rmt_response.content, rmt_response=rmt_response)
else:
return render_template('layout.html', rmt_response=rmt_response)
if __name__ == '__main__':
app.run(debug=True)
以下是将在新服务器实例上启动的python应用程序
import sys, socket
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import requests
HandlerClass = SimpleHTTPRequestHandler
ServerClass = BaseHTTPServer.HTTPServer
Protocol = "HTTP/1.0"
local_ip = socket.gethostbyname(socket.gethostname())
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port = 9090
#Send the ip and the port num to deployment host
r = requests.get("http://127.0.0.1:5000/%s/%s"%(local_ip,port))
#For debug only
rtext = "http://127.0.0.1:5000/%s/%s"%(local_ip,port)
server_address=(local_ip, port)
HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
print local_ip
print r
print rtext
httpd.serve_forever()
当我运行instace代码(上面)并通过浏览器发出get请求并运行python请求时,我会收到预期的结果,即id_rsa.pub文件的内容。但是当Flask应用程序发出确切的请求时,它会给我一个错误。
ConnectionError: HTTPConnectionPool(host='127.0.1.1', port=9090): Max retries exceeded with url: /id_rsa.pub (Caused by <class 'socket.error'>: [Errno 111] Connection refused)
我确实研究了这个错误,因为它与python请求有关,但无法找到确凿的解决方案。我知道该文件已经提供,因为我可以从浏览器下载它,我可以发出请求
x = requests.get("http://127.0.1.1:9090/id_rsa.pub")
能够获取文件的内容但由于某种原因它在flask应用程序中不起作用。
答案 0 :(得分:0)
第二个脚本中的请求:
r = requests.get("http://127.0.0.1:5000/%s/%s"%(local_ip,port))
在服务器开始侦听之前发生,位于该脚本的底部。烧瓶应用程序同时立即回请:
rmt_response = requests.get('http://127.0.1.1:9090/id_rsa.pub', timeout=1)
如果服务器已经在监听并且速度很慢,那么timeout参数会起作用,但由于服务器没有监听,因此&#34;连接被拒绝&#34;立即发生。在9090的服务器甚至正在侦听之前,您的烧瓶请求会引发异常。
为了完成这项工作,您必须在接收传入请求和发出出站请求之间引入烧瓶应用程序的延迟,或者在服务器开始监听后将启动请求设置为在线程中运行