Skip to content

Instantly share code, notes, and snippets.

@keegoo
Last active October 12, 2025 07:40
Show Gist options
  • Select an option

  • Save keegoo/c2e69a1a70d3cee75ff998266be31fc5 to your computer and use it in GitHub Desktop.

Select an option

Save keegoo/c2e69a1a70d3cee75ff998266be31fc5 to your computer and use it in GitHub Desktop.

说明

我买的Khadas型号是VIM1S。它的用户手册在官网产品的购买界面。这里可以找到自带的OOWOW嵌入式系统的文档。

这里介绍一下安装Kubernetes的过程。

Specification
SOC Amlogic S905Y4 SoC
内存 2GB
存储 16GB(可用部分14.2GB)
蓝牙 5.0
WIFI 2.4G/5G

修改登录密码

Khadas官方ubuntu镜像安装成功后,默认的用户名和密码都是khadas。第一次SSH登录时最好修改默认密码。

# ssh [email protected]
~$ passwd
# Changing password for khadas.
# Current password: 
# New password: 
# Retype new password: 

安装MicroSD卡

我加了一个64GB的Micro SD卡,所以第一步是mount。参考Mount Micro SD Card Ubuntu

~$ lsblk
# => 其中mmcblk0是产品自带的那16G存储空间,当然只有14.6G可用。
# => 其中mmcblk1就是这个SD卡,mmcblk1p1指的是卡上的分区。

# NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
# mmcblk0      179:0    0  14.6G  0 disk 
# ├─mmcblk0p1  179:1    0   240M  0 part /boot
# └─mmcblk0p2  179:2    0  14.2G  0 part /
# mmcblk0boot0 179:32   0     4M  0 disk 
# mmcblk0boot1 179:64   0     4M  0 disk 
# mmcblk1      179:96   0  59.5G  0 disk 
# └─mmcblk1p1  179:97   0  59.5G  0 part 
# zram0        253:0    0     0B  0 disk 
# zram1        253:1    0 248.6M  0 disk [SWAP]
# zram2        253:2    0 248.6M  0 disk [SWAP]
# zram3        253:3    0 248.6M  0 disk [SWAP]
# zram4        253:4    0 248.6M  0 disk [SWAP]
# zram5        253:5    0     0B  0 disk 

# 查看分区格式
~$ lsblk -f
# NAME         FSTYPE FSVER LABEL  UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
# mmcblk1                                                                              
# ├─mmcblk1p1  vfat   FAT32 esp    492E-xxxx                                           
# ├─mmcblk1p2  vfat   FAT32 efi    4934-xxxx                                           
# ├─mmcblk1p3  btrfs        rootfs 304d3526-c99e-45e9-81b5-xxxxxxxxxxxx                
# ├─mmcblk1p4  ext4   1.0   var    17d46966-cb62-416d-8c9d-xxxxxxxxxxxx                
# └─mmcblk1p5  ext4   1.0   home   952128a7-3815-484e-9fe9-xxxxxxxxxxxx                
# ...                                                                     

# 建立分区,再格式化成exfat格式(别忘记备份资料),
~$ sudo apt update
~$ sudo apt install exfatprogs
~$ sudo fdisk /dev/mmcblk1
# step 1: Press `n` to create a new partition
# step 2: Press `p` for primary.
# step 3: Choose the partition number(e.g. 1).
# step 4: Accept the default start and end sectors to use the entire disk.
# step 5: Press `w` to write the changes and exit.
~$ sudo mkfs.exfat -n SanDisk /dev/mmcblk1p1      # 其中SanDisk只是一个名字,可以任意指定。

~$ sudo mkdir /media/microsd
# 1000 是用户ID(当前使用的khadas用户),可以用`id -u`获得。
# umask=002,指的是用户ID为1000的用户和admin有写权限;其他人有只读权限。
~$ sudo mount -o uid=1000,umask=002 /dev/mmcblk1p1 /media/microsd

