Running Minikube in AWS EC2 (Ubuntu)

If you are studying Kubernetes and having a hard time running Minikube on an EC2 Instance, you are not alone. I had a hard time doing it when it was my first time.

Below are the steps (and some comments) that I took to help me run Minikube on my EC2 Instance.

Installation of Minikube on EC2 Ubuntu

1. Run a public EC2 Server with the following setup

AMI Ubuntu Server 18.04 LTS (HVM), SSD Volume Type
Instance Type t3.micro (2 vCPU, 1GB Memory)
Storage 8 GB (gp2)
Tags – Key: Name
– Value: Minikube
Security Group Name: Minikube Security Group
– SSH, 0.0.0.0/0
Later we will be editing this.
Key Pair Create your own keypair.
You will need this to SSH to your EC2 Instance

Update: I changed the Instance Type from t2.micro (1 vCPU) to t3.micro (2 vCPU). An update to Minikube required a minimum of 2 vCPUs. The error when running with t2.micro was Requested cpu count 1 is less than the minimum allowed of 2.

t3.micro is no longer in the Free Tier, make sure to stop or terminate the instance after you are done testing to avoid a huge AWS bill.

Thank you to everyone in the comments section who pointed this change.

2. SSH into your created EC2 Instance using your keypair.

ssh ubuntu@<ipv4_public_ip> -i <keypair>.pem

3. Install kubectl

curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

4. Install Docker

sudo apt-get update && \
    sudo apt-get install docker.io -y

Minikube requires Docker.

5. Install Minikube

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

6. Check Minikube Version

minikube version

We have now successfully installed Minikube!

Let’s test it!

Running Minikube on EC2 Ubuntu

Become a root user.

sudo -i

If you are not comfortable running commands as root, you must always add sudo before the commands minikube and kubectl.

2. Start Minikube

minikube start --vm-driver=none

Do not worry about the warning. As long as you see the message ‘Kubectl is now configured to use the cluster.’ you have successfully ran Minikube.

Note: In the Install Minikube documentation from Kubernetes.io it says that you need to enable virtualization by accessing the computer’s BIOS. For EC2 Instances we do not have access to the BIOS since AWS EC2 instance is a Virtual Machine. Thus we are using the --vm-driver=none tag. No need to install a Hypervisor (VirtualBox or KVM)

3. Check the status of Minikube

minikube status

If you see the status as ‘running’ then we can now run kubectl commands.

4. Let us run our first container

kubectl run hello-minikube --image=gcr.io/google_containers/echoserver:1.4 --port=8080

5. Expose the container ports so that we can access it.

kubectl expose deployment hello-minikube --type=NodePort

6. Find where port 8080 in container exposed in EC2 Instance port.

kubectl get services

Note: Port 30263 is the EC2 Instance Port where the Port 8080 of the container is exposed.

The EC2 Instance Port changes each time you expose a port, you may have been given a different value than what I have.

kubectl get services command shows the list of services and their exposed ports.

Let us check by accessing this via a web browser on our local computer. But first we need to edit our EC2 Security Group.

7. Edit Security Group of the EC2 Instance to be access

The goal is for us to be able to access the EC2 Instance Port (30263 for me) via the internet.

EC2 >> (Network & Security) Security Groups >> Minikube Security Group >> Ingress

Press Edit. Then Add Rule.

Add the following.

Type Custom TCP Rule
Protocol TCP
Port Range 30263 (the port given to you by the kubectl get services command)
Source Custom
0.0.0.0/0 (Accessible via the internet)

Click Save.

8. Access the our container via the EC2 Instance Port on a web browser.

The address is <ipv4_public_ip>:<ec2_port>.

My EC2 Instance has an IPv4 Public IP of 13.250.43.8. And since my hello-minikube port 8080 is exposed on port 30263, the address that I placed on my browser is 13.250.43.8:30263.

See the request_uri of the page displayed by the web browser, it says that I am accessing via port 8080.

I accessed my container deployment using Chrome on my laptop. You can use any web browser you like (Safari, Internet Explorer, Edge, Firefox, etc.)

Now that we know that we can access our container, let us finish this and clean up.

9. Delete the exposed service (port)

kubectl delete services hello-minikube

10. Delete the deployed container (hello-minikube)

kubectl delete deployment hello-minikube

Stopping Minikube/Shutting Down the Cluster

minikube stop

I hope the above helps when you want to use Minikube on EC2 Ubuntu.

If there are errors, comments, suggestions, or clarifications you can comment them below.

50 thoughts on “Running Minikube in AWS EC2 (Ubuntu)”

  1. Hi, I tried following the steps, but VM is needed for minikube to run first. Not sure why you mentioned it’s not needed.

  2. Hi! Thank you so much for such an easy-to-follow article! It helped me to get my first minikube up and running on a free EC2 instance without any problem.

  3. my apiserver won’t run and I’m unable to run any commands following the start command. Any ideas?

    root@ip-172-31-26-29:~# minikube status
    host: Running
    kubelet: Running
    apiserver: Error
    kubectl: Correctly Configured: pointing to minikube-vm at 172.31.26.29root@ip-172-31-26-29:~#

    1. I’d suggest you throw in 4 gigs of RAM to the instance and try again. This seem to have worked for me (apparently)!

        1. I suggest editing the post to suggest that t2.large be the instance type used. Although the post worked fine for me with t3.micro, when I tried to stop and restart minikube I ran into problems. After switching to t2.large (thanks to comments here), the problems went away.

  4. HI, Thanks for the detailed steps.
    But I am struck at below step ‘ minikube start –vm-driver=none’

    …….. ..after some logs ……..below waiting for pods hungs for long time.
    – Pulling images required by Kubernetes v1.14.0 …
    : Relaunching Kubernetes v1.14.0 using kubeadm …
    : Waiting for pods: apiserver proxy

    I could start service and cluster.
    But accessing from browser http://: – will give “- Host not found. DNS error “. I had followed step-7 as-well. i.e., EC2 >> (Network & Security) Security Groups >> Minikube Security Group >> Ingress.

    Still no luck. Even curl command also says connection refused.
    curl $(minikube service hello-minikube –url)

    Am I missing something ? Appreciate if this can be cracked.

    Thanks.
    Venkat

  5. One step is missing in this procedure.
    In order to forward the traffic to the service you must run:
    $ kubectl port-forward –address 0.0.0.0 svc/hello-minikube 30263:80
    (with the appropriate port)
    Otherwise, you will get connection refused

      1. t2.large is not free.
        t2.micro is free for the first 12 months of your AWS Account.

        If your AWS Account is more than 12 months and you need a really cheap instance go for a t3a.micro.

  6. Thank you for this tutorial. I was able to start minikube but encountered this error on one of the steps.
    # kubectl run hello-minikube –image=gcr.io/google_containers/echoserver:1.4 –port=8080
    error: failed to discover supported resources: Get http://localhost:8080/apis/apps/v1?timeout=32s: dial tcp 127.0.0.1:8080: connect: connection refused
    Do you have any suggestions?

  7. Great article. Thanks for that. One thing though: when working with Ubuntu 18.04, I had to install CRI using the instructions at: https://kubernetes.io/docs/setup/production-environment/container-runtimes/

    And this action was taken because when minikube was started it output some warnings – one of which was this warning: [WARNING IsDockerSystemdCheck]: detected “cgroupfs” as the Docker cgroup driver. The recommended driver is “systemd”. Please follow the guide at https://kubernetes.io/docs/setup/cri/

  8. Getting this while executing with T2.micro, does this mean 1 CPU is not good enough handle this? please advise
    [ec2-user@ip-172-31-85-16 ~]$ minikube start –vm-driver=none
    😄 minikube v1.4.0 on Amazon 2018.03 (xen/amd64)
    💡 Requested CPU count 1 is less than the minimum allowed of 2

    1. Looks like Minikube now requires a minimum of 2 vCPU.
      Try using the following.
      – t3a.micro
      – t3.micro

      Note: The above is no longer included in the Free Tier of AWS.

      1. Use this command to proceed with 1 vCPU (t2.micro).
        minikube start –vm-driver=none –extra-config=kubeadm.ignore-preflight-errors=NumCPU –force –cpus 1

  9. can we access minikube dashboard with –vm-driver=none argument? I am not able to access minikube dashboard in ec2 instance.

  10. ubuntu@i:~$ minikube start –vm-driver=none
    * minikube v1.6.1 on Ubuntu 18.04 (xen/amd64)
    * Selecting ‘none’ driver from user configuration (alternates: [])
    * Requested cpu count 1 is less than the minimum allowed of 2

    So its not possible to run in t2.micro or any other suggestions

    1. Hey Sankar, I tried doing some configuration to make minikube to run on t2.micro. Unfortunately, I was not able to make it work.

      You can use t3a.micro or t3a.nano if you are avoiding any charges.

      Or you can try using Google Cloud Compute Instances. You can run an Instance that has 2 vCPU or more and you are still in the Free Tier.

  11. Yes, you can run on a t2.micro. Just tested this as of today. Use the following command to start it:

    minikube start –vm-driver=none –extra-config=kubeadm.ignore-preflight-errors=NumCPU –force –cpus 1

  12. I tried the steps to install minikube on t3.micro but, I’m getting the below error at the step: minikube start

    root@ip-172-31-17-160:~# minikube start –vm-driver=none
    😄 minikube v1.9.0 on Ubuntu 18.04
    ✨ Using the none driver based on user configuration
    💣 The none driver requires conntrack to be installed for kubernetes version 1.18.0

    I’m not understanding where exactly, i’m going wrong!

  13. Thanks for this detailed steps. When I tried the above commands on EC2 (t2.medium; Ubuntu 18.04) I got the error as below :

    X Sorry, Kubernetes 1.18.3 requires conntrack to be installed in root’s path

    As per the below URL, I had to install conntrack (apt-get install conntrack) package and then I was able to start the minikube.

    “https://stackoverflow.com/questions/61238136/cant-start-minikube-in-ec2-shows-x-sorry-kubernetes-v1-18-0-requires-conntrac”

    Pls document this.

  14. excuse me for a medium scale company can we use minikube and jenkins in ec2 with micro.t3 as deployment means or would you suggest any other

  15. Thanks for the effort, but there are several issues. 1) you have to install something called conntrack. 2) minikube somehow destroys the kubectl config files so they cannot be read – kubectl config view returns permission errors. 3) Using ‘sudo -i’ is not able to get kubectl to work because there is no local cluster named minikube, and one can’t be started with minikube start because ‘the “docker” driver should not be used with root privileges. 4) all of this has to be re-done on startup, or you have to leave the instance running.

  16. Hi Not sure why i get this garbage error

    ubuntu@ip-172-31-6-135:~$ kubectl get pods
    NAME AGE
    hello-minikube-wnhvd 26m
    kamil-c87tm 8m
    nginx-8f2bg 24m
    nginx123-kbhjl 24s
    ubuntu@ip-172-31-6-135:~$ kubectl describe pod nginx123-kbhjl
    Pod ‘nginx123-kbhjl’: error ‘v1.Pod: ObjectMeta: v1.ObjectMeta: readObjectFieldAsBytes: expect : after object field, parsing 754 …:{},”k:{\”… at {“kind”:”Pod”,”apiVersion”:”v1″,”metadata”:{“name”:”nginx123-kbhjl”,”generateName”:”nginx123-“,”namespace”:”default”,”selfLink”:”/api/v1/namespaces/default/pods/nginx123-kbhjl”,”uid”:”524c114c-0d8c-471e-a501-2b87347fcec2″,”resourceVersion”:”2359″,”creationTimestamp”:”2020-09-30T12:44:50Z”,”labels”:{“run”:”nginx123″},”ownerReferences”:[{“apiVersion”:”v1″,”kind”:”ReplicationController”,”name”:”nginx123″,”uid”:”bbfd1b03-a0c4-4301-b404-81c5a2e91d26″,”controller”:true,”blockOwnerDeletion”:true}],”managedFields”:[{“manager”:”kube-controller-manager”,”operation”:”Update”,”apiVersion”:”v1″,”time”:”2020-09-30T12:44:50Z”,”fieldsType”:”FieldsV1″,”fieldsV1″:{“f:metadata”:{“f:generateName”:{},”f:labels”:{“.”:{},”f:run”:{}},”f:ownerReferences”:{“.”:{},”k:{\”uid\”:\”bbfd1b03-a0c4-4301-b404-81c5a2e91d26\”}”:{“.”:{},”f:apiVersion”:{},”f:blockOwnerDeletion”:{},”f:controller”:{},”f:kind”:{},”f:name”:{},”f:uid”:{}}}},”f:spec”:{“f:containers”:{“k:{\”name\”:\”nginx123\”}”:{“.”:{},”f:image”:{},”f:imagePullPolicy”:{},”f:name”:{},”f:resources”:{},”f:terminationMessagePath”:{},”f:terminationMessagePolicy”:{}}},”f:dnsPolicy”:{},”f:enableServiceLinks”:{},”f:restartPolicy”:{},”f:schedulerName”:{},”f:securityContext”:{},”f:terminationGracePeriodSeconds”:{}}}},{“manager”:”kubelet”,”operation”:”Update”,”apiVersion”:”v1″,”time”:”2020-09-30T12:45:09Z”,”fieldsType”:”FieldsV1″,”fieldsV1″:{“f:status”:{“f:conditions”:{“k:{\”type\”:\”ContainersReady\”}”:{“.”:{},”f:lastProbeTime”:{},”f:lastTransitionTime”:{},”f:status”:{},”f:type”:{}},”k:{\”type\”:\”Initialized\”}”:{“.”:{},”f:lastProbeTime”:{},”f:lastTransitionTime”:{},”f:status”:{},”f:type”:{}},”k:{\”type\”:\”Ready\”}”:{“.”:{},”f:lastProbeTime”:{},”f:lastTransitionTime”:{},”f:status”:{},”f:type”:{}}},”f:containerStatuses”:{},”f:hostIP”:{},”f:phase”:{},”f:podIP”:{},”f:podIPs”:{“.”:{},”k:{\”ip\”:\”172.17.0.6\”}”:{“.”:{},”f:ip”:{}}},”f:startTime”:{}}}}]},”spec”:{“volumes”:[{“name”:”default-token-lplps”,”secret”:{“secretName”:”default-token-lplps”,”defaultMode”:420}}],”containers”:[{“name”:”nginx123″,”image”:”nginx”,”resources”:{},”volumeMounts”:[{“name”:”default-token-lplps”,”readOnly”:true,”mountPath”:”/var/run/secrets/kubernetes.io/serviceaccount”}],”terminationMessagePath”:”/dev/termination-log”,”terminationMessagePolicy”:”File”,”imagePullPolicy”:”Always”}],”restartPolicy”:”Always”,”terminationGracePeriodSeconds”:30,”dnsPolicy”:”ClusterFirst”,”serviceAccountName”:”default”,”serviceAccount”:”default”,”nodeName”:”ip-172-31-6-135″,”securityContext”:{},”schedulerName”:”default-scheduler”,”tolerations”:[{“key”:”node.kubernetes.io/not-ready”,”operator”:”Exists”,”effect”:”NoExecute”,”tolerationSeconds”:300},{“key”:”node.kubernetes.io/unreachable”,”operator”:”Exists”,”effect”:”NoExecute”,”tolerationSeconds”:300}],”priority”:0,”enableServiceLinks”:true,”preemptionPolicy”:”PreemptLowerPriority”},”status”:{“phase”:”Running”,”conditions”:[{“type”:”Initialized”,”status”:”True”,”lastProbeTime”:null,”lastTransitionTime”:”2020-09-30T12:44:50Z”},{“type”:”Ready”,”status”:”True”,”lastProbeTime”:null,”lastTransitionTime”:”2020-09-30T12:45:09Z”},{“type”:”ContainersReady”,”status”:”True”,”lastProbeTime”:null,”lastTransitionTime”:”2020-09-30T12:45:09Z”},{“type”:”PodScheduled”,”status”:”True”,”lastProbeTime”:null,”lastTransitionTime”:”2020-09-30T12:44:50Z”}],”hostIP”:”172.31.6.135″,”podIP”:”172.17.0.6″,”podIPs”:[{“ip”:”172.17.0.6″}],”startTime”:”2020-09-30T12:44:50Z”,”containerStatuses”:[{“name”:”nginx123″,”state”:{“running”:{“startedAt”:”2020-09-30T12:45:08Z”}},”lastState”:{},”ready”:true,”restartCount”:0,”image”:”nginx:latest”,”imageID”:”docker-pullable://nginx@sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0″,”containerID”:”docker://a0e4897ccc06b8dcfde363f87de5f131076c9c8005c5ef3f728c300f371ccda8″,”started”:true}],”qosClass”:”BestEffort”}}’, but found events.
    Events:
    Type Reason Age From Message
    —- —— —- —- ——-
    Normal Scheduled 1m default-scheduler Successfully assigned default/nginx123-kbhjl to ip-172-31-6-135
    Normal Pulling 48s kubelet, ip-172-31-6-135 Pulling image “nginx”
    Normal Pulled 45s kubelet, ip-172-31-6-135 Successfully pulled image “nginx” in 3.576630161s
    Normal Created 44s kubelet, ip-172-31-6-135 Created container nginx123
    Normal Started 44s kubelet, ip-172-31-6-135 Started container nginx123

  17. Your trick of not setting a hypervisor saved my work. Thank you. Setting it to Docker was blocking the ports for the browser.

  18. Hey! You have a little error in that you run an ephemeral pod and then want to expose a deployment, where you never created a deployment.

    You would need to switch your `kubectl run` command to:
    kubectl create deployment hello-minikube –image=gcr.io/google_containers/echoserver:1.4 –port=8080

  19. Hi,
    AM able to access the node port url using curl http://19.168.10.3:30812, But i try using the same url in default browser its getting connection timeout page error, i have tried even with ec2 public ip, but still issue reamins. could you please assist

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.