Minishift notes

Background: attempting to allow external hosts on the same network as the KVM host on which minishift VM is running to be able to access the minishift web UI and optionally via SSH. In this example, is the IP assigned to minishift after starting it, and is the IP range of the network on which the KVM host is running.

On my KVM Linux host, installing libvirtd had created the virbr0 bridge. Subsequently setting up minishift setup a second bridge named virbr1 to which the vNIC assigned to the minishift VM is slaved. Interestingly enough, the minishift VM is then given 2x interfaces with one attached to each bridge (virbr0 and virbr1). In the minishift VM, the default route is assigned to the interface (e.g., eth0) attached to the first bridge (virbr0) with IP, even though when minishift starts, it displays a URL with the IP address ( assigned to the interface connected to the second bridge as the way to access the minishift web UI. This works fine as long as you are attempting to access the URL from the KVM host, but won’t work without some extra steps if you want to access the minishift UI from an external host.
wlp5s0 is the “public” interface on my KVM host.

Setup and start minishift (equivalent to RedHat CDK if you have the right subscription):
itababa@itamint:~$ sudo apt update -y
itababa@itamint:~$ sudo apt install qemu-kvm qemu-system qemu-utils python3 python3-pip libvirt-clients libvirt-daemon-system bridge-utils virtinst libvirt-daemon virt-manager cpu-checker -y
itababa@itamint:~$ usermod -aG libvirt $(whoami)
itababa@itamint:~$ newgrp libvirt
itababa@itamint:~$ sudo systemctl enable libvirtd
itababa@itamint:~$ sudo systemctl start libvirtd
itababa@itamint:~$ sudo virsh net-start default
itababa@itamint:~$ sudo virsh net-autostart default
itababa@itamint:~$ sudo curl -L -o /usr/local/bin/docker-machine-driver-kvm
itababa@itamint:~$ sudo chmod +x /usr/local/bin/docker-machine-driver-kvm
itababa@itamint:~$ curl -L -o minishift-1.34.3-linux-amd64.tgz
itababa@itamint:~$ tar xf minishift-1.34.3-linux-amd64.tgz
itababa@itamint:~$ sudo cp minishift-1.34.3-linux-amd64/minishift /usr/local/bin/
itababa@itamint:~$ minishift start

NOTE: the “minishift start” command will display the minishift web UI at the end of its run.

Settings needed on the KVM host:
- configure the KVM host to redirect connections to it on 8443/tcp to the minishift host ( Optionally redirect 2222/tcp to the minishift host as well:
iptables -F
iptables -F -t nat
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/conf/virbr0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/virbr1/proxy_arp    (required so that the host can answer when the minishift VM tries to find the ARP of external hosts, otherwise the minshift will not respond to any connection attempts)
iptables -t nat -A POSTROUTING -o wlp5s0 -j MASQUERADE
iptables -t nat -A PREROUTING -i wlp5s0 -p tcp --dport 8443 -j DNAT --to-destination
iptables -t nat -A PREROUTING -i wlp5s0 -p tcp --dport 2222 -j DNAT --to-destination
Settings needed on the minishift VM after it is running (execute "minishift ssh" to SSH into the minishift VM):
- NOTE: this whole section can be skipped if you choose to "DNAT" port 8443/tcp to the IP address on the virbr0 vNIC on the KVM host:
itababa@itamint:~$ minishift ssh
[docker@minishift ~]$
 sudo su -
[root@minishift ~]# ip a     (find the interface with the 192.168.42.x IP e.g., eth1)
[root@minishift ~]# ip route add via dev eth1 (this is because the default route uses the NIC with 192.168.122.x IP and used by minishift to access the Internet)
[root@minishift ~]# ip route show
default via dev eth0 proto dhcp metric 100 dev docker0 proto kernel scope link src dev eth1 scope link dev eth1 proto kernel scope link src metric 101 dev eth0 proto kernel scope link src metric 100
[root@minishift ~]#
NOTE: if you restart the minishift VM, you have to SSH into it again and re-add the route to the network.

Settings needed on the external host:
In this example, I want to access the minishift web UI from a Windows system on my home network. You need to add a route to the minishift IP address using the KVM host IP as the gateway (using the command line):
C:\Windows\system32>route add MASK

Launch a browser on the external host and go directly to

NOTE: if you attempt to login via , you will encounter this error/bug after entering your credentials (e.g., admin/admin)
Error: “Error. Invalid request. Client state could not be verified. Return to the console.”
Bug: “”
Found the solution (use the /console/catalog URL):

after login with admin/admin credential

Other commands:
minishift delete –clear-cache (solution for error similar to: “Cannot start – error starting the VM: error getting the state for host: machine dies not exist-docker” when attempting to start minishift)
sudo virsh stop minishift; sudo undefine minishift; (might be needed if the “delete” command does not fix the issue)
sudo arp -a (on the KVM host to see the IPs of the minishift VM or SSH into the minishift VM)

– To restart the minishift VM (from the KVM host):
itababa@itamint:~$ minishift stop
itababa@itamint:~$ minishift start


The purpose of this guide is to run an Oracle Linux container on a Windows 10 system using Windows Subsystem for Linux v2.
(This may be an alternative to using a full-blown hypervisor type 2 such as Oracle VirtualBox or VMWare Player/Workstation.)

NOTE: Using container images from the official Oracle repository
NOTE: You will need to be running Windows 10 build 18917 or higher to use WSL 2. If you are on an earlier Windows 10 build, launch Windows Update Settings, you should be able to update it to the latest available version.
NOTE: there are docker images for 7/8/9 and slim versions of 7/8/9 (minimal environment with minimal number of packages) from the repository.

1. Prepare an Oracle Linux 8.x container and export it to a single TAR file using an existing Linux system as the work platform:

[root@wip]# yum install -y docker
[root@wip]# usermod -aG docker root
[root@wip]# newgrp docker
[root@wip]# id
uid=0(root) gid=992(docker) groups=992(docker),0(root)
[root@wip]# systemctl start docker.service
[root@wip]# systemctl enable docker.service

– Create the Dockerfile to use to build the container:
[root@wip]# vi Dockerfile
[root@wip]# cat Dockerfile

CMD [“/bin/bash”]

– Build the docker container:
[root@wip]# docker build -t .
Sending build context to Docker daemon 23.04kB
Step 1/2 : FROM
8: Pulling from oracle/oraclelinux
4c770e098606: Pull complete
Digest: sha256:07a995ecaf9db1ce613648a08facc162de69f26c39712f1acc93629c2e6c4e73
Status: Downloaded newer image for
—> b0045ea7bbde
Step 2/2 : CMD [“/bin/bash”]
—> Running in 168cb6d08c9e
Removing intermediate container 168cb6d08c9e
—> 53be01d92e18
Successfully built 53be01d92e18
Successfully tagged

– Test the container:
[root@wip]# docker run -it 53be01d92e18
[root@ec6e4b0f7c3b /]# cat /etc/oracle-release
Oracle Linux Server release 8.7
[root@ec6e4b0f7c3b /]# exit

– List all containers (note the container id ec6e4b0f7c3b associated with the image id 53be01d92e18 from the earlier build command output):

[root@wip]# docker ps -a
CONTAINER ID    IMAGE          COMMAND       CREATED              STATUS                         PORTS     NAMES
ec6e4b0f7c3b    53be01d92e18   "/bin/bash"   About a minute ago   Exited (0) 23 seconds ago                reverent_ellis

– Export the container into a single TAR file (222M size):
[root@wip]# docker export –output=”oellinux8.tar” aa565b335857

– Optionally zip the file (85MB zipped) to reduce the amount of data transferred when copying it to the Windows 10 system:
[root@wip]# gzip oellinux8.tar

– Transfer the container output TAR file to the Windows 10 system. In this case I will be using pscp to pull the file down into the Windows 10 system using a user other than root, so I copied the file to /tmp which is accessible to all users and changed the permission on the file so other users can read it:
[root@wip]# cp oellinux8.tar.gz /tmp/
[root@wip]# chmod 666 /tmp/oellinux8.tar.gz

2. SETUP WSL2 on Windows 10:
– Using elavated/admin powershell, run: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
– Using elavated/admin command or powershell, run: dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
– Reboot the Windows 10 system (WSL2 upgrade fails without a reboot after installing WSL)
– Upgrade WSL to WSL2 via the installer

3. Pull down the container file to the local Windows 10 system with WSL2 installed:
C:\Users\user1> md wsl2\oellinux8
C:\Users\user1\wsl2\oellinux8>cd wsl2\oellinux8
C:\Users\user1\wsl2\oellinux8>pscp -i ….\Downloads\centos8.ppk ec2-user@my-linux-wip-server:/tmp/oellinux8.tar.gz .

4. Unzip the container file oellinux8.tar.gz (if you compressed the original TAR file):

5. Import the TAR file into WSL (syntax: wsl –import [DISTRO NAME] [STORAGE LOCATION] [FILE NAME]):
C:\Users\user1\wsl2\oellinux8>wsl –import oellinux8 “C:\Users\user1\wsl2\oellinux8” oellinux8.tar

NOTE: the import step extracts the TAR file into rootfs and temp directories:
12/07/2022 11:47 PM 232,101,888 oellinux8.tar
12/07/2022 11:59 PM 84,593,746 oellinux8.tar.gz
12/08/2022 12:25 AM rootfs
12/08/2022 12:46 AM temp

6. Start the new WSL container (which ends at the running Linux prompt):
C:\Users\user1\wsl2\oellinux8> wsl -d oellinux8
[root@mywinpc wsl2]#

7. Execute some commands in the running container:
[root@mywinpc wsl2]# ping
PING ( 56(84) bytes of data.
64 bytes from ( icmp_seq=1 ttl=59 time=4.64 ms
64 bytes from ( icmp_seq=2 ttl=59 time=5.59 ms
— ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 4.639/5.116/5.594/0.482 ms
[root@mywinpc wsl2]#
[root@mywinpc wsl2]# yum repolist
repo id repo name
ol8_appstream Oracle Linux 8 Application Stream (x86_64)
ol8_baseos_latest Oracle Linux 8 BaseOS Latest (x86_64)
[root@mywinpc user1]#
[root@mywinpc user1]# yum provides gdisk
Oracle Linux 8 BaseOS Latest (x86_64) 805 kB/s | 53 MB 01:07
Oracle Linux 8 Application Stream (x86_64) 926 kB/s | 42 MB 00:45
Last metadata expiration check: 0:00:14 ago on Thu 08 Dec 2022 12:29:18 AM MST.
gdisk-1.0.3-6.el8.x86_64 : An fdisk-like partitioning tool for GPT disks
Repo : ol8_baseos_latest
Matched from:
Provide : gdisk = 1.0.3-6.el8

gdisk-1.0.3-9.el8.x86_64 : An fdisk-like partitioning tool for GPT disks
Repo : ol8_baseos_latest
Matched from:
Provide : gdisk = 1.0.3-9.el8

gdisk-1.0.3-11.el8.x86_64 : An fdisk-like partitioning tool for GPT disks
Repo : ol8_baseos_latest
Matched from:
Provide : gdisk = 1.0.3-11.el8

[root@mywinpc user1]#

8. Optionally ENTER exit command to quit the running Linux container:
[root@mywinpc user1]# exit

—————— END OF PROCEDURE ———————————

The following setup is to allow remote connectivity to the container

- Start a  temporary container (e.g., using the image id) to copy SSHD config files from it:
[root@ip-172-31-6-136 ~]# mkdir /oel8_etc_ssh
[root@ip-172-31-6-136 ~]# docker run --name wip -it -v /oel8_etc_ssh:/tmp/mpoint 18a22840eed9
[root@609b0ec071bb /]#
[root@609b0ec071bb /]# cp -a /etc/ssh /tmp/mpoint/
[root@609b0ec071bb /]# exit

- Delete the temporary container:
[root@ip-172-31-6-136 ~]# docker rm wip

- Start the "production" container with /oel8_etc_ssh/ssh on the host mounted to /etc/ssh in the container (running headless or detached mode with "-d"):
  NOTE: mapped port 2222/tcp on the host to the SSH port in the container. This is handy to access the container remotely from outside the host.
[root@ip-172-31-6-136 ~]# docker run --name oel87c -it -p 2222:22 -v /oel8_etc_ssh/ssh:/etc/ssh -d 18a22840eed9

- Attach to the console of the container:
[root@ip-172-31-6-136 ~]# docker attach d99789174764

- Create the ssh host keys (one-time task since they are stored persistently on the underlying host):
[root@d99789174764 /]# ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''
[root@d99789174764 /]# ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''
[root@d99789174764 /]# ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''

- Create the system log file (otherwise SSHD will be unable to authenticate login attempts):
[root@d99789174764 /]# touch /var/log/messages

- Start SSHD service:
[root@d99789174764 /]# /usr/sbin/sshd &

- Add a user to the container to login remotely:
[root@d99789174764 /]# useradd user1
[root@d99789174764 /]# passwd user1

- Optionally install/configure visudo to allow "user1" switch to the root user:
[root@d99789174764 /]# yum install -y sudo
[root@d99789174764 /]# visudo
[root@d99789174764 /]# grep user1 /etc/sudoers
user1   ALL=(ALL)       NOPASSWD: ALL
[root@d99789174764 /]#

- Detach from the container and keep it running: Press Ctrl-P, followed by Ctrl-Q,
  NOTE: if you mistakenly typed exit in the container which causes it to stop, start it again with "docker start <container-id>" on the host

- It is now possible to access the container remotely from outside the host. SSH to the container using the hosts' IP address on port 2222/tcp e.g.
  From a Windows/Linux system (you can also use Putty): ssh user@<host-ip> -p 2222

------------------- END -------------------

- Sample command to retrieve the IP of the container from the underlying host. [root@ip-172-31-6-136 ~]# docker ps    (command to get the container id)
[root@ip-172-31-6-136 ~]# docker container inspect -f '{{ .NetworkSettings.IPAddress }}' d99789174764

- Note: mounting the whole /etc and /var/log to directories on the underlying host should help to "persist" all the relevant configuration of the container.