# 查看分区的文件系统
~$ df -T
# =>
# Filesystem     Type  1K-blocks    Used Available Use% Mounted on
# tmpfs          tmpfs    203656   14392    189264   8% /run
# /dev/mmcblk0p2 ext4   14555288 4533428   9811992  32% /
# tmpfs          tmpfs   1018272       0   1018272   0% /dev/shm
# tmpfs          tmpfs      5120       4      5116   1% /run/lock
# tmpfs          tmpfs   1018272       0   1018272   0% /tmp
# /dev/mmcblk0p1 ext4     221664   41116    170724  20% /boot
# tmpfs          tmpfs    203652      68    203584   1% /run/user/1000
# /dev/mmcblk1p1 exfat  62334976   11136  62323840   1% /media/microsd

WiFi network

NetworkManager是一个网络管理服务,用于简化计算机系统的网络连接管理。可以使用nmcli命令和NetworkManager进行交互。

~$ nmcli d 
# => 
# DEVICE         TYPE      STATE         CONNECTION         
# eth0           ethernet  connected     Wired connection 1 
# wlan0          wifi      disconnected  --                 
# wlan1          wifi      disconnected  --                 
# dummy0         dummy     unmanaged     --                 
# ip6tnl0        iptunnel  unmanaged     --                 
# lo             loopback  unmanaged     --                 
# ip_vti0        vti       unmanaged     --                 
# p2p-dev-wlan0  wifi-p2p  unmanaged     --                 
# p2p-dev-wlan1  wifi-p2p  unmanaged     --                 

# check WiFi radio status
~$ nmcli r wifi

# 显示可用的WiFi网络
~$ nmcli d wifi list
# =>
# IN-USE  BSSID              SSID  MODE   CHAN  RATE        SIGNAL  BARS  SECURITY 
#         B4:xx:xx:xx:xx:7C  X&Y   Infra  149   270 Mbit/s  72      ▂▄▆_  WPA2     
#         B4:xx:xx:xx:xx:78  X&Y   Infra  11    270 Mbit/s  62      ▂▄▆_  WPA2     

# 连接到WiFi X&Y (X&Y是我家WiFi的名字,可以使用单引号来转译特殊字符)
~$ sudo nmcli d wifi connect 'X&Y' password '<password>'
# => 
# Device 'wlan0' successfully activated with 'ff2579be-81e6-xxxx-xxxx-xxxxxxxxxxxx'.

SELinux (has problem)

系统应该是默认安装了SELinux,因为/sys/fs/selinux/etc/selinux两个目录确实存在。具体可以参见官方selinux-notebook文档。

/sys/fs/selinux: The SELinux filesystem that interfaces with the kernel based security server. The new location has been available since Fedora 17.

/etc/selinux: The SELinux configuration directory that holds the sub-system configuration files and policies.

/var/lib/selinux/<SELINUXTYPE>: The SELinux policy store that holds policy modules and configuration details. The new location has been available since Fedora 23.

可以使用getenforcesestatus命令来查看SELinux是否处于开启状态。但是系统默认并没有安装这两个命令。下面是安装过程和简单的使用方式。

# check SELinux status
~$ sudo apt update
~$ sudo apt install selinux-utils
~$ getenforce
# =>
# Disabled
#
~$ sudo apt install policycoreutils
~$ sestatus
# 
# 修改/etc/selinux/config
#
# SELINUX=enforcing
# 修改为
# SELINUX=disabled

~$ reboot

安装MicroK8s

首先安装snap包管理系统。snap相比于apt的优势是它是自包含的(self-contained),即运行所需的所有库文件都存放在安装目录中,独立于系统存在。由此可以避免当两个应用程序依赖于同一个系统文件时导致的版本兼容问题。

~$ sudo apt install snapd
~$ snap version

其次,使用microk8s构建一个小型的Kubernetes系统。可以参见Ubuntu microk8s的官方文档。

~$ sudo snap install microk8s --classic
~$ microk8s version

