Add HTTP health check server for Knative
Validate and publish container image / build (push) Successful in 3m58s
Validate and publish container image / build (push) Successful in 3m58s
This commit is contained in:
@@ -80,7 +80,32 @@ cp .env.example .env
|
|||||||
# .envファイルを編集して実際の値を設定
|
# .envファイルを編集して実際の値を設定
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚢 Agents `container_tools` へのデプロイ
|
## 🚢 Knative へのデプロイ
|
||||||
|
|
||||||
|
Knativeサービスとしてデプロイするには、`knative-service.yaml` を使用します。
|
||||||
|
|
||||||
|
### 1. マニフェストの適用
|
||||||
|
|
||||||
|
環境変数に必要な情報を設定した上で、Knativeサービスを作成します。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f knative-service.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 環境変数の設定
|
||||||
|
|
||||||
|
`knative-service.yaml` 内の `env` セクションを、環境に応じて適切に更新してください。機密情報は Kubernetes Secret として管理し、マニフェストから参照するように構成することを強く推奨します。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# knative-service.yaml の env を更新例
|
||||||
|
env:
|
||||||
|
- name: EMAIL_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: email-secrets
|
||||||
|
key: email-user
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
`container_tools` はイメージをビルドせず、レジストリからpullして起動します。このリポジトリでは、`main` へのpush時にGitea Actionsが次のイメージをHarborへ公開します。
|
`container_tools` はイメージをビルドせず、レジストリからpullして起動します。このリポジトリでは、`main` へのpush時にGitea Actionsが次のイメージをHarborへ公開します。
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import logging
|
|||||||
import requests
|
import requests
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
import signal
|
|
||||||
import threading
|
import threading
|
||||||
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
# ログ設定
|
# ログ設定
|
||||||
@@ -28,6 +28,25 @@ logging.basicConfig(
|
|||||||
)
|
)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class HealthCheckHandler(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
if self.path == '/health':
|
||||||
|
self.send_response(200)
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(b'OK')
|
||||||
|
else:
|
||||||
|
self.send_response(404)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
# ヘルスチェックのログがうるさいため抑制
|
||||||
|
return
|
||||||
|
|
||||||
|
def run_http_server():
|
||||||
|
server = HTTPServer(('0.0.0.0', 8080), HealthCheckHandler)
|
||||||
|
logger.info("Health check server started on port 8080")
|
||||||
|
server.serve_forever()
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class EmailMessage:
|
class EmailMessage:
|
||||||
"""メールメッセージのデータクラス"""
|
"""メールメッセージのデータクラス"""
|
||||||
@@ -445,9 +464,6 @@ class EmailMonitor:
|
|||||||
logger.debug(f"{self.check_interval}秒後に次のチェックを実行します")
|
logger.debug(f"{self.check_interval}秒後に次のチェックを実行します")
|
||||||
time.sleep(self.check_interval)
|
time.sleep(self.check_interval)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
logger.info("キーボード割り込みを受信しました")
|
|
||||||
break
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"監視ループでエラーが発生しました: {str(e)}")
|
logger.error(f"監視ループでエラーが発生しました: {str(e)}")
|
||||||
self.disconnect_from_email()
|
self.disconnect_from_email()
|
||||||
@@ -480,9 +496,13 @@ def main():
|
|||||||
signal.signal(signal.SIGINT, lambda s, f: signal_handler(s, f, monitor))
|
signal.signal(signal.SIGINT, lambda s, f: signal_handler(s, f, monitor))
|
||||||
signal.signal(signal.SIGTERM, lambda s, f: signal_handler(s, f, monitor))
|
signal.signal(signal.SIGTERM, lambda s, f: signal_handler(s, f, monitor))
|
||||||
|
|
||||||
|
# メール監視をバックグラウンドスレッドで開始
|
||||||
|
monitor_thread = threading.Thread(target=monitor.start_monitoring, daemon=True)
|
||||||
|
monitor_thread.start()
|
||||||
|
|
||||||
|
# メインスレッドでヘルスチェックサーバーを実行
|
||||||
try:
|
try:
|
||||||
# 監視開始
|
run_http_server()
|
||||||
monitor.start_monitoring()
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"アプリケーションエラー: {str(e)}")
|
logger.error(f"アプリケーションエラー: {str(e)}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
apiVersion: serving.knative.dev/v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: email-to-discord
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: harbor.mukan.0am.jp/knative-func/email-to-discord:latest
|
||||||
|
env:
|
||||||
|
- name: IMAP_SERVER
|
||||||
|
value: "imap.gmail.com"
|
||||||
|
- name: EMAIL_USER
|
||||||
|
value: "your-email@gmail.com"
|
||||||
|
- name: EMAIL_PASSWORD
|
||||||
|
value: "your-app-password"
|
||||||
|
- name: DISCORD_WEBHOOK_URL
|
||||||
|
value: "https://discord.com/api/webhooks/..."
|
||||||
|
- name: CHECK_INTERVAL
|
||||||
|
value: "60"
|
||||||
|
# Knative services are expected to listen on a port,
|
||||||
|
# but this app is a worker. For now, we set it up as a service.
|
||||||
|
# If it needs to be a web hook receiver, the app needs modification.
|
||||||
|
# Assuming this runs as a worker periodically triggered or running in a loop.
|
||||||
|
# In Knative, if it doesn't listen on a port, it might be terminated.
|
||||||
|
# But let's assume it works for the user's intent.
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
Reference in New Issue
Block a user