Build a vm based on Lima for the development of OSM - flomesh-io/osm GitHub Wiki

Prerequisites

Install lima

brew install lima

git clone https://github.com/lima-vm/vde_vmnet.git
cd vde_vmnet
brew install autoconf automake
sudo make PREFIX=/opt/vde install
cd ..
sudo rm -rf vde_vmnet

limactl sudoers | sudo tee /private/etc/sudoers.d/lima

Embedded Template

tee ~/ubuntu.yaml <<-'EOF'
# This example requires Lima v0.7.0 or later.

# ===================================================================== #
# BASIC CONFIGURATION
# ===================================================================== #

# Arch: "default", "x86_64", "aarch64".
# "default" corresponds to the host architecture.
arch: "default"

# An image must support systemd and cloud-init.
# Ubuntu and Fedora are known to work.
# Image is set to focal (20.04 LTS) for long-term stability
# Default: none (must be specified)
images:
  # Try to use a local image first.
  - location: "~/Downloads/ubuntu-20.04-server-cloudimg-amd64.img"
    arch: "x86_64"
  - location: "~/Downloads/ubuntu-20.04-server-cloudimg-arm64.img"
    arch: "aarch64"

  # Download the file from the internet when the local file is missing.
  # Hint: run `limactl prune` to invalidate the "current" cache
  - location: "https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img"
    arch: "x86_64"
  - location: "https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-arm64.img"
    arch: "aarch64"

# CPUs: if you see performance issues, try limiting cpus to 1.
# Default: 4
cpus: 4

# Memory size
# Default: "4GiB"
memory: "8GiB"

# Disk size
# Default: "100GiB"
disk: "80GiB"

# Expose host directories to the guest, the mount point might be accessible from all UIDs in the guest
# Default: none
mounts:
  - location: "~"
    # CAUTION: `writable` SHOULD be false for the home directory.
    # Setting `writable` to true is possible, but untested and dangerous.
    writable: false
  - location: "/tmp/lima"
    writable: true

ssh:
  # A localhost port of the host. Forwarded to port 22 of the guest.
  # Default: 0 (automatically assigned to a free port)
  localPort: 0
  # Load ~/.ssh/*.pub in addition to $LIMA_HOME/_config/user.pub .
  # This option is useful when you want to use other SSH-based
  # applications such as rsync with the Lima instance.
  # If you have an insecure key under ~/.ssh, do not use this option.
  # Default: true
  loadDotSSHPubKeys: true
  # Forward ssh agent into the instance.
  # Default: false
  forwardAgent: false

# containerd is managed by k3s, not by Lima, so the values are set to false here.
containerd:
  system: false
  user: false

networks:
  # Lima can manage daemons for networks defined in $LIMA_HOME/_config/networks.yaml
  # automatically. Both vde_switch and vde_vmnet binaries must be installed into
  # secure locations only alterable by the "root" user.
  # https://github.com/lima-vm/lima/blob/dcda59c5fde06a5231110059fe5628a1ad624fe9/docs/network.md
  - lima: bridged
EOF

Install OSM VM

Install lima vm

limactl start --name osm ubuntu.yaml

limactl shell osm

sudo ip r delete 0.0.0.0/0 via 192.168.5.2

sudo apt update
sudo apt install -y net-tools build-essential

#fix routes and ip
sudo tee /lib/systemd/system/rc-local.service <<-'EOF'
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

[Install]
WantedBy=multi-user.target
Alias=rc-local.service
EOF

#Replace 192.168.11.61 with your IP address
sudo tee /etc/rc.local <<-'EOF'
#!/bin/bash
sudo route del default gw 192.168.5.2
sudo ip addr add 192.168.11.61/24 dev lima0
exit 0
EOF

sudo chmod +x /etc/rc.local
sudo systemctl daemon-reload
sudo systemctl enable rc-local.service
sudo systemctl start rc-local.service

#Adjust time zone
sudo tzselect
4
10
1
1

sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

timedatectl

sudo hostnamectl set-hostname osm

#Replace 192.168.11.61 with your IP address
sudo sed -i '/127.0.0./a\192.168.11.61 osm' /etc/hosts

sudo systemctl stop ufw
sudo systemctl disable ufw

sudo systemctl stop swap.target
sudo systemctl disable swap.target

