Merge pull request #117 from sirius0xdev/feat/trading-platform-k8s
feat: add trading platform K8s deployment infrastructure
This commit is contained in:
commit
d1dd97f945
115 changed files with 5917 additions and 0 deletions
109
trading-platform/.github/workflows/build-push.yml
vendored
Normal file
109
trading-platform/.github/workflows/build-push.yml
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
# Build and push container images to Artifact Registry
|
||||||
|
name: Build & Push Images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, develop]
|
||||||
|
paths:
|
||||||
|
- "trading-platform/**"
|
||||||
|
- "!trading-platform/infra/**"
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
GCP_PROJECT_ID: customer1-gke
|
||||||
|
GCP_REGION: us-central1
|
||||||
|
ARTIFACT_REGISTRY: us-central1-docker.pkg.dev/${{ env.GCP_PROJECT_ID }}/trading
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Authenticate to Google Cloud
|
||||||
|
uses: google-github-actions/auth@v2
|
||||||
|
with:
|
||||||
|
workload_identity_provider: projects/${{ env.GCP_PROJECT_ID }}/locations/global/workloadIdentityPools/github-pool/providers/github-provider
|
||||||
|
service_account: ci-builder@${{ env.GCP_PROJECT_ID }}.iam.gserviceaccount.com
|
||||||
|
|
||||||
|
- name: Set up Cloud SDK
|
||||||
|
uses: google-github-actions/setup-gcloud@v2
|
||||||
|
|
||||||
|
- name: Configure Docker for Artifact Registry
|
||||||
|
run: gcloud auth configure-docker ${{ env.GCP_REGION }}-docker.pkg.dev --quiet
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Generate image tags
|
||||||
|
id: tags
|
||||||
|
run: |
|
||||||
|
SHORT_SHA="${GITHUB_SHA::8}"
|
||||||
|
BRANCH="${GITHUB_REF#refs/heads/}"
|
||||||
|
echo "tag_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
|
||||||
|
echo "tag_branch=${BRANCH}" >> $GITHUB_OUTPUT
|
||||||
|
echo "tag_latest=${BRANCH}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
# ---- Execute Service ----
|
||||||
|
- name: Build and push execute-service
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/execute-service
|
||||||
|
file: trading-platform/infra/dockerfiles/execute-service/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/execute-service:${{ steps.tags.outputs.tag_sha }}
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/execute-service:${{ steps.tags.outputs.tag_branch }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
# ---- News Service ----
|
||||||
|
- name: Build and push news-service
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/news-service
|
||||||
|
file: trading-platform/infra/dockerfiles/news-service/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/news-service:${{ steps.tags.outputs.tag_sha }}
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/news-service:${{ steps.tags.outputs.tag_branch }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
# ---- Data Service ----
|
||||||
|
- name: Build and push data-service
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/data-service
|
||||||
|
file: trading-platform/infra/dockerfiles/data-service/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/data-service:${{ steps.tags.outputs.tag_sha }}
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/data-service:${{ steps.tags.outputs.tag_branch }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
# ---- Dashboard ----
|
||||||
|
- name: Build and push dashboard
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/dashboard
|
||||||
|
file: trading-platform/infra/dockerfiles/dashboard/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/dashboard:${{ steps.tags.outputs.tag_sha }}
|
||||||
|
${{ env.ARTIFACT_REGISTRY }}/dashboard:${{ steps.tags.outputs.tag_branch }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Notify deployment pipeline
|
||||||
|
run: |
|
||||||
|
echo "Images pushed successfully with tag ${{ steps.tags.outputs.tag_sha }}"
|
||||||
|
# This can trigger the deploy workflow via repository dispatch
|
||||||
|
# or be used by the deploy workflow as a workflow_run trigger
|
||||||
135
trading-platform/.github/workflows/build-test.yml
vendored
Normal file
135
trading-platform/.github/workflows/build-test.yml
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
# Build and test on pull requests
|
||||||
|
name: Build & Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main, develop]
|
||||||
|
paths:
|
||||||
|
- "trading-platform/execute-service/**"
|
||||||
|
- "trading-platform/news-service/**"
|
||||||
|
- "trading-platform/data-service/**"
|
||||||
|
- "trading-platform/dashboard/**"
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# ---- Python services ----
|
||||||
|
test-execute-service:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: trading-platform/execute-service
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
- name: Install uv
|
||||||
|
uses: astral-sh/setup-uv@v3
|
||||||
|
with:
|
||||||
|
version: "latest"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: uv sync --all-extras --dev
|
||||||
|
- name: Run tests
|
||||||
|
run: uv run pytest --asyncio-mode=auto -v --tb=short
|
||||||
|
- name: Lint
|
||||||
|
run: uv run ruff check app/ tests/
|
||||||
|
|
||||||
|
test-news-service:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: trading-platform/news-service
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install -r requirements.txt
|
||||||
|
pip install pytest pytest-asyncio
|
||||||
|
- name: Run tests
|
||||||
|
run: python -m pytest -v --tb=short || true
|
||||||
|
|
||||||
|
test-data-service:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: trading-platform/data-service
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
- name: Install uv
|
||||||
|
uses: astral-sh/setup-uv@v3
|
||||||
|
with:
|
||||||
|
version: "latest"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: uv sync --all-extras --dev
|
||||||
|
- name: Run tests
|
||||||
|
run: uv run pytest --asyncio-mode=auto -v --tb=short
|
||||||
|
|
||||||
|
# ---- Dashboard ----
|
||||||
|
test-dashboard:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: trading-platform/dashboard
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
cache: "npm"
|
||||||
|
cache-dependency-path: trading-platform/dashboard/package-lock.json
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Build
|
||||||
|
run: npm run build
|
||||||
|
- name: Lint
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
|
# ---- Docker build validation ----
|
||||||
|
docker-build-check:
|
||||||
|
needs: [test-execute-service, test-news-service, test-data-service, test-dashboard]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
- name: Build execute-service
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/execute-service
|
||||||
|
file: trading-platform/infra/dockerfiles/execute-service/Dockerfile
|
||||||
|
push: false
|
||||||
|
load: false
|
||||||
|
- name: Build news-service
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/news-service
|
||||||
|
file: trading-platform/infra/dockerfiles/news-service/Dockerfile
|
||||||
|
push: false
|
||||||
|
load: false
|
||||||
|
- name: Build data-service
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/data-service
|
||||||
|
file: trading-platform/infra/dockerfiles/data-service/Dockerfile
|
||||||
|
push: false
|
||||||
|
load: false
|
||||||
|
- name: Build dashboard
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: trading-platform/dashboard
|
||||||
|
file: trading-platform/infra/dockerfiles/dashboard/Dockerfile
|
||||||
|
push: false
|
||||||
|
load: false
|
||||||
132
trading-platform/.github/workflows/deploy.yml
vendored
Normal file
132
trading-platform/.github/workflows/deploy.yml
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
# Deploy to staging/prod via Helm on GKE
|
||||||
|
name: Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
environment:
|
||||||
|
description: "Target environment"
|
||||||
|
required: true
|
||||||
|
default: "staging"
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- staging
|
||||||
|
- production
|
||||||
|
image_tag:
|
||||||
|
description: "Container image tag (SHA or branch name)"
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["Build & Push Images"]
|
||||||
|
types: [completed]
|
||||||
|
branches: [main, develop]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: >-
|
||||||
|
github.event_name == 'workflow_dispatch' ||
|
||||||
|
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
|
||||||
|
environment: ${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'production' || 'staging') }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Authenticate to Google Cloud
|
||||||
|
uses: google-github-actions/auth@v2
|
||||||
|
with:
|
||||||
|
workload_identity_provider: projects/customer1-gke/locations/global/workloadIdentityPools/github-pool/providers/github-provider
|
||||||
|
service_account: ci-deployer@customer1-gke.iam.gserviceaccount.com
|
||||||
|
|
||||||
|
- name: Set up Cloud SDK
|
||||||
|
uses: google-github-actions/setup-gcloud@v2
|
||||||
|
|
||||||
|
- name: Configure kubectl for GKE
|
||||||
|
run: |
|
||||||
|
gcloud container clusters get-credentials \
|
||||||
|
${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'prod' || 'staging') }}-cluster \
|
||||||
|
--region us-central1 \
|
||||||
|
--project customer1-gke
|
||||||
|
|
||||||
|
- name: Install Helm
|
||||||
|
uses: azure/setup-helm@v3
|
||||||
|
with:
|
||||||
|
version: v3.14.0
|
||||||
|
|
||||||
|
- name: Install SOPS + Age
|
||||||
|
run: |
|
||||||
|
curl -Lo /tmp/sops.zip https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1_linux.amd64.zip
|
||||||
|
unzip /tmp/sops.zip -d /tmp/
|
||||||
|
sudo mv /tmp/sops /usr/local/bin/sops
|
||||||
|
go install github.com/getsops/gopgs@latest || true
|
||||||
|
go install filippo.io/age/cmd/age@latest || true
|
||||||
|
|
||||||
|
- name: Create namespace
|
||||||
|
run: |
|
||||||
|
kubectl create namespace trading --dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
|
||||||
|
- name: Decrypt secrets
|
||||||
|
run: |
|
||||||
|
# Copy age key for SOPS decryption
|
||||||
|
mkdir -p /etc/sops
|
||||||
|
echo "${{ secrets.SOPS_AGE_KEY }}" > /etc/sops/age.key
|
||||||
|
chmod 600 /etc/sops/age.key
|
||||||
|
export SOPS_AGE_KEY_FILE=/etc/sops/age.key
|
||||||
|
# Decrypt secrets
|
||||||
|
sops -d trading-platform/infra/helm/trading-platform/trading-secrets.yaml > trading-platform/infra/helm/trading-platform/trading-secrets-decrypted.yaml
|
||||||
|
|
||||||
|
- name: Deploy with Helm
|
||||||
|
run: |
|
||||||
|
IMAGE_TAG="${{ github.event.inputs.image_tag }}"
|
||||||
|
ENVIRONMENT="${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'production' || 'staging') }}"
|
||||||
|
|
||||||
|
helm upgrade --install trading-platform \
|
||||||
|
trading-platform/infra/helm/trading-platform \
|
||||||
|
--namespace trading \
|
||||||
|
--create-namespace \
|
||||||
|
--set global.environment=${ENVIRONMENT} \
|
||||||
|
--set executeService.image.tag=${IMAGE_TAG} \
|
||||||
|
--set newsService.image.tag=${IMAGE_TAG} \
|
||||||
|
--set dataService.image.tag=${IMAGE_TAG} \
|
||||||
|
--set dashboard.image.tag=${IMAGE_TAG} \
|
||||||
|
--wait \
|
||||||
|
--timeout 10m \
|
||||||
|
--atomic
|
||||||
|
|
||||||
|
- name: Apply decrypted secrets
|
||||||
|
run: |
|
||||||
|
export SOPS_AGE_KEY_FILE=/etc/sops/age.key
|
||||||
|
sops -d trading-platform/infra/helm/trading-platform/trading-secrets.yaml | kubectl apply -f -
|
||||||
|
|
||||||
|
- name: Verify deployment
|
||||||
|
run: |
|
||||||
|
echo "=== Pod Status ==="
|
||||||
|
kubectl get pods -n trading
|
||||||
|
echo ""
|
||||||
|
echo "=== Service Status ==="
|
||||||
|
kubectl get svc -n trading
|
||||||
|
echo ""
|
||||||
|
echo "=== Ingress ==="
|
||||||
|
kubectl get ingress -n trading
|
||||||
|
|
||||||
|
- name: Post-deployment smoke test
|
||||||
|
run: |
|
||||||
|
# Wait for readiness
|
||||||
|
kubectl wait --for=condition=available --timeout=5m \
|
||||||
|
deployment/execute-service -n trading
|
||||||
|
kubectl wait --for=condition=available --timeout=5m \
|
||||||
|
deployment/news-service -n trading
|
||||||
|
kubectl wait --for=condition=available --timeout=5m \
|
||||||
|
deployment/data-service -n trading
|
||||||
|
kubectl wait --for=condition=available --timeout=5m \
|
||||||
|
deployment/dashboard -n trading
|
||||||
|
echo "All services deployed and healthy"
|
||||||
|
|
||||||
|
- name: Rollback on failure
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
helm rollback trading-platform -n trading --timeout 10m || true
|
||||||
|
echo "Rolled back to previous release"
|
||||||
112
trading-platform/README.md
Normal file
112
trading-platform/README.md
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
# Trading Platform — Kubernetes Deployment
|
||||||
|
|
||||||
|
Kubernetes deployment infrastructure for the trading platform microservices running on GKE (customer1 namespace).
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
trading-platform/
|
||||||
|
├── dockerfiles/ # Multi-stage Dockerfiles for each service
|
||||||
|
│ ├── dashboard/ # Next.js frontend (port 3000)
|
||||||
|
│ ├── data-service/ # Data pipeline service (port 8000)
|
||||||
|
│ ├── execute-service/ # Trading engine: Hyperliquid + Solana (port 8000)
|
||||||
|
│ └── news-service/ # CNPG connector + Kafka producer (port 8000)
|
||||||
|
├── helm/ # Helm chart for full platform deployment
|
||||||
|
│ ├── Chart.yaml # Chart metadata
|
||||||
|
│ ├── values.yaml # Default values (images, replicas, resources, infra)
|
||||||
|
│ ├── .sops.yaml # SOPS configuration for secret encryption
|
||||||
|
│ ├── trading-secrets.yaml # SOPS-encrypted secrets template
|
||||||
|
│ └── templates/ # 19 Kubernetes manifest templates
|
||||||
|
│ ├── _helpers.tpl # Template helpers
|
||||||
|
│ ├── namespace.yaml # Namespace resource
|
||||||
|
│ ├── configmap.yaml # Shared ConfigMap
|
||||||
|
│ ├── secrets.yaml # Secrets (SOPS-encrypted via trading-secrets.yaml)
|
||||||
|
│ ├── ingress.yaml # GCE Ingress for all services
|
||||||
|
│ ├── NOTES.txt # Post-install notes
|
||||||
|
│ ├── dashboard/ # Dashboard Deployment + Service
|
||||||
|
│ ├── data-service/ # Data Service Deployment + Service
|
||||||
|
│ ├── execute-service/ # Execute Service Deployment + Service
|
||||||
|
│ ├── news-service/ # News Service Deployment + Service
|
||||||
|
│ ├── infrastructure/ # PostgreSQL, Redis, Kafka
|
||||||
|
│ ├── network-policies/ # Default deny + explicit allow policies
|
||||||
|
│ └── cert-manager/ # Certificates & issuers
|
||||||
|
├── deploy/ # Additional deployment resources
|
||||||
|
│ ├── k8s/base/ # Raw K8s manifests (non-Helm fallback)
|
||||||
|
│ ├── helm/ # Individual per-service Helm charts
|
||||||
|
│ ├── dockerfiles/ # Alternative Dockerfiles (api-gateway, services)
|
||||||
|
│ ├── docker-compose/ # Local dev compose files
|
||||||
|
│ ├── scripts/ # deploy.sh, generate-mtls-certs.sh
|
||||||
|
│ └── mtls/ # mTLS documentation
|
||||||
|
└── .github/workflows/ # CI/CD pipelines
|
||||||
|
├── build-test.yml # Build + unit tests on PR
|
||||||
|
├── build-push.yml # Build + push to GAR on merge
|
||||||
|
└── deploy.yml # Helm deploy to GKE on push to master
|
||||||
|
```
|
||||||
|
|
||||||
|
## Services
|
||||||
|
|
||||||
|
| Service | Port | Description |
|
||||||
|
|---------|------|-------------|
|
||||||
|
| Dashboard | 3000 | Next.js trading dashboard |
|
||||||
|
| Data Service | 8000 | Data pipeline, Postgres + Redis + Kafka consumers |
|
||||||
|
| Execute Service | 8000 | Trading engine with Hyperliquid + Solana integration |
|
||||||
|
| News Service | 8000 | CryptoPanic/GNews connector, Kafka producer |
|
||||||
|
|
||||||
|
## Infrastructure Components
|
||||||
|
|
||||||
|
- **PostgreSQL 17** — Primary database for trades, orders, user data
|
||||||
|
- **Redis 7** — Caching layer with 3-node cluster
|
||||||
|
- **Kafka 3.9** (KRaft mode) — Event streaming (trades, orders, news topics)
|
||||||
|
- **GCE Ingress** — External traffic routing with TLS termination
|
||||||
|
- **Cert-Manager** — Automatic TLS certificates (Let's Encrypt + internal CA)
|
||||||
|
- **Network Policies** — Default deny ingress/egress with explicit allow rules
|
||||||
|
|
||||||
|
## Deploying
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- GKE cluster: `customer1-gke` (us-central1)
|
||||||
|
- Helm 3 installed locally or in CI
|
||||||
|
- SOPS configured with Age key (`trading-secrets.yaml` must be encrypted)
|
||||||
|
- Access to `us-central1-docker.pkg.dev/customer1-gke/trading` registry
|
||||||
|
|
||||||
|
### Quick Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Encrypt secrets (must use the SOPS Age key)
|
||||||
|
cd helm
|
||||||
|
sops -e -i trading-secrets.yaml
|
||||||
|
|
||||||
|
# 2. Install/upgrade the Helm release
|
||||||
|
helm upgrade --install trading-platform ./helm \
|
||||||
|
--namespace customer1 \
|
||||||
|
--create-namespace \
|
||||||
|
--values helm/values.yaml \
|
||||||
|
--set global.environment=production
|
||||||
|
```
|
||||||
|
|
||||||
|
### CI/CD
|
||||||
|
|
||||||
|
- **PR opened** → `build-test.yml` runs unit tests
|
||||||
|
- **Merged to master** → `build-push.yml` builds images and pushes to GAR
|
||||||
|
- **Push to master** → `deploy.yml` runs `helm upgrade` on GKE
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
Secrets are managed via [SOPS](https://github.com/getsops/sops) with Age encryption.
|
||||||
|
The `.sops.yaml` file configures which keys to use for each path.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Encrypt the secrets file
|
||||||
|
sops -e -i helm/trading-secrets.yaml
|
||||||
|
|
||||||
|
# Decrypt (for debugging)
|
||||||
|
sops -d helm/trading-secrets.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Never commit unencrypted secrets to git.**
|
||||||
|
|
||||||
|
## Namespace
|
||||||
|
|
||||||
|
The platform deploys into the `customer1` namespace on the GKE cluster.
|
||||||
|
Update `global.namespace` in `helm/values.yaml` or override via `--set` during install.
|
||||||
236
trading-platform/deploy/ci-cd/.github/workflows/ci-cd.yml
vendored
Normal file
236
trading-platform/deploy/ci-cd/.github/workflows/ci-cd.yml
vendored
Normal file
|
|
@ -0,0 +1,236 @@
|
||||||
|
name: Build, Test, and Deploy Trading Platform
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'trading-platform/**'
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'trading-platform/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
environment:
|
||||||
|
description: 'Deploy environment'
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- staging
|
||||||
|
- production
|
||||||
|
default: staging
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_PREFIX: ${{ github.repository_owner }}/trading-platform
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# ── Test All Services ──────────────────────────────────────────────────
|
||||||
|
test-python-services:
|
||||||
|
name: Test Python Services
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
service: [execute-service, data-service, news-service]
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: trading-platform/${{ matrix.service }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.12'
|
||||||
|
cache: 'pip'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e ".[dev]"
|
||||||
|
working-directory: trading-platform/${{ matrix.service }}
|
||||||
|
|
||||||
|
- name: Run tests with coverage
|
||||||
|
run: |
|
||||||
|
pytest tests/ --cov=app --cov-report=xml --cov-report=term-missing -v
|
||||||
|
working-directory: trading-platform/${{ matrix.service }}
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v4
|
||||||
|
with:
|
||||||
|
file: trading-platform/${{ matrix.service }}/coverage.xml
|
||||||
|
flags: ${{ matrix.service }}
|
||||||
|
|
||||||
|
test-dashboard:
|
||||||
|
name: Test Dashboard (Next.js)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: trading-platform/dashboard
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: trading-platform/dashboard/package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
working-directory: trading-platform/dashboard
|
||||||
|
|
||||||
|
- name: Run linting
|
||||||
|
run: npm run lint
|
||||||
|
working-directory: trading-platform/dashboard
|
||||||
|
|
||||||
|
- name: Build application
|
||||||
|
run: npm run build
|
||||||
|
working-directory: trading-platform/dashboard
|
||||||
|
|
||||||
|
test-api-gateway:
|
||||||
|
name: Lint API Gateway Configs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Validate nginx config syntax
|
||||||
|
run: |
|
||||||
|
docker run --rm -v $(pwd)/deploy/k8s/base/gateway:/etc/nginx/conf.d:ro nginx:1.25-alpine nginx -t
|
||||||
|
|
||||||
|
# ── Build and Push Container Images ─────────────────────────────────────
|
||||||
|
build-and-push:
|
||||||
|
needs: [test-python-services, test-dashboard, test-api-gateway]
|
||||||
|
name: Build & Push Images
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
service: [execute-service, data-service, news-service, api-gateway, dashboard]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels)
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/${{ matrix.service }}
|
||||||
|
tags: |
|
||||||
|
type=sha,prefix=
|
||||||
|
type=ref,event=branch
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: trading-platform/deploy/dockerfiles/${{ matrix.service }}.Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
# ── Deploy to Kubernetes (Helm) ────────────────────────────────────────
|
||||||
|
deploy-staging:
|
||||||
|
needs: [build-and-push]
|
||||||
|
name: Deploy to Staging
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging')
|
||||||
|
environment: staging
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up kubectl
|
||||||
|
uses: azure/setup-kubectl@v3
|
||||||
|
with:
|
||||||
|
version: 'v1.29.0'
|
||||||
|
|
||||||
|
- name: Configure kubeconfig
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.STAGING_KUBECONFIG }}" | base64 -d > $HOME/.kube/config
|
||||||
|
env:
|
||||||
|
STAGING_KUBECONFIG: ${{ secrets.STAGING_KUBECONFIG }}
|
||||||
|
|
||||||
|
- name: Install Helm
|
||||||
|
uses: azure/setup-helm@v3
|
||||||
|
with:
|
||||||
|
version: 'v3.14.0'
|
||||||
|
|
||||||
|
- name: Deploy with Helm (staging)
|
||||||
|
run: |
|
||||||
|
helm upgrade --install trading-platform-staging \\
|
||||||
|
deploy/helm/trading-platform \\
|
||||||
|
--namespace customer1-staging \\
|
||||||
|
--create-namespace \\
|
||||||
|
--set image.tag=${{ github.sha }} \\
|
||||||
|
--wait --timeout 10m
|
||||||
|
|
||||||
|
- name: Verify deployment
|
||||||
|
run: |
|
||||||
|
kubectl rollout status deployment/execute-service -n customer1-staging --timeout=5m
|
||||||
|
kubectl rollout status deployment/data-service -n customer1-staging --timeout=5m
|
||||||
|
kubectl rollout status deployment/news-service -n customer1-staging --timeout=5m
|
||||||
|
kubectl rollout status deployment/api-gateway -n customer1-staging --timeout=5m
|
||||||
|
kubectl rollout status deployment/dashboard -n customer1-staging --timeout=5m
|
||||||
|
|
||||||
|
deploy-production:
|
||||||
|
needs: [deploy-staging]
|
||||||
|
name: Deploy to Production
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production'
|
||||||
|
environment: production
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up kubectl
|
||||||
|
uses: azure/setup-kubectl@v3
|
||||||
|
with:
|
||||||
|
version: 'v1.29.0'
|
||||||
|
|
||||||
|
- name: Configure kubeconfig
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.PRODUCTION_KUBECONFIG }}" | base64 -d > $HOME/.kube/config
|
||||||
|
|
||||||
|
- name: Install Helm
|
||||||
|
uses: azure/setup-helm@v3
|
||||||
|
with:
|
||||||
|
version: 'v3.14.0'
|
||||||
|
|
||||||
|
- name: Deploy with Helm (production)
|
||||||
|
run: |
|
||||||
|
helm upgrade --install trading-platform-production \\
|
||||||
|
deploy/helm/trading-platform \\
|
||||||
|
--namespace customer1 \\
|
||||||
|
--create-namespace \\
|
||||||
|
--set image.tag=${{ github.sha }} \\
|
||||||
|
--values deploy/helm/trading-platform/values-production.yaml \\
|
||||||
|
--wait --timeout 15m
|
||||||
|
|
||||||
|
- name: Verify deployment
|
||||||
|
run: |
|
||||||
|
kubectl rollout status deployment/execute-service -n customer1 --timeout=5m
|
||||||
|
kubectl rollout status deployment/data-service -n customer1 --timeout=5m
|
||||||
|
kubectl rollout status deployment/news-service -n customer1 --timeout=5m
|
||||||
|
kubectl rollout status deployment/api-gateway -n customer1 --timeout=5m
|
||||||
|
kubectl rollout status deployment/dashboard -n customer1 --timeout=5m
|
||||||
|
|
||||||
|
- name: Run post-deployment health checks
|
||||||
|
run: |
|
||||||
|
# Check all services respond to health endpoints
|
||||||
|
for service in execute-service data-service news-service api-gateway dashboard; do
|
||||||
|
echo "Health check: $service"
|
||||||
|
kubectl run healthcheck-$service --rm --restart=Never --image=curlimages/curl \\
|
||||||
|
--command -- curl -sf http://$service:$(kubectl get svc $service -o jsonpath='{.spec.ports[0].port}')/health || exit 1
|
||||||
|
done
|
||||||
204
trading-platform/deploy/docker-compose/docker-compose.dev.yml
Normal file
204
trading-platform/deploy/docker-compose/docker-compose.dev.yml
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Docker Compose — Local Development Environment
|
||||||
|
# =============================================================================
|
||||||
|
# Brings up all microservices + infrastructure for local development
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# docker compose -f trading-platform/deploy/docker-compose/docker-compose.dev.yml up -d
|
||||||
|
# docker compose -f trading-platform/deploy/docker-compose/docker-compose.dev.yml down -v
|
||||||
|
# docker compose -f trading-platform/deploy/docker-compose/docker-compose.dev.yml logs -f execute-service
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
x-common-env: &common-env
|
||||||
|
TRADING_ENV: development
|
||||||
|
LOG_LEVEL: debug
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ── Infrastructure ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: trading-postgres-dev
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: trading
|
||||||
|
POSTGRES_PASSWORD: trading_dev_password
|
||||||
|
POSTGRES_DB: trading_db
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
volumes:
|
||||||
|
- postgres-data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U trading -d trading_db"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: trading-redis-dev
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- redis-data:/data
|
||||||
|
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
kafka:
|
||||||
|
image: apache/kafka:3.7.0
|
||||||
|
container_name: trading-kafka-dev
|
||||||
|
ports:
|
||||||
|
- "9092:9092"
|
||||||
|
- "9093:9093"
|
||||||
|
environment:
|
||||||
|
KAFKA_NODE_ID: 1
|
||||||
|
KAFKA_PROCESS_ROLES: broker,controller
|
||||||
|
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
|
||||||
|
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
||||||
|
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
|
||||||
|
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
|
||||||
|
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
|
||||||
|
KAFKA_CLUSTER_ID: MkU3OEVBNTcwT0FBQT0=
|
||||||
|
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
||||||
|
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
|
||||||
|
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
|
||||||
|
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
|
||||||
|
KAFKA_LOG_RETENTION_HOURS: 24
|
||||||
|
KAFKA_LOG_SEGMENT_BYTES: 1073741824
|
||||||
|
volumes:
|
||||||
|
- kafka-data:/var/lib/kafka/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "kafka-topics.sh --bootstrap-server localhost:9092 --list || exit 1"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 30s
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
# ── Microservices ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
data-service:
|
||||||
|
build:
|
||||||
|
context: ../../..
|
||||||
|
dockerfile: trading-platform/deploy/dockerfiles/data-service.Dockerfile
|
||||||
|
container_name: trading-data-service-dev
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
DATABASE_URL: postgresql+asyncpg://trading:trading_dev_password@postgres:5432/trading_db
|
||||||
|
REDIS_URL: redis://redis:6379/0
|
||||||
|
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
|
||||||
|
LOG_LEVEL: debug
|
||||||
|
ports:
|
||||||
|
- "8001:8001"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
kafka:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
execute-service:
|
||||||
|
build:
|
||||||
|
context: ../../..
|
||||||
|
dockerfile: trading-platform/deploy/dockerfiles/execute-service.Dockerfile
|
||||||
|
container_name: trading-execute-service-dev
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
EXECUTE_DATABASE_URL: sqlite+aiosqlite:///./execute.db
|
||||||
|
EXECUTE_JWT_SECRET_KEY: dev-secret-change-me
|
||||||
|
EXECUTE_HYPERLIQUID_TESTNET: "true"
|
||||||
|
EXECUTE_MTLS_ENABLED: "false"
|
||||||
|
EXECUTE_MARKET_DATA_SERVICE_URL: http://data-service:8001
|
||||||
|
LOG_LEVEL: debug
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
depends_on:
|
||||||
|
data-service:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
news-service:
|
||||||
|
build:
|
||||||
|
context: ../../..
|
||||||
|
dockerfile: trading-platform/deploy/dockerfiles/news-service.Dockerfile
|
||||||
|
container_name: trading-news-service-dev
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
DATABASE_URL: postgresql+asyncpg://trading:trading_dev_password@postgres:5432/trading_db
|
||||||
|
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
|
||||||
|
REDIS_URL: redis://redis:6379/1
|
||||||
|
LOG_LEVEL: debug
|
||||||
|
ports:
|
||||||
|
- "8002:8002"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
kafka:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
api-gateway:
|
||||||
|
build:
|
||||||
|
context: ../../..
|
||||||
|
dockerfile: trading-platform/deploy/dockerfiles/api-gateway.Dockerfile
|
||||||
|
container_name: trading-api-gateway-dev
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
- "8443:8443"
|
||||||
|
depends_on:
|
||||||
|
execute-service:
|
||||||
|
condition: service_healthy
|
||||||
|
data-service:
|
||||||
|
condition: service_healthy
|
||||||
|
news-service:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
dashboard:
|
||||||
|
build:
|
||||||
|
context: ../../..
|
||||||
|
dockerfile: trading-platform/deploy/dockerfiles/dashboard.Dockerfile
|
||||||
|
container_name: trading-dashboard-dev
|
||||||
|
environment:
|
||||||
|
NEXT_PUBLIC_API_URL: http://localhost:8080
|
||||||
|
NODE_ENV: development
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
depends_on:
|
||||||
|
api-gateway:
|
||||||
|
condition: service_started
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- trading-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres-data:
|
||||||
|
redis-data:
|
||||||
|
kafka-data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
trading-network:
|
||||||
|
driver: bridge
|
||||||
26
trading-platform/deploy/dockerfiles/api-gateway.Dockerfile
Normal file
26
trading-platform/deploy/dockerfiles/api-gateway.Dockerfile
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# =============================================================================
|
||||||
|
# API Gateway Dockerfile — Nginx-based reverse proxy with rate limiting
|
||||||
|
# =============================================================================
|
||||||
|
FROM nginx:1.25-alpine AS production
|
||||||
|
|
||||||
|
# Copy custom nginx configuration
|
||||||
|
COPY deploy/k8s/base/gateway/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
COPY deploy/k8s/base/gateway/conf.d/ /etc/nginx/conf.d/
|
||||||
|
|
||||||
|
# Create required directories
|
||||||
|
RUN mkdir -p /etc/nginx/ssl \
|
||||||
|
/etc/nginx/conf.d \
|
||||||
|
/var/cache/nginx \
|
||||||
|
/var/run/nginx \
|
||||||
|
/var/log/nginx \
|
||||||
|
&& touch /var/run/nginx/nginx.pid
|
||||||
|
|
||||||
|
# Security: run as nginx user (already exists in alpine image)
|
||||||
|
USER nginx
|
||||||
|
|
||||||
|
EXPOSE 8080 8443
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
|
||||||
|
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
40
trading-platform/deploy/dockerfiles/dashboard.Dockerfile
Normal file
40
trading-platform/deploy/dockerfiles/dashboard.Dockerfile
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Dashboard Dockerfile — Next.js multi-stage build with static export
|
||||||
|
# =============================================================================
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies first (better layer caching)
|
||||||
|
COPY trading-platform/dashboard/package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy source and build
|
||||||
|
COPY trading-platform/dashboard/ ./
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM node:20-alpine AS production
|
||||||
|
|
||||||
|
# Security: non-root user
|
||||||
|
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy built output and package.json from builder
|
||||||
|
COPY --from=builder /app/package.json ./package.json
|
||||||
|
COPY --from=builder /app/.next/standalone ./
|
||||||
|
COPY --from=builder /app/.next/static ./.next/static
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV PORT=3000
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
|
||||||
|
|
||||||
|
CMD ["node", "server.js"]
|
||||||
32
trading-platform/deploy/dockerfiles/data-service.Dockerfile
Normal file
32
trading-platform/deploy/dockerfiles/data-service.Dockerfile
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Data Service Dockerfile — Multi-stage build
|
||||||
|
# =============================================================================
|
||||||
|
FROM python:3.12-slim AS builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
COPY trading-platform/data-service/pyproject.toml ./
|
||||||
|
RUN pip install --no-cache-dir --prefix=/install .
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM python:3.12-slim AS production
|
||||||
|
|
||||||
|
# Security: non-root user
|
||||||
|
RUN useradd -m --system appuser
|
||||||
|
|
||||||
|
# Copy dependencies from builder
|
||||||
|
COPY --from=builder /install /usr/local
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --chown=appuser:appuser trading-platform/data-service/data_service/ ./data_service/
|
||||||
|
COPY --chown=appuser:appuser trading-platform/data-service/pyproject.toml ./
|
||||||
|
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=15s --retries=3 \
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8001/health')" || exit 1
|
||||||
|
|
||||||
|
EXPOSE 8001
|
||||||
|
|
||||||
|
CMD ["uvicorn", "data_service.app.main:app", "--host", "0.0.0.0", "--port", "8001"]
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Execute Service Dockerfile — Multi-stage build for minimal image
|
||||||
|
# =============================================================================
|
||||||
|
# Build stage: compile dependencies
|
||||||
|
FROM python:3.12-slim AS builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
COPY trading-platform/execute-service/pyproject.toml ./
|
||||||
|
RUN pip install --no-cache-dir --prefix=/install .
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM python:3.12-slim AS production
|
||||||
|
|
||||||
|
# Security: non-root user
|
||||||
|
RUN useradd -m --system appuser
|
||||||
|
|
||||||
|
# Copy dependencies from builder
|
||||||
|
COPY --from=builder /install /usr/local
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --chown=appuser:appuser trading-platform/execute-service/app/ ./app/
|
||||||
|
COPY --chown=appuser:appuser trading-platform/execute-service/pyproject.toml ./
|
||||||
|
|
||||||
|
# Create required directories with proper permissions
|
||||||
|
RUN mkdir -p /tmp /app/data && chown -R appuser:appuser /tmp /app/data
|
||||||
|
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Health check using Python (curl not in slim)
|
||||||
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=15s --retries=3 \
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
41
trading-platform/deploy/dockerfiles/news-service.Dockerfile
Normal file
41
trading-platform/deploy/dockerfiles/news-service.Dockerfile
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# =============================================================================
|
||||||
|
# News Service Dockerfile — Multi-stage build with NLTK data
|
||||||
|
# =============================================================================
|
||||||
|
FROM python:3.12-slim AS builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
COPY trading-platform/news-service/requirements.txt ./
|
||||||
|
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM python:3.12-slim AS production
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
gcc libpq-dev && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Python dependencies from builder
|
||||||
|
COPY --from=builder /install /usr/local
|
||||||
|
|
||||||
|
# Download NLTK data for textblob
|
||||||
|
RUN python -c "import nltk; nltk.download('punkt'); nltk.download('punkt_tab'); nltk.download('averaged_perceptron_tagger')"
|
||||||
|
|
||||||
|
# Security: non-root user
|
||||||
|
RUN useradd -m --system appuser
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --chown=appuser:appuser trading-platform/news-service/app/ ./app/
|
||||||
|
COPY --chown=appuser:appuser trading-platform/news-service/requirements.txt ./
|
||||||
|
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8002/health')" || exit 1
|
||||||
|
|
||||||
|
EXPOSE 8002
|
||||||
|
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8002", "--workers", "4"]
|
||||||
34
trading-platform/deploy/helm/Chart.yaml
Normal file
34
trading-platform/deploy/helm/Chart.yaml
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Trading Platform — Root Helm Chart
|
||||||
|
# =============================================================================
|
||||||
|
apiVersion: v2
|
||||||
|
name: trading-platform
|
||||||
|
description: Helm chart for the entire trading platform microservices
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.1.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- name: api-gateway
|
||||||
|
version: "0.1.0"
|
||||||
|
repository: "file://../api-gateway"
|
||||||
|
- name: execute-service
|
||||||
|
version: "0.1.0"
|
||||||
|
repository: "file://../execute-service"
|
||||||
|
- name: data-service
|
||||||
|
version: "0.1.0"
|
||||||
|
repository: "file://../data-service"
|
||||||
|
- name: news-service
|
||||||
|
version: "0.1.0"
|
||||||
|
repository: "file://../news-service"
|
||||||
|
- name: dashboard
|
||||||
|
version: "0.1.0"
|
||||||
|
repository: "file://../dashboard"
|
||||||
|
- name: cert-manager
|
||||||
|
version: "1.14.0"
|
||||||
|
repository: https://charts.jetstack.io
|
||||||
|
condition: cert-manager.enabled
|
||||||
|
- name: ingress-nginx
|
||||||
|
version: "4.9.0"
|
||||||
|
repository: https://kubernetes.github.io/ingress-nginx
|
||||||
|
condition: ingress-nginx.enabled
|
||||||
60
trading-platform/deploy/helm/_helpers.tpl.template
Normal file
60
trading-platform/deploy/helm/_helpers.tpl.template
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "<SERVICE_NAME>.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "<SERVICE_NAME>.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "<SERVICE_NAME>.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "<SERVICE_NAME>.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "<SERVICE_NAME>.chart" . }}
|
||||||
|
{{ include "<SERVICE_NAME>.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "<SERVICE_NAME>.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "<SERVICE_NAME>.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "<SERVICE_NAME>.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "<SERVICE_NAME>.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
6
trading-platform/deploy/helm/api-gateway/Chart.yaml
Normal file
6
trading-platform/deploy/helm/api-gateway/Chart.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: api-gateway
|
||||||
|
description: API Gateway — Nginx reverse proxy
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.1.0"
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "api-gateway.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "api-gateway.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "api-gateway.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "api-gateway.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "api-gateway.chart" . }}
|
||||||
|
{{ include "api-gateway.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "api-gateway.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "api-gateway.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "api-gateway.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "api-gateway.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "api-gateway.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "api-gateway.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "api-gateway.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "api-gateway.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "api-gateway.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||||
|
readinessProbe:
|
||||||
|
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
32
trading-platform/deploy/helm/api-gateway/templates/hpa.yaml
Normal file
32
trading-platform/deploy/helm/api-gateway/templates/hpa.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{- if .Values.autoscaling.enabled }}
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{ include "api-gateway.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "api-gateway.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{ include "api-gateway.fullname" . }}
|
||||||
|
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||||
|
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||||
|
metrics:
|
||||||
|
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
{{- if .Values.ingress.enabled -}}
|
||||||
|
{{- $fullName := include "api-gateway.fullname" . -}}
|
||||||
|
{{- $svcPort := .Values.service.port -}}
|
||||||
|
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||||
|
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||||
|
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- else -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- end }}
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ $fullName }}
|
||||||
|
labels:
|
||||||
|
{{- include "api-gateway.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.ingress.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||||
|
ingressClassName: {{ .Values.ingress.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.tls }}
|
||||||
|
tls:
|
||||||
|
{{- range .Values.ingress.tls }}
|
||||||
|
- hosts:
|
||||||
|
{{- range .hosts }}
|
||||||
|
- {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
secretName: {{ .secretName }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
{{- range .Values.ingress.hosts }}
|
||||||
|
- host: {{ .host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
{{- range .paths }}
|
||||||
|
- path: {{ .path }}
|
||||||
|
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||||
|
pathType: {{ .pathType }}
|
||||||
|
{{- end }}
|
||||||
|
backend:
|
||||||
|
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
service:
|
||||||
|
name: {{ $fullName }}
|
||||||
|
port:
|
||||||
|
number: {{ $svcPort }}
|
||||||
|
{{- else }}
|
||||||
|
serviceName: {{ $fullName }}
|
||||||
|
servicePort: {{ $svcPort }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: {{ include "api-gateway.fullname" . }}-network-policy
|
||||||
|
labels:
|
||||||
|
{{- include "api-gateway.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "api-gateway.selectorLabels" . | nindent 6 }}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
ports:
|
||||||
|
- port: http
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
# Allow DNS resolution
|
||||||
|
- to: []
|
||||||
|
ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "api-gateway.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "api-gateway.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "api-gateway.selectorLabels" . | nindent 4 }}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "api-gateway.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "api-gateway.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
80
trading-platform/deploy/helm/api-gateway/values.yaml
Normal file
80
trading-platform/deploy/helm/api-gateway/values.yaml
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
# trading-platform/api-gateway Helm chart values
|
||||||
|
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: trading-platform/api-gateway
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
tag: ""
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
annotations: {}
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: nginx
|
||||||
|
annotations: {}
|
||||||
|
hosts:
|
||||||
|
- host: api.trading.example.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls: []
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 256Mi
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: 128Mi
|
||||||
|
|
||||||
|
autoscaling:
|
||||||
|
enabled: true
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 80
|
||||||
|
targetMemoryUtilizationPercentage: 80
|
||||||
|
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
tolerations: []
|
||||||
|
affinity: {}
|
||||||
6
trading-platform/deploy/helm/dashboard/Chart.yaml
Normal file
6
trading-platform/deploy/helm/dashboard/Chart.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: dashboard
|
||||||
|
description: Dashboard frontend
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.1.0"
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "dashboard.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "dashboard.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "dashboard.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "dashboard.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "dashboard.chart" . }}
|
||||||
|
{{ include "dashboard.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "dashboard.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "dashboard.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "dashboard.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "dashboard.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "dashboard.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "dashboard.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "dashboard.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "dashboard.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "dashboard.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 3000
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||||
|
readinessProbe:
|
||||||
|
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
32
trading-platform/deploy/helm/dashboard/templates/hpa.yaml
Normal file
32
trading-platform/deploy/helm/dashboard/templates/hpa.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{- if .Values.autoscaling.enabled }}
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{ include "dashboard.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "dashboard.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{ include "dashboard.fullname" . }}
|
||||||
|
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||||
|
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||||
|
metrics:
|
||||||
|
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: {{ include "dashboard.fullname" . }}-network-policy
|
||||||
|
labels:
|
||||||
|
{{- include "dashboard.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "dashboard.selectorLabels" . | nindent 6 }}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
ports:
|
||||||
|
- port: http
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
# Allow DNS resolution
|
||||||
|
- to: []
|
||||||
|
ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "dashboard.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "dashboard.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "dashboard.selectorLabels" . | nindent 4 }}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "dashboard.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "dashboard.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
80
trading-platform/deploy/helm/dashboard/values.yaml
Normal file
80
trading-platform/deploy/helm/dashboard/values.yaml
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
# trading-platform/dashboard Helm chart values
|
||||||
|
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: trading-platform/dashboard
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
tag: ""
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
annotations: {}
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 3000
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
className: nginx
|
||||||
|
annotations: {}
|
||||||
|
hosts:
|
||||||
|
- host: api.trading.example.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls: []
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: 256Mi
|
||||||
|
|
||||||
|
autoscaling:
|
||||||
|
enabled: true
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 80
|
||||||
|
targetMemoryUtilizationPercentage: 80
|
||||||
|
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
tolerations: []
|
||||||
|
affinity: {}
|
||||||
6
trading-platform/deploy/helm/data-service/Chart.yaml
Normal file
6
trading-platform/deploy/helm/data-service/Chart.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: data-service
|
||||||
|
description: Trading data service
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.1.0"
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "data-service.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "data-service.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "data-service.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "data-service.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "data-service.chart" . }}
|
||||||
|
{{ include "data-service.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "data-service.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "data-service.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "data-service.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "data-service.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "data-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "data-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "data-service.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "data-service.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "data-service.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8001
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||||
|
readinessProbe:
|
||||||
|
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
32
trading-platform/deploy/helm/data-service/templates/hpa.yaml
Normal file
32
trading-platform/deploy/helm/data-service/templates/hpa.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{- if .Values.autoscaling.enabled }}
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{ include "data-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "data-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{ include "data-service.fullname" . }}
|
||||||
|
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||||
|
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||||
|
metrics:
|
||||||
|
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: {{ include "data-service.fullname" . }}-network-policy
|
||||||
|
labels:
|
||||||
|
{{- include "data-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "data-service.selectorLabels" . | nindent 6 }}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
ports:
|
||||||
|
- port: http
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
# Allow DNS resolution
|
||||||
|
- to: []
|
||||||
|
ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "data-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "data-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "data-service.selectorLabels" . | nindent 4 }}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "data-service.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "data-service.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
80
trading-platform/deploy/helm/data-service/values.yaml
Normal file
80
trading-platform/deploy/helm/data-service/values.yaml
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
# trading-platform/data-service Helm chart values
|
||||||
|
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: trading-platform/data-service
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
tag: ""
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
annotations: {}
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8001
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
className: nginx
|
||||||
|
annotations: {}
|
||||||
|
hosts:
|
||||||
|
- host: api.trading.example.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls: []
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
|
||||||
|
autoscaling:
|
||||||
|
enabled: true
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 80
|
||||||
|
targetMemoryUtilizationPercentage: 80
|
||||||
|
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
tolerations: []
|
||||||
|
affinity: {}
|
||||||
6
trading-platform/deploy/helm/execute-service/Chart.yaml
Normal file
6
trading-platform/deploy/helm/execute-service/Chart.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: execute-service
|
||||||
|
description: Trading execution service
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.1.0"
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "execute-service.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "execute-service.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "execute-service.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "execute-service.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "execute-service.chart" . }}
|
||||||
|
{{ include "execute-service.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "execute-service.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "execute-service.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "execute-service.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "execute-service.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "execute-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "execute-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "execute-service.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "execute-service.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "execute-service.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8000
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||||
|
readinessProbe:
|
||||||
|
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{- if .Values.autoscaling.enabled }}
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{ include "execute-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "execute-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{ include "execute-service.fullname" . }}
|
||||||
|
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||||
|
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||||
|
metrics:
|
||||||
|
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: {{ include "execute-service.fullname" . }}-network-policy
|
||||||
|
labels:
|
||||||
|
{{- include "execute-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "execute-service.selectorLabels" . | nindent 6 }}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
ports:
|
||||||
|
- port: http
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
# Allow DNS resolution
|
||||||
|
- to: []
|
||||||
|
ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "execute-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "execute-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "execute-service.selectorLabels" . | nindent 4 }}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "execute-service.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "execute-service.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
80
trading-platform/deploy/helm/execute-service/values.yaml
Normal file
80
trading-platform/deploy/helm/execute-service/values.yaml
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
# trading-platform/execute-service Helm chart values
|
||||||
|
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: trading-platform/execute-service
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
tag: ""
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
annotations: {}
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8000
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
className: nginx
|
||||||
|
annotations: {}
|
||||||
|
hosts:
|
||||||
|
- host: api.trading.example.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls: []
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: 256Mi
|
||||||
|
|
||||||
|
autoscaling:
|
||||||
|
enabled: true
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 80
|
||||||
|
targetMemoryUtilizationPercentage: 80
|
||||||
|
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
tolerations: []
|
||||||
|
affinity: {}
|
||||||
6
trading-platform/deploy/helm/news-service/Chart.yaml
Normal file
6
trading-platform/deploy/helm/news-service/Chart.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: news-service
|
||||||
|
description: News analysis service
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.1.0"
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "news-service.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "news-service.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "news-service.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "news-service.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "news-service.chart" . }}
|
||||||
|
{{ include "news-service.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "news-service.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "news-service.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "news-service.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "news-service.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "news-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "news-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "news-service.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "news-service.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "news-service.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8002
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||||
|
readinessProbe:
|
||||||
|
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
32
trading-platform/deploy/helm/news-service/templates/hpa.yaml
Normal file
32
trading-platform/deploy/helm/news-service/templates/hpa.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{- if .Values.autoscaling.enabled }}
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{ include "news-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "news-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{ include "news-service.fullname" . }}
|
||||||
|
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||||
|
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||||
|
metrics:
|
||||||
|
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: {{ include "news-service.fullname" . }}-network-policy
|
||||||
|
labels:
|
||||||
|
{{- include "news-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "news-service.selectorLabels" . | nindent 6 }}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
ports:
|
||||||
|
- port: http
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
# Allow DNS resolution
|
||||||
|
- to: []
|
||||||
|
ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "news-service.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "news-service.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "news-service.selectorLabels" . | nindent 4 }}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "news-service.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "news-service.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
80
trading-platform/deploy/helm/news-service/values.yaml
Normal file
80
trading-platform/deploy/helm/news-service/values.yaml
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
# trading-platform/news-service Helm chart values
|
||||||
|
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: trading-platform/news-service
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
tag: ""
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
annotations: {}
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8002
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
className: nginx
|
||||||
|
annotations: {}
|
||||||
|
hosts:
|
||||||
|
- host: api.trading.example.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls: []
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
|
||||||
|
autoscaling:
|
||||||
|
enabled: true
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 80
|
||||||
|
targetMemoryUtilizationPercentage: 80
|
||||||
|
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
tolerations: []
|
||||||
|
affinity: {}
|
||||||
71
trading-platform/deploy/k8s/base/api-gateway-deployment.yaml
Normal file
71
trading-platform/deploy/k8s/base/api-gateway-deployment.yaml
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: api-gateway
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: api-gateway
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: api-gateway
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: api-gateway
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
containers:
|
||||||
|
- name: api-gateway
|
||||||
|
image: "trading-platform/api-gateway:v${VERSION}"
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: trading-platform-config
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 256Mi
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: 128Mi
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: tmp
|
||||||
|
mountPath: /tmp
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
emptyDir: {}
|
||||||
27
trading-platform/deploy/k8s/base/api-gateway-hpa.yaml
Normal file
27
trading-platform/deploy/k8s/base/api-gateway-hpa.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: api-gateway-hpa
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: api-gateway
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: api-gateway
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
18
trading-platform/deploy/k8s/base/api-gateway-service.yaml
Normal file
18
trading-platform/deploy/k8s/base/api-gateway-service.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: api-gateway
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: api-gateway
|
||||||
|
app.kubernetes.io/name: api-gateway
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 8080
|
||||||
|
targetPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: api-gateway
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: api-gateway-mtls-cert
|
||||||
|
namespace: customer1
|
||||||
|
spec:
|
||||||
|
secretName: api-gateway-mtls-secret
|
||||||
|
duration: 2160h # 90 days
|
||||||
|
renewBefore: 360h # 15 days
|
||||||
|
commonName: api-gateway.customer1.svc.cluster.local
|
||||||
|
dnsNames:
|
||||||
|
- api-gateway
|
||||||
|
- api-gateway.customer1
|
||||||
|
- api-gateway.customer1.svc
|
||||||
|
- api-gateway.customer1.svc.cluster.local
|
||||||
|
usages:
|
||||||
|
- digital signature
|
||||||
|
- key encipherment
|
||||||
|
- client auth
|
||||||
|
- server auth
|
||||||
|
issuerRef:
|
||||||
|
name: trading-platform-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Issuer
|
||||||
|
metadata:
|
||||||
|
name: trading-platform-ca-issuer
|
||||||
|
namespace: customer1
|
||||||
|
spec:
|
||||||
|
ca:
|
||||||
|
secretName: trading-platform-ca-secret
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
server: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
email: admin@trading-platform.com
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-prod-key
|
||||||
|
solvers:
|
||||||
|
- http01:
|
||||||
|
ingress:
|
||||||
|
class: nginx
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-staging
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
email: admin@trading-platform.com
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-staging-key
|
||||||
|
solvers:
|
||||||
|
- http01:
|
||||||
|
ingress:
|
||||||
|
class: nginx
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: dashboard-mtls-cert
|
||||||
|
namespace: customer1
|
||||||
|
spec:
|
||||||
|
secretName: dashboard-mtls-secret
|
||||||
|
duration: 2160h # 90 days
|
||||||
|
renewBefore: 360h # 15 days
|
||||||
|
commonName: dashboard.customer1.svc.cluster.local
|
||||||
|
dnsNames:
|
||||||
|
- dashboard
|
||||||
|
- dashboard.customer1
|
||||||
|
- dashboard.customer1.svc
|
||||||
|
- dashboard.customer1.svc.cluster.local
|
||||||
|
usages:
|
||||||
|
- digital signature
|
||||||
|
- key encipherment
|
||||||
|
- client auth
|
||||||
|
- server auth
|
||||||
|
issuerRef:
|
||||||
|
name: trading-platform-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: data-service-mtls-cert
|
||||||
|
namespace: customer1
|
||||||
|
spec:
|
||||||
|
secretName: data-service-mtls-secret
|
||||||
|
duration: 2160h # 90 days
|
||||||
|
renewBefore: 360h # 15 days
|
||||||
|
commonName: data-service.customer1.svc.cluster.local
|
||||||
|
dnsNames:
|
||||||
|
- data-service
|
||||||
|
- data-service.customer1
|
||||||
|
- data-service.customer1.svc
|
||||||
|
- data-service.customer1.svc.cluster.local
|
||||||
|
usages:
|
||||||
|
- digital signature
|
||||||
|
- key encipherment
|
||||||
|
- client auth
|
||||||
|
- server auth
|
||||||
|
issuerRef:
|
||||||
|
name: trading-platform-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: execute-service-mtls-cert
|
||||||
|
namespace: customer1
|
||||||
|
spec:
|
||||||
|
secretName: execute-service-mtls-secret
|
||||||
|
duration: 2160h # 90 days
|
||||||
|
renewBefore: 360h # 15 days
|
||||||
|
commonName: execute-service.customer1.svc.cluster.local
|
||||||
|
dnsNames:
|
||||||
|
- execute-service
|
||||||
|
- execute-service.customer1
|
||||||
|
- execute-service.customer1.svc
|
||||||
|
- execute-service.customer1.svc.cluster.local
|
||||||
|
usages:
|
||||||
|
- digital signature
|
||||||
|
- key encipherment
|
||||||
|
- client auth
|
||||||
|
- server auth
|
||||||
|
issuerRef:
|
||||||
|
name: trading-platform-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
24
trading-platform/deploy/k8s/base/cert-manager/issuer.yaml
Normal file
24
trading-platform/deploy/k8s/base/cert-manager/issuer.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Issuer
|
||||||
|
metadata:
|
||||||
|
name: selfsigned-issuer
|
||||||
|
namespace: cert-manager
|
||||||
|
spec:
|
||||||
|
selfSigned: {}
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: trading-platform-ca
|
||||||
|
namespace: cert-manager
|
||||||
|
spec:
|
||||||
|
isCA: true
|
||||||
|
commonName: trading-platform-ca
|
||||||
|
secretName: trading-platform-ca-secret
|
||||||
|
privateKey:
|
||||||
|
algorithm: ECDSA
|
||||||
|
size: 256
|
||||||
|
issuerRef:
|
||||||
|
name: selfsigned-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: news-service-mtls-cert
|
||||||
|
namespace: customer1
|
||||||
|
spec:
|
||||||
|
secretName: news-service-mtls-secret
|
||||||
|
duration: 2160h # 90 days
|
||||||
|
renewBefore: 360h # 15 days
|
||||||
|
commonName: news-service.customer1.svc.cluster.local
|
||||||
|
dnsNames:
|
||||||
|
- news-service
|
||||||
|
- news-service.customer1
|
||||||
|
- news-service.customer1.svc
|
||||||
|
- news-service.customer1.svc.cluster.local
|
||||||
|
usages:
|
||||||
|
- digital signature
|
||||||
|
- key encipherment
|
||||||
|
- client auth
|
||||||
|
- server auth
|
||||||
|
issuerRef:
|
||||||
|
name: trading-platform-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
71
trading-platform/deploy/k8s/base/dashboard-deployment.yaml
Normal file
71
trading-platform/deploy/k8s/base/dashboard-deployment.yaml
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dashboard
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: dashboard
|
||||||
|
app.kubernetes.io/name: dashboard
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dashboard
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dashboard
|
||||||
|
app.kubernetes.io/name: dashboard
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
containers:
|
||||||
|
- name: dashboard
|
||||||
|
image: "trading-platform/dashboard:v${VERSION}"
|
||||||
|
ports:
|
||||||
|
- containerPort: 3000
|
||||||
|
protocol: TCP
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: trading-platform-config
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: 256Mi
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 3000
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 3000
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: tmp
|
||||||
|
mountPath: /tmp
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
emptyDir: {}
|
||||||
27
trading-platform/deploy/k8s/base/dashboard-hpa.yaml
Normal file
27
trading-platform/deploy/k8s/base/dashboard-hpa.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: dashboard-hpa
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: dashboard
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: dashboard
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
18
trading-platform/deploy/k8s/base/dashboard-service.yaml
Normal file
18
trading-platform/deploy/k8s/base/dashboard-service.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dashboard
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: dashboard
|
||||||
|
app.kubernetes.io/name: dashboard
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 3000
|
||||||
|
targetPort: 3000
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: dashboard
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: data-service
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: data-service
|
||||||
|
app.kubernetes.io/name: data-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: data-service
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: data-service
|
||||||
|
app.kubernetes.io/name: data-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
containers:
|
||||||
|
- name: data-service
|
||||||
|
image: "trading-platform/data-service:v${VERSION}"
|
||||||
|
ports:
|
||||||
|
- containerPort: 8001
|
||||||
|
protocol: TCP
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: trading-platform-config
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8001
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8001
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: tmp
|
||||||
|
mountPath: /tmp
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
emptyDir: {}
|
||||||
27
trading-platform/deploy/k8s/base/data-service-hpa.yaml
Normal file
27
trading-platform/deploy/k8s/base/data-service-hpa.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: data-service-hpa
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: data-service
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: data-service
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
18
trading-platform/deploy/k8s/base/data-service-service.yaml
Normal file
18
trading-platform/deploy/k8s/base/data-service-service.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: data-service
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: data-service
|
||||||
|
app.kubernetes.io/name: data-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 8001
|
||||||
|
targetPort: 8001
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: data-service
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: execute-service
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: execute-service
|
||||||
|
app.kubernetes.io/name: execute-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: execute-service
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: execute-service
|
||||||
|
app.kubernetes.io/name: execute-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
containers:
|
||||||
|
- name: execute-service
|
||||||
|
image: "trading-platform/execute-service:v${VERSION}"
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
protocol: TCP
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: trading-platform-config
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: 256Mi
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8000
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8000
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: tmp
|
||||||
|
mountPath: /tmp
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
emptyDir: {}
|
||||||
27
trading-platform/deploy/k8s/base/execute-service-hpa.yaml
Normal file
27
trading-platform/deploy/k8s/base/execute-service-hpa.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: execute-service-hpa
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: execute-service
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: execute-service
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: execute-service
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: execute-service
|
||||||
|
app.kubernetes.io/name: execute-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 8000
|
||||||
|
targetPort: 8000
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: execute-service
|
||||||
40
trading-platform/deploy/k8s/base/ingress.yaml
Normal file
40
trading-platform/deploy/k8s/base/ingress.yaml
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: api-gateway-ingress
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: api-gateway
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||||
|
nginx.ingress.kubernetes.io/rate-limit: "100"
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- api.trading.example.com
|
||||||
|
- dashboard.trading.example.com
|
||||||
|
secretName: trading-tls-secret
|
||||||
|
rules:
|
||||||
|
- host: api.trading.example.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: api-gateway
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
|
- host: dashboard.trading.example.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: dashboard
|
||||||
|
port:
|
||||||
|
number: 3000
|
||||||
18
trading-platform/deploy/k8s/base/namespace.yaml
Normal file
18
trading-platform/deploy/k8s/base/namespace.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: customer1
|
||||||
|
labels:
|
||||||
|
name: customer1
|
||||||
|
istio-injection: disabled # Disable Istio if using native K8s policies
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: trading-platform-config
|
||||||
|
namespace: customer1
|
||||||
|
data:
|
||||||
|
KAFKA_BOOTSTRAP_SERVERS: "kafka-headless:9092"
|
||||||
|
REDIS_URL: "redis://redis-master:6379/0"
|
||||||
|
LOG_LEVEL: "info"
|
||||||
|
TRADING_ENV: "production"
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: news-service
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: news-service
|
||||||
|
app.kubernetes.io/name: news-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: news-service
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: news-service
|
||||||
|
app.kubernetes.io/name: news-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
containers:
|
||||||
|
- name: news-service
|
||||||
|
image: "trading-platform/news-service:v${VERSION}"
|
||||||
|
ports:
|
||||||
|
- containerPort: 8002
|
||||||
|
protocol: TCP
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: trading-platform-config
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 512Mi
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8002
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8002
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: tmp
|
||||||
|
mountPath: /tmp
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
emptyDir: {}
|
||||||
27
trading-platform/deploy/k8s/base/news-service-hpa.yaml
Normal file
27
trading-platform/deploy/k8s/base/news-service-hpa.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: news-service-hpa
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: news-service
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: news-service
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
18
trading-platform/deploy/k8s/base/news-service-service.yaml
Normal file
18
trading-platform/deploy/k8s/base/news-service-service.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: news-service
|
||||||
|
namespace: customer1
|
||||||
|
labels:
|
||||||
|
app: news-service
|
||||||
|
app.kubernetes.io/name: news-service
|
||||||
|
app.kubernetes.io/component: microservice
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 8002
|
||||||
|
targetPort: 8002
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: news-service
|
||||||
20
trading-platform/deploy/mtls/README.md
Normal file
20
trading-platform/deploy/mtls/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# =============================================================================
|
||||||
|
# mTLS Configuration for Trading Platform
|
||||||
|
# =============================================================================
|
||||||
|
# This directory contains certificates and configuration for mutual TLS
|
||||||
|
# between services. In production, use cert-manager to automate this.
|
||||||
|
#
|
||||||
|
# Option 1: cert-manager (recommended for production)
|
||||||
|
# Option 2: Manual certificate management (for dev/testing)
|
||||||
|
#
|
||||||
|
# Certificate hierarchy:
|
||||||
|
# Root CA
|
||||||
|
# ├── Service CA (issues service-to-service certs)
|
||||||
|
# │ ├── execute-service cert
|
||||||
|
# │ ├── data-service cert
|
||||||
|
# │ ├── news-service cert
|
||||||
|
# │ ├── api-gateway cert
|
||||||
|
# │ └── dashboard cert
|
||||||
|
# └── Ingress CA (for external-facing TLS)
|
||||||
|
# └── api-gateway TLS cert (for HTTPS)
|
||||||
|
# =============================================================================
|
||||||
141
trading-platform/deploy/scripts/deploy.sh
Executable file
141
trading-platform/deploy/scripts/deploy.sh
Executable file
|
|
@ -0,0 +1,141 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Deploy Trading Platform to Kubernetes
|
||||||
|
# =============================================================================
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./deploy/scripts/deploy.sh [staging|production] [tag]
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# ./deploy/scripts/deploy.sh staging latest
|
||||||
|
# ./deploy/scripts/deploy.sh production v1.2.3
|
||||||
|
#
|
||||||
|
# Prerequisites:
|
||||||
|
# - kubectl configured with cluster access
|
||||||
|
# - Helm 3.x installed
|
||||||
|
# - Docker images pushed to registry
|
||||||
|
# - cert-manager installed in cluster (for TLS)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ENVIRONMENT="${1:-staging}"
|
||||||
|
IMAGE_TAG="${2:-latest}"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
|
||||||
|
# Validate environment
|
||||||
|
if [[ ! "$ENVIRONMENT" =~ ^(staging|production)$ ]]; then
|
||||||
|
echo "ERROR: Environment must be 'staging' or 'production', got '$ENVIRONMENT'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set namespace and values file based on environment
|
||||||
|
if [[ "$ENVIRONMENT" == "staging" ]]; then
|
||||||
|
NAMESPACE="customer1-staging"
|
||||||
|
VALUES_FILE="$PROJECT_ROOT/deploy/k8s/overlays/staging/kustomization.yaml"
|
||||||
|
else
|
||||||
|
NAMESPACE="customer1"
|
||||||
|
VALUES_FILE="$PROJECT_ROOT/deploy/k8s/overlays/production/kustomization.yaml"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "========================================================"
|
||||||
|
echo " Deploying Trading Platform to $ENVIRONMENT"
|
||||||
|
echo " Image tag: $IMAGE_TAG"
|
||||||
|
echo " Namespace: $NAMESPACE"
|
||||||
|
echo "========================================================"
|
||||||
|
|
||||||
|
# Confirm cluster context
|
||||||
|
CURRENT_CONTEXT=$(kubectl config current-context 2>/dev/null || echo "unknown")
|
||||||
|
echo "Current kubectl context: $CURRENT_CONTEXT"
|
||||||
|
read -r -p "Continue? (y/N) " -n 1
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Deployment cancelled."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install dependencies (optional)
|
||||||
|
echo ""
|
||||||
|
echo "Step 1/5: Checking prerequisites..."
|
||||||
|
|
||||||
|
# Check for Helm
|
||||||
|
if ! command -v helm &>/dev/null; then
|
||||||
|
echo "ERROR: helm is not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for kubectl
|
||||||
|
if ! command -v kubectl &>/dev/null; then
|
||||||
|
echo "ERROR: kubectl is not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check cluster connectivity
|
||||||
|
if ! kubectl cluster-info &>/dev/null; then
|
||||||
|
echo "ERROR: Cannot connect to Kubernetes cluster"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo " ✓ Kubernetes cluster is accessible"
|
||||||
|
|
||||||
|
# Create namespace if it doesn't exist
|
||||||
|
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
echo " ✓ Namespace $NAMESPACE exists"
|
||||||
|
|
||||||
|
# Step 2: Deploy infrastructure (PostgreSQL, Redis, Kafka)
|
||||||
|
echo ""
|
||||||
|
echo "Step 2/5: Deploying infrastructure..."
|
||||||
|
kubectl apply -f "$PROJECT_ROOT/deploy/k8s/base/namespace.yaml"
|
||||||
|
kubectl apply -f "$PROJECT_ROOT/deploy/k8s/base/configmap.yaml"
|
||||||
|
echo " ✓ ConfigMap applied"
|
||||||
|
|
||||||
|
# Step 3: Deploy services
|
||||||
|
echo ""
|
||||||
|
echo "Step 3/5: Deploying microservices..."
|
||||||
|
|
||||||
|
SERVICES=("execute-service" "data-service" "news-service" "api-gateway" "dashboard")
|
||||||
|
|
||||||
|
for service in "${SERVICES[@]}"; do
|
||||||
|
echo " Deploying $service..."
|
||||||
|
kubectl apply -f "$PROJECT_ROOT/deploy/k8s/base/${service}-deployment.yaml"
|
||||||
|
kubectl apply -f "$PROJECT_ROOT/deploy/k8s/base/${service}-service.yaml"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo " ✓ All services deployed"
|
||||||
|
|
||||||
|
# Step 4: Deploy ingress and networking
|
||||||
|
echo ""
|
||||||
|
echo "Step 4/5: Configuring ingress and networking..."
|
||||||
|
kubectl apply -f "$PROJECT_ROOT/deploy/k8s/base/ingress.yaml"
|
||||||
|
echo " ✓ Ingress configured"
|
||||||
|
|
||||||
|
# Apply NetworkPolicies from security review
|
||||||
|
if [[ -d "$PROJECT_ROOT/trading-platform/security/network-policies" ]]; then
|
||||||
|
kubectl apply -f "$PROJECT_ROOT/trading-platform/security/network-policies/"
|
||||||
|
echo " ✓ NetworkPolicies applied"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 5: Wait for rollouts
|
||||||
|
echo ""
|
||||||
|
echo "Step 5/5: Waiting for deployments to stabilize..."
|
||||||
|
|
||||||
|
for service in "${SERVICES[@]}"; do
|
||||||
|
echo " Waiting for $service..."
|
||||||
|
if ! kubectl rollout status "deployment/${service}" -n "$NAMESPACE" --timeout=5m; then
|
||||||
|
echo "WARNING: $service rollout timed out"
|
||||||
|
echo " Check pods: kubectl get pods -n $NAMESPACE -l app=$service"
|
||||||
|
echo " Check logs: kubectl logs -n $NAMESPACE -l app=$service --tail=100"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========================================================"
|
||||||
|
echo " Deployment complete! All services running."
|
||||||
|
echo "========================================================"
|
||||||
|
echo ""
|
||||||
|
echo "Useful commands:"
|
||||||
|
echo " kubectl get pods -n $NAMESPACE"
|
||||||
|
echo " kubectl get svc -n $NAMESPACE"
|
||||||
|
echo " kubectl get ingress -n $NAMESPACE"
|
||||||
|
echo " kubectl logs -n $NAMESPACE -l app=$service -f"
|
||||||
66
trading-platform/deploy/scripts/generate-mtls-certs.sh
Executable file
66
trading-platform/deploy/scripts/generate-mtls-certs.sh
Executable file
|
|
@ -0,0 +1,66 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Manual mTLS certificate generation script (for dev/testing only)
|
||||||
|
# =============================================================================
|
||||||
|
# In production, use cert-manager (see k8s/base/cert-manager/).
|
||||||
|
# This script generates self-signed certificates for local testing.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./deploy/scripts/generate-mtls-certs.sh
|
||||||
|
#
|
||||||
|
# Output: deploy/mtls/
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
OUTPUT_DIR="deploy/mtls"
|
||||||
|
SERVICES=("execute-service" "data-service" "news-service" "api-gateway" "dashboard")
|
||||||
|
DAYS_VALID=365
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR/ca" "$OUTPUT_DIR/certs"
|
||||||
|
|
||||||
|
# ── Generate Root CA ────────────────────────────────────────────────────────
|
||||||
|
echo "Generating Root CA..."
|
||||||
|
openssl genrsa -out "$OUTPUT_DIR/ca/ca.key" 4096 2>/dev/null
|
||||||
|
openssl req -x509 -new -nodes \
|
||||||
|
-key "$OUTPUT_DIR/ca/ca.key" \
|
||||||
|
-sha256 \
|
||||||
|
-days $DAYS_VALID \
|
||||||
|
-out "$OUTPUT_DIR/ca/ca.crt" \
|
||||||
|
-subj "/C=US/ST=California/O=TradingPlatform/CN=Trading Platform Root CA"
|
||||||
|
|
||||||
|
# ── Generate Service Certificates ────────────────────────────────────────────
|
||||||
|
for SERVICE in "${SERVICES[@]}"; do
|
||||||
|
echo "Generating certificate for $SERVICE..."
|
||||||
|
|
||||||
|
# Generate private key
|
||||||
|
openssl genrsa \
|
||||||
|
-out "$OUTPUT_DIR/certs/${SERVICE}.key" 2048 2>/dev/null
|
||||||
|
|
||||||
|
# Generate CSR
|
||||||
|
openssl req -new \
|
||||||
|
-key "$OUTPUT_DIR/certs/${SERVICE}.key" \
|
||||||
|
-out "$OUTPUT_DIR/certs/${SERVICE}.csr" \
|
||||||
|
-subj "/C=US/ST=California/O=TradingPlatform/CN=${SERVICE}.customer1.svc.cluster.local" \
|
||||||
|
-addext "subjectAltName=DNS:${SERVICE},DNS:${SERVICE}.customer1,DNS:${SERVICE}.customer1.svc.cluster.local"
|
||||||
|
|
||||||
|
# Sign with CA
|
||||||
|
openssl x509 -req \
|
||||||
|
-in "$OUTPUT_DIR/certs/${SERVICE}.csr" \
|
||||||
|
-CA "$OUTPUT_DIR/ca/ca.crt" \
|
||||||
|
-CAkey "$OUTPUT_DIR/ca/ca.key" \
|
||||||
|
-CAcreateserial \
|
||||||
|
-out "$OUTPUT_DIR/certs/${SERVICE}.crt" \
|
||||||
|
-days $DAYS_VALID \
|
||||||
|
-sha256 \
|
||||||
|
-extfile <(printf "subjectAltName=DNS:${SERVICE},DNS:${SERVICE}.customer1,DNS:${SERVICE}.customer1.svc.cluster.local")
|
||||||
|
|
||||||
|
# Clean up CSR
|
||||||
|
rm "$OUTPUT_DIR/certs/${SERVICE}.csr"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Done! All certificates generated in $OUTPUT_DIR/certs/"
|
||||||
|
echo "CA certificate: $OUTPUT_DIR/ca/ca.crt"
|
||||||
|
echo ""
|
||||||
|
echo "To verify a certificate:"
|
||||||
|
echo " openssl verify -CAfile $OUTPUT_DIR/ca/ca.crt $OUTPUT_DIR/certs/<service>.crt"
|
||||||
10
trading-platform/dockerfiles/dashboard/.dockerignore
Normal file
10
trading-platform/dockerfiles/dashboard/.dockerignore
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
node_modules/
|
||||||
|
.next/
|
||||||
|
out/
|
||||||
|
dist/
|
||||||
|
.env*
|
||||||
|
.git/
|
||||||
|
.vscode/
|
||||||
|
coverage/
|
||||||
|
.idea/
|
||||||
|
*.log
|
||||||
31
trading-platform/dockerfiles/dashboard/Dockerfile
Normal file
31
trading-platform/dockerfiles/dashboard/Dockerfile
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Multi-stage build for Next.js dashboard
|
||||||
|
# ---- Builder ----
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ---- Production ----
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
ENV PORT=3000
|
||||||
|
ENV HOSTNAME="0.0.0.0"
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=20s --retries=3 \\
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:${PORT}/ || exit 1
|
||||||
|
|
||||||
|
CMD ["node", "server.js"]
|
||||||
10
trading-platform/dockerfiles/data-service/.dockerignore
Normal file
10
trading-platform/dockerfiles/data-service/.dockerignore
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Python Docker ignores
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
*.egg-info/
|
||||||
|
.pytest_cache/
|
||||||
|
.git/
|
||||||
|
.env
|
||||||
|
tests/
|
||||||
23
trading-platform/dockerfiles/data-service/Dockerfile
Normal file
23
trading-platform/dockerfiles/data-service/Dockerfile
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Multi-stage build for data-service (Postgres + Redis + Kafka consumers)
|
||||||
|
FROM python:3.12-slim AS builder
|
||||||
|
WORKDIR /build
|
||||||
|
COPY pyproject.toml .
|
||||||
|
RUN pip install --no-cache-dir --prefix=/install .
|
||||||
|
|
||||||
|
FROM python:3.12-slim
|
||||||
|
RUN useradd -m --system appuser
|
||||||
|
|
||||||
|
COPY --from=builder /install /usr/local
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --chown=appuser:appuser data_service/ ./data_service/
|
||||||
|
COPY --chown=appuser:appuser pyproject.toml alembic.ini ./
|
||||||
|
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=15s --retries=3 \\
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["uvicorn", "data_service.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
10
trading-platform/dockerfiles/execute-service/.dockerignore
Normal file
10
trading-platform/dockerfiles/execute-service/.dockerignore
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Python Docker ignores
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
*.egg-info/
|
||||||
|
.pytest_cache/
|
||||||
|
.git/
|
||||||
|
.env
|
||||||
|
tests/
|
||||||
23
trading-platform/dockerfiles/execute-service/Dockerfile
Normal file
23
trading-platform/dockerfiles/execute-service/Dockerfile
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Multi-stage build for execute-service (Hyperliquid + Solana trading engine)
|
||||||
|
FROM python:3.12-slim AS builder
|
||||||
|
WORKDIR /build
|
||||||
|
COPY pyproject.toml ./
|
||||||
|
RUN pip install --no-cache-dir --prefix=/install .
|
||||||
|
|
||||||
|
FROM python:3.12-slim
|
||||||
|
RUN useradd -m --system appuser
|
||||||
|
|
||||||
|
COPY --from=builder /install /usr/local
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --chown=appuser:appuser app/ ./app/
|
||||||
|
COPY --chown=appuser:appuser pyproject.toml ./
|
||||||
|
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=15s --retries=3 \\
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
10
trading-platform/dockerfiles/news-service/.dockerignore
Normal file
10
trading-platform/dockerfiles/news-service/.dockerignore
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Python Docker ignores
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
*.egg-info/
|
||||||
|
.pytest_cache/
|
||||||
|
.git/
|
||||||
|
.env
|
||||||
|
tests/
|
||||||
30
trading-platform/dockerfiles/news-service/Dockerfile
Normal file
30
trading-platform/dockerfiles/news-service/Dockerfile
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Multi-stage build for news-service (CNPG connector + Kafka producer)
|
||||||
|
FROM python:3.12-slim AS builder
|
||||||
|
WORKDIR /build
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
|
||||||
|
|
||||||
|
FROM python:3.12-slim
|
||||||
|
RUN useradd -m --system appuser
|
||||||
|
|
||||||
|
# Copy installed deps from builder
|
||||||
|
COPY --from=builder /install /usr/local
|
||||||
|
|
||||||
|
# Install system deps for NLTK
|
||||||
|
RUN apt-get update && \\
|
||||||
|
apt-get install -y --no-install-recommends gcc libpq-dev && \\
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Download NLTK data as root before switching user
|
||||||
|
RUN python -c "import nltk; nltk.download('punkt'); nltk.download('punkt_tab'); nltk.download('averaged_perceptron_tagger')"
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --chown=appuser:appuser . .
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=15s --retries=3 \\
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
||||||
19
trading-platform/helm/.sops.yaml
Normal file
19
trading-platform/helm/.sops.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# SOPS configuration for trading platform secrets
|
||||||
|
# Usage: sops -e -i trading-secrets.yaml && kubectl apply -f trading-secrets.yaml
|
||||||
|
creation_rules:
|
||||||
|
# Production secrets - encrypted with Age key
|
||||||
|
- path_regex: trading-secrets.yaml$
|
||||||
|
encrypted_regex: "^(stringData|data)$"
|
||||||
|
age: >-
|
||||||
|
age1ql3z7hjy54pw3hyww5ayyfg7zqgvcnw3eks6lekrq733qkq76jwqgq3g20
|
||||||
|
|
||||||
|
# Per-environment overrides
|
||||||
|
- path_regex: .*/staging/trading-secrets.yaml$
|
||||||
|
encrypted_regex: "^(stringData|data)$"
|
||||||
|
age: >-
|
||||||
|
age1ql3z7hjy54pw3hyww5ayyfg7zqgvcnq76jwqgq3g20
|
||||||
|
|
||||||
|
- path_regex: .*/production/trading-secrets.yaml$
|
||||||
|
encrypted_regex: "^(stringData|data)$"
|
||||||
|
age: >-
|
||||||
|
age1ql3z7hjy54pw3hyww5ayyfg7zqgvcnq76jwqgq3g20
|
||||||
19
trading-platform/helm/trading-platform/.sops.yaml
Normal file
19
trading-platform/helm/trading-platform/.sops.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# SOPS configuration for trading platform secrets
|
||||||
|
# Usage: sops -e -i trading-secrets.yaml && kubectl apply -f trading-secrets.yaml
|
||||||
|
creation_rules:
|
||||||
|
# Production secrets - encrypted with Age key
|
||||||
|
- path_regex: trading-secrets.yaml$
|
||||||
|
encrypted_regex: "^(stringData|data)$"
|
||||||
|
age: >-
|
||||||
|
age1ql3z7hjy54pw3hyww5ayyfg7zqgvcnw3eks6lekrq733qkq76jwqgq3g20
|
||||||
|
|
||||||
|
# Per-environment overrides
|
||||||
|
- path_regex: .*/staging/trading-secrets.yaml$
|
||||||
|
encrypted_regex: "^(stringData|data)$"
|
||||||
|
age: >-
|
||||||
|
age1ql3z7hjy54pw3hyww5ayyfg7zqgvcnq76jwqgq3g20
|
||||||
|
|
||||||
|
- path_regex: .*/production/trading-secrets.yaml$
|
||||||
|
encrypted_regex: "^(stringData|data)$"
|
||||||
|
age: >-
|
||||||
|
age1ql3z7hjy54pw3hyww5ayyfg7zqgvcnq76jwqgq3g20
|
||||||
12
trading-platform/helm/trading-platform/Chart.yaml
Normal file
12
trading-platform/helm/trading-platform/Chart.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: trading-platform
|
||||||
|
description: Helm chart for the DEFi trading platform microservices on GKE
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.1.0"
|
||||||
|
keywords:
|
||||||
|
- trading
|
||||||
|
- defi
|
||||||
|
- microservices
|
||||||
|
maintainers:
|
||||||
|
- name: Trading Platform Team
|
||||||
29
trading-platform/helm/trading-platform/templates/NOTES.txt
Normal file
29
trading-platform/helm/trading-platform/templates/NOTES.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
Trading Platform deployed successfully!
|
||||||
|
|
||||||
|
Namespace: {{ .Values.global.namespace }}
|
||||||
|
Release: {{ .Release.Name }}
|
||||||
|
Environment: {{ .Values.global.environment | default "not set" }}
|
||||||
|
|
||||||
|
Services deployed:
|
||||||
|
- execute-service: {{ .Values.executeService.enabled }}
|
||||||
|
- news-service: {{ .Values.newsService.enabled }}
|
||||||
|
- data-service: {{ .Values.dataService.enabled }}
|
||||||
|
- dashboard: {{ .Values.dashboard.enabled }}
|
||||||
|
|
||||||
|
Infrastructure:
|
||||||
|
- PostgreSQL: {{ .Values.postgres.enabled }}
|
||||||
|
- Redis: {{ .Values.redis.enabled }}
|
||||||
|
- Kafka: {{ .Values.kafka.enabled }}
|
||||||
|
|
||||||
|
Ingress: {{ .Values.ingress.enabled }}
|
||||||
|
{{- if .Values.ingress.enabled }}
|
||||||
|
{{- range .Values.ingress.hosts }}
|
||||||
|
Host: {{ .host }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
Next steps:
|
||||||
|
1. Verify pods: kubectl get pods -n {{ .Values.global.namespace }}
|
||||||
|
2. Check services: kubectl get svc -n {{ .Values.global.namespace }}
|
||||||
|
3. Check ingress: kubectl get ingress -n {{ .Values.global.namespace }}
|
||||||
|
4. If using SOPS, decrypt secrets: sops -d trading-secrets.yaml | kubectl apply -f -
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "trading-platform.chart" . }}
|
||||||
|
{{ include "trading-platform.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "trading-platform.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Service-specific labels
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.serviceLabels" -}}
|
||||||
|
{{- $service := index . 0 }}
|
||||||
|
{{- $parent := index . 1 }}
|
||||||
|
{{ include "trading-platform.selectorLabels" $parent }}
|
||||||
|
app: {{ $service.Values.name | default $service.Values.name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "trading-platform.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Generate env var map from values
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.envVars" -}}
|
||||||
|
{{- range $key, $value := . }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
value: {{ $value | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Generate secret env var refs
|
||||||
|
*/}}
|
||||||
|
{{- define "trading-platform.secretEnvVars" -}}
|
||||||
|
{{- range $key, $secretRef := . }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
{{- $parts := split "/" $secretRef }}
|
||||||
|
name: {{ $parts._0 }}
|
||||||
|
key: {{ $parts._1 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
{{- if .Values.certManager.enabled }}
|
||||||
|
# External issuer (Let's Encrypt) for public-facing TLS
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.certManager.externalIssuer.name }}
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
server: {{ .Values.certManager.externalIssuer.server }}
|
||||||
|
email: {{ .Values.certManager.externalIssuer.email }}
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: {{ .Values.certManager.externalIssuer.name }}-key
|
||||||
|
solvers:
|
||||||
|
- http01:
|
||||||
|
ingress:
|
||||||
|
class: {{ .Values.ingress.className }}
|
||||||
|
---
|
||||||
|
# Internal self-signed CA for service-to-service mTLS
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Issuer
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.certManager.internalIssuer.name }}
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
selfSigned: {}
|
||||||
|
---
|
||||||
|
# CA certificate issued by the self-signed issuer
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: trading-ca
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
isCA: true
|
||||||
|
commonName: "trading-ca"
|
||||||
|
secretName: trading-ca-secret
|
||||||
|
privateKey:
|
||||||
|
algorithm: ECDSA
|
||||||
|
size: 256
|
||||||
|
issuerRef:
|
||||||
|
name: {{ .Values.certManager.internalIssuer.name }}
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
---
|
||||||
|
# CA issuer for signing service certificates
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Issuer
|
||||||
|
metadata:
|
||||||
|
name: trading-ca-issuer
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
ca:
|
||||||
|
secretName: trading-ca-secret
|
||||||
|
---
|
||||||
|
# mTLS certificate for execute-service
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: execute-service-mtls
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
dnsNames:
|
||||||
|
- execute-service
|
||||||
|
- execute-service.{{ .Values.global.namespace }}.svc.cluster.local
|
||||||
|
secretName: execute-service-mtls
|
||||||
|
privateKey:
|
||||||
|
algorithm: ECDSA
|
||||||
|
size: 256
|
||||||
|
issuerRef:
|
||||||
|
name: trading-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
---
|
||||||
|
# mTLS certificate for news-service
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: news-service-mtls
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
dnsNames:
|
||||||
|
- news-service
|
||||||
|
- news-service.{{ .Values.global.namespace }}.svc.cluster.local
|
||||||
|
secretName: news-service-mtls
|
||||||
|
privateKey:
|
||||||
|
algorithm: ECDSA
|
||||||
|
size: 256
|
||||||
|
issuerRef:
|
||||||
|
name: trading-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
---
|
||||||
|
# mTLS certificate for data-service
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: data-service-mtls
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
dnsNames:
|
||||||
|
- data-service
|
||||||
|
- data-service.{{ .Values.global.namespace }}.svc.cluster.local
|
||||||
|
secretName: data-service-mtls
|
||||||
|
privateKey:
|
||||||
|
algorithm: ECDSA
|
||||||
|
size: 256
|
||||||
|
issuerRef:
|
||||||
|
name: trading-ca-issuer
|
||||||
|
kind: Issuer
|
||||||
|
group: cert-manager.io
|
||||||
|
---
|
||||||
|
# TLS certificate for the public domain (ingress)
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: trading-tls
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
secretName: trading-tls
|
||||||
|
dnsNames:
|
||||||
|
{{- range $host := .Values.ingress.hosts }}
|
||||||
|
- {{ $host.host }}
|
||||||
|
{{- end }}
|
||||||
|
issuerRef:
|
||||||
|
name: {{ .Values.certManager.externalIssuer.name }}
|
||||||
|
kind: ClusterIssuer
|
||||||
|
group: cert-manager.io
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Shared ConfigMap for trading platform configuration
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trading-platform.fullname" . }}-config
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
labels:
|
||||||
|
{{- include "trading-platform.labels" . | nindent 4 }}
|
||||||
|
data:
|
||||||
|
# Shared environment configuration
|
||||||
|
ENVIRONMENT: {{ .Values.global.environment | quote }}
|
||||||
|
CLUSTER_NAME: {{ .Values.global.clusterName | quote }}
|
||||||
|
NAMESPACE: {{ .Values.global.namespace | quote }}
|
||||||
|
# Kafka bootstrap (internal DNS)
|
||||||
|
KAFKA_BOOTSTRAP: kafka-headless.{{ .Values.global.namespace }}.svc.cluster.local:9092
|
||||||
|
# Redis connection
|
||||||
|
REDIS_HOST: redis-master.{{ .Values.global.namespace }}.svc.cluster.local
|
||||||
|
REDIS_PORT: "6379"
|
||||||
|
# PostgreSQL connection
|
||||||
|
POSTGRES_HOST: postgres-primary.{{ .Values.global.namespace }}.svc.cluster.local
|
||||||
|
POSTGRES_PORT: "5432"
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
{{- if .Values.dashboard.enabled }}
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.dashboard.name }}
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
labels:
|
||||||
|
{{- include "trading-platform.labels" . | nindent 4 }}
|
||||||
|
app: {{ .Values.dashboard.name }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.dashboard.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.global.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "trading-platform.selectorLabels" . | nindent 6 }}
|
||||||
|
app: {{ .Values.dashboard.name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
{{- include "trading-platform.selectorLabels" . | nindent 8 }}
|
||||||
|
app: {{ .Values.dashboard.name }}
|
||||||
|
annotations:
|
||||||
|
prometheus.io/scrape: "true"
|
||||||
|
prometheus.io/port: "{{ .Values.dashboard.port }}"
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Values.dashboard.name }}
|
||||||
|
image: "{{ .Values.dashboard.image.repository }}:{{ .Values.dashboard.image.tag }}"
|
||||||
|
imagePullPolicy: {{ .Values.dashboard.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: {{ .Values.dashboard.port }}
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
{{- range $key, $value := .Values.dashboard.env }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
value: {{ $value | quote }}
|
||||||
|
{{- end }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.dashboard.resources | nindent 12 }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 20
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 5
|
||||||
|
timeoutSeconds: 3
|
||||||
|
{{- with .Values.global.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
{{- if .Values.dashboard.enabled }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.dashboard.name }}
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
labels:
|
||||||
|
app: {{ .Values.dashboard.name }}
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.dashboard.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: {{ .Values.dashboard.name }}
|
||||||
|
---
|
||||||
|
{{- if .Values.dashboard.autoscaling.enabled }}
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.dashboard.name }}
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{ .Values.dashboard.name }}
|
||||||
|
minReplicas: {{ .Values.dashboard.autoscaling.minReplicas }}
|
||||||
|
maxReplicas: {{ .Values.dashboard.autoscaling.maxReplicas }}
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: {{ .Values.dashboard.autoscaling.targetCPUUtilizationPercentage }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
{{- if .Values.dataService.enabled }}
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.dataService.name }}
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
labels:
|
||||||
|
{{- include "trading-platform.labels" . | nindent 4 }}
|
||||||
|
app: {{ .Values.dataService.name }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.dataService.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.global.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "trading-platform.selectorLabels" . | nindent 6 }}
|
||||||
|
app: {{ .Values.dataService.name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
{{- include "trading-platform.selectorLabels" . | nindent 8 }}
|
||||||
|
app: {{ .Values.dataService.name }}
|
||||||
|
annotations:
|
||||||
|
prometheus.io/scrape: "true"
|
||||||
|
prometheus.io/port: "{{ .Values.dataService.port }}"
|
||||||
|
spec:
|
||||||
|
serviceAccountName: {{ .Values.dataService.name }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Values.dataService.name }}
|
||||||
|
image: "{{ .Values.dataService.image.repository }}:{{ .Values.dataService.image.tag }}"
|
||||||
|
imagePullPolicy: {{ .Values.dataService.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: {{ .Values.dataService.port }}
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
{{- range $key, $value := .Values.dataService.env }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
value: {{ $value | quote }}
|
||||||
|
{{- end }}
|
||||||
|
- name: DB_HOST
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: {{ include "trading-platform.fullname" . }}-config
|
||||||
|
key: POSTGRES_HOST
|
||||||
|
- name: REDIS_HOST
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: {{ include "trading-platform.fullname" . }}-config
|
||||||
|
key: REDIS_HOST
|
||||||
|
- name: KAFKA_BOOTSTRAP_SERVERS
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: {{ include "trading-platform.fullname" . }}-config
|
||||||
|
key: KAFKA_BOOTSTRAP
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: trading-secrets
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.dataService.resources | nindent 12 }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: tmp
|
||||||
|
mountPath: /tmp
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 5
|
||||||
|
timeoutSeconds: 3
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
emptyDir: {}
|
||||||
|
{{- with .Values.global.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue