CHORE(app): use kaniko as separate job
Architecture (Option 3 - Recommended):
Runner Pod (DinD maintained)
└─ kubectl create job
└─ Kaniko Pod (isolated)
Benefits:
- Resource isolation
- Parallel builds possible
- Build failures don't affect runner
- Pod-level isolation
- Proper security boundaries
Changes:
- Restore kubectl and kubeconfig setup
- Use kubeconfig from Gitea Secret
- Create Kaniko Job in separate namespace
- Wait for Job completion
- Proper cleanup after build
Infrastructure (already deployed via ArgoCD):
- kaniko-builds namespace
- RBAC for gitea runner ServiceAccount
- Proper permission boundaries
This commit is contained in:
@@ -26,11 +26,32 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Verify Docker access
|
- name: Setup kubectl
|
||||||
run: |
|
run: |
|
||||||
echo "Checking Docker availability..."
|
if ! command -v kubectl &> /dev/null; then
|
||||||
docker version
|
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl"
|
||||||
docker info | head -20
|
chmod +x kubectl
|
||||||
|
sudo mv kubectl /usr/local/bin/
|
||||||
|
fi
|
||||||
|
kubectl version --client
|
||||||
|
|
||||||
|
- name: Setup kubeconfig from Secret
|
||||||
|
env:
|
||||||
|
KUBECONFIG_B64: ${{ secrets.KUBECONFIG }}
|
||||||
|
run: |
|
||||||
|
if [ -z "$KUBECONFIG_B64" ]; then
|
||||||
|
echo "❌ KUBECONFIG secret not set"
|
||||||
|
echo "Please add KUBECONFIG to repository secrets"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $HOME/.kube
|
||||||
|
echo "$KUBECONFIG_B64" | base64 -d > $HOME/.kube/config
|
||||||
|
chmod 600 $HOME/.kube/config
|
||||||
|
|
||||||
|
echo "✅ Kubeconfig configured"
|
||||||
|
kubectl cluster-info
|
||||||
|
kubectl get nodes -o wide
|
||||||
|
|
||||||
- name: Lowercase repository name
|
- name: Lowercase repository name
|
||||||
id: lowercase
|
id: lowercase
|
||||||
@@ -50,42 +71,67 @@ jobs:
|
|||||||
type=sha,prefix={{branch}}-sha-,format=long
|
type=sha,prefix={{branch}}-sha-,format=long
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
- name: Prepare Kaniko credentials
|
- name: Create registry credentials in Kubernetes
|
||||||
run: |
|
run: |
|
||||||
mkdir -p /tmp/kaniko-config
|
# Ensure namespace exists
|
||||||
echo "{\"auths\":{\"${{ env.REGISTRY }}\":{\"auth\":\"$(echo -n bluemayne:${{ secrets.GITEAREGISTRY }} | base64)\"}}}" > /tmp/kaniko-config/config.json
|
kubectl get namespace kaniko-builds 2>/dev/null || kubectl create namespace kaniko-builds
|
||||||
|
|
||||||
- name: Build and push with Kaniko (Docker)
|
# Create/update registry secret
|
||||||
|
kubectl create secret docker-registry kaniko-registry-creds \
|
||||||
|
--docker-server=${{ env.REGISTRY }} \
|
||||||
|
--docker-username=bluemayne \
|
||||||
|
--docker-password=${{ secrets.GITEAREGISTRY }} \
|
||||||
|
--namespace=kaniko-builds \
|
||||||
|
--dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
|
||||||
|
- name: Build and push with Kaniko Job
|
||||||
id: build
|
id: build
|
||||||
run: |
|
run: |
|
||||||
TAGS="${{ steps.meta.outputs.tags }}"
|
TAGS="${{ steps.meta.outputs.tags }}"
|
||||||
|
|
||||||
# Prepare destination arguments for all tags
|
# Prepare destination arguments
|
||||||
DESTINATIONS=""
|
DESTINATIONS=""
|
||||||
while IFS= read -r tag; do
|
while IFS= read -r tag; do
|
||||||
DESTINATIONS="$DESTINATIONS --destination=$tag"
|
DESTINATIONS="$DESTINATIONS\n - --destination=$tag"
|
||||||
done <<< "$TAGS"
|
done <<< "$TAGS"
|
||||||
|
|
||||||
echo "📦 Building image with tags:"
|
# Create unique build name
|
||||||
echo "$TAGS"
|
BUILD_NAME="kaniko-build-${{ github.run_number }}-$(date +%s)"
|
||||||
|
|
||||||
# Build and push with Kaniko via Docker
|
echo "📦 Building image: ${BUILD_NAME}"
|
||||||
docker run --rm \
|
echo "Tags: $TAGS"
|
||||||
-v $(pwd):/workspace \
|
|
||||||
-v /tmp/kaniko-config:/kaniko/.docker:ro \
|
|
||||||
gcr.io/kaniko-project/executor:latest \
|
|
||||||
--context=/workspace/services/nextjs \
|
|
||||||
--dockerfile=/workspace/deploy/docker/Dockerfile.prod \
|
|
||||||
$DESTINATIONS \
|
|
||||||
--cache=true \
|
|
||||||
--cache-repo=${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }}/cache \
|
|
||||||
--compressed-caching=false \
|
|
||||||
--snapshot-mode=redo \
|
|
||||||
--use-new-run \
|
|
||||||
--verbosity=info
|
|
||||||
|
|
||||||
echo "✅ Image built and pushed successfully"
|
# Generate Kaniko Job from template
|
||||||
echo "digest=unknown" >> $GITHUB_OUTPUT
|
sed -e "s|KANIKO_BUILD_NAME|${BUILD_NAME}|g" \
|
||||||
|
-e "s|GIT_REPO_URL|https://gitea0213.kro.kr/${{ github.repository }}.git|g" \
|
||||||
|
-e "s|GIT_SHA|${{ github.sha }}|g" \
|
||||||
|
-e "s|CACHE_REPO|${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }}/cache|g" \
|
||||||
|
-e "s|# DESTINATIONS will be added here|${DESTINATIONS}|g" \
|
||||||
|
deploy/kaniko/job.yaml > /tmp/kaniko-job.yaml
|
||||||
|
|
||||||
|
# Apply Job
|
||||||
|
kubectl apply -f /tmp/kaniko-job.yaml
|
||||||
|
|
||||||
|
# Wait for completion
|
||||||
|
echo "⏳ Waiting for Kaniko Job to complete..."
|
||||||
|
kubectl wait --for=condition=complete --timeout=600s job/${BUILD_NAME} -n kaniko-builds || {
|
||||||
|
echo "❌ Job failed or timed out"
|
||||||
|
POD=$(kubectl get pods -n kaniko-builds -l job-name=${BUILD_NAME} -o jsonpath='{.items[0].metadata.name}')
|
||||||
|
echo "📋 Logs:"
|
||||||
|
kubectl logs -n kaniko-builds ${POD} --all-containers=true || true
|
||||||
|
kubectl delete job ${BUILD_NAME} -n kaniko-builds || true
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "✅ Image built successfully"
|
||||||
|
|
||||||
|
# Get digest
|
||||||
|
POD=$(kubectl get pods -n kaniko-builds -l job-name=${BUILD_NAME} -o jsonpath='{.items[0].metadata.name}')
|
||||||
|
DIGEST=$(kubectl logs -n kaniko-builds ${POD} -c kaniko 2>/dev/null | grep -oP 'digest: \K[a-zA-Z0-9:]+' | tail -1 || echo "unknown")
|
||||||
|
echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
kubectl delete job ${BUILD_NAME} -n kaniko-builds || true
|
||||||
|
|
||||||
- name: Extract SHA tag
|
- name: Extract SHA tag
|
||||||
id: extract-tag
|
id: extract-tag
|
||||||
|
|||||||
Reference in New Issue
Block a user