exit

limactl stop osm
limactl start osm
limactl shell osm

Install Docker

sudo apt -y update
sudo apt -y remove docker docker-engine docker.io containerd runc

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt -y update
sudo apt -y install ca-certificates curl gnupg lsb-release
sudo apt -y install docker-ce docker-ce-cli containerd.io

sudo apt-cache madison docker-ce

Set up user groups

sudo groupadd docker
sudo gpasswd -a $USER docker
sudo systemctl restart docker
sudo newgrp docker

Prepare the basic environment

#Turn off swap
sudo swapoff -a  
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab
cat /etc/fstab

sudo tee /etc/modprobe.d/nf_conntrack.conf <<-'EOF'
options nf_conntrack hashsize=16384
EOF

#sudo sed -i '$anet.netfilter.nf_conntrack_max = 131072' /etc/sysctl.conf

#Iptables allowed bridge flow check
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sudo sysctl --system

Adjust apt source

sudo apt -y update && sudo apt install -y apt-transport-https

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - 

sudo tee /etc/apt/sources.list.d/kubernetes.list <<-'EOF'
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

sudo apt -y update

Install k8s tools

sudo apt install -y kubelet=1.23.4-00 kubeadm=1.23.4-00 kubectl=1.23.4-00

sudo curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-arm64
sudo chmod a+x ./kind
sudo cp ./kind /usr/local/sbin
sudo rm -rf ./kind

sudo snap install helm --classic

Install GOLANG

sudo apt install -y build-essential

cat >> ~/.bashrc <<EOF
export GOROOT=/golang/build/1.17.8/goroot
export GOPATH=/opt/go
export PATH=\$GOROOT/bin:\$PATH
EOF

source ~/.bashrc

sudo tee Makefile <<-'EOF'
GO_REPO ?= /golang
BUILDDIR ?= $(GO_REPO)/build
OUTDIR ?= $(CURDIR)/out
RELEASEDIR ?= $(CURDIR)/release
SBINDIR ?= usr/sbin/
ETCDIR ?= etc/
DESTDIR ?= /

GO_ARCH_MAP_x86 := 386
GO_ARCH_MAP_x86_64 := amd64
GO_ARCH_MAP_arm := arm
GO_ARCH_MAP_arm64 := arm64
GO_ARCH_MAP_aarch64 := arm64
GO_ARCH_MAP_mips := mipsx
GO_ARCH_MAP_mips64 := mips64x

#export GOPROXY := https://goproxy.cn
export GOOS := linux
export CGO_ENABLED := 1

default: GolangInstall

GOBUILDARCH := $(GO_ARCH_MAP_$(shell uname -m))
GOBUILDOS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
GOBUILDVERSION := 1.17.8
GOBUILDTARBALL := https://dl.google.com/go/go$(GOBUILDVERSION).$(GOBUILDOS)-$(GOBUILDARCH).tar.gz
GOBUILDVERSION_NEEDED := go version go$(GOBUILDVERSION) $(GOBUILDOS)/$(GOBUILDARCH)
export GOROOT := $(BUILDDIR)/$(GOBUILDVERSION)/goroot
export GOPATH := $(BUILDDIR)/$(GOBUILDVERSION)/gopath
export PATH := $(GOROOT)/bin:$(PATH)
GOBUILDVERSION_CURRENT := $(shell $(GOROOT)/bin/go version 2>/dev/null)
ifneq ($(GOBUILDVERSION_NEEDED),$(GOBUILDVERSION_CURRENT))
$(shell rm -f $(GOROOT)/bin/go)
endif
$(GOROOT)/bin/go:
\trm -rf "$(GOROOT)"
\tmkdir -p "$(GOROOT)"
\tcurl "$(GOBUILDTARBALL)" | tar -C "$(GOROOT)" --strip-components=1 -xzf - || { rm -rf "$(GOROOT)"; exit 1; }

GolangInstall: $(GOROOT)/bin/go
\tgo env -w GOPROXY=https://goproxy.cn
\tgo env -w GOSUMDB=sum.golang.google.cn
\tgo env -w GO111MODULE=on
\tgo env
EOF

sudo sed -i 's/\\t/\t/g' Makefile

sudo make GolangInstall

Enjoy it!