使用 cloud-init 的 K8s

来自 Alpine Linux

Alpine Linux 🌦️ 使用 nocloud cloud-init 镜像在 1 分钟内搭建 K8s

这是一个非常早期的版本,包含一些 hack

摘要

这是一个关于如何使用 cloud-init 设置 Alpine 的想法。当前版本已使用 nocloud Alpine 3.19 cloudinit 基础镜像进行了测试。这个想法受到了 k8s 的启发,旨在为虚拟和裸金属机器提供无需管理员的设置。目前,这仅是一个概念验证,还需要扩展到真正的多服务器部署。

k8s 的必要修复

runcmd 命令 修复了镜像的几个问题以及服务启动的方式。

  1. 添加了另一个用户 k8s
  2. 将名称和 IP 地址添加到 /etc/hosts
  3. 通过 /lib/modules 中的一个快速 hack 链接来对齐模块版本
  4. 一些使用 sed 的配置补丁
  5. 由于某些原因,需要启动 croup 服务,否则 containerd 无法启动

其余的安装都开箱即用。完整代码可在 github 上找到。

你需要两个文件:metadata 用于标识系统

alpine
local-hostname: alpine

以及 user-data,其中包含实际配置。

package_update: true
package_upgrade: true
package_reboot_if_required: true
#package_reboot: true

write_files:
  - path: /etc/apk/repositories
    content: |
      #https://dl-cdn.alpinelinux.org/alpine/v3.19/testing
      http://dl-cdn.alpinelinux.org/alpine/edge/community
      http://dl-cdn.alpinelinux.org/alpine/edge/testing
    append: true
  - path: /etc/modules-load.d/k8s.conf
    content: |
      br_netfilter
  - path: /etc/sysctl.conf
    content: |
      net.bridge.bridge-nf-call-iptables=1
      net.ipv4.ip_forward=1
  - path: /etc/crictl.yaml
    content: |
      runtime-endpoint: unix:///run/containerd/containerd.sock
      image-endpoint: unix:///run/containerd/containerd.sock
      timeout: 2
      pull-image-on-create: false

    
packages:
 - cni-plugin-flannel
 - cni-plugins
 - flannel
 - flannel-contrib-cni
 - kubelet
 - kubeadm
 - kubectl
 - containerd
 - containerd-ctr
 - k9s
 - uuidgen
 - openssh-server-pam

ssh_pwauth: true # sshd service will be configured to accept password authentication method
password: changeme # Set a password for alpine
chpasswd:
    expire: false # Don't ask for password reset after the first log-in
ssh_authorized_keys:
- ssh-ed25519 your key you@example.com

users:
- default
- name: k8s
  doas:
  - permit nopass k8s as root
  ssh_authorized_keys:
  - ssh-ed25519 your key you@example.com

runcmd:
  - |
    # mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
    uuidgen > /etc/machine-id
    sed -i 's/^#UsePAM no/UsePAM yes/' /etc/ssh/sshd_config && /etc/init.d/sshd restart
    echo $(ifconfig eth0 | grep 'inet addr:' | cut -d: -f2| cut -d' ' -f1) $(hostname) >> /etc/hosts
    (cd /lib/modules && ln -s 6.6.28-0-virt 6.6.14-0-virt && depmod)
    modprobe br_netfilter
    sed -ie '/swap/ s/^/#/' /etc/fstab && swapoff -a
    mount --make-rshared /
    echo "#!/bin/sh" > /etc/local.d/sharedmetrics.start
    echo "mount --make-rshared /" >> /etc/local.d/sharedmetrics.start
    chmod +x /etc/local.d/sharedmetrics.start
    rc-update add local default
    rc-update add cgroups
    rc-update add containerd
    rc-update add kubelet
    rc-update add ntpd
    rc-service ntpd start
    rc-service cgroups start
    rc-service containerd start
    echo 1 > /proc/sys/net/ipv4/ip_forward
    kubeadm config images pull
    kubeadm init --pod-network-cidr=10.244.0.0/16 --node-name=$(hostname) --apiserver-advertise-address $(hostname -i) --control-plane-endpoint=$(hostname -i) --upload-certs
    mkdir ~/.kube
    mkdir -p /root/.kube/ && ln -s /etc/kubernetes/admin.conf /root/.kube/config
    export KUBECONFIG=/etc/kubernetes/admin.conf
    while ! kubectl cluster-info ; do echo waiting for api server ; sleep 1; done
    kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
    kubectl taint nodes --all node-role.kubernetes.io/control-plane-
    echo "cloud-init schema"
    cloud-init schema --system
    echo "cloud-init status"
    cloud-init status --long