從零開始基於Archlinux 安裝 containerd + k8s

Berkaroad發表於2023-04-27

下載ISO檔案:https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/latest/

k8s: v1.26.4; calico: 3.25.1; dashboard:v2.7.0

1. 準備工作

以虛擬機器VMWare為例。

使用EFI 非預設BIOS啟動。如果不使用EFI,那麼後續安裝引導時也使用非EFI。

  • Controller-Panel節點(master)

    節點列表:

    hostname ip
    k8s-master1 10.0.2.101/24
    k8s-master2 10.0.2.102/24
    k8s-master3 10.0.2.103/24

    CPU設定:2Core

    記憶體設定:2GB

    磁碟:20GB

    網路卡設定:網路卡1(ens33)為自定義NAT

  • Worker節點

    節點列表:

    hostname ip
    k8s-worker1 10.0.2.111/24
    k8s-worker2 10.0.2.112/24
    k8s-worker3 10.0.2.113/24

    CPU設定:2Core

    記憶體設定:4GB

    磁碟:20GB

    網路卡設定:網路卡1(ens33)為自定義NAT

2. 磁碟管理

2.1 磁碟分割槽

使用GUID分割槽表,分2個區:

  • 1)EFI System(EF00),Last sector: +500M (500MB)

  • 2)Linux filesystem(8300) ,Last sector:<回車>(為剩餘容量)

gdisk /dev/sda

2.2 磁碟格式化

mkfs.vfat -F32 /dev/sda1 # ESP分割槽 掛載 /boot
mkfs.ext4 /dev/sda2 # LFS分割槽 掛載 /

2.3 磁碟掛載

mount /dev/sda2 /mnt # 掛載root分割槽
mkdir /mnt/boot # 建立 /boot 目錄
mount /dev/sda2 /mnt/boot # 掛載boot分割槽

lsblk # 檢視分割槽掛載情況

3. 安裝系統

3.1 安裝系統檔案

vim /etc/pacman.d/mirrorlist # 在頂部新增如下映象伺服器

Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
#Server = https://mirrors.aliyun.com/archlinux/$repo/os/$arch
# 安裝系統
pacstrap /mnt base base-devel

3.2 配置fstab

genfstab -U /mnt > /mnt/etc/fstab # 生成分割槽掛載表

編輯 fstab

vim /mnt/etc/fstab
# SSD的追加options “discard,noatime”

3.3 配置系統

編輯 /mnt/etc/pacman.conf檔案,加入下面的內容:

[archlinuxcn]
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
#Server = https://mirrors.aliyun.com/archlinuxcn/$arch

切換root目錄到新系統

arch-chroot /mnt /bin/bash

現在可以全面升級系統:

pacman -Syy # 切換了root目錄,因此需要重新更新軟體包快取
pacman -S archlinuxcn-keyring
pacman -S vim bash-completion yay fakeroot
ln -s /usr/bin/vim /usr/bin/vi

3.4 安裝載入程式

# 安裝linux核心
pacman -S linux-lts linux-firmware
# 安裝 Micro Code
pacman -S amd-ucode # intel安裝 intel-ucode
bootctl install # boot-loader

vim /boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux-lts
initrd /amd-ucode.img # intel的為 /intel-ucode.img
initrd /initramfs-linux-lts.img
options root=/dev/sda2 rw

vim /boot/loader/entries/arch-fallback.conf
title Arch Linux (fallback initramfs)
linux /vmlinuz-linux-lts
initrd /amd-ucode.img # intel的為 /intel-ucode.img
initrd /initramfs-linux-lts-fallback.img
options root=/dev/sda2 rw

vim /boot/efi/loader/loader.conf
default arch.conf
timeout 2
console-mode max
editor no

# 驗證檔案路徑是否正確
bootctl list
bootctl status

3.5 安裝OpenSSH

pacman -S openssh

sed -i 's/#PermitRootLogin\ prohibit-passwd/PermitRootLogin yes/g' /etc/ssh/sshd_config

systemctl enable sshd

3.6 主機名

echo <host-name> > /etc/hostname

3.7 設定root密碼

passwd

3.8 網路配置

使用 systemd-networkd

VMWare 網路配置:
NAT模式
網段:10.0.2.0/24
DHCP:10.0.2.200 - 10.0.2.254
閘道器:10.0.2.2 (不要設定為10.0.2.1,否則會導致無法訪問外網)
vim /etc/systemd/network/20-wired.network
[Match]
Name=ens33

