Setting up container registry for kubeflow - docker

I am using ubuntu 20.04
while following book -> https://www.oreilly.com/library/view/kubeflow-for-machine/9781492050117/
on page 17, it says the following (only relevant parts) which I don't understand....
You will want to store container images called a
container registry. The container registry will be accessed by your Kubeflow cluster.
I am going to use docker hub as container registry. Next
we'll assume that you've set your container registry via an environment variable
$CONTAINER_REGISTRY, in your shell" NOTE: If you use registry that isn't on Google Cloud
Platform, you will need to configure Kubeflow pipelines container builder to have access to
your registry by following the Kaniko configuration guide -> https://oreil.ly/88Ep-
First, I do not understand how to set container registry through environment variable, am I supposed to give it a link??
Second, I've gone into Kaniko config guide and did everything as told -> creating config.json with "auth":"mypassword for dockerhub". After that In the book it says:
To make sure your docker installation is properly configured, you can write one line Dc and
push it to your registry."
Example 2.7 Specify the new container is built on top of Kubeflow's
container
FROM gcr.io/kubeflow-images-public/tensorflow-2.1.0-notebook-cpu:1.0.0
Example 2.8 Build new container and push to registry for use
IMAGE="${CONTAINER_REGISTRY}/kubeflow/test:v1"
docker build -t "${IMAGE}" -f Dockerfile . docker push "${IMAGE}"
I've created Dockerfile with code from Example2.7 inside it, then ran code from Example 2.8 however not working.

Make sure that:
You set the environment variable using export CONTAINER_REGISTRY=docker.io/your_username in your terminal (or in your ~/.bash_profile and run source ~/.bash_profile).
Your .docker/config.json does not have your password in plain text but in base64, for example the output of echo -n 'username:password' | base64
The docker build and the docker push are two separate commands, in your example they're seen as one command, unlike the book.

Related

OpenShift: Can I set up a build that copies a docker image from an imagestream to an external docker repository?

We are trying to set up an OpenShift flow as close to the defaults as possible, without having to use Jenkins.
So far I have managed to adapt a s2i-generated Dockerfile to our needs (to get the benefits of the s2i images) and set up a simple "oc new-app" pipeline which creates a build following a git repository pushing the generated docker image to an image stream and a deployment triggered by the image stream update pushing to a default pod. This works well.
Now we want to additionally have this docker image pushed to an external docker repository (the RED HAT CONTAINER REGISTRY known by OpenShift) and I would essentially like to keep the existing flow instead of adapting it to use the external registry instead of the internal.
So, can I set up a "build" or something like it which does nothing but take that image and push it to the docker registry? How do I set it up using the oc command?
Would you like to push the image builded by buildConfig to external registry, right ?
I think the work flow is like this:Using Docker Credentials for Private Registries.
Create credential secret
$ oc create secret generic <secret_name> \
--from-file=.dockerconfigjson=<path/to/.docker/config.json> \
--type=kubernetes.io/dockerconfigjson
Link the secret with builder ServiceAccount.
Configure the build image push target in the buildConfig as follows.
spec:
output:
to:
kind: DockerImage
name: external.registry.io/subpath/imagename:latest
pushSecret:
name: <secret_name>
I hope it help you.
You can use the skopeo command-line tool to copy container images from one docker registry to another without needing to build the image a second time.
This is an officially supported tool by Red Hat that is part of the new suite of tools (buildah, podman, skopeo, etc) to support running OpenShift and Kubernetes on top of the daemonless cri-o container runtime instead of docker.
Either log in to the source and destination registries via docker login or use the --src-creds and --dest-creds flags.
skopeo copy \
--src-creds=testuser:testpassword \
--dest-creds=otheruser:otherpassword \
docker://myregistrydomain.com:5000/dockerimage:tag \
docker://mysecondregistrydomain.com:5000/dockerimage:tag

How do I run startup scripts for DOCKER when deployed via Cloud Compute Engine instances?

