136 lines
4.1 KiB
Markdown
136 lines
4.1 KiB
Markdown
# devops-base-images
|
|
|
|
One-time-setup repo for mirroring minimized base images into Harbor's
|
|
`base-images` project, so language builds (via `devops-lib`'s
|
|
`buildDocker.groovy` fallback templates) never depend on Docker Hub at
|
|
build time, and the images that actually ship are the leanest official
|
|
variant available for each language.
|
|
|
|
Not wired into any Jenkins pipeline — this is deliberately a manual,
|
|
occasional operation (re-run when `images.txt` changes: a new language,
|
|
a version bump, or picking up an upstream base-image update), using the
|
|
same one-off `kubectl`-based DinD pod pattern `devops-lib`'s
|
|
`build-tools.Dockerfile` bootstrap already uses, since the VM itself may
|
|
not have Docker installed directly.
|
|
|
|
## One-time setup
|
|
|
|
**1. Create the Harbor project** (public — these are just re-hosted
|
|
public images, no confidentiality concern, and public avoids needing any
|
|
pull credentials wired into every build):
|
|
|
|
Harbor UI → New Project → name `base-images` → check **Public** → Create.
|
|
|
|
Or via API:
|
|
```
|
|
curl -X POST -u admin:'<harbor admin password>' -H "Content-Type: application/json" \
|
|
-d '{"project_name":"base-images","metadata":{"public":"true"}}' \
|
|
"http://harbor.192.168.1.7.nip.io/api/v2.0/projects"
|
|
```
|
|
|
|
**2. Run the mirror**, via a throwaway DinD pod (same shape as the
|
|
`build-tools` image bootstrap):
|
|
|
|
```
|
|
cat <<'EOF' | kubectl apply -f -
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: base-images-mirror
|
|
namespace: jenkins
|
|
data:
|
|
images.txt: |
|
|
golang:1.22-alpine golang:1.22-alpine
|
|
alpine:3.20 alpine:3.20
|
|
node:20-alpine node:20-alpine
|
|
python:3.12-alpine python:3.12-alpine
|
|
maven:3-eclipse-temurin-21-alpine maven:3-eclipse-temurin-21-alpine
|
|
eclipse-temurin:21-jre-alpine eclipse-temurin:21-jre-alpine
|
|
php:8.3-cli-alpine php:8.3-cli-alpine
|
|
mirror.sh: |
|
|
#!/bin/sh
|
|
set -eu
|
|
REGISTRY="harbor.192.168.1.7.nip.io"
|
|
PROJECT="base-images"
|
|
while read -r src target; do
|
|
[ -z "$src" ] && continue
|
|
case "$src" in \#*) continue ;; esac
|
|
dest="${REGISTRY}/${PROJECT}/${target}"
|
|
echo "=== ${src} -> ${dest} ==="
|
|
docker pull "$src"
|
|
docker tag "$src" "$dest"
|
|
docker push "$dest"
|
|
done < images.txt
|
|
echo "=== done ==="
|
|
---
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: base-images-mirror
|
|
namespace: jenkins
|
|
spec:
|
|
restartPolicy: Never
|
|
containers:
|
|
- name: docker
|
|
image: docker:27-dind
|
|
securityContext:
|
|
privileged: true
|
|
args:
|
|
- "--insecure-registry=harbor.192.168.1.7.nip.io"
|
|
env:
|
|
- name: DOCKER_TLS_CERTDIR
|
|
value: ""
|
|
volumeMounts:
|
|
- name: docker-graph-storage
|
|
mountPath: /var/lib/docker
|
|
- name: docker-cli
|
|
image: docker:27-cli
|
|
command: ["cat"]
|
|
tty: true
|
|
env:
|
|
- name: DOCKER_HOST
|
|
value: tcp://localhost:2375
|
|
volumeMounts:
|
|
- name: mirror
|
|
mountPath: /mirror
|
|
- name: docker-config
|
|
mountPath: /root/.docker
|
|
readOnly: true
|
|
volumes:
|
|
- name: docker-graph-storage
|
|
emptyDir: {}
|
|
- name: mirror
|
|
configMap:
|
|
name: base-images-mirror
|
|
defaultMode: 0755
|
|
- name: docker-config
|
|
secret:
|
|
secretName: harbor-robot-dockerconfig
|
|
items:
|
|
- key: .dockerconfigjson
|
|
path: config.json
|
|
EOF
|
|
|
|
kubectl wait --for=condition=Ready pod/base-images-mirror -n jenkins --timeout=120s
|
|
kubectl exec -n jenkins base-images-mirror -c docker-cli -- sh -c '
|
|
for i in $(seq 1 30); do docker info >/dev/null 2>&1 && break; sleep 2; done
|
|
cd /mirror && sh mirror.sh
|
|
'
|
|
kubectl delete pod base-images-mirror -n jenkins
|
|
kubectl delete configmap base-images-mirror -n jenkins
|
|
```
|
|
|
|
**3. Verify:**
|
|
```
|
|
curl -s http://harbor.192.168.1.7.nip.io/v2/_catalog
|
|
```
|
|
Should list `base-images/golang`, `base-images/alpine`,
|
|
`base-images/node`, `base-images/python`,
|
|
`base-images/maven`, `base-images/eclipse-temurin`, `base-images/php`.
|
|
|
|
## Adding a new image / updating a version
|
|
|
|
Add a line to `images.txt`, commit, push, then re-run step 2 above (the
|
|
ConfigMap's `images.txt` needs updating to match — copy the current file
|
|
content in, same as the initial setup).
|