[Network]
#DHCP=ipv4 # 使用dhcp時啟用
Address=10.0.2.101/24
Gateway=10.0.2.2
DNS=223.5.5.5
DNS=223.6.6.6
systemctl enable systemd-networkd
systemctl enable systemd-resolved

3.9 重啟系統,並從硬碟引導

exit # 退出chroot
reboot # 重啟後重新引導進入已安裝的系統

3.10 本地化配置

vim /etc/locale.gen

en_US.UTF-8 UTF-8
zh_CN.GBK GBK
zh_CN.UTF-8 UTF-8
zh_CN GB2312
locale-gen # 生成locale
echo 'LANG=en_US.UTF-8' > /etc/locale.conf # 設定預設的 locale

3.11 時區配置

ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

3.12 硬體時間設定

# date -s '2022-7-5 16:49:45'
hwclock --systohc --utc #採用UTC,將系統時間寫入硬體時鐘
# hwclock --hctosys --utc #採用UTC,將硬體時鐘寫入系統時間

3.13 安裝DNS服務

pacman -S bind
# 參見: https://wiki.archlinux.org/title/BIND

4. 安裝k8s

使用kubeadm安裝: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

pacman -S kubeadm kubelet kubectl containerd
systemctl enable containerd
systemctl start containerd
systemctl enable kubelet
systemctl start kubelet

4.1 配置containerd

建立 /etc/modules-load.d/containerd.conf 配置檔案:

cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

修改 containerd 配置:

# 修改配置
mkdir -p /etc/containerd
if [ ! -f /etc/containerd/config.toml ]; then
    containerd config default > /etc/containerd/config.toml
fi

# 設定 systemd_cgroup 為 true
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sed -i 's/k8s.gcr.io/registry.aliyuncs.com\/google_containers/g' /etc/containerd/config.toml
sed -i 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/g' /etc/containerd/config.toml

配置mirrors映象:

vim /etc/containerd/config.toml
# 查詢 [plugins."io.containerd.grpc.v1.cri".registry.mirrors],在其後新增如下:
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
          endpoint = ["https://docker.mirrors.ustc.edu.cn"]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
          endpoint = ["https://registry.aliyuncs.com/google_containers"]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
          endpoint = ["https://registry.aliyuncs.com/google_containers"]

重啟containerd,並檢查狀態:

systemctl restart containerd

# 確保containerd 的cgroup 為 SystemdCgroup
crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock info | grep SystemdCgroup | awk -F ': ' '{ print $2 }'
true

設定crictl別名:

echo 'alias docker="crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock"' > /etc/profile.d/containerd.sh
source /etc/profile.d/containerd.sh

4.2 拉取k8s映象

透過引數 --image-repository 指定k8s映象的倉庫地址

kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.26.4

4.3 建立k8s叢集

# 應搭建負載均衡後,使用負載均衡IP,此處用自建DNS服務來實現: 10.0.2.101 cluster.berkaroad.com

# 這個版本的kubelet,命令列引數 `--cni-bin-dir` 已經取消,因此需要拿掉此引數
sed -i 's/--cni-bin-dir=\/usr\/lib\/cni//g' /etc/kubernetes/kubelet.env

# 初始化k8s叢集
kubeadm init  --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.26.4 --control-plane-endpoint=cluster.berkaroad.com --apiserver-advertise-address=10.0.2.101 --pod-network-cidr=10.100.0.0/16 --service-cidr=10.101.0.0/16 --service-dns-domain=cluster.berkaroad.com --upload-certs --v=5

# 執行成功後,根據提示,配置
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 注意:叢集中時間必須保持一致,否則會加入叢集失敗,錯誤資訊: x509: certificate has expired or is not yet valid: current time 2022-07-05T03:57:41+08:00 is before 2022-07-04T23:42:18Z

# You can now join any number of the control-plane node running the following command on each as root:
kubeadm join cluster.berkaroad.com:6443 --token v3e3b4.a52hqkbd1rlxgkun \
    --discovery-token-ca-cert-hash sha256:877bc4de6051c6aee8401bb99e6a3114f6d5a5fa7d87131c0b6377ce2419e5a3 \
    --control-plane --certificate-key 6b6050b43696814460032c521569377829e6bda6d39ac69e1d650d5bfdad1a44