I'm creating an instance template under GCP's Cloud Engine section.
Usually when deploying a docker image, there's a docker file that includes some startup scripts after specifying the base image to pull and build, but I can't see where I can either submit a docker file, or enter startup scripts.
I can see a field for startup scripts for the Cloud Compute instance, but that's different from the scripts passed on for the Docker's startup.
Are these perhaps to be filled in under "Command", "Command arguments", or "Environment Variables"?
For clarification, this is someone else's image of a dockerfile I pulled from Google Images. The part I wish to add is "rectangled" in red, the RUN commands, but not these exact commands.
In my case, I would like to add something like
RUN python /pythonscript.py
If I understood well, you are trying to create a Docker image not a compute instance image.
Compute instance can run a docker image that you already builded and pushed to either gcr or any other repository.
Try to build your docker image normaly, push it in a docker repo then use it.
You can run a startup script directly in the Docker container by using a ‘command’ section. If you need to install something after starting a container for example Apache, you should use a Docker image that has Apache.
If you need to run some other arguments, like creating environment variables, here you can find the full list of flags when creating a container image on VM instance.

GCE doesn't deploy GCR image correctly

I have followed this guide from Google documentation in order to be able to push a custom Docker image to Google Container Registry and then be able to start a new GCE instance with this image. At first I wanted to try using an anaconda3 public image from docker hub without any modification (in order to test).
So here is the steps I have done so far after installing gcloud and docker:
gcloud auth configure-docker -> configured docker with my gcloud crendentials
docker pull continuumio/anaconda3 -> pulled the public image
docker tag continuumio/anaconda3 eu.gcr.io/my-project-id/anaconda3 -> tagged the local image with the registry name as specified in the doc
docker push eu.gcr.io/my-project-id/anaconda3 -> pushed the image to GCR
Good ! I am now able to see my image trough GCR interface, and also able to deploy it with GCE. I choose to deploy it with a f1-micro instance, Container-Optimized OS 67-10575.62.0 stable, 10 Go boot disk, Allow HTTP traffic, etc.
But when I connect with ssh to the freshly new created VM instance, I can't find anaconda3 librairies (which are supposed to be created in /opt/conda). Instead, I can see a /opt/google directory which makes me think that the image has not been deployed correctly and GCE is using a default image...
So I tried to check if the image was pushed correctly in GCR, so I decided to delete my local image and pull it once again from GCR:
docker rmi -f eu.gcr.io/my-project-id/anaconda3
docker pull eu.gcr.io/my-project-id/anaconda3:latest
I run the image
docker run -t -i eu.gcr.io/my-project-id/anaconda3
and I can see that everything is fine, I have anaconda3 installed correctly inside /opt/conda with all the toolts needed (Pandas, Numpy, Jupyter notebook, etc.)
I tried to find people with the same problem as me without any success... maybe I have done something wrong in my proccess ?
Thanks !
TL;DR My problem is that I have pushed an anaconda3 image on Google GCR, but when I launch a virtual instance with this image, I do not have anaconda on it
It's normal that you can't find anaconda libraries installed directly on the GCE instance.
Actually, when you choose to deploy a container image on a GCE VM instance, a Docker container is started from the image you provide (in your example, eu.gcr.io/my-project-id/anaconda3). The libraries are not installed on the host, but rather inside that container (run docker ps to see it, but normally it has the same name as your VM instance). If you run something like :
docker exec -it <docker_container_name> ls /opt/conda
Then you should see the anaconda libraries, only existing inside the container.
When you run docker run -t -i eu.gcr.io/my-project-id/anaconda3, you're actually starting the container and running an interactive bash session inside that container (see the CMD here). That's why you can find anaconda libraries : you are inside the container!
Containerization software (docker here) provides isolation between your host and your containers. I'll suggest you to read documentation about containerization, Docker and how to run containers on Container-Optimized OS.

OpenWhisk support custom registry