# 查看micro8s的运行状态,这里显示默认状态下dns, ha-cluster, helm, helm3插件是启动的。
~$ sudo microk8s status --wait-ready
# =>
# 2024/01/28 08:00:40.554644 cmd_run.go:1046: WARNING: cannot create user data directory: failed to verify SELinux context of /root/snap: exec: "matchpathcon": # executable file not found in $PATH
# microk8s is running
# high-availability: no
#   datastore master nodes: 127.0.0.1:19001
#   datastore standby nodes: none
# addons:
#   enabled:
#     dns                  # (core) CoreDNS
#     ha-cluster           # (core) Configure high availability on the current node
#     helm                 # (core) Helm - the package manager for Kubernetes
#     helm3                # (core) Helm 3 - the package manager for Kubernetes
#   disabled:
#     cert-manager         # (core) Cloud native certificate management
#     cis-hardening        # (core) Apply CIS K8s hardening
#     community            # (core) The community addons repository
#     dashboard            # (core) The Kubernetes dashboard
#     host-access          # (core) Allow Pods connecting to Host services smoothly
#     hostpath-storage     # (core) Storage class; allocates storage from host directory
#     ingress              # (core) Ingress controller for external access
#     kube-ovn             # (core) An advanced network fabric for Kubernetes
#     mayastor             # (core) OpenEBS MayaStor
#     metallb              # (core) Loadbalancer for your Kubernetes cluster
#     metrics-server       # (core) K8s Metrics Server for API access to service metrics
#     minio                # (core) MinIO object storage
#     observability        # (core) A lightweight observability stack for logs, traces and metrics
#     prometheus           # (core) Prometheus operator for monitoring and logging
#     rbac                 # (core) Role-Based Access Control for authorisation
#     registry             # (core) Private image registry exposed on localhost:32000
#     rook-ceph            # (core) Distributed Ceph storage using Rook
#     storage              # (core) Alias to hostpath-storage add-on, deprecated

# 将khadas用户加入到管理microk8s的用户组中,这样就不需要每次使用`microk8s`命令时加上`sudo`了。
# 需要退出shell并重新连接使其生效。
~$ sudo usermod -a -G microk8s khadas
# 开启dashboard插件。
~$ microk8s enable dashboard
# 启动dashboard
~$ microk8s dashboard-proxy
# => 
# 2024/01/28 08:26:35.117767 cmd_run.go:1046: WARNING: cannot create user data directory: failed to verify SELinux context of /home/khadas/snap: exec: "matchpathcon": executable file not found in $PATH
# Checking if Dashboard is running.
# Infer repository core for addon dashboard
# Waiting for Dashboard to come up.
# Trying to get token from microk8s-dashboard-token
# Waiting for secret token (attempt 0)
# Dashboard will be available at https://127.0.0.1:10443
# Use the following token to login:
# xxxx

按照提示,你就可以用另一台局域网内的电脑,通过网络访问到Kubernetes,并使用提供的token登录UI。

最后,安装并使用kubectl来管理kubernetes。

# 在microk8s的机器上打输出config的内容
~$ microk8s config
# 将输出的内容复制并拷贝到另一台机器的.kube/config中
# 修改config里面的IP,用免费的域名替代

~$ kubectl config set-cluster artra_kubernetes --server=https://192.168.3.73:16443 --insecure-skip-tls-verify=true
~$ kubectl config get-clusters
# =>
# NAME
# artra_kubernetes

# 看能否成功获取pod信息,以此来判断kubectl是否连接正确。
~$ kubectl get pod

配置集群cluster

MicroK8s的官方文档在建立多个节点的集群这块已经说的很好了,可以参见Create a MicroK8s cluster

