REFACTOR(app): extract kaniko manifest
- Create deploy/kaniko/job.yaml as template - Use sed for template variable substitution - Remove inline YAML heredoc from workflow - Simplify workflow logic with template-based approach - Add resource limits for Kaniko container - Improve logging and error handling Benefits: - Better code organization and readability - Easier to maintain and test - Reusable manifest template - Version controlled configuration
This commit is contained in:
@@ -85,99 +85,47 @@ jobs:
|
|||||||
# Prepare destination arguments
|
# 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"
|
||||||
|
|
||||||
# Create temporary pod name
|
# Create unique build name
|
||||||
POD_NAME="kaniko-build-${{ github.run_number }}-$(date +%s)"
|
BUILD_NAME="kaniko-build-${{ github.run_number }}-$(date +%s)"
|
||||||
|
|
||||||
# Create Kaniko Job
|
# Prepare Kaniko Job manifest from template
|
||||||
cat <<EOF | sudo kubectl apply -f -
|
sed -e "s|KANIKO_BUILD_NAME|${BUILD_NAME}|g" \
|
||||||
apiVersion: v1
|
-e "s|GIT_REPO_URL|https://gitea0213.kro.kr/${{ github.repository }}.git|g" \
|
||||||
kind: ConfigMap
|
-e "s|GIT_SHA|${{ github.sha }}|g" \
|
||||||
metadata:
|
-e "s|CACHE_REPO|${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }}/cache|g" \
|
||||||
name: ${POD_NAME}-context
|
-e "s|# DESTINATIONS will be added here|${DESTINATIONS}|g" \
|
||||||
namespace: kaniko-builds
|
deploy/kaniko/job.yaml > /tmp/kaniko-job.yaml
|
||||||
data:
|
|
||||||
Dockerfile: |
|
echo "📋 Generated Kaniko Job manifest:"
|
||||||
$(sed 's/^/ /' deploy/docker/Dockerfile.prod)
|
cat /tmp/kaniko-job.yaml
|
||||||
---
|
|
||||||
apiVersion: batch/v1
|
# Apply the Job
|
||||||
kind: Job
|
sudo kubectl apply -f /tmp/kaniko-job.yaml
|
||||||
metadata:
|
|
||||||
name: ${POD_NAME}
|
|
||||||
namespace: kaniko-builds
|
|
||||||
spec:
|
|
||||||
ttlSecondsAfterFinished: 600
|
|
||||||
backoffLimit: 0
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
restartPolicy: Never
|
|
||||||
initContainers:
|
|
||||||
- name: prepare-context
|
|
||||||
image: alpine:latest
|
|
||||||
command: ["/bin/sh", "-c"]
|
|
||||||
args:
|
|
||||||
- |
|
|
||||||
apk add --no-cache git
|
|
||||||
git clone https://gitea0213.kro.kr/${{ github.repository }}.git /workspace/repo
|
|
||||||
cd /workspace/repo
|
|
||||||
git checkout ${{ github.sha }}
|
|
||||||
cp -r services/nextjs/* /workspace/build/
|
|
||||||
volumeMounts:
|
|
||||||
- name: workspace
|
|
||||||
mountPath: /workspace
|
|
||||||
containers:
|
|
||||||
- name: kaniko
|
|
||||||
image: gcr.io/kaniko-project/executor:latest
|
|
||||||
args:
|
|
||||||
- --context=/workspace/build
|
|
||||||
- --dockerfile=/workspace/Dockerfile
|
|
||||||
- --cache=true
|
|
||||||
- --cache-repo=${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }}/cache
|
|
||||||
- --compressed-caching=false
|
|
||||||
- --snapshot-mode=redo
|
|
||||||
- --use-new-run
|
|
||||||
$DESTINATIONS
|
|
||||||
volumeMounts:
|
|
||||||
- name: workspace
|
|
||||||
mountPath: /workspace
|
|
||||||
- name: dockerfile
|
|
||||||
mountPath: /workspace/Dockerfile
|
|
||||||
subPath: Dockerfile
|
|
||||||
- name: docker-config
|
|
||||||
mountPath: /kaniko/.docker
|
|
||||||
volumes:
|
|
||||||
- name: workspace
|
|
||||||
emptyDir: {}
|
|
||||||
- name: dockerfile
|
|
||||||
configMap:
|
|
||||||
name: ${POD_NAME}-context
|
|
||||||
- name: docker-config
|
|
||||||
secret:
|
|
||||||
secretName: kaniko-registry-creds
|
|
||||||
items:
|
|
||||||
- key: .dockerconfigjson
|
|
||||||
path: config.json
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Wait for job to complete
|
# Wait for job to complete
|
||||||
echo "Waiting for Kaniko job to complete..."
|
echo "⏳ Waiting for Kaniko job to complete..."
|
||||||
sudo kubectl wait --for=condition=complete --timeout=600s job/${POD_NAME} -n kaniko-builds || {
|
sudo kubectl wait --for=condition=complete --timeout=600s job/${BUILD_NAME} -n kaniko-builds || {
|
||||||
echo "Job failed or timed out. Showing logs:"
|
echo "❌ Job failed or timed out. Showing logs:"
|
||||||
POD=$(sudo kubectl get pods -n kaniko-builds -l job-name=${POD_NAME} -o jsonpath='{.items[0].metadata.name}')
|
POD=$(sudo kubectl get pods -n kaniko-builds -l job-name=${BUILD_NAME} -o jsonpath='{.items[0].metadata.name}')
|
||||||
sudo kubectl logs -n kaniko-builds ${POD} --all-containers=true || true
|
sudo kubectl logs -n kaniko-builds ${POD} --all-containers=true || true
|
||||||
sudo kubectl delete job ${POD_NAME} -n kaniko-builds || true
|
sudo kubectl delete job ${BUILD_NAME} -n kaniko-builds || true
|
||||||
sudo kubectl delete configmap ${POD_NAME}-context -n kaniko-builds || true
|
sudo kubectl delete configmap ${BUILD_NAME}-dockerfile -n kaniko-builds || true
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "✅ Image built successfully"
|
echo "✅ Image built successfully"
|
||||||
echo "digest=unknown" >> $GITHUB_OUTPUT
|
|
||||||
|
# Get digest from logs
|
||||||
|
POD=$(sudo kubectl get pods -n kaniko-builds -l job-name=${BUILD_NAME} -o jsonpath='{.items[0].metadata.name}')
|
||||||
|
DIGEST=$(sudo 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
|
# Cleanup
|
||||||
sudo kubectl delete job ${POD_NAME} -n kaniko-builds || true
|
sudo kubectl delete job ${BUILD_NAME} -n kaniko-builds || true
|
||||||
sudo kubectl delete configmap ${POD_NAME}-context -n kaniko-builds || true
|
sudo kubectl delete configmap ${BUILD_NAME}-dockerfile -n kaniko-builds || true
|
||||||
|
|
||||||
- name: Extract SHA tag
|
- name: Extract SHA tag
|
||||||
id: extract-tag
|
id: extract-tag
|
||||||
|
|||||||
72
deploy/kaniko/job.yaml
Normal file
72
deploy/kaniko/job.yaml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: KANIKO_BUILD_NAME-dockerfile
|
||||||
|
namespace: kaniko-builds
|
||||||
|
data:
|
||||||
|
Dockerfile: |
|
||||||
|
# This will be replaced by the actual Dockerfile content
|
||||||
|
DOCKERFILE_CONTENT
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: KANIKO_BUILD_NAME
|
||||||
|
namespace: kaniko-builds
|
||||||
|
spec:
|
||||||
|
ttlSecondsAfterFinished: 600
|
||||||
|
backoffLimit: 0
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: kaniko-build
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
initContainers:
|
||||||
|
- name: prepare-context
|
||||||
|
image: alpine/git:latest
|
||||||
|
command: ["/bin/sh", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
git clone GIT_REPO_URL /workspace/repo
|
||||||
|
cd /workspace/repo
|
||||||
|
git checkout GIT_SHA
|
||||||
|
cp -r services/nextjs/* /workspace/build/
|
||||||
|
cp deploy/docker/Dockerfile.prod /workspace/build/Dockerfile
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
containers:
|
||||||
|
- name: kaniko
|
||||||
|
image: gcr.io/kaniko-project/executor:latest
|
||||||
|
args:
|
||||||
|
- --context=/workspace/build
|
||||||
|
- --dockerfile=/workspace/build/Dockerfile
|
||||||
|
- --cache=true
|
||||||
|
- --cache-repo=CACHE_REPO
|
||||||
|
- --compressed-caching=false
|
||||||
|
- --snapshot-mode=redo
|
||||||
|
- --use-new-run
|
||||||
|
- --verbosity=info
|
||||||
|
# DESTINATIONS will be added here
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: docker-config
|
||||||
|
mountPath: /kaniko/.docker
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
limits:
|
||||||
|
memory: "2Gi"
|
||||||
|
cpu: "2000m"
|
||||||
|
volumes:
|
||||||
|
- name: workspace
|
||||||
|
emptyDir: {}
|
||||||
|
- name: docker-config
|
||||||
|
secret:
|
||||||
|
secretName: kaniko-registry-creds
|
||||||
|
items:
|
||||||
|
- key: .dockerconfigjson
|
||||||
|
path: config.json
|
||||||
Reference in New Issue
Block a user