# Harbor and container images
Few more samples how you can work with container images in Harbor.
# Upload docker image
Create simple Docker image
echo admin | docker login --username aduser05 --password-stdin harbor.${MY_DOMAIN}
Output:
WARNING! Your password will be stored unencrypted in /home/pruzicka/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
Download kuard
docker image:
docker pull gcr.io/kuar-demo/kuard-amd64:blue
Output:
blue: Pulling from kuar-demo/kuard-amd64
8e402f1a9c57: Pull complete
8df70f469ef0: Pull complete
Digest: sha256:1ecc9fb2c871302fdb57a25e0c076311b7b352b0a9246d442940ca8fb4efe229
Status: Downloaded newer image for gcr.io/kuar-demo/kuard-amd64:blue
Tag kuard
with customized name to push to the private repository in Harbor:
docker tag gcr.io/kuar-demo/kuard-amd64:blue harbor.${MY_DOMAIN}/my_project/kuard-amd64:blue
List all images:
docker images
Output:
REPOSITORY TAG IMAGE ID CREATED SIZE
gcr.io/kuar-demo/kuard-amd64 blue 1db936caa6ac 3 months ago 23MB
harbor.mylabs.dev/my_project/kuard-amd64 blue 1db936caa6ac 3 months ago 23MB
Push docker image to Harbor:
docker push harbor.${MY_DOMAIN}/my_project/kuard-amd64:blue
Output:
The push refers to repository [harbor.mylabs.dev/my_project/kuard-amd64]
656e9c47289e: Pushed
bcf2f368fe23: Pushed
blue: digest: sha256:1ecc9fb2c871302fdb57a25e0c076311b7b352b0a9246d442940ca8fb4efe229 size: 739
It should be visible in the Harbor UI:
# Signed container image
YouTube video: https://youtu.be/pPklSTJZY2E (opens new window)
Tag the kuard
image to be pulled to Harbor library
project:
docker tag gcr.io/kuar-demo/kuard-amd64:blue harbor.${MY_DOMAIN}/library/kuard-amd64:blue
Push there the image:
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER=https://notary.${MY_DOMAIN}
export DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE="mypassphrase123"
export DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE="rootpassphrase123"
docker push harbor.${MY_DOMAIN}/library/kuard-amd64:blue
unset DOCKER_CONTENT_TRUST
Output:
The push refers to repository [harbor.mylabs.dev/library/kuard-amd64]
656e9c47289e: Mounted from my_project/kuard-amd64
bcf2f368fe23: Mounted from my_project/kuard-amd64
blue: digest: sha256:1ecc9fb2c871302fdb57a25e0c076311b7b352b0a9246d442940ca8fb4efe229 size: 739
Signing and pushing trust metadata
Finished initializing "harbor.mylabs.dev/library/kuard-amd64"
Successfully signed harbor.mylabs.dev/library/kuard-amd64:blue
You should be able to see the signed container image in the Harbor web interface:
Install Notary (opens new window) which can show you the signature form "Harbor":
sudo curl -sL https://github.com/theupdateframework/notary/releases/download/v0.6.1/notary-Linux-amd64 -o /usr/local/bin/notary
sudo chmod a+x /usr/local/bin/notary
Access Notary using the standard client:
notary -s https://notary.${MY_DOMAIN} list harbor.${MY_DOMAIN}/library/kuard-amd64
Output:
NAME DIGEST SIZE (BYTES) ROLE
---- ------ ------------ ----
blue 1ecc9fb2c871302fdb57a25e0c076311b7b352b0a9246d442940ca8fb4efe229 739 targets
# Vulnerability scan
YouTube video: https://youtu.be/K4tJ6B2cGR4 (opens new window)
Wait for Clair to finish updating the "Vulnerability database" (it may take a long time).
Wait for Clair to update the vulnerability data:
CLAIR_POD=$(kubectl get pods -l "app=harbor,component=clair" -n harbor-system -o jsonpath="{.items[0].metadata.name}")
while ! kubectl logs -n harbor-system ${CLAIR_POD} | grep "update finished"; do echo -n ". "; sleep 10; done
Output:
{"Event":"update finished","Level":"info","Location":"updater.go:223","Time":"2019-07-19 10:15:24.517724"}
See if "Vulnerability database" was successfully updated using API:
curl -s -u "admin:admin" "https://harbor.${MY_DOMAIN}/api/systeminfo" | jq ".clair_vulnerability_status"
Output:
{
"overall_last_update": 1563531324,
"details": [
{
"namespace": "debian",
"last_update": 1563531324
},
{
"namespace": "alpine",
"last_update": 1563531324
},
{
"namespace": "ubuntu",
"last_update": 1563531324
},
{
"namespace": "oracle",
"last_update": 1563531324
},
{
"namespace": "centos",
"last_update": 1563531324
}
]
}
Scan the image kuard-amd64:blue
for vulnerabilities (using API):
curl -u "aduser05:admin" --header "Content-Type: application/json" -X POST "https://harbor.${MY_DOMAIN}/api/repositories/my_project/kuard-amd64/tags/blue/scan"
Everything should be "green" - no vulnerability found:
Let's download popular web server Nginx (opens new window) based on Debian Stretch from Docker Hub. The image is is one year old: https://hub.docker.com/_/nginx?tab=tags&page=5 (opens new window)
docker pull nginx:1.13.12
Output:
1.13.12: Pulling from library/nginx
f2aa67a397c4: Pull complete
3c091c23e29d: Pull complete
4a99993b8636: Pull complete
Digest: sha256:b1d09e9718890e6ebbbd2bc319ef1611559e30ce1b6f56b2e3b479d9da51dc35
Status: Downloaded newer image for nginx:1.13.12
Tag nginx
to push to the private repository in Harbor:
docker tag nginx:1.13.12 harbor.${MY_DOMAIN}/my_project/nginx:1.13.12
List all images:
docker images
Output:
REPOSITORY TAG IMAGE ID CREATED SIZE
gcr.io/kuar-demo/kuard-amd64 blue 1db936caa6ac 3 months ago 23MB
harbor.mylabs.dev/library/kuard-amd64 blue 1db936caa6ac 3 months ago 23MB
harbor.mylabs.dev/my_project/kuard-amd64 blue 1db936caa6ac 3 months ago 23MB
nginx 1.13.12 ae513a47849c 14 months ago 109MB
harbor.mylabs.dev/my_project/nginx 1.13.12 ae513a47849c 14 months ago 109MB
Push nginx
docker image to Harbor:
docker push harbor.${MY_DOMAIN}/my_project/nginx:1.13.12
Output:
The push refers to repository [harbor.mylabs.dev/my_project/nginx]
7ab428981537: Pushed
82b81d779f83: Pushed
d626a8ad97a1: Pushed
1.13.12: digest: sha256:e4f0474a75c510f40b37b6b7dc2516241ffa8bde5a442bde3d372c9519c84d90 size: 948
Scan the image for vulnerabilities:
curl -u "aduser06:admin" --header "Content-Type: application/json" -X POST "https://harbor.${MY_DOMAIN}/api/repositories/my_project%2Fnginx/tags/1.13.12/scan"
You should see many vulnerabilities in the container image:
Vulnerability list for container image:
# Replication
YouTube video: https://youtu.be/1NPlzrm5ozE (opens new window)
You can configure replication form other registries to replicate helm charts or containers.
Create new Registry Endpoint:
curl -X POST -H "Content-Type: application/json" -u "admin:admin" "https://harbor.${MY_DOMAIN}/api/registries" -d \
"{
\"name\": \"Docker Hub\",
\"type\": \"docker-hub\",
\"url\": \"https://hub.docker.com\",
\"description\": \"Docker Hub Registry Endpoint\"
}"
In the Web GUI you should see:
Create new Replication Rule:
curl -X POST -H "Content-Type: application/json" -u "admin:admin" "https://harbor.${MY_DOMAIN}/api/replication/policies" -d \
"{
\"name\": \"Replication of paulbouwer/hello-kubernetes\",
\"type\": \"docker-hub\",
\"url\": \"https://hub.docker.com\",
\"description\": \"Replication Rule for paulbouwer/hello-kubernetes\",
\"enabled\": true,
\"src_registry\": {
\"id\": 1
},
\"dest_namespace\": \"library\",
\"filters\": [{
\"type\": \"name\",
\"value\": \"paulbouwer/hello-kubernetes\"
}],
\"trigger\": {
\"type\": \"manual\"
}
}"
Start the replication:
curl -X POST -H "Content-Type: application/json" -u "admin:admin" "https://harbor.${MY_DOMAIN}/api/replication/executions" -d "{ \"policy_id\": 1 }"
Prepare ingress for running the application hello-kubernetes
:
export APP=hello-kubernetes
envsubst < ../files/app_ingress.yaml | kubectl create -f -
Output:
ingress.extensions/hello-kubernetes created
The Replications and Execution tabs looks like:
Let's run the replicated docker image:
kubectl run hello-kubernetes --image=harbor.${MY_DOMAIN}/library/hello-kubernetes:1.5 --port=8080 --expose=true --labels="app=hello-kubernetes" -n mytest
Output:
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
service/hello-kubernetes created
deployment.apps/hello-kubernetes created
Open the web browser with URL: https://hello-kubernetes.mylabs.dev (opens new window)