Skip to content

Instantly share code, notes, and snippets.

@MovGP0
Last active August 19, 2018 16:59
Show Gist options
  • Select an option

  • Save MovGP0/4bc11f2e2801364a2cb4d9e90db67c4b to your computer and use it in GitHub Desktop.

Select an option

Save MovGP0/4bc11f2e2801364a2cb4d9e90db67c4b to your computer and use it in GitHub Desktop.
Kubernetes on Rasperry Pi

Setting up Kubernetes (k8s) on Rasperry Pi

This manual is to set up Kubernetes an Rasperry Pi 2 and 3.

Sources used:

Terms

  • Master a server that manages nodes
  • Node a server that hosts pods
  • Pod one or more applications that are bundled together to solve a business case
  • Container contains a single application

Warranty

This manual is provided as-is with no warranty whatsoever. Use the information herein at your own risk.

# Find Raspberries on Network
# Note: This is currently very slow. Use a tool like "Angry IP Scanner" instead.
<#
.SYNOPSIS
Returns an array of IP Addresses based on a start and end address
.DESCRIPTION
Returns an array of IP Addresses based on a start and end address
.PARAMETER Start
Starting IP Address
.PARAMETER End
Ending IP Address
.PARAMETER Exclude
Exclude addresses with this final octet
Default excludes 0, 1, and 255
e.g. 5 excludes *.*.*.5
.EXAMPLE
New-IPRange -Start 192.168.1.5 -End 192.168.20.254
Create an array from 192.168.1.5 to 192.168.20.254, excluding *.*.*.[0,1,255] (default exclusion)
.NOTES
Modified version of the version used in the WFTools package.
Install-Module WFTools -Force -AllowClobber -Confirm:$false;
Import-Module WFTools;
.FUNCTIONALITY
Network
#>
function New-IpRange
{
param(
[Parameter(Mandatory = $true, Position = 0)]
[System.Net.IPAddress]$Start,
[Parameter(Mandatory = $true, Position = 1)]
[System.Net.IPAddress]$End,
[int[]]$Exclude = @( 0, 1, 255 )
)
process{
for($currentIP = $startIP.Address; $currentIP -le $endIp.Address; $currentIP++){
$IPBytes = ([System.Net.IPAddress]$currentIP).GetAddressBytes();
[Array]::Reverse($IPBytes);
if($Exclude -notcontains $IPBytes[3])
{
$IPToPing = [System.Net.IPAddress]$currentIP;
Write-Output $IPToPing;
}
}
}
}
function Ping-IpAddress
{
[cmdletbinding()]
param(
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
[System.Net.IPAddress]$Address
)
process {
$Timeout = 10;
$Ping = New-Object System.Net.NetworkInformation.Ping;
$Response = $Ping.Send($Address, $Timeout);
Write-Output $Response;
}
}
$startIP = [System.Net.IPAddress]"10.0.0.0";
$endIP = [System.Net.IPAddress]"10.0.0.255";
New-IpRange -Start $startIP -End $endIP | Ping-IpAddress | where ($_.Status -ne "TimedOut") | select -Property Address
###################################
# Create SSH Connection to Target #
###################################
Install-Module -Name Posh-SSH -Force -AllowClobber -Confirm:$false;
Import-Module Posh-SSH;
$user = "pi";
$password = ConvertTo-SecureString -String "raspberry" -AsPlainText -Force;
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user, $password;
$session = New-SSHSession -ComputerName 10.0.0.17 -Credential $cred -Force
################
# Set Hostname #
################
$hostname = "k8s-master-01";
Invoke-SSHCommand -SSHSession $session -Command "echo '$($hostname)' | sudo tee /etc/hostname ";
Invoke-SSHCommand -SSHSession $session -Command "sudo reboot";
###############################
# Set Static IP Configuration #
###############################
#################
# WIFI SETTINGS #
#################
# in /etc/wpa_supplicant/wpa_supplicant.conf
## ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
## update_config=1
##
## network={
## ssid="homenetwork"
## psk="h0mepassw0rd"
## }
############################
# Using DHCP Configuration #
############################
$script = @'
interface eth0
static ip_address=10.0.0.20/24
static routers=10.0.0.254/24
static domain_name_servers=8.8.8.8 4.4.4.4
'@;
ForEach ($line in $($script -split "[\r\n]+"))
{
Invoke-SSHCommand -SSHSession $session -Command "echo '$line' | sudo tee --append /etc/dhcpcd.conf "
}
##############
# OLD METHOD #
##############
# this does not work anymore!
# see https://raspberrypi.stackexchange.com/questions/39785/dhcpcd-vs-etc-network-interfaces for details
# in /etc/network/interfaces:
## auto lo
## iface lo inet loopback
##
## allow-hotplug wlan0
## iface wlan0 inet manual
## wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
##
## allow-hotplug wlan1
## iface wlan1 inet manual
## wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
##
## allow-hotplug wlan0
## #iface wlan0 inet dhcp
## iface wlan0 inet static
## address 192.168.0.110
## netmask 255.255.255.0
## network 192.168.0.1
## gateway 192.168.0.1
## wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
## #iface default inet dhcp
##
##
## iface eth0 inet static
## address 192.168.0.115
## netmask 255.255.255.0
## network 192.168.0.1
## gateway 192.168.0.1
###########
# Restart #
###########
# restart to propagate changes
Invoke-SSHCommand -SSHSession $session -Command "sudo reboot";
#############################
# Connect to new IP Address #
#############################
$session = New-SSHSession -ComputerName 10.0.0.20 -Credential $cred -Force;
##################
# Install Docker #
##################
# dowload docker script (curl) and execute in bash (sh)
Invoke-SSHCommand -SSHSession $session -Command "curl -sSL get.docker.com | sh" -TimeOut (5*60);
# apply rights of user 'pi' to group 'docker'
Invoke-SSHCommand -SSHSession $session -Command "sudo usermod pi -aG docker";
######################
# Disable Swap-File #
######################
Invoke-SSHCommand -SSHSession $session -Command "sudo dphys-swapfile swapoff";
Invoke-SSHCommand -SSHSession $session -Command "sudo dphys-swapfile uninstall";
Invoke-SSHCommand -SSHSession $session -Command "sudo update-rc.d dphys-swapfile remove";
# Hint: Settings in cmdline.txt must be all in one line
# echo -n supresses newline
Invoke-SSHCommand -SSHSession $session -Command "echo -n ' cgroup_enable=cpuset cgroup_enable=memory' | sudo tee --append /boot/cmdline.txt";
# restart to propagate changes
Invoke-SSHCommand -SSHSession $session -Command "sudo reboot";
###########################
# Install kubeadm/kubectl #
###########################
# Hint: apt-get parameters:
# -q quiet
# -y assume yes on promts
[string]$script = @'
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update -q
sudo apt-get upgrade -qy
sudo apt-get install -qy kubelet kubeadm kubectl kubernetes-cni
'@;
# Hint:
# kubelet: Kubernetes node agent
# kubeadm: Kubernetes cluster administration tool
# kubectl: manage and deploy Kubernetes applications
# kubernetes-cni: Kubernetes networking plugin
ForEach ($line in $($script -split "[\r\n]+"))
{
# Hint: installing kubeadm takes a long time, so we set a larger timeout here
Invoke-SSHCommand -SSHSession $session -Command $line -Timeout (5*60);
}
#####################################
# Initialize Kubernetes Master Node #
#####################################
# Sources:
# https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/
# https://unofficial-kubernetes.readthedocs.io/en/latest/admin/kubeadm/
[string]$command = "sudo kubeadm init
--apiserver-advertise-address 10.0.0.1
--apiserver-bind-port 6443
--apiserver-cert-extra-sans 'k8s-master-01.kubernetes.local,k8s-master-02.kubernetes.local,10.0.0.20,10.0.0.21'
--cert-dir '/etc/kubernetes/pki'
--kubernetes-version 'latest'
--pod-network-cidr '10.244.0.0/16'
--service-cidr '10.96.0.0/12'
--service-dns-domain 'cluster.local'
";
$command = $command.Replace("\n", " ").Replace("\r", " ");
# initialize Kubernetes; with 30 min timeout
Invoke-SSHCommand -SSHSession $session -Command $command -Timeout (30*60);
############################
# Manage Kubernetes Tokens #
############################
# Sources:
# https://unofficial-kubernetes.readthedocs.io/en/latest/admin/kubeadm/#manage-tokens
# https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-token/#cmd-token-generate
# List Tokens
kubeadm token list
# Generate new token
# typically needed in 'kubeadm init'
kubeadm token generate --description "description" --ttl $ttlInSeconds --usages 'signing,authentication'
# Generate new token and add it to the server
kubeadm token create --description "description" --ttl $ttlInSeconds --usages 'signing,authentication'
# Delete token
kubeadm token delete $tokenId
# Join master node with token
kubeadm join --token=$token 10.0.0.20:6443
# check on the master that the node was added
kubectl get nodes
##################################
# Set up Node-to-Node Networking #
##################################
# Template can be downloaded from the CoreOS project
# ARM Powered Raspberry Pi
# requires replacing the CPU settings
curl https://rawgit.com/coreos/flannel/master/Documentation/kube-flannel.yml | sed "s/amd64/arm/g" | sed "s/vxlan/host-gw/g" > kube-flannel.yaml
# x64 Computers/Servers
# works as is
curl https://rawgit.com/coreos/flannel/master/Documentation/kube-flannel.yml > kube-flannel.yaml
# apply settings
kubectl apply -f kube-flannel.yaml
# check configuration
kubectl describe --namespace=kube-system configmaps/kube-flannel-cfg
kubectl describe --namespace=kube-system configmaps/kube-flannel-cfg
# Sources:
# https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/
# host docker container for k8s Dashboard
$master = 'https://raw.githubusercontent.com/kubernetes/dashboard/master'
$url = "$master/src/deploy/recommended/kubernetes-dashboard-arm-head.yaml";
curl -sSL $url | kubectl apply -f -
kubectl proxy
# access the Dashboard using http://MASTERHOSTNAME:8001/ui
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment