añadido gitea y medio argos
This commit is contained in:
@@ -18,6 +18,13 @@ data:
|
|||||||
192.168.200.13 muc.chat.apolo.c2et.net
|
192.168.200.13 muc.chat.apolo.c2et.net
|
||||||
192.168.200.12 streaming.apolo.c2et.net
|
192.168.200.12 streaming.apolo.c2et.net
|
||||||
192.168.200.14 meeting.apolo.c2et.net
|
192.168.200.14 meeting.apolo.c2et.net
|
||||||
|
|
||||||
|
# === ARGOS (videovigilancia) ===
|
||||||
|
192.168.200.15 mqtt.argos.interna
|
||||||
|
192.168.200.16 mediamtx.argos.interna
|
||||||
|
192.168.200.10 s3.argos.interna
|
||||||
|
192.168.200.10 minio.argos.interna
|
||||||
|
192.168.200.10 panel.argos.c2et.net
|
||||||
fallthrough
|
fallthrough
|
||||||
}
|
}
|
||||||
forward . /etc/resolv.conf
|
forward . /etc/resolv.conf
|
||||||
|
|||||||
12
argos/certs/certificate-argos-panel.yaml
Normal file
12
argos/certs/certificate-argos-panel.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: panel-argos-cert
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
secretName: panel-argos-tls
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- panel.argos.c2et.net
|
||||||
15
argos/configmaps/configmap-mediamtx.yaml
Normal file
15
argos/configmaps/configmap-mediamtx.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: mediamtx-config
|
||||||
|
namespace: argos-core
|
||||||
|
data:
|
||||||
|
mediamtx.yml: |
|
||||||
|
logLevel: info
|
||||||
|
rtsp: yes
|
||||||
|
rtmp: no
|
||||||
|
hls: no
|
||||||
|
webrtc: yes
|
||||||
|
paths:
|
||||||
|
all:
|
||||||
|
sourceOnDemand: yes
|
||||||
9
argos/configmaps/configmap-mosquitto.yaml
Normal file
9
argos/configmaps/configmap-mosquitto.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: mosquitto-conf
|
||||||
|
namespace: argos-core
|
||||||
|
data:
|
||||||
|
mosquitto.conf: |
|
||||||
|
listener 1883 0.0.0.0
|
||||||
|
allow_anonymous true
|
||||||
156
argos/configmaps/configmap-orchestrator.yaml
Normal file
156
argos/configmaps/configmap-orchestrator.yaml
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: argos-orchestrator-config
|
||||||
|
namespace: argos-core
|
||||||
|
data:
|
||||||
|
settings.yaml: |
|
||||||
|
mqtt:
|
||||||
|
host: mqtt.argos.interna
|
||||||
|
port: 1883
|
||||||
|
topic: frigate/events
|
||||||
|
client_id: argos-core
|
||||||
|
minio:
|
||||||
|
bucket: argos
|
||||||
|
region: us-east-1
|
||||||
|
edges:
|
||||||
|
- name: rpi01
|
||||||
|
base_url: http://10.20.0.10:5000 # URL del Frigate del edge (VPN). 5000 por defecto.
|
||||||
|
api_token: "" # si usas auth, ponlo aquí
|
||||||
|
cameras:
|
||||||
|
- name: cam1
|
||||||
|
rtsp_main: rtsp://10.20.0.10:8554/cam1_main
|
||||||
|
path_mtx: cam1 # para abrir live en MediaMTX: /?path=cam1
|
||||||
|
app.py: |
|
||||||
|
import os, json, time, datetime, sqlite3, subprocess, yaml, requests
|
||||||
|
from pathlib import Path
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
from minio import Minio
|
||||||
|
|
||||||
|
CFG_PATH="/app/settings.yaml"
|
||||||
|
DB_PATH="/data/argos.db"
|
||||||
|
TMP="/tmp"
|
||||||
|
with open(CFG_PATH,"r") as f:
|
||||||
|
CFG=yaml.safe_load(f)
|
||||||
|
|
||||||
|
# Map quick-lookup: camera -> (edge, cfg)
|
||||||
|
CAM_MAP={}
|
||||||
|
for e in CFG.get("edges", []):
|
||||||
|
for c in e.get("cameras", []):
|
||||||
|
CAM_MAP[c["name"]]=(e, c)
|
||||||
|
|
||||||
|
# MinIO
|
||||||
|
mc=Minio(os.getenv("MINIO_ENDPOINT","s3.argos.interna"),
|
||||||
|
access_key=os.getenv("MINIO_ACCESS_KEY"),
|
||||||
|
secret_key=os.getenv("MINIO_SECRET_KEY"),
|
||||||
|
secure=os.getenv("MINIO_SECURE","false").lower()=="true")
|
||||||
|
BUCKET=CFG["minio"]["bucket"]
|
||||||
|
if not mc.bucket_exists(BUCKET): mc.make_bucket(BUCKET)
|
||||||
|
|
||||||
|
# DB
|
||||||
|
Path("/data").mkdir(parents=True, exist_ok=True)
|
||||||
|
con=sqlite3.connect(DB_PATH, check_same_thread=False)
|
||||||
|
cur=con.cursor()
|
||||||
|
cur.execute("""CREATE TABLE IF NOT EXISTS events(
|
||||||
|
id TEXT PRIMARY KEY, ts INTEGER, edge TEXT, camera TEXT, label TEXT,
|
||||||
|
s3url TEXT, thumb_s3 TEXT
|
||||||
|
)""")
|
||||||
|
con.commit()
|
||||||
|
|
||||||
|
def upload_file(local_path, key, content_type):
|
||||||
|
mc.fput_object(BUCKET, key, local_path, content_type=content_type)
|
||||||
|
return f"s3://{BUCKET}/{key}"
|
||||||
|
|
||||||
|
def fetch_frigate_clip(edge_cfg, ev_id):
|
||||||
|
""" Descarga el clip nativo de Frigate si existe """
|
||||||
|
base=edge_cfg["base_url"]
|
||||||
|
url=urljoin(base, f"/api/events/{ev_id}/clip")
|
||||||
|
headers={}
|
||||||
|
if edge_cfg.get("api_token"):
|
||||||
|
headers["Authorization"]=f"Bearer {edge_cfg['api_token']}"
|
||||||
|
r=requests.get(url, headers=headers, stream=True, timeout=30)
|
||||||
|
if r.status_code!=200: return None
|
||||||
|
tmp=f"{TMP}/{ev_id}.mp4"
|
||||||
|
with open(tmp,"wb") as f:
|
||||||
|
for chunk in r.iter_content(1<<20):
|
||||||
|
if chunk: f.write(chunk)
|
||||||
|
return tmp
|
||||||
|
|
||||||
|
def fetch_frigate_thumb(edge_cfg, ev_id):
|
||||||
|
base=edge_cfg["base_url"]
|
||||||
|
url=urljoin(base, f"/api/events/{ev_id}/thumbnail.jpg")
|
||||||
|
headers={}
|
||||||
|
if edge_cfg.get("api_token"):
|
||||||
|
headers["Authorization"]=f"Bearer {edge_cfg['api_token']}"
|
||||||
|
r=requests.get(url, headers=headers, timeout=10)
|
||||||
|
if r.status_code!=200: return None
|
||||||
|
tmp=f"{TMP}/{ev_id}.jpg"
|
||||||
|
with open(tmp,"wb") as f: f.write(r.content)
|
||||||
|
return tmp
|
||||||
|
|
||||||
|
def record_rtsp(rtsp_url, seconds=30):
|
||||||
|
tmp=f"{TMP}/rtsp_{int(time.time())}.mp4"
|
||||||
|
cmd=["ffmpeg","-nostdin","-y","-rtsp_transport","tcp","-i",rtsp_url,"-t",str(seconds),"-c","copy",tmp]
|
||||||
|
try:
|
||||||
|
subprocess.run(cmd, check=True)
|
||||||
|
return tmp
|
||||||
|
except Exception as e:
|
||||||
|
print("FFmpeg fallback failed:", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def on_message(client, userdata, msg):
|
||||||
|
try:
|
||||||
|
payload=json.loads(msg.payload.decode("utf-8"))
|
||||||
|
except Exception as e:
|
||||||
|
print("Bad JSON", e); return
|
||||||
|
|
||||||
|
ev_type=payload.get("type")
|
||||||
|
after=payload.get("after") or {}
|
||||||
|
ev_id=after.get("id") or payload.get("id")
|
||||||
|
cam=after.get("camera") or payload.get("camera")
|
||||||
|
label=after.get("label") or payload.get("label","")
|
||||||
|
|
||||||
|
if ev_type!="new" or not cam or not ev_id: return
|
||||||
|
if cam not in CAM_MAP:
|
||||||
|
print("Unknown camera:", cam); return
|
||||||
|
|
||||||
|
edge_cfg, cam_cfg = CAM_MAP[cam]
|
||||||
|
ts=int(time.time())
|
||||||
|
print(f"[ARGOS] {ev_id} {cam} → try Frigate clip")
|
||||||
|
path_local = fetch_frigate_clip(edge_cfg, ev_id)
|
||||||
|
if not path_local:
|
||||||
|
print(f"[ARGOS] {ev_id} no native clip, fallback RTSP")
|
||||||
|
path_local = record_rtsp(cam_cfg["rtsp_main"], seconds=30)
|
||||||
|
if not path_local:
|
||||||
|
print(f"[ARGOS] {ev_id} failed recording"); return
|
||||||
|
|
||||||
|
# upload clip
|
||||||
|
date=datetime.datetime.utcfromtimestamp(ts)
|
||||||
|
key=f"{cam}/{date.year:04d}/{date.month:02d}/{date.day:02d}/{ts}_{ev_id}.mp4"
|
||||||
|
s3url=upload_file(path_local, key, "video/mp4")
|
||||||
|
try: os.remove(path_local)
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
# thumbnail
|
||||||
|
thumb_local = fetch_frigate_thumb(edge_cfg, ev_id)
|
||||||
|
thumb_s3=None
|
||||||
|
if thumb_local:
|
||||||
|
tkey=f"{cam}/thumbs/{ts}_{ev_id}.jpg"
|
||||||
|
thumb_s3=upload_file(thumb_local, tkey, "image/jpeg")
|
||||||
|
try: os.remove(thumb_local)
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
cur.execute("INSERT OR REPLACE INTO events(id, ts, edge, camera, label, s3url, thumb_s3) VALUES (?,?,?,?,?,?,?)",
|
||||||
|
(ev_id, ts, edge_cfg["name"], cam, label, s3url, thumb_s3))
|
||||||
|
con.commit()
|
||||||
|
print(f"[ARGOS] stored {s3url}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
m=mqtt.Client(client_id=CFG["mqtt"]["client_id"], clean_session=True)
|
||||||
|
m.connect(CFG["mqtt"]["host"], CFG["mqtt"]["port"], keepalive=60)
|
||||||
|
m.subscribe(CFG["mqtt"]["topic"])
|
||||||
|
m.on_message=on_message
|
||||||
|
m.loop_forever()
|
||||||
|
|
||||||
|
if __name__=="__main__": main()
|
||||||
87
argos/configmaps/configmap-panel.yaml
Normal file
87
argos/configmaps/configmap-panel.yaml
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: argos-panel-config
|
||||||
|
namespace: argos-core
|
||||||
|
data:
|
||||||
|
app.py: |
|
||||||
|
import os, sqlite3, time
|
||||||
|
from fastapi import FastAPI, HTTPException
|
||||||
|
from fastapi.responses import HTMLResponse
|
||||||
|
from minio import Minio
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
DB="/data/argos.db"
|
||||||
|
mc=Minio(os.getenv("MINIO_ENDPOINT","s3.argos.interna"),
|
||||||
|
access_key=os.getenv("MINIO_ACCESS_KEY"),
|
||||||
|
secret_key=os.getenv("MINIO_SECRET_KEY"),
|
||||||
|
secure=os.getenv("MINIO_SECURE","false").lower()=="true")
|
||||||
|
app=FastAPI()
|
||||||
|
|
||||||
|
def rows(limit=100, camera=None, since=None):
|
||||||
|
q="SELECT id, ts, edge, camera, label, s3url, thumb_s3 FROM events"
|
||||||
|
cond=[]; args=[]
|
||||||
|
if camera: cond.append("camera=?"); args.append(camera)
|
||||||
|
if since: cond.append("ts>=?"); args.append(int(since))
|
||||||
|
if cond: q+=" WHERE "+ " AND ".join(cond)
|
||||||
|
q+=" ORDER BY ts DESC LIMIT ?"; args.append(limit)
|
||||||
|
con=sqlite3.connect(DB); cur=con.cursor()
|
||||||
|
cur.execute(q, tuple(args)); r=cur.fetchall(); con.close()
|
||||||
|
return r
|
||||||
|
|
||||||
|
@app.get("/api/events")
|
||||||
|
def api_events(limit:int=100, camera:str=None, since:int=None):
|
||||||
|
return [dict(id=i, ts=t, edge=e, camera=c, label=l or "", s3url=s, thumb=th or "")
|
||||||
|
for (i,t,e,c,l,s,th) in rows(limit,camera,since)]
|
||||||
|
|
||||||
|
@app.get("/api/url/{event_id}")
|
||||||
|
def presign(event_id: str, expires: int = 600):
|
||||||
|
con=sqlite3.connect(DB); cur=con.cursor()
|
||||||
|
cur.execute("SELECT s3url FROM events WHERE id=?", (event_id,))
|
||||||
|
row=cur.fetchone(); con.close()
|
||||||
|
if not row: raise HTTPException(404, "Not found")
|
||||||
|
s3url=row[0]; p=urlparse(s3url); b=p.netloc; k=p.path.lstrip("/")
|
||||||
|
return {"url": mc.presigned_get_object(b, k, expires=expires)}
|
||||||
|
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
def index():
|
||||||
|
return """
|
||||||
|
<!doctype html><meta charset="utf-8"><title>ARGOS Panel</title>
|
||||||
|
<style>body{font-family:system-ui;margin:1.5rem} .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px}
|
||||||
|
.card{border:1px solid #ddd;border-radius:10px;padding:10px} img{width:100%;height:160px;object-fit:cover;border-radius:8px}
|
||||||
|
button{padding:.4rem .6rem;margin-right:.3rem}</style>
|
||||||
|
<h1>ARGOS – Alarmas</h1>
|
||||||
|
<div class="grid" id="grid"></div>
|
||||||
|
<div style="margin-top:1rem"><video id="player" width="960" controls></video></div>
|
||||||
|
<script>
|
||||||
|
const fmt=t=>new Date(t*1000).toLocaleString();
|
||||||
|
async function load(){
|
||||||
|
const r=await fetch('/api/events?limit=100'); const data=await r.json();
|
||||||
|
const g=document.getElementById('grid'); g.innerHTML='';
|
||||||
|
for(const ev of data){
|
||||||
|
const d=document.createElement('div'); d.className='card';
|
||||||
|
const img = ev.thumb ? `<img src="${ev.thumb.replace('s3://','/api/url/THUMB?key=')}" alt="thumb">` : '';
|
||||||
|
d.innerHTML = `${img}<div><b>${ev.camera}</b> — ${fmt(ev.ts)}<br>${ev.label||''}</div>
|
||||||
|
<div style="margin-top:.4rem">
|
||||||
|
<button data-id="${ev.id}" data-action="clip">Ver clip</button>
|
||||||
|
<button data-path="${ev.camera}" data-action="live">En directo</button>
|
||||||
|
</div>`;
|
||||||
|
g.appendChild(d);
|
||||||
|
}
|
||||||
|
g.onclick=async (e)=>{
|
||||||
|
if(e.target.tagName!=='BUTTON') return;
|
||||||
|
const v=document.getElementById('player');
|
||||||
|
if(e.target.dataset.action==='clip'){
|
||||||
|
const id=e.target.dataset.id;
|
||||||
|
const j=await (await fetch('/api/url/'+id)).json();
|
||||||
|
v.src=j.url; v.play();
|
||||||
|
}else if(e.target.dataset.action==='live'){
|
||||||
|
const path=e.target.dataset.path;
|
||||||
|
// usa MediaMTX web player
|
||||||
|
window.open('http://mediamtx.argos.interna/?path='+encodeURIComponent(path),'_blank');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
load(); setInterval(load,10000);
|
||||||
|
</script>
|
||||||
|
"""
|
||||||
34
argos/deployments/deploy-mediamtx.yaml
Normal file
34
argos/deployments/deploy-mediamtx.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mediamtx
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector: { matchLabels: { app: mediamtx } }
|
||||||
|
template:
|
||||||
|
metadata: { labels: { app: mediamtx } }
|
||||||
|
spec:
|
||||||
|
hostNetwork: true
|
||||||
|
dnsPolicy: ClusterFirstWithHostNet
|
||||||
|
containers:
|
||||||
|
- name: mediamtx
|
||||||
|
image: bluenviron/mediamtx:1.14.0
|
||||||
|
command: ["/bin/sh","-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
ulimit -n 1048576
|
||||||
|
exec mediamtx /config/mediamtx.yml
|
||||||
|
volumeMounts:
|
||||||
|
- name: cfg
|
||||||
|
mountPath: /config
|
||||||
|
ports:
|
||||||
|
- containerPort: 8554 # RTSP
|
||||||
|
- containerPort: 8189 # SRT
|
||||||
|
- containerPort: 8889 # WHIP
|
||||||
|
- containerPort: 8880 # HTTP/API
|
||||||
|
volumes:
|
||||||
|
- name: cfg
|
||||||
|
configMap:
|
||||||
|
name: mediamtx-config
|
||||||
27
argos/deployments/deploy-minio.yaml
Normal file
27
argos/deployments/deploy-minio.yaml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: minio
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector: { matchLabels: { app: minio } }
|
||||||
|
template:
|
||||||
|
metadata: { labels: { app: minio } }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: minio
|
||||||
|
image: quay.io/minio/minio:latest
|
||||||
|
args: ["server", "/data", "--console-address", ":9001"]
|
||||||
|
envFrom:
|
||||||
|
- secretRef: { name: minio-creds }
|
||||||
|
ports:
|
||||||
|
- containerPort: 9000
|
||||||
|
- containerPort: 9001
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: minio-data
|
||||||
26
argos/deployments/deploy-mosquitto.yaml
Normal file
26
argos/deployments/deploy-mosquitto.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mosquitto
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector: { matchLabels: { app: mosquitto } }
|
||||||
|
template:
|
||||||
|
metadata: { labels: { app: mosquitto } }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mosquitto
|
||||||
|
image: harbor.c2et.net/library/eclipse-mosquitto:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 1883
|
||||||
|
volumeMounts:
|
||||||
|
- name: cfg
|
||||||
|
mountPath: /mosquitto/config
|
||||||
|
volumes:
|
||||||
|
- name: cfg
|
||||||
|
configMap:
|
||||||
|
name: mosquitto-conf
|
||||||
|
items:
|
||||||
|
- key: mosquitto.conf
|
||||||
|
path: mosquitto.conf
|
||||||
35
argos/deployments/deploy-orchestrator.yaml
Normal file
35
argos/deployments/deploy-orchestrator.yaml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: argos-orchestrator
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector: { matchLabels: { app: argos-orchestrator } }
|
||||||
|
template:
|
||||||
|
metadata: { labels: { app: argos-orchestrator } }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: orchestrator
|
||||||
|
image: harbor.c2et.net/library/python:3.13.7-slim-bookworm
|
||||||
|
command: ["/bin/sh","-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
apt-get update && apt-get install -y --no-install-recommends ffmpeg curl && rm -rf /var/lib/apt/lists/*
|
||||||
|
pip install paho-mqtt minio pyyaml requests
|
||||||
|
python /app/app.py
|
||||||
|
envFrom:
|
||||||
|
- secretRef: { name: argos-orchestrator-secret }
|
||||||
|
volumeMounts:
|
||||||
|
- { name: cfg, mountPath: /app }
|
||||||
|
- { name: data, mountPath: /data }
|
||||||
|
volumes:
|
||||||
|
- name: cfg
|
||||||
|
configMap:
|
||||||
|
name: argos-orchestrator-config
|
||||||
|
items:
|
||||||
|
- { key: app.py, path: app.py }
|
||||||
|
- { key: settings.yaml, path: settings.yaml }
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
34
argos/deployments/deploy-panel.yaml
Normal file
34
argos/deployments/deploy-panel.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: argos-panel
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector: { matchLabels: { app: argos-panel } }
|
||||||
|
template:
|
||||||
|
metadata: { labels: { app: argos-panel } }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: panel
|
||||||
|
image: docker.io/library/python:3.13.7-slim-bookworm
|
||||||
|
command: ["/bin/sh","-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
pip install fastapi uvicorn minio
|
||||||
|
uvicorn app:app --host 0.0.0.0 --port 8000
|
||||||
|
envFrom:
|
||||||
|
- secretRef: { name: argos-panel-secret }
|
||||||
|
volumeMounts:
|
||||||
|
- { name: app, mountPath: /app }
|
||||||
|
- { name: data, mountPath: /data }
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
volumes:
|
||||||
|
- name: app
|
||||||
|
configMap:
|
||||||
|
name: argos-panel-config
|
||||||
|
items: [ { key: app.py, path: app.py } ]
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
26
argos/ingress/ingress-minio.yaml
Normal file
26
argos/ingress/ingress-minio.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: minio-ingress
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
rules:
|
||||||
|
- host: s3.argos.interna
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: minio
|
||||||
|
port: { number: 9000 }
|
||||||
|
- host: minio.argos.interna
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: minio
|
||||||
|
port: { number: 9001 }
|
||||||
18
argos/ingress/ingress-panel.yaml
Normal file
18
argos/ingress/ingress-panel.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: argos-panel-internal
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx-internal
|
||||||
|
rules:
|
||||||
|
- host: panel.argos.c2et.net # mismo FQDN
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service: { name: argos-panel, port: { number: 80 } }
|
||||||
|
tls:
|
||||||
|
- hosts: ["panel.argos.c2et.net"]
|
||||||
|
secretName: panel-argos-tls
|
||||||
48
argos/kustomization.yaml
Normal file
48
argos/kustomization.yaml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
namespace: argos-core
|
||||||
|
|
||||||
|
commonLabels:
|
||||||
|
app.kubernetes.io/part-of: argos
|
||||||
|
app.kubernetes.io/managed-by: kustomize
|
||||||
|
|
||||||
|
resources:
|
||||||
|
# Namespace y políticas
|
||||||
|
- namespace.yaml
|
||||||
|
- policies/network-policy.yaml
|
||||||
|
|
||||||
|
# ConfigMaps
|
||||||
|
- configmaps/configmap-mediamtx.yaml
|
||||||
|
- configmaps/configmap-mosquitto.yaml
|
||||||
|
- configmaps/configmap-orchestrator.yaml
|
||||||
|
- configmaps/configmap-panel.yaml
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
- secrets/secret-minio.yaml
|
||||||
|
- secrets/secret-orchestrator.yaml
|
||||||
|
- secrets/secret-panel.yaml
|
||||||
|
|
||||||
|
# Storage
|
||||||
|
- pvc/pvc-minio.yaml
|
||||||
|
|
||||||
|
# Deployments
|
||||||
|
- deployments/deploy-mediamtx.yaml
|
||||||
|
- deployments/deploy-mosquitto.yaml
|
||||||
|
- deployments/deploy-orchestrator.yaml
|
||||||
|
- deployments/deploy-panel.yaml
|
||||||
|
- deployments/deploy-minio.yaml
|
||||||
|
|
||||||
|
# Services
|
||||||
|
- services/argos-panel.yaml
|
||||||
|
- services/svc-mediamtx-tcp.yaml
|
||||||
|
- services/svc-mediamtx-udp.yaml
|
||||||
|
- services/svc-minio.yaml
|
||||||
|
- services/svc-mosquitto.yaml
|
||||||
|
|
||||||
|
# Ingress
|
||||||
|
- ingress/ingress-minio.yaml
|
||||||
|
- ingress/ingress-panel.yaml
|
||||||
|
|
||||||
|
# Certificados (si usas ACME en el externo y compartes el secret)
|
||||||
|
- certs/certificate-argos-panel.yaml
|
||||||
4
argos/namespace.yaml
Normal file
4
argos/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: argos-core
|
||||||
12
argos/policies/network-policy.yaml
Normal file
12
argos/policies/network-policy.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-from-wg-and-200
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes: [Ingress]
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- ipBlock: { cidr: 192.168.254.0/24 } # WireGuard peers
|
||||||
|
- ipBlock: { cidr: 192.168.200.0/24 } # red 200 (acceso interno/admin)
|
||||||
11
argos/pvc/pvc-minio.yaml
Normal file
11
argos/pvc/pvc-minio.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: minio-data
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
storageClassName: ceph-rbd
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Ti # ajusta capacidad
|
||||||
9
argos/secrets/secret-harbor-cred.yaml
Normal file
9
argos/secrets/secret-harbor-cred.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
data:
|
||||||
|
.dockerconfigjson: eyJhdXRocyI6eyJoYXJib3IuYzJldC5jb20iOnsidXNlcm5hbWUiOiJ4YXZvciIsInBhc3N3b3JkIjoiTUBuYWJvMjAyNSIsImVtYWlsIjoibm8tcmVwbHlAYzJldC5jb20iLCJhdXRoIjoiZUdGMmIzSTZUVUJ1WVdKdk1qQXlOUT09In19fQ==
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: harbor-cred
|
||||||
|
namespace: apolo
|
||||||
|
type: kubernetes.io/dockerconfigjson
|
||||||
9
argos/secrets/secret-minio.yaml
Normal file
9
argos/secrets/secret-minio.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: minio-creds
|
||||||
|
namespace: argos-core
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
MINIO_ROOT_USER: admin
|
||||||
|
MINIO_ROOT_PASSWORD: adminadmin123
|
||||||
11
argos/secrets/secret-orchestrator.yaml
Normal file
11
argos/secrets/secret-orchestrator.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: argos-orchestrator-secret
|
||||||
|
namespace: argos-core
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
MINIO_ENDPOINT: minio.argos-core.svc.cluster.local:9000
|
||||||
|
MINIO_ACCESS_KEY: admin
|
||||||
|
MINIO_SECRET_KEY: adminadmin123
|
||||||
|
MINIO_SECURE: "false"
|
||||||
11
argos/secrets/secret-panel.yaml
Normal file
11
argos/secrets/secret-panel.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: argos-panel-secret
|
||||||
|
namespace: argos-core
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
MINIO_ENDPOINT: minio.argos-core.svc.cluster.local:9000
|
||||||
|
MINIO_ACCESS_KEY: admin
|
||||||
|
MINIO_SECRET_KEY: adminadmin123
|
||||||
|
MINIO_SECURE: "false"
|
||||||
10
argos/services/argos-panel.yaml
Normal file
10
argos/services/argos-panel.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: argos-panel
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector: { app: argos-panel }
|
||||||
|
ports:
|
||||||
|
- { name: http, port: 80, targetPort: 8000 }
|
||||||
15
argos/services/svc-mediamtx-tcp.yaml
Normal file
15
argos/services/svc-mediamtx-tcp.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mediamtx-tcp
|
||||||
|
namespace: argos-core
|
||||||
|
annotations:
|
||||||
|
metallb.universe.tf/allow-shared-ip: "mediamtx-addr"
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
loadBalancerIP: 192.168.200.16
|
||||||
|
selector: { app: mediamtx }
|
||||||
|
ports:
|
||||||
|
- { name: rtsp, port: 8554, targetPort: 8554, protocol: TCP }
|
||||||
|
- { name: http, port: 8880, targetPort: 8880, protocol: TCP }
|
||||||
|
- { name: whip, port: 8889, targetPort: 8889, protocol: TCP }
|
||||||
13
argos/services/svc-mediamtx-udp.yaml
Normal file
13
argos/services/svc-mediamtx-udp.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mediamtx-udp
|
||||||
|
namespace: argos-core
|
||||||
|
annotations:
|
||||||
|
metallb.universe.tf/allow-shared-ip: "mediamtx-addr"
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
loadBalancerIP: 192.168.200.16
|
||||||
|
selector: { app: mediamtx }
|
||||||
|
ports:
|
||||||
|
- { name: srt, port: 8189, targetPort: 8189, protocol: UDP }
|
||||||
11
argos/services/svc-minio.yaml
Normal file
11
argos/services/svc-minio.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: minio
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector: { app: minio }
|
||||||
|
ports:
|
||||||
|
- { name: api, port: 9000, targetPort: 9000, protocol: TCP }
|
||||||
|
- { name: console, port: 9001, targetPort: 9001, protocol: TCP }
|
||||||
14
argos/services/svc-mosquitto.yaml
Normal file
14
argos/services/svc-mosquitto.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mosquitto
|
||||||
|
namespace: argos-core
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
loadBalancerIP: 192.168.200.15
|
||||||
|
selector: { app: mosquitto }
|
||||||
|
ports:
|
||||||
|
- name: mqtt
|
||||||
|
port: 1883
|
||||||
|
targetPort: 1883
|
||||||
|
protocol: TCP
|
||||||
17
gitea/copypod.yaml
Normal file
17
gitea/copypod.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata: { name: loader, namespace: gitea }
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: sh
|
||||||
|
image: alpine:latest
|
||||||
|
command: ["sh","-c","sleep 36000"]
|
||||||
|
volumeMounts:
|
||||||
|
- { name: gitea, mountPath: /mnt/gitea }
|
||||||
|
- { name: mysql, mountPath: /mnt/mysql }
|
||||||
|
volumes:
|
||||||
|
- name: gitea
|
||||||
|
persistentVolumeClaim: { claimName: gitea-data }
|
||||||
|
- name: mysql
|
||||||
|
persistentVolumeClaim: { claimName: gitea-db }
|
||||||
36
gitea/deployments/gitea-db.yaml
Normal file
36
gitea/deployments/gitea-db.yaml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: gitea-db
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: gitea-db
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: gitea-db
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:8
|
||||||
|
env:
|
||||||
|
- name: MYSQL_ROOT_PASSWORD
|
||||||
|
value: gitea123
|
||||||
|
- name: MYSQL_DATABASE
|
||||||
|
value: gitea
|
||||||
|
- name: MYSQL_USER
|
||||||
|
value: gitea
|
||||||
|
- name: MYSQL_PASSWORD
|
||||||
|
value: gitea123
|
||||||
|
ports:
|
||||||
|
- containerPort: 3306
|
||||||
|
volumeMounts:
|
||||||
|
- name: gitea-db
|
||||||
|
mountPath: /var/lib/mysql
|
||||||
|
volumes:
|
||||||
|
- name: gitea-db
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: gitea-db
|
||||||
42
gitea/deployments/gitea.yaml
Normal file
42
gitea/deployments/gitea.yaml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: gitea
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: gitea
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: gitea
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 3000
|
||||||
|
env:
|
||||||
|
- name: USER_UID
|
||||||
|
value: "1000"
|
||||||
|
- name: USER_GID
|
||||||
|
value: "1000"
|
||||||
|
- name: GITEA__database__DB_TYPE
|
||||||
|
value: "mysql"
|
||||||
|
- name: GITEA__database__HOST
|
||||||
|
value: "gitea-db:3306"
|
||||||
|
- name: GITEA__database__NAME
|
||||||
|
value: "gitea"
|
||||||
|
- name: GITEA__database__USER
|
||||||
|
value: "gitea"
|
||||||
|
- name: GITEA__database__PASSWD
|
||||||
|
value: "gitea123"
|
||||||
|
volumeMounts:
|
||||||
|
- name: gitea-data
|
||||||
|
mountPath: /data
|
||||||
|
volumes:
|
||||||
|
- name: gitea-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: gitea-data
|
||||||
28
gitea/ingress/ingress.yaml
Normal file
28
gitea/ingress/ingress.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
|
namespace: gitea
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||||
|
# nginx.ingress.kubernetes.io/proxy-body-size: "20m"
|
||||||
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
|
||||||
|
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- git.c2et.net
|
||||||
|
secretName: gitea-tls
|
||||||
|
rules:
|
||||||
|
- host: git.c2et.net
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: gitea
|
||||||
|
port:
|
||||||
|
number: 3000
|
||||||
9
gitea/kustomization.yaml
Normal file
9
gitea/kustomization.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- pvc/gitea-data.yaml
|
||||||
|
- pvc/gitea-db.yaml
|
||||||
|
- deployments/gitea.yaml
|
||||||
|
- deployments/gitea-db.yaml
|
||||||
|
- services/gitea.yaml
|
||||||
|
- services/gitea-db.yaml
|
||||||
|
- ingress/ingress.yaml
|
||||||
4
gitea/namespace.yaml
Normal file
4
gitea/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
12
gitea/pvc/gitea-data.yaml
Normal file
12
gitea/pvc/gitea-data.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: gitea-data
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
storageClassName: ceph-rbd
|
||||||
12
gitea/pvc/gitea-db.yaml
Normal file
12
gitea/pvc/gitea-db.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: gitea-db
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 2Gi
|
||||||
|
storageClassName: ceph-rbd
|
||||||
12
gitea/readme.md
Normal file
12
gitea/readme.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Manifiestos para Gitea
|
||||||
|
Este repositorio contiene los manifiestos necesarios para desplegar Gitea, un servidor Git ligero, en el namespace gitea.
|
||||||
|
|
||||||
|
## Despliegue
|
||||||
|
|
||||||
|
kubectl apply -f namespace.yaml
|
||||||
|
kubectl apply -f pvc/gitea-data.yaml
|
||||||
|
kubectl apply -f pvc/gitea-db.yaml
|
||||||
|
kubectl apply -f deployments/gitea-db.yaml
|
||||||
|
kubectl apply -f services/gitea-db.yaml
|
||||||
|
kubectl apply -f deployments/gitea.yaml
|
||||||
|
kubectl apply -f services/gitea.yaml
|
||||||
11
gitea/services/gitea-db.yaml
Normal file
11
gitea/services/gitea-db.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: gitea-db
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: gitea-db
|
||||||
|
ports:
|
||||||
|
- port: 3306
|
||||||
14
gitea/services/gitea.yaml
Normal file
14
gitea/services/gitea.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app: gitea
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 3000
|
||||||
|
targetPort: 3000
|
||||||
|
nodePort: 30300
|
||||||
56
harbor/values.yaml
Normal file
56
harbor/values.yaml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
expose:
|
||||||
|
type: ingress
|
||||||
|
tls:
|
||||||
|
enabled: true
|
||||||
|
certSource: auto
|
||||||
|
ingress:
|
||||||
|
ingressClassName: nginx
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
hosts:
|
||||||
|
core: harbor.c2et.net
|
||||||
|
notary: notary.harbor.c2et.net
|
||||||
|
|
||||||
|
externalURL: https://harbor.c2et.net
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
resourcePolicy: "keep"
|
||||||
|
persistentVolumeClaim:
|
||||||
|
registry:
|
||||||
|
storageClass: "ceph-rbd"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
chartmuseum:
|
||||||
|
storageClass: "ceph-rbd"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
jobservice:
|
||||||
|
storageClass: "ceph-rbd"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
database:
|
||||||
|
storageClass: "ceph-rbd"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
redis:
|
||||||
|
storageClass: "ceph-rbd"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
trivy:
|
||||||
|
storageClass: "ceph-rbd"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
|
||||||
|
harborAdminPassword: Pozuelo12345
|
||||||
|
|
||||||
|
portal:
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
core:
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
registry:
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
database:
|
||||||
|
type: internal
|
||||||
|
internal:
|
||||||
|
password: "root123"
|
||||||
|
|
||||||
|
redis:
|
||||||
|
type: internal
|
||||||
@@ -15,6 +15,8 @@ spec:
|
|||||||
- "192.168.4.0/24"
|
- "192.168.4.0/24"
|
||||||
cluster:
|
cluster:
|
||||||
- "192.168.4.0/24"
|
- "192.168.4.0/24"
|
||||||
|
mgr:
|
||||||
|
count: 2
|
||||||
|
|
||||||
mon:
|
mon:
|
||||||
count: 3
|
count: 3
|
||||||
@@ -34,6 +36,16 @@ spec:
|
|||||||
operator: In
|
operator: In
|
||||||
values: ["site-a","site-b"]
|
values: ["site-a","site-b"]
|
||||||
|
|
||||||
|
mgr:
|
||||||
|
nodeAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
preference:
|
||||||
|
matchExpressions:
|
||||||
|
- key: kubernetes.io/hostname
|
||||||
|
operator: In
|
||||||
|
values: ["srvfkvm01","srvfkvm04"]
|
||||||
|
|
||||||
storage:
|
storage:
|
||||||
useAllNodes: false
|
useAllNodes: false
|
||||||
useAllDevices: false
|
useAllDevices: false
|
||||||
|
|||||||
Reference in New Issue
Block a user