|
1 | 1 | # Kubernetes Deployment of the Universal Resolver |
2 | 2 |
|
3 | | -## Usage with Docker |
4 | | -Setting the environment: |
| 3 | +## Overview |
5 | 4 |
|
6 | | - export KUBE_CONFIG_DATA=$(cat /home/pp/dev/devops/universal-resolver-kubernetes/aws/danubetech-dev-cluster10/danubetech-dev-cluster10-KUBE_CONFIG_DATA.txt) |
| 5 | +This GitHub Action deploys the Universal Resolver to a Kubernetes cluster using a smart deployment strategy that minimizes downtime and only updates services when their container images have changed. |
7 | 6 |
|
8 | | -Build: |
| 7 | +**Version:** 2.0.0 |
9 | 8 |
|
10 | | - docker build -t ur-deployer . |
| 9 | +## Features |
11 | 10 |
|
12 | | -Run: |
| 11 | +- **Smart Deployment**: Only updates deployments when container images differ from the running version |
| 12 | +- **Zero Downtime**: Unchanged services continue running without interruption |
| 13 | +- **Automatic Cleanup**: Removes orphaned deployments not defined in docker-compose.yml |
| 14 | +- **ConfigMap Management**: Automatically creates ConfigMaps from .env file |
| 15 | +- **Health Verification**: Verifies all deployments are healthy before completing |
| 16 | +- **Special Case Handling**: Manages secrets for driver-did-btcr |
13 | 17 |
|
14 | | - docker run -t ur-deployer |
| 18 | +## Architecture |
15 | 19 |
|
| 20 | +The action is composed of modular bash scripts that handle different aspects of deployment: |
16 | 21 |
|
17 | | -## Usage via script |
18 | | -Setting the environment: |
| 22 | +1. **parse-compose.sh** - Parses docker-compose.yml and extracts service definitions |
| 23 | +2. **process-env.sh** - Creates ConfigMaps from .env file |
| 24 | +3. **deploy-services.sh** - Implements smart deployment logic |
| 25 | +4. **handle-btcr-secret.sh** - Handles driver-did-btcr secret configuration |
| 26 | +5. **cleanup-orphaned.sh** - Removes orphaned resources |
| 27 | +6. **verify-deployment.sh** - Verifies deployment health |
| 28 | +7. **entrypoint.sh** - Orchestrates all scripts |
19 | 29 |
|
20 | | - export KUBECONFIG=/home/pp/dev/devops/universal-resolver-kubernetes/aws/danubetech-dev-cluster10/kubeconfig-danubetech-dev-cluster10.yaml |
| 30 | +## Usage in GitHub Actions |
21 | 31 |
|
22 | | -Run: |
23 | | - |
24 | | - cd scripts |
25 | | - ./entrypoint.sh |
| 32 | +```yaml |
| 33 | +- name: Deploy to AWS Kubernetes Cluster |
| 34 | + uses: ./ci/deploy-k8s-aws |
| 35 | + with: |
| 36 | + kube-config-data: ${{ secrets.KUBE_CONFIG_DATA }} |
| 37 | + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} |
| 38 | + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| 39 | + namespace: 'uni-resolver' |
| 40 | + rpc-url-testnet: ${{ secrets.RPC_URL_TESTNET }} |
| 41 | + rpc-cert-testnet: ${{ secrets.RPC_CERT_TESTNET }} |
| 42 | +``` |
26 | 43 |
|
| 44 | +## Inputs |
| 45 | +
|
| 46 | +| Input | Description | Required | Default | |
| 47 | +|-------|-------------|----------|---------| |
| 48 | +| `kube-config-data` | Base64-encoded Kubernetes configuration | Yes | - | |
| 49 | +| `aws-access-key-id` | AWS Access Key ID | Yes | - | |
| 50 | +| `aws-secret-access-key` | AWS Secret Access Key | Yes | - | |
| 51 | +| `namespace` | Kubernetes namespace | No | `uni-resolver` | |
| 52 | +| `rpc-url-testnet` | RPC URL for driver-did-btcr | No | - | |
| 53 | +| `rpc-cert-testnet` | RPC certificate for driver-did-btcr | No | - | |
| 54 | + |
| 55 | +## How It Works |
| 56 | + |
| 57 | +### 1. Parse docker-compose.yml |
| 58 | +The action reads your docker-compose.yml file (the source of truth) and extracts all service definitions including: |
| 59 | +- Container images and tags |
| 60 | +- Port mappings |
| 61 | +- Environment variables |
| 62 | +- Volume mounts |
| 63 | + |
| 64 | +### 2. Smart Deployment Logic |
| 65 | +For each service in docker-compose.yml: |
| 66 | +- **If deployment exists**: Compare current image with desired image |
| 67 | + - If different: Update deployment and wait for rollout |
| 68 | + - If same: Skip (no downtime) |
| 69 | +- **If deployment doesn't exist**: Create new deployment and service |
| 70 | + |
| 71 | +### 3. Automatic Cleanup |
| 72 | +After deploying all services: |
| 73 | +- Identify deployments with `managed-by=github-action` label |
| 74 | +- Compare with services in docker-compose.yml |
| 75 | +- Remove any orphaned resources (deployments, services, configmaps) |
| 76 | + |
| 77 | +### 4. Health Verification |
| 78 | +Verify that all deployments are healthy: |
| 79 | +- Check ready replicas match desired replicas |
| 80 | +- Display pod status and recent events |
| 81 | +- Exit with error if any deployment is unhealthy |
| 82 | + |
| 83 | +## Benefits Over Previous Approach |
| 84 | + |
| 85 | +### Previous (Destructive) |
| 86 | +- Deleted entire namespace on every deployment |
| 87 | +- All services restarted, causing downtime |
| 88 | +- No version checking |
| 89 | +- Inefficient for versioned containers |
| 90 | + |
| 91 | +### Current (Smart) |
| 92 | +- Only updates changed services |
| 93 | +- Zero downtime for unchanged services |
| 94 | +- Faster deployments |
| 95 | +- Maintains persistent state |
| 96 | +- Better observability |
| 97 | + |
| 98 | +## Local Development |
| 99 | + |
| 100 | +### Build Docker Image |
| 101 | +```bash |
| 102 | +cd ci/deploy-k8s-aws |
| 103 | +docker build -t ur-deployer . |
| 104 | +``` |
27 | 105 |
|
28 | | -## Usage as GitHub Action |
| 106 | +### Run Locally |
| 107 | +```bash |
| 108 | +docker run -t \ |
| 109 | + -e KUBE_CONFIG_DATA="$(cat ~/.kube/config | base64)" \ |
| 110 | + -e AWS_ACCESS_KEY_ID="your-key" \ |
| 111 | + -e AWS_SECRET_ACCESS_KEY="your-secret" \ |
| 112 | + -e NAMESPACE="uni-resolver" \ |
| 113 | + -v $(pwd)/../..:/workspace \ |
| 114 | + -w /workspace \ |
| 115 | + ur-deployer |
| 116 | +``` |
29 | 117 |
|
30 | | -Github Action workflow-file: |
| 118 | +## Directory Structure |
31 | 119 |
|
32 | 120 | ``` |
33 | | -name: CI/CD Workflow for universal-resolver |
34 | | -
|
35 | | -on: |
36 | | - push: |
37 | | - branches: |
38 | | - - master |
39 | | - pull_request: |
40 | | - branches: |
41 | | - - master |
42 | | -
|
43 | | -jobs: |
44 | | - build: |
45 | | - runs-on: ubuntu-latest |
46 | | - steps: |
47 | | - - uses: actions/checkout@master |
48 | | - - name: Deploy to AWS |
49 | | - uses: philpotisk/universal-resolver-k8s-deployment@master |
50 | | - env: |
51 | | - KUBE_CONFIG_DATA: ${{secrets.KUBE_CONFIG_DATA}} |
52 | | - AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}} |
53 | | - AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}} |
54 | | -``` |
| 121 | +ci/deploy-k8s-aws/ |
| 122 | +├── action.yml # GitHub Action definition |
| 123 | +├── Dockerfile # Container image with tools |
| 124 | +├── README.md # This file |
| 125 | +└── scripts/ |
| 126 | + ├── entrypoint.sh # Main orchestration script |
| 127 | + ├── parse-compose.sh # Parse docker-compose.yml |
| 128 | + ├── process-env.sh # Create ConfigMaps |
| 129 | + ├── deploy-services.sh # Smart deployment logic |
| 130 | + ├── handle-btcr-secret.sh # Special case handling |
| 131 | + ├── cleanup-orphaned.sh # Remove orphaned resources |
| 132 | + └── verify-deployment.sh # Health verification |
| 133 | +``` |
| 134 | +
|
| 135 | +## Requirements |
| 136 | +
|
| 137 | +### Container Image Includes |
| 138 | +- AWS CLI v2 |
| 139 | +- AWS IAM Authenticator |
| 140 | +- kubectl (latest stable) |
| 141 | +- yq (YAML processor) |
| 142 | +- jq (JSON processor) |
| 143 | +
|
| 144 | +### Source of Truth |
| 145 | +- **docker-compose.yml** - All services must be defined here |
| 146 | +- **.env** - Environment variables (optional) |
| 147 | +
|
| 148 | +## Troubleshooting |
| 149 | +
|
| 150 | +### Deployment Fails |
| 151 | +Check the logs for each step. The action provides detailed output for: |
| 152 | +- Parsing errors |
| 153 | +- Connection issues |
| 154 | +- Deployment failures |
| 155 | +- Health check failures |
| 156 | +
|
| 157 | +### Service Not Updating |
| 158 | +Ensure the image tag in docker-compose.yml is different from the deployed version. |
| 159 | +
|
| 160 | +### Orphaned Resources Not Cleaned |
| 161 | +Only resources with the `managed-by=github-action` label are cleaned up. Manually created resources are not affected. |
| 162 | +
|
| 163 | +## Migration from Previous Version |
| 164 | +
|
| 165 | +The previous version used Python scripts and a destructive deployment strategy. This version: |
| 166 | +1. Uses bash scripts for better maintainability |
| 167 | +2. Implements smart deployment logic |
| 168 | +3. Eliminates unnecessary downtime |
| 169 | +4. Removes dependency on manually maintained deployment specs |
| 170 | +
|
| 171 | +All services must now be defined in docker-compose.yml. The app-specs and namespace folders are no longer used. |
| 172 | +
|
| 173 | +## Version History |
| 174 | +
|
| 175 | +### 2.0.0 (Current) |
| 176 | +- Complete refactor to bash-based approach |
| 177 | +- Smart deployment strategy |
| 178 | +- Automatic cleanup of orphaned resources |
| 179 | +- ConfigMap management from .env |
| 180 | +- Improved health verification |
| 181 | +- Zero downtime for unchanged services |
| 182 | +
|
| 183 | +### 1.0.0 (Legacy) |
| 184 | +- Python-based scripts |
| 185 | +- Destructive deployment (delete namespace) |
| 186 | +- Manual deployment spec maintenance |
0 commit comments