We’re giving away 1,500 more DJI Tello drones. Enter to win ›
Nidhi Shah | Published February 8, 2019
CloudHybrid CloudContainersObject Storage
Docker is one of the more popular container platforms for developers and sysadmins to develop, deploy, and run applications with containers. The use of Linux containers to deploy applications is called containerization that has lot more advantages over traditional virtualization as containers are much more efficient, fast, and lightweight.
Docker features the Docker Engine, which is a runtime and allows you to build and run containers, and includes DockerHub, a service for storing and sharing images. Docker also offers its own native clustering tool that can be used to orchestrate and schedule containers on machine clusters.
Since we’re talking about Docker, it’s natural that we also talk about Kubernetes, a container orchestration system for Docker containers that is more extensive than Docker Swarm and is meant to coordinate clusters of nodes at scale in production in an efficient manner.
Kubernetes and Docker are essentially the same technology – they orchestrate containers and they both use containerd or runC to do so. But they are different projects with a differing view on how users get their job done – they also work very well together, and both facilitate the management and deployment of containers in a distributed architecture.
Most organizations store proprietary Docker images in private registries. While it is easy to deploy public Docker images to Kubernetes, there are some additional steps involved when you’re dealing with private images. Docker Cloud uses DockerHub as its native registry for storing both public and private repositories.
This tutorial shows you how to configure a Kubernetes cluster to access public and private images from DockerHub.
In this tutorial, you’ll learn the following:
Before you begin, you’ll need
Completing this tutorial should take about 30-40 minutes.
You can use Docker images that are running on your local machine or download the example images used for this tutorial.
Here are the downloadable example images:
In this section, we’re going to start with current working directory of your application folder.
If you’re using the Python Example, change your working directory to get-started-python.
Log in to DockerHub.
Click on Create Repository.
Choose a name for your public image repository, that you will use in place of the field in following steps (e.g., get-started-python) and a description for your repository. Select Public to create public repository and click Create.
Set the variable “docker_username” as your username. This allows you to copy and paste the commands directly from this tutorial:
Log in to DockerHub from the command line:
Build an image if you are using Python Example from this tutorial. (You can skip this step if you are using your local image and head to #8 Tag your image):
docker build -t $docker_username/<YOUR_PUBLIC_REPO_IMAGE_NAME>:<TAG>
docker build -t $docker_username/get-started-python:v1.0.0
In general, a good choice for a <TAG> is something that will help you understand what this container should be used with or what it represents. If this container contains the analysis for a paper, consider using that paper’s DOI or journal-issued serial number; if it’s meant for use with a particular version of a code or data version control repo, that’s a good choice, too – whatever will help you understand what this particular image is intended for.
After executing the above command, you should see something like the following as output:
Successfully built f7757ff0ebce
Successfully tagged nidhinshah/get-started-python:v1.0.0
Check the image ID by using following command.
You should see something like the following output:
REPOSITORY TAG IMAGE ID CREATED SIZE
nidhinshah/get-started-python v1.0.0 f7757ff0ebce 5 minutes ago 914MB
Note : You don’t need to do this step if you built it, because we built it with the right tag name already. This step is only needed if you’re going to use some other image. So skip to the next step if applicable.
Tag your image:
docker tag <IMAGE ID> $docker_username/<YOUR_PUBLIC_REPO_IMAGE_NAME>:<TAG>
docker tag f7757ff0ebce $docker_username/get-started-python:v1.0.0
Push your image to DockerHub.
docker push $docker_username/<YOUR_PUBLIC_REPO_IMAGE_NAME>:<TAG>
docker push $docker_username/get-started-python:v1.0.0
You should see something like the following as output:
The push refers to repository [docker.io/nidhinshah/get-started-python]
v1.0.0: digest: sha256:b2ee76e81575bd74bad80d95f983af5701e2df4a8ed5288739c654aa6e591301 size: 2642
Go to your DockerHub UI and you can see that your image is pushed to the public repository:
Run your image on Docker:
docker run -it -d -p <PORT>:<PORT> $docker_username/<YOUR_PUBLIC_REPO_IMAGE_NAME>:<TAG>
Note: You have to mention the Port number that you used to expose your application in your Dockerfile.
docker run -it -d -p 5000:5000 $docker_username/get-started-python:v1.0.0
You can now access the application at http://localhost:5000.
Note: You can convert between private and public via the Settings page in DockerHub. You’re not stuck with the choice that you originally made when you first created the repo.
Private repositories allow you to have repositories that contain images that you want to keep private, either to your own account or within an organization or team.
To work with a private repository on DockerHub, you need to add one by using the Add Repository Procedure (Steps 1 – 3 from Create a public image repository on DockerHub). Then select Privat at Step 3.
If you wish to use the Node Example from this tutorial, download it and cd into it, else cd into your work directory:
For our Node example:
Follow Steps 4-12 from Create a public image repository on DockerHub to push this private image to your DockerHub account.
You will see the following when accessing the Node Example.
We have created both public and private images and pushed them to our DockerHub account in previous steps. To access these repositories from IBM Cloud, we’ll configure the IBM Cloud Kubernetes Cluster.
Log into your IBM Cloud account:
If you have a federated ID, use following:
ibmcloud login --sso
Install the Container Registry plug-in:
ibmcloud plugin install container-registry -r "IBM Cloud"
Install the Container Service plug-in:
ibmcloud plugin install IBM-Containers -r "IBM Cloud"
Install kubectl (follow directions here).
Create the cluster:
ibmcloud cs cluster-create --name <YOUR_CLUSTER_NAME>
Where you see , give your cluster a unique name.
Configure Kubernetes cluster:
ibmcloud cs cluster-config <YOUR_CLUSTER_NAME>
Set the KUBECONFIG environment variable. Copy the output from the previous command and paste it in your terminal.
The command output should look similar to the following:
export KUBECONFIG=/Users/$USER/.bluemix/plugins/container-service/clusters/cluster-demo/kube-config-hou02- <YOUR_CLUSTER_NAME>.yml
Verify that you can connect to your cluster by listing your worker nodes:
kubectl get nodes
You should see STATUS = Ready:
NAME STATUS AGE VERSION
10.44.103.91 Ready 1d v1.10.8+IKS
This is an easy approach and no additional setup is needed for your cluster.
Make sure you are logged into your Docker account:
Run the following command to deploy your application to IBM Cloud Kubernetes Service (IKS) Cluster:
kubectl run <YOUR_DEPLOYMENT_NAME> --image=docker.io/$docker_username/<YOUR_PUBLIC_REPO_IMAGE_NAME>:<TAG>
Where you see <YOUR_DEPLOYMENT_NAME>, give your deployment a unique name. Where you see <YOUR_PUBLIC_REPO_IMAGE_NAME>, give your DockerHub Public Image Repository a unique name.
kubectl run get-started-python --image=docker.io/$docker_username/get-started-python:v1.0.0
You will see an output with the following message:
deployment "get-started-python" created
To check your application pod, use:
kubectl get pods
You will see “Running” under your Pod STATUS for your deployed Application:
NAME READY STATUS RESTARTS AGE
get-started-python-6b7b786d7-47htj 1/1 Running 0 30s
Expose the app to the web by setting the port.
kubectl expose deployment/<YOUR_DEPLOYMENT_NAME> --type=NodePort --name=<YOUR_SERVICE_NAME> --port=<PORT>
Where you see <YOUR_DEPLOYMENT_NAME>, give a name to your deployment. Where you see <YOUR_SERVICE_NAME>, give your service a unique name. Where you see <PORT>, the port should be the same as exposed in your Dockerfile.
kubectl expose deployment/get-started-python --type=NodePort --name=get-started-python --port=5000
service "get-started-python" exposed
You can connect any existing private registry to your IKS cluster by creating an imagePullSecret. The secret is used to securely save your registry URL and credentials in a Kubernetes secret.
Create the Secret.
kubectl create secret docker-registry <SECRET-NAME> --docker-server=<YOUR-REGISTRY-SERVER> --docker-username= <YOUR_DOCKER_USERNAME> --docker-password=<YOUR_DOCKER_PASSWORD> --docker-email=<YOUR_DOCKER_EMAIL>
Where you see <SECRET-NAME>, give a name that you want to use for your imagePullSecret.
Where you see <YOUR-REGISTRY-SERVER>, input the URL to the registry where your private images are stored (https://index.docker.io/v1/ for DockerHub).
Where you see <YOUR_DOCKER_USERNAME>, use your Docker username to log in to your private registry. Where you see <YOUR_DOCKER_PASSWORD>, use your Docker password.
Where you see <YOUR_DOCKER_EMAIL>, use your Docker email address.
You have now successfully set your Docker credentials in the cluster as a Secret called <SECRET-NAME>.
Log in to your Docker account:
Create the deployment.yaml file:
Paste the following code to the deployment.yaml file and save the changes. Replace the values according to your credentials or use deployment.yaml file if you are using the Node Example.
- port: 3000
- name: <YOUR_IMAGE_CONTAINER_NAME>
- containerPort: 3000
- name: <SECRET-NAME>
Where you see <YOUR_SERVICE_NAME>, give your service a unique name. Where you see <YOUR_PRIVATE_IMAGE_NAME>, use your DockerHub Private Image name. Where you see <YOUR_DEPLOYMENT_NAME>, give your deployment a unique name. Where you see <YOUR_IMAGE_CONTAINER_NAME>, give your image container a unique name. Where you see <SECRET-NAME>, use the secret that you created in previous step (step 1).
Run the application on Kubernetes with a yaml file:
kubectl create -f deployment.yaml
The output will display the following message:
service "get-started-node-service" created
deployment "get-started-node-deployment" created
NAME READY STATUS RESTARTS AGE
get-started-node-deployment-85b96dd6cf-mt6pd 1/1 Running 0 10s
Note: To access your application, you will need the public IP address of your cluster and NodePort of the service.
For clusters provisioned with IBM Cloud, use:
ibmcloud cs workers <YOUR_CLUSTER_NAME>
ibmcloud cs workers cluster-demo
You will see an output similar to the following:
ID Public IP Private IP Machine Type State Status Zone Version
kube-hou02-pafd0092d812024958b05e2e9f1a88c8d9-w1 18.104.22.168 10.44.103.91 free normal Ready hou02 1.10.8_1528
For details on a specific Kubernetes service, use:
kubectl describe service <YOUR_SERVICE_NAME>
You can use this command to get details of both private/public images that you deployed from DockerHub.
kubectl describe service get-started-node-service
Port: http 3000/TCP
NodePort: http 30090/TCP
Session Affinity: None
You can now access the application at http://IP_ADDRESS:NODE_PORT.
A cleanup will save you time and space, in case you decide you no longer want to use this deployment again.
kubectl delete deployment <YOUR_DEPLOYMENT_NAME> && kubectl delete deployment <YOUR_SERVICE_NAME> && kubectl delete deployment <SECRET-NAME>
Kubernetes is the tool for you if you’re looking for a deployment tool that can provide automation, scalability, and management of a deployed application. This tutorial detailed a step-by-step walkthrough of deploying and accessing public and private images from a DockerHub account.
Now that you know how to access your public and private images, make sure to regularly scan your images with the free IBM Cloud Image Scanning Service. This service will scan the provided container image for vulnerabilities using the IBM Cloud Vulnerability Advisor. The image must be publicly available via a docker pull command without any authentication or login required.
You can also explore more code examples on orchestrating your containers by going through our Container Orchestration Code Patterns.
If you’re interested in other alternatives to DockerHub, check out the IBM Cloud Container Registry, where you can securely store and share Docker images with other users by adding images to your namespace.
Learn how to create and connect to a MySQL database in a Docker container and Loopback development environment.
Back to top