# 使用如下命令查看集群节点具体运行的service
~$ kubectl get pods -A -o wide
# NAMESPACE     NAME                                         READY   STATUS    RESTARTS         AGE     IP              NODE      NOMINATED NODE   READINESS GATES
# ingress       nginx-ingress-microk8s-controller-7k4ns      1/1     Running   0                3m26s   10.1.120.44     khadas2   <none>           <none>
# ingress       nginx-ingress-microk8s-controller-zvklh      1/1     Running   0                3m26s   10.1.126.193    khadas1   <none>           <none>
# kube-system   calico-kube-controllers-77bd7c5b-sxqrs       1/1     Running   2065 (58m ago)   197d    10.1.120.52     khadas2   <none>           <none>
# kube-system   calico-node-sqcwq                            1/1     Running   1 (58m ago)      60m     192.168.3.190   khadas2   <none>           <none>
# kube-system   calico-node-xkhvc                            0/1     Running   0                49m     192.168.3.189   khadas1   <none>           <none>
# kube-system   coredns-864597b5fd-w6ssl                     1/1     Running   1888 (58m ago)   197d    10.1.120.42     khadas2   <none>           <none>
# kube-system   dashboard-metrics-scraper-5657497c4c-kq9hl   1/1     Running   3 (58m ago)      17h     10.1.120.48     khadas2   <none>           <none>
# kube-system   kubernetes-dashboard-54b48fbf9-pj6t7         1/1     Running   3 (58m ago)      17h     10.1.120.41     khadas2   <none>           <none>
# kube-system   metrics-server-6d484c6d7d-qmgbj              1/1     Running   3 (58m ago)      17h     10.1.120.39     khadas2   <none>           <none>

Certificate的问题

具体参见stack overflow

# 将免费域名加入到microk8s的配置中
# 编辑/var/snap/microk8s/current/certs/csr.conf.template文件,加入所需的DNS

[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.default.svc.cluster.local
DNS.6 = your.dns.com
IP.1 = 127.0.0.1
IP.2 = ...

DDNS和域名

  1. 华为路由器的端口映射。
  2. 注册dynu,获取免费域名。
  3. 配置kubectl。
# 拷贝配置文件到本地
~$ microk8s config > config

# 在另外一台电脑:
# 修改config里面的IP,用免费的域名替代
# 这个要弄清证书信任的问题。
~$ kubectl cluster-info --insecure-skip-tls-verify

Notes

  1. Boot OOWOW - hold FUNCTION and short press RESET.
  2. 在OOWOW中还是连不上Huawei wifi 6;需要用到手机的热点。后面发现连不上的原因是我的Wifi名字里面有特殊字符,比如X&Y,&就是特殊字符。我家里的东芝的洗衣机也有这个问题。
  3. 当Kubernetes搭建好后,会有以下端口。
    • kubectl的管理端口:16443。
    • UI界面的端口:10443.
  4. Batocera v33有游戏保存跨设备同步功能,用syncthing实现的;可以考虑在建好的k8s中设置这个服务。
@keegoo
Copy link
Author

keegoo commented Aug 9, 2025

使用kubectl管理kubernetes

由于下面两个原因,我可以使用kubectl通过外网访问到我家里的Kubernetes。

  1. 我已经在路由器端,将Kubernetes的管理端口: 16443,和UI端口: 10443配置了端口映射
  2. 将路由器的WAN口IP绑定了Dynu上的免费Domain

下面是一些基本的信息。

~$ kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
# => https://xxxxxx.freeddns.org:16443

~$ kubectl config get-contexts
# CURRENT   NAME       CLUSTER            AUTHINFO   NAMESPACE
# *         microk8s   microk8s-cluster   admin      

~$ kubectl get nodes
# NAME      STATUS   ROLES    AGE    VERSION
# khadas1   Ready    <none>   209d   v1.28.15
# khadas2   Ready    <none>   406d   v1.29.15

~$ kubectl get namespaces
# default           Active   406d
# ingress           Active   209d
# kube-node-lease   Active   406d
# kube-public       Active   406d
# kube-system       Active   406d

@keegoo
Copy link
Author

keegoo commented Aug 9, 2025

搭建Jupyter Notebook

~$ kubectl create namespace jupyter-notebook
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jupyter-notebook
  namespace: jupyter-notebook
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jupyter-notebook
  template:
    metadata:
      labels:
        app: jupyter-notebook
    spec:
      containers:
      - name: jupyter-notebook
        image: jupyter/base-notebook:latest
        ports:
        - containerPort: 8888
        env:
        - name: JUPYTER_TOKEN
          value: "xuer1231"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment