下面是一个完整的 **Python 脚本**,用于:
1. 检查本地是否已安装 Java(Elasticsearch 依赖)
2. 下载指定版本的 Elasticsearch(以 `.tar.gz` 为例)
3. 解压并初始化基本配置(单节点模式、数据目录、日志、网络绑定等)
4. 启动 Elasticsearch 实例
5. 等待服务就绪,并通过 Python 的 `requests` 发送请求验证
6. 设置默认密码(仅适用于首次启动)
> ✅ 适用场景:开发/测试环境快速部署单节点 Elasticsearch
---
### ✅ 前提要求
- 操作系统:Linux / macOS / WSL(Windows 推荐使用 WSL)
- 已安装 `wget` 或 `curl` 和 `tar`
- Python 3.7+,并安装了 `requests`
```bash
pip install requests
```
---
### ✅ Python 脚本:`install_and_start_elasticsearch.py`
```python
#!/usr/bin/env python3
import os
import sys
import subprocess
import time
import requests
from pathlib import Path
# ================= 配置参数 =================
VERSION = "8.11.0" # 可修改为你需要的版本
DOWNLOAD_URL = f"https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-{VERSION}-linux-x86_64.tar.gz"
ES_HOME = Path(f"./elasticsearch-{VERSION}")
DATA_DIR = ES_HOME / "data"
LOGS_DIR = ES_HOME / "logs"
CONFIG_DIR = ES_HOME / "config"
ES_TAR = f"elasticsearch-{VERSION}-linux-x86_64.tar.gz"
JAVA_MIN_VERSION = 17
# 网络配置
ES_HOST = "http://localhost:9200"
ES_USER = "elastic"
ES_PASSWORD = "elastic_password_123" # 初始临时密码(首次设置用)
print("🔍 正在准备安装和启动 Elasticsearch...")
# ================= 1. 检查 Java 版本 =================
def check_java():
try:
result = subprocess.run(["java", "-version"], capture_output=True, text=True)
if "version" in result.stderr:
version_line = [line for line in result.stderr.split('\n') if "version" in line][0]
version_str = version_line.split('"')[1].split('.')[0]
version = int(version_str)
if version >= JAVA_MIN_VERSION:
print(f"✅ Java {version} 满足要求")
return True
else:
print(f"❌ Java 版本过低,需要至少 {JAVA_MIN_VERSION},当前为 {version}")
return False
except FileNotFoundError:
print("❌ 未找到 Java,请先安装 JDK {JAVA_MIN_VERSION}+")
return False
# ================= 2. 下载 Elasticsearch =================
def download_es():
if not os.path.exists(ES_TAR):
print(f"⬇️ 正在下载 Elasticsearch {VERSION}...")
try:
subprocess.run(["wget", DOWNLOAD_URL], check=True)
except subprocess.CalledProcessError:
print("❌ 下载失败,尝试使用 curl...")
try:
subprocess.run(["curl", "-O", DOWNLOAD_URL], check=True)
except Exception as e:
print(f"❌ curl 也失败: {e}")
sys.exit(1)
else:
print("📦 安装包已存在,跳过下载")
# ================= 3. 解压 Elasticsearch =================
def extract_es():
if not ES_HOME.exists():
print("🗂️ 正在解压...")
try:
subprocess.run(["tar", "-xzf", ES_TAR, "--strip-components=1"], cwd=".", check=True)
print("✅ 解压完成")
except subprocess.CalledProcessError as e:
print(f"❌ 解压失败: {e}")
sys.exit(1)
else:
print("📂 Elasticsearch 已解压,跳过")
# ================= 4. 创建数据和日志目录 =================
def setup_directories():
DATA_DIR.mkdir(parents=True, exist_ok=True)
LOGS_DIR.mkdir(exist_ok=True)
print(f"📁 数据目录: {DATA_DIR}")
print(f"📁 日志目录: {LOGS_DIR}")
# ================= 5. 配置 elasticsearch.yml =================
def configure_es():
config_file = CONFIG_DIR / "elasticsearch.yml"
with open(config_file, 'w') as f:
f.write(f"""
# 单节点开发模式
cluster.name: my-dev-cluster
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
path.data: {DATA_DIR}
path.logs: {LOGS_DIR}
# 安全设置
xpack.security.enabled: true
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
# CORS(可选)
http.cors.enabled: true
http.cors.allow-origin: "*"
""")
print("✅ 配置文件已生成:", config_file)
# ================= 6. 启动 Elasticsearch =================
def start_elasticsearch():
bin_dir = ES_HOME / "bin"
es_exec = bin_dir / "elasticsearch"
env = os.environ.copy()
env["ES_JAVA_OPTS"] = "-Xms1g -Xmx1g" # 控制内存使用
env["ES_PATH_CONF"] = str(CONFIG_DIR)
print("🚀 正在启动 Elasticsearch,请稍候...")
process = subprocess.Popen(
[str(es_exec)],
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
cwd=ES_HOME,
universal_newlines=True
)
# 实时输出日志
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
# 检查是否启动成功
if "started" in output and "http" in output:
print("🎉 Elasticsearch 已成功启动!")
return process
time.sleep(1)
return process
# ================= 7. 等待服务可用并设置密码 =================
def wait_and_setup():
print("⏳ 等待 Elasticsearch 可访问...")
started = False
for _ in range(60): # 最多等待 60 秒
try:
response = requests.get(f"{ES_HOST}/_cluster/health", auth=(ES_USER, ""), timeout=5)
if response.status_code == 200:
print("🟢 集群健康接口已就绪")
started = True
break
except requests.exceptions.ConnectionError:
pass
time.sleep(5)
if not started:
print("❌ Elasticsearch 启动超时或无法访问")
sys.exit(1)
# 设置初始密码(适用于首次启动)
print("🔐 正在设置 elastic 用户密码...")
passwd_cmd = [
str(ES_HOME / "bin" / "elasticsearch-reset-password"),
"-u", "elastic",
"-i",
"-s" # 静默模式,自动设置
]
try:
result = subprocess.run(passwd_cmd, input=f"{ES_PASSWORD}\n{ES_PASSWORD}\n", text=True, timeout=30)
if result.returncode == 0:
print(f"✅ elastic 用户密码已设置为: {ES_PASSWORD}")
else:
print("⚠️ 密码可能已存在,跳过设置")
except subprocess.TimeoutExpired:
print("⚠️ 密码设置超时,可能已配置过")
# 测试登录
print("🧪 测试连接...")
for _ in range(10):
try:
resp = requests.get(f"{ES_HOST}", auth=(ES_USER, ES_PASSWORD), timeout=5)
if resp.status_code == 200:
print("🎉 成功连接到 Elasticsearch!")
print("💡 使用方式:")
print(f" Host: {ES_HOST}")
print(f" User: {ES_USER}")
print(f" Password: {ES_PASSWORD}")
return
except:
time.sleep(3)
print("❌ 无法连接到 Elasticsearch")
# ================= 主函数 =================
def main():
if not check_java():
sys.exit(1)
download_es()
extract_es()
setup_directories()
configure_es()
# 在后台启动(非阻塞)——这里我们模拟异步启动
import threading
p = None
def run_es():
nonlocal p
p = start_elasticsearch()
thread = threading.Thread(target=run_es, daemon=True)
thread.start()
# 给一点时间让进程启动
time.sleep(10)
# 尝试连接和设置
wait_and_setup()
# 保持脚本运行,以便查看日志(实际中可改为守护进程或退出)
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\n🛑 收到退出信号,终止 Elasticsearch...")
if p:
p.terminate()
p.wait()
if __name__ == "__main__":
main()
```
---
### ✅ 使用方法
```bash
# 1. 保存为 install_and_start_elasticsearch.py
# 2. 赋予执行权限(Linux/macOS)
chmod +x install_and_start_elasticsearch.py
# 3. 运行
python3 install_and_start_elasticsearch.py
```
---
### ✅ 输出示例
```
🔍 正在准备安装和启动 Elasticsearch...
✅ Java 17 满足要求
⬇️ 正在下载 Elasticsearch 8.11.0...
...
🎉 Elasticsearch 已成功启动!
⏳ 等待 Elasticsearch 可访问...
🟢 集群健康接口已就绪
🔐 正在设置 elastic 用户密码...
✅ elastic 用户密码已设置为: elastic_password_123
🎉 成功连接到 Elasticsearch!
💡 使用方式:
Host: http://localhost:9200
User: elastic
Password: elastic_password_123
```
---
### ✅ 注意事项
- 生产环境不建议使用此脚本,应使用 systemd、Docker 或 Ansible 管理。
- 默认关闭 HTTPS,仅限本地测试。
- 第一次运行后再次启动会提示密码已存在,需手动处理。
- 可将 `single-node` 改为集群发现机制以支持多节点。
---
###