<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>flannel. qemu &#8211; richliu&#039;s blog</title>
	<atom:link href="https://blog.richliu.com/tag/flannel-qemu/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.richliu.com</link>
	<description>Linux, 工作, 生活, 家人</description>
	<lastBuildDate>Mon, 21 Mar 2022 08:01:33 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>
	<item>
		<title>Install Kubernetes on ARM64 Ubuntu 18.04 (with QEMU)</title>
		<link>https://blog.richliu.com/2019/09/25/4160/install-kubernetes-on-arm64-ubuntu-18-04/</link>
					<comments>https://blog.richliu.com/2019/09/25/4160/install-kubernetes-on-arm64-ubuntu-18-04/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Wed, 25 Sep 2019 03:39:36 +0000</pubDate>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[18.04]]></category>
		<category><![CDATA[aarch64]]></category>
		<category><![CDATA[flannel. qemu]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[weave]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=4160</guid>

					<description><![CDATA[<p>Install Kubernetes on Ubuntu 18.04 is very easy now, bu [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2019/09/25/4160/install-kubernetes-on-arm64-ubuntu-18-04/">Install Kubernetes on ARM64 Ubuntu 18.04 (with QEMU)</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Install Kubernetes on Ubuntu 18.04 is very easy now, but only for x86 platform. If on ARM64 environment, it might have some other problem. <br />Some old article mentioned a lot of information but software version is too old for deploy a new version software. <br /><br />After a lot of time to have research, here is instruction for how to install Kubernetes on ARM64 Ubuntu 18.04</p>



<span id="more-4160"></span>



<h2 class="wp-block-heading">Environment</h2>



<p>Hardware : Ampere eMag Server with 128G RAM and 1T storage<br />Kubernetes master and nodes are running in QEMU image, so, we prepared three QEMU  ARM64 ubuntu 18.04 images for kubernetes running. It also can use two VM to run this demo. </p>



<h2 class="wp-block-heading">Prepare QEMU Image</h2>



<p>It can download Ubuntu bionic cloud image from Taiwan mirror site</p>



<pre class="wp-block-preformatted">wget http://ftp.yzu.edu.tw/Linux/ubuntu-cloud-images/bionic/current/bionic-server-cloudimg-arm64.img </pre>



<p>or international mirror site </p>



<pre class="wp-block-preformatted">https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-arm64.img</pre>



<h4 class="wp-block-heading">Install Necessary Package  </h4>



<p>Run following command to install necessary packages . </p>



<pre class="wp-block-preformatted">apt install -y qemu-system-arm bridge-utils cloud-image-utils git qemu-efi</pre>



<h4 class="wp-block-heading">Increase QEMU image size</h4>



<pre class="wp-block-preformatted">qemu-img resize bionic-server-cloudimg-arm64.img +200G</pre>



<p>Create UEFI bios and nvram for qemu image boot. </p>



<pre class="wp-block-preformatted">dd if=/dev/zero of=flash0.img bs=1M count=64
dd if=/usr/share/qemu-efi/QEMU_EFI.fd of=flash0.img conv=notrunc
dd if=/dev/zero of=flash1.img bs=1M count=64</pre>



<p>Copy Image to three spare images </p>



<pre class="wp-block-preformatted">cp flash0.img flash0-1.img
cp flash0.img flash0-2.img 
cp flash0.img flash0-3.img 
cp flash1.img flash1-1.img
cp flash1.img flash1-2.img
cp flash1.img flash1-3.img
cp  bionic-server-cloudimg-arm64.img   bionic-server-cloudimg-arm64-1.img 
cp  bionic-server-cloudimg-arm64.img   bionic-server-cloudimg-arm64-2.img 
cp  bionic-server-cloudimg-arm64.img   bionic-server-cloudimg-arm64-3.img </pre>



<h2 class="wp-block-heading"> Set up bridge and network devices </h2>



<p>

We already install bridge-utils before, now, it should configure bridge devices.

</p>



<pre class="wp-block-preformatted"> mkdir -p /etc/qemu ; echo "allow br0" > /etc/qemu/bridge.conf </pre>



<p> Because there is only one network interface on machine, we should use this interface as bridge device, save text below (name nic-br.sh or what you like) and modify it to fit your environment. <br /></p>



<pre class="wp-block-preformatted">ORIGNIC=enP6p1s0
ip addr flush $ORIGINIC
brctl addbr br0
brctl addif br0 $ORIGINIC
ifconfig br0 up
ifconfig br0 192.168.110.1 netmask 255.255.0.0
route add default gw 192.168.1.1
echo nameserver 8.8.8.8 &gt;&gt; /etc/resolv.conf </pre>



<h2 class="wp-block-heading">Configure Hugepage On Host Site (Option)</h2>



<p>Due to previous research on dpdk runs on ARM64 server, so, configure hugepages here. But not necessary for run k8s environment. <br />You can ignore this part </p>



<h4 class="wp-block-heading"> Configure Line Kernel boot command </h4>



<p> It needs to reserve hugepages memory space for Linux kernel, it reserves 32 pages and each pages 1GB, total 32GB. Please modify /etc/default/grub , and add hugepagesz=1GB hugepages=32 to GRUB_CMDLINE_LINUX, ex: </p>



<pre class="wp-block-preformatted">GRUB_CMDLINE_LINUX="console=tty0 hugepagesz=1GB hugepages=32"</pre>



<p> then run foloowing command to update grub.cfg </p>



<pre class="wp-block-preformatted"> update-grub </pre>



<h4 class="wp-block-heading"> Mount hugetlbfs by default </h4>



<p>

If wants to use hugepage, it needs to mount hugetlbfs somewhere, we can create a directory, ex: /mnt/hugepages and mount hugetblsfs there by default.

</p>



<pre class="wp-block-preformatted">mkdir -p /mnt/hugepages 
echo "nodev   /mnt/hugepages                  hugetlbfs       defaults,pagesize=1G    0 0 none" &gt;&gt; /etc/fstab </pre>



<p>Now, please reboot to make huagpage works. </p>



<h2 class="wp-block-heading">Running QEMU</h2>



<p>Following is QEMU script, save it (ex: named run-qemu.sh). It can be more simplification, but this script would be more understand what different. </p>



<pre class="wp-block-preformatted">IMAGE1=bionic-server-cloudimg-arm64-1.img
sudo qemu-system-aarch64 -name vm1 \
         -machine virt,gic_version=3,accel=kvm,usb=off \
         -cpu host -m 8192 \
         -uuid d0000000-1111-1111-1111-11111aaaaaaa \
         -smp 12,sockets=1,cores=12,threads=1 \
         -nographic -nodefaults \
         -pflash flash0-1.img -pflash flash1-1.img \
         -drive file=$IMAGE1,if=none,id=disk1 \
         -device virtio-blk-device,scsi=off,drive=disk1,id=virtio-disk1,bootindex=1 \
         -netdev tap,id=net0,ifname=tap0 \
         -device virtio-net-device,netdev=net0,mac=52:54:00:11:11:11 \
         -mem-path /mnt/hugepages \
         -serial telnet::9001,server,nowait &gt; guest_log-1.txt 2&gt;&gt; guest_log-1.txt &amp;
IMAGE2=bionic-server-cloudimg-arm64-2.img
sudo qemu-system-aarch64 -name vm2 \
         -machine virt,gic_version=3,accel=kvm,usb=off \
         -cpu host -m 8192 \
         -uuid d0000000-2222-2222-2222-22222bbbbbbb \
         -smp 12,sockets=1,cores=12,threads=1 \
         -nographic -nodefaults \
         -pflash flash0-2.img -pflash flash1-2.img \
         -drive file=$IMAGE2,if=none,id=disk2 \
         -device virtio-blk-device,scsi=off,drive=disk2,id=virtio-disk1,bootindex=1 \
         -netdev tap,id=net2,ifname=tap1 \
         -device virtio-net-device,netdev=net2,mac=52:54:00:22:22:22 \
         -mem-path /mnt/hugepages \
         -serial telnet::9002,server,nowait &gt; guest_log-2.txt 2&gt;&gt; guest_log-2.txt &amp;
IMAGE3=bionic-server-cloudimg-arm64-3.img
sudo qemu-system-aarch64 -name vm3 \
         -machine virt,gic_version=3,accel=kvm,usb=off \
         -cpu host -m 8192 \
         -uuid d0000000-3333-3333-3333-33333ccccccc \
         -smp 12,sockets=1,cores=12,threads=1 \
         -nographic -nodefaults \
         -pflash flash0-3.img -pflash flash1-3.img \
         -drive file=$IMAGE3,if=none,id=disk3 \
         -device virtio-blk-device,scsi=off,drive=disk3,id=virtio-disk1,bootindex=1 \
         -netdev tap,id=net3,ifname=tap2 \
         -device virtio-net-device,netdev=net3,mac=52:54:00:33:33:33 \
         -mem-path /mnt/hugepages \
         -serial telnet::9003,server,nowait &gt; guest_log-3.txt 2&gt;&gt; guest_log-3.txt &amp;
sleep 5
brctl addif br0 tap0
brctl addif br0 tap1
brctl addif br0 tap2</pre>



<p>There are some parameters need to understand in QEMU script. <br /><br />-uuid d0000000-1111-1111-1111-11111aaaaaaa \<br /><br />this will assign a unique uuid for each VM, k8s needs different VM run with different uuid and MAC address. <br />It also can use command &#8220;uuidgen&#8221; to generate different uuid for each VM, but here just for debug so assign a &#8220;easy to read&#8221; uuid. <br /><br />-device virtio-net-device,netdev=net3,mac=52:54:00:33:33:33 \<br /><br />Assign a special mac address for VM, because for k8s internal communication, use the same mac address will cause problem, please configure different address before run qemu script. It not easy to modify it after first boot (with cloud image)<br /><br />* Notice, first number for mac address cannot be odd , it would cause problem. <br /><br />-mem-path /mnt/hugepages \<br /><br />Tell VM to use hugepage, if were not configure host with hugepage, please remove this line. </p>



<p>Now,  please run scripts </p>



<pre class="wp-block-preformatted">bash nic-br.sh
bash run-qemu.sh </pre>



<p>Now, it can use telnet to connect each VM&#8217;s console </p>



<pre class="wp-block-preformatted">telnet localhost 9001<br /># or <br />telnet localhost 9002<br /># or <br />telnet localhost 9003</pre>



<p>After system booted/initialed, if you cannot login, please &#8220;killall qemu-system-aarch64&#8221; and follow this article <a href="https://blog.richliu.com/2017/08/31/2165/change-ubuntu-cloud-image-password">Change Ubuntu Cloud Image Password</a> to change all images&#8217;s password.  <br /><br />Somehow, for recent cloud image, it cannot modify password before run qemu script.</p>



<h2 class="wp-block-heading">Install Kubernetes </h2>



<p>There are a lot of article to talk about how to install on Ubuntu, I choice one for reference : <a href="https://vitux.com/install-and-deploy-kubernetes-on-ubuntu/" target="_blank" rel="noopener">Install and Deploy Kubernetes on Ubuntu 18.04 LTS</a><br /><br />Below will shortly note install command here. </p>



<h4 class="wp-block-heading">Install Docker and Kubeadm on every node </h4>



<pre class="wp-block-preformatted">sudo apt update 
sudo apt -y upgrade 

# install and enable docker
sudo apt -y install docker.io 
sudo systemctl enable docker 
sudo systemctl start docker 

# Install k8s
sudo apt -y install apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add 
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt update
sudo apt-get install kubeadm -y</pre>



<h4 class="wp-block-heading">Configure Network IP address (Optional)</h4>



<p> Update to you network environment, here we used fix ip address.<br /><br /> Add new record to /etc/hosts   </p>



<pre class="wp-block-preformatted">192.168.110.50     k8s-master
192.168.110.60     k8s-worker-node1
192.168.110.70     k8s-worker-node2</pre>



<p>Please modify /etc/netplan/50-cloud-init.yam, remove dhcp and add fix address. remember, each node has different IP.  Following is only for k8s-master. </p>



<pre class="wp-block-preformatted">network:
     ethernets:
         eth0:
<strong>             addresses: [192.168.110.50/16,]
             gateway4: 192.168.1.1
             nameservers:
                 addresses: [8.8.8.8,8.8.4.4]</strong>
             match:
                 macaddress: '52:54:00:11:11:11'
             set-name: eth0
     version: 2</pre>



<h4 class="wp-block-heading">Configure Host name </h4>



<p>Run following command on master node </p>



<pre class="wp-block-preformatted">sudo hostnamectl set-hostname  k8s-master</pre>



<p> Run following command on other nodes</p>



<pre class="wp-block-preformatted">sudo hostnamectl set-hostname   k8s-worker-node1 
sudo hostnamectl set-hostname   k8s-worker-node2</pre>



<h4 class="wp-block-heading">Disable swap (Option)</h4>



<p>if image is not from cloud image, default Linux enabled swap function, k8s doesn&#8217;t support it, please disable it manually on all nodes and remove swap mount in /etc/fstab. </p>



<pre class="wp-block-preformatted"> sudo swapoff -a </pre>



<h2 class="wp-block-heading">Configure Kubernetes</h2>



<p>Now, we can initial Kubernetes. Run following command</p>



<pre class="wp-block-preformatted"> sudo kubeadm init --pod-network-cidr=10.244.0.0/16 </pre>



<p>wait for few minutes, it will show some result like this </p>



<figure class="wp-block-image"><img fetchpriority="high" decoding="async" width="1024" height="749" src="https://blog.richliu.com/wp-content/uploads/2019/09/image-1024x749.png" alt="" class="wp-image-4172" srcset="https://blog.richliu.com/wp-content/uploads/2019/09/image-1024x749.png 1024w, https://blog.richliu.com/wp-content/uploads/2019/09/image-300x220.png 300w, https://blog.richliu.com/wp-content/uploads/2019/09/image-768x562.png 768w, https://blog.richliu.com/wp-content/uploads/2019/09/image.png 1398w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Run following command to assign current account has right to access k8s. </p>



<pre class="wp-block-preformatted">mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config</pre>



<p>Run this command on another node(k8s-worker-node1 and k8s-worker-node2).</p>



<pre class="wp-block-preformatted">sudo kubeadm join 192.168.110.50:6443 --token 46c1oj.i00vyfyn027pgew9 \
     --discovery-token-ca-cert-hash sha256:ed05198cc603ae009a862477bacef329a9e9a2bedc4a040bc4731e6d5cf4f48e</pre>



<figure class="wp-block-image"><img decoding="async" width="1024" height="737" src="https://blog.richliu.com/wp-content/uploads/2019/09/image-1-1024x737.png" alt="" class="wp-image-4174" srcset="https://blog.richliu.com/wp-content/uploads/2019/09/image-1-1024x737.png 1024w, https://blog.richliu.com/wp-content/uploads/2019/09/image-1-300x216.png 300w, https://blog.richliu.com/wp-content/uploads/2019/09/image-1-768x552.png 768w, https://blog.richliu.com/wp-content/uploads/2019/09/image-1.png 1204w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Run get nodes command, it will show current status, the master node status is NotReady, but don&#8217;t worry, it will become Ready after add pod and CNI (container networking interface) plugin. </p>



<pre class="wp-block-preformatted">ubuntu@k8s-master:~$ kubectl get nodes
 NAME         STATUS     ROLES    AGE     VERSION
 k8s-master   NotReady   master   3m42s   v1.16.0</pre>



<p>This action is very import on ARM64 k8s platform, in other document, they told you use flannel or some other document told you used old flannel. all of them not work for me. Please instead flannel with weave net. <br />(Ref <a rel="noreferrer noopener" aria-label="Weave Net for NetworkPolicy (opens in a new tab)" href="https://kubernetes.io/docs/tasks/administer-cluster/network-policy-provider/weave-network-policy/" target="_blank">Weave Net for NetworkPolicy</a> and <a rel="noreferrer noopener" aria-label="CoreDNS is not starting on Ubuntu 18.04.Bionic Beaver #980 (opens in a new tab)" href="https://github.com/kubernetes/kubeadm/issues/980" target="_blank">CoreDNS is not starting on Ubuntu 18.04.Bionic Beaver #980</a>)<br />Run following command to install weave net </p>



<pre class="wp-block-preformatted">kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"</pre>



<figure class="wp-block-image"><img decoding="async" width="1024" height="232" src="https://blog.richliu.com/wp-content/uploads/2019/09/image-2-1024x232.png" alt="" class="wp-image-4175" srcset="https://blog.richliu.com/wp-content/uploads/2019/09/image-2-1024x232.png 1024w, https://blog.richliu.com/wp-content/uploads/2019/09/image-2-300x68.png 300w, https://blog.richliu.com/wp-content/uploads/2019/09/image-2-768x174.png 768w, https://blog.richliu.com/wp-content/uploads/2019/09/image-2.png 1397w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p> Use the following command to view the status of the network:</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="330" src="https://blog.richliu.com/wp-content/uploads/2019/09/image-3-1024x330.png" alt="" class="wp-image-4176" srcset="https://blog.richliu.com/wp-content/uploads/2019/09/image-3-1024x330.png 1024w, https://blog.richliu.com/wp-content/uploads/2019/09/image-3-300x97.png 300w, https://blog.richliu.com/wp-content/uploads/2019/09/image-3-768x248.png 768w, https://blog.richliu.com/wp-content/uploads/2019/09/image-3-620x200.png 620w, https://blog.richliu.com/wp-content/uploads/2019/09/image-3.png 1398w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p> Get nodes again. </p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="142" src="https://blog.richliu.com/wp-content/uploads/2019/09/image-4-1024x142.png" alt="" class="wp-image-4177" srcset="https://blog.richliu.com/wp-content/uploads/2019/09/image-4-1024x142.png 1024w, https://blog.richliu.com/wp-content/uploads/2019/09/image-4-300x42.png 300w, https://blog.richliu.com/wp-content/uploads/2019/09/image-4-768x107.png 768w, https://blog.richliu.com/wp-content/uploads/2019/09/image-4.png 1395w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Great!! it works. </p>



<h2 class="wp-block-heading">MicroK8s</h2>



<p>If you think steps above are too complex and you would like to only run k8s on one machine, microk8s is a good friend for you, can run on ARM64 and very easy to use, just run command </p>



<p>sudo snap install microk8s</p>



<p>And just add a prefix &#8220;microk8s.&#8221; before k8s command, ex:</p>



<pre class="wp-block-preformatted">microk8s.kubectl get nodes</pre>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="854" height="133" src="https://blog.richliu.com/wp-content/uploads/2019/09/image-5.png" alt="" class="wp-image-4178" srcset="https://blog.richliu.com/wp-content/uploads/2019/09/image-5.png 854w, https://blog.richliu.com/wp-content/uploads/2019/09/image-5-300x47.png 300w, https://blog.richliu.com/wp-content/uploads/2019/09/image-5-768x120.png 768w" sizes="(max-width: 854px) 100vw, 854px" /></figure>



<p>See, it&#8217;s very easy to use. right?</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2019/09/25/4160/install-kubernetes-on-arm64-ubuntu-18-04/">Install Kubernetes on ARM64 Ubuntu 18.04 (with QEMU)</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2019/09/25/4160/install-kubernetes-on-arm64-ubuntu-18-04/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