# 如果 --certificate-key 過期了,執行如下:
kubeadm init phase upload-certs --upload-certs


# Then you can join any number of worker nodes by running the following on each as root:
kubeadm join cluster.berkaroad.com:6443 --token v3e3b4.a52hqkbd1rlxgkun \
    --discovery-token-ca-cert-hash sha256:877bc4de6051c6aee8401bb99e6a3114f6d5a5fa7d87131c0b6377ce2419e5a3

# 如果token過期了,可以執行如下:
kubeadm token create --print-join-command


# 如果失敗,檢查 cgroup 是否一致(docker或者containerd 和 kubelet)
# 檢視 kubeadm 使用的 CRI 為 containerd 還是 docker
cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9"

# 檢視 kubelet 的 cgroup driver
cat /var/lib/kubelet/config.yaml | grep cgroupDriver | awk -F ': ' '{ print $2 }'
systemd

4.4 加入control-plane節點

# 應搭建負載均衡後,使用負載均衡IP
echo '10.0.2.101 cluster.berkaroad.com' >> /etc/hosts

# 這個版本的kubelet,命令列引數 `--cni-bin-dir` 已經取消,因此需要拿掉此引數
sed -i 's/--cni-bin-dir=\/usr\/lib\/cni//g' /etc/kubernetes/kubelet.env


# 注意:叢集中時間必須保持一致,否則會加入叢集失敗,錯誤資訊: x509: certificate has expired or is not yet valid: current time 2022-07-05T03:57:41+08:00 is before 2022-07-04T23:42:18Z

# You can now join any number of the control-plane node running the following command on each as root:
kubeadm join cluster.berkaroad.com:6443 --token v3e3b4.a52hqkbd1rlxgkun \
    --discovery-token-ca-cert-hash sha256:877bc4de6051c6aee8401bb99e6a3114f6d5a5fa7d87131c0b6377ce2419e5a3 \
    --control-plane --certificate-key 6b6050b43696814460032c521569377829e6bda6d39ac69e1d650d5bfdad1a44

# 如果 --certificate-key 過期了,執行如下:
kubeadm init phase upload-certs --upload-certs

# 如果token過期了,可以執行如下:
kubeadm token create --print-join-command

# 執行成功後,根據提示,配置
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

4.5 加入worker節點

# 應搭建負載均衡後,使用負載均衡IP
echo '10.0.2.101 cluster.berkaroad.com' >> /etc/hosts

# 這個版本的kubelet,命令列引數 `--cni-bin-dir` 已經取消,因此需要拿掉此引數
sed -i 's/--cni-bin-dir=\/usr\/lib\/cni//g' /etc/kubernetes/kubelet.env


# 執行成功後,根據提示,配置
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 注意:叢集中時間必須保持一致,否則會加入叢集失敗,錯誤資訊: x509: certificate has expired or is not yet valid: current time 2022-07-05T03:57:41+08:00 is before 2022-07-04T23:42:18Z

# Then you can join any number of worker nodes by running the following on each as root:
kubeadm join cluster.berkaroad.com:6443 --token v3e3b4.a52hqkbd1rlxgkun \
    --discovery-token-ca-cert-hash sha256:877bc4de6051c6aee8401bb99e6a3114f6d5a5fa7d87131c0b6377ce2419e5a3

# 如果token過期了,可以執行如下:
kubeadm token create --print-join-command

4.6 安裝CNI:Calico

kubectl apply -f https://projectcalico.docs.tigera.io/archive/v3.25/manifests/calico.yaml

4.7 安裝Dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

新建 dashboard-admin.yaml

cat << EOF > dashboard-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: dashboard-admin
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-admin-cluster-role
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: dashboard-admin
    namespace: kubernetes-dashboard
EOF

kubectl apply -f dashboard-admin.yaml

新建 dashboard-admin-token.yaml

cat << EOF > dashboard-admin-token.yaml
apiVersion: v1
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: dashboard-admin
  labels:
    k8s-app: kubernetes-dashboard
  name: dashboard-admin-token
  namespace: kubernetes-dashboard
type: kubernetes.io/service-account-token
EOF

kubectl apply -f dashboard-admin-token.yaml

獲取登入用的token:

kubectl -n kubernetes-dashboard describe secret dashboard-admin-token | grep 'token:' | awk -F ' ' '{print $2}'

訪問Dashboard:

# 方法一:開啟proxy
kubectl proxy --address <本機ip> --port=8001 --accept-hosts='^*$'
# 開啟瀏覽器,訪問 http://<proxy的IP>:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

# 方法二:設定NodePort
kubectl patch svc kubernetes-dashboard -p '{"spec":{"type":"NodePort", "ports":[{"nodePort":30443, "port":443}]}}' -n kubernetes-dashboard
# 開啟瀏覽器,訪問 https://<node-ip>:30443/

4.8 檢視k8s叢集

節點資訊:

kubectl get no -o wide
NAME          STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE     KERNEL-VERSION   CONTAINER-RUNTIME
k8s-master1   Ready    control-plane   23m   v1.26.3   10.0.2.101    <none>        Arch Linux   6.1.25-1-lts     containerd://1.7.0
k8s-master2   Ready    control-plane   22m   v1.26.3   10.0.2.102    <none>        Arch Linux   6.1.25-1-lts     containerd://1.7.0
k8s-master3   Ready    control-plane   22m   v1.26.3   10.0.2.103    <none>        Arch Linux   6.1.25-1-lts     containerd://1.7.0
k8s-worker1   Ready    <none>          20m   v1.26.3   10.0.2.111    <none>        Arch Linux   6.1.25-1-lts     containerd://1.7.0
k8s-worker2   Ready    <none>          18m   v1.26.3   10.0.2.112    <none>        Arch Linux   6.1.25-1-lts     containerd://1.7.0
k8s-worker3   Ready    <none>          17m   v1.26.3   10.0.2.113    <none>        Arch Linux   6.1.25-1-lts     containerd://1.7.0

pod資訊:

kubectl get po -n kube-system
calico-kube-controllers-57b57c56f-g62jv   1/1     Running   0                   120m
calico-node-2b5f9                         1/1     Running   0                   120m
calico-node-flbmt                         1/1     Running   0                   120m
calico-node-hwtvh                         1/1     Running   0                   120m
calico-node-j6dkp                         1/1     Running   0                   120m
calico-node-jqcfg                         1/1     Running   0                   120m
calico-node-lrq7q                         1/1     Running   0                   120m
coredns-5bbd96d687-fd9j7                  1/1     Running   0                   139m
coredns-5bbd96d687-kd48v                  1/1     Running   0                   139m
etcd-k8s-master1                          1/1     Running   0                   139m
etcd-k8s-master2                          1/1     Running   0                   139m
etcd-k8s-master3                          1/1     Running   0                   137m
kube-apiserver-k8s-master1                1/1     Running   0                   139m
kube-apiserver-k8s-master2                1/1     Running   0                   139m
kube-apiserver-k8s-master3                1/1     Running   0                   139m
kube-controller-manager-k8s-master1       1/1     Running   0                   139m
kube-controller-manager-k8s-master2       1/1     Running   0                   137m
kube-controller-manager-k8s-master3       1/1     Running   0                   136m
kube-proxy-6v7b9                          1/1     Running   0                   132m
kube-proxy-7dnmx                          1/1     Running   0                   136m
kube-proxy-c2cdd                          1/1     Running   0                   137m
kube-proxy-k4l4c                          1/1     Running   0                   134m
kube-proxy-rjw8j                          1/1     Running   0                   139m
kube-proxy-zrcvw                          1/1     Running   0                   137m
kube-scheduler-k8s-master1                1/1     Running   0                   139m
kube-scheduler-k8s-master2                1/1     Running   0                   139m
kube-scheduler-k8s-master3                1/1     Running   0                   139m


kubectl get po -n kubernetes-dashboard
NAME                                        READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-7bc864c59-flhzz   1/1     Running   0          13m
kubernetes-dashboard-6c7ccbcf87-8qgmg       1/1     Running   0          13m

附錄

包簽名錯誤

error: libcap: signature from "David Runge <dvzrv@archlinux.org>" is marginal trust
:: File /var/cache/pacman/pkg/libcap-2.65-1-x86_64.pkg.tar.zst is corrupted (invalid or corrupted package (PGP signature)).
Do you want to delete it? [Y/n] Y
error: failed to commit transaction (invalid or corrupted package)
Errors occurred, no packages were upgraded.

更新pacman key證書

pacman -S gnupg
pacman -Sy archlinux-keyring
pacman-key --populate archlinux
pacman-key --refresh-keys
pacman -Syux

相關文章