I need to run a Docker action in OpenWhisk. Inside the Docker Container, I execute a Java program.
Now I pulled the docker skeleton from Openwhisk and installed Java on it.
I also put my Java program inside the container and replaced the exec.
I can create the action with:
wsk create action NAME --docker myDockerHub/repo:1 -i
This is not optimal since my code should not be on DockerHub. Does OpenWhisk provide usage for my local Registy?
wsk action create ImportRegionJob --docker server.domain.domain:5443/import-region-job:v0.0.2 -i
error: Unable to create action 'ImportRegionJob': The request content was malformed:
image prefix not is not valid (code qXB0Tu65zOfayHCqVgrYJ33RMewTtph9)
Run 'wsk --help' for usage.
I know you can provide a .zip file to a docker action when creating it, but that does not work because the default image used does not have Java installed.
I achieved this for a distributed OpenWhisk environment. The docker actions are hosted in GitLab, built by GitLab CI and deployed to a custom container registry in their respective GitLab repositories. Pulls from the local registry are significantly faster than pulls from docker hub.
In OpenWhisk, create an action using the full path including registry url.
wsk create action NAME --docker YourRegistry:port/namespace/image[:tag]
On invocation, the pull command for the action will be carried out inside the invoker containers on the compute nodes. The following table shows in the first column an example setup of invoker hosts (configured in openwhisk/ansible/environments/distributed/hosts, section [invokers]), and in the second column the respective invoker container name running on that host. The invoker container in the second column should show up, when doing a docker ps on the hostname from the first column:
invoker-host-0 invoker0
invoker-host-1 invoker1
...
invoker-host-2 invokerN
for $I in $(seq 0 N); do ssh invoker-host-$I docker ps | grep invoker$I; done
Now, you can do a docker login for all invokers in one command.
for $I in $(seq 0 N); do ssh invoker-host-$I docker exec invoker$I docker login YourRegistry:port -u username -p TokenOrPassword; done
As a prerequisite, inside all invoker containers, I had to add the root certificates for the registry, update-ca-certificates and restart the docker deamon.
An improvement might be to do this already in the invoker container image, that is built when deploying openwhisk (before running) invoker.yml, which is imported in openwhisk.yml.
Docker images can be specified when deploying applications from zip files. This allows you use the existing Java runtime with the zip file, which has Java installed, removing the need for a custom image.
wsk action update --docker openwhisk/java8action action_name action_files.zip

Create a new image from a container’s changes in Google Cloud Container

I have an Image which i should add a dependency to it. Therefore I have tried to change the image when is running on the container and create new Image.
I have follow this article with the following commands after :
kubectl run my-app --image=gcr.io/my-project-id/my-app-image:v1 --port 8080
kubectl get pods
kubectl exec -it my-app-container-id -- /bin/bash
then in the shell of container, i have installed the dependency using "pip install NAME_OF_Dependncy".
Then I have exited from the shell of container and as it have been explained in the article, i should commit the change using this command :
sudo docker commit CONTAINER_ID nginx-template
But I can not find the corresponding command for Google Kubernetes Engine with kubectl
How should i do the commit in google container engine?
As with K8s Version 1.8. There is no way to do Hot Fix changes directly to the images.For example, Committing new image from running container. If you still change or add something by using exec it will stay until the container is running. It's not best practice in K8s eco-system.
The recommended way is to use Dockerfile and customise the images according to the necessity and requirements.After that, you can push that images to the registry(public/ private ) and deploy it with K8s manifest file.
Solution to your issue
Create a Dockerfile for your images.
Build the image by using Dockerfile.
Push the image to the registry.
write the deployment manifest file as well service manifest file.
apply the manifest file to the k8s cluster.
Now If you want to change/modify something, you just need to change/modify the Dockerfile and follow the remaining steps.
As you know that containers are a short living creature which does not have persist changed behaviour ( modified configuration, changing file system).Therefore, It's better to give new behaviour or modification at the Dockerfile.
Kubernetes Mantra
Kubernetes is Cloud Native product which means it does not matter whether you are using Google Cloud, AWS or Azure. It needs to have consistent behaviour on each cloud provider.

Resources