当前位置:主页 > 列表页 > 正文

使用 kubeadm、containerd、gvisor 部署 Akash Provider

2021-11-17 22:01 | 出处: Akash


这篇文章将指导您使用 kubeadm 完成 Akash Provider 部署。

文章更新记录:

  • 2021 年 7 月 12 日:最初使用 Akash 0.12.0 发布。

  • 2021 年 10 月 30 日:针对 Akash 0.14.0 更新,多 master/worker节点设置。还通过非常简单的轮询 DNS A 记录方式,添加了 HA 支持。

一、介绍

这篇文章将指导您完成,在您自己的 Linux 发行版系统上运行 Akash Provider 所需的必要配置和设置步骤。(我使用的 x86_64 Ubuntu Focal)。 步骤中还包括注册和激活 Akash Provider。

我们将使用 containerd,因此你无需安装docker

我没有像官方文档所建议的那样使用kubespray。因为我想对系统中的每个组件有更多的控制权,也不想安装 docker。

译者注:

Q:containerd 和 docker 是什么?他们有什么区别?

A:他们都是运行时组件,负责管理镜像和容器的生命周期。

作为 K8s 容器运行时,调用链的区别:

  • kubelet -> docker shim (在 kubelet 进程中) -> dockerd -> containerd

  • kubelet -> cri plugin(在 containerd 进程中) -> containerd

更详细的描述可以看这篇文章,很好的描述了他们之间的区别:https://www.tutorialworks.com/difference-docker-containerd-runc-crio-oci

二、准备工作

2.1 设置主机名

设置一个有意义的主机名:


hostnamectl set-hostname akash-single.domainXYZ.com

如果您打算使用推荐的方式与 3 个 master 节点(控制平面)和 N 个 worker 节点,那么您可以像下面这样设置主机名:

强烈推荐:如果您要部署多 master 节点和 worker 节点,您可以使用如下主机名。

# master 节点(控制平面)
akash-master-01.domainXYZ.com
akash-master-02.domainXYZ.com
akash-master-03.domainXYZ.com
# worker 节点
akash-worker-01.domainXYZ.com
...
akash-worker-NN.domainXYZ.com

在下面的示例中,我使用了我在 Akash Provider 上的实际地址*.ingress.nixaid.com。在您的操作中,您需要将其替换为您的域名。

2.2 启用 netfilter 和内核 IP 转发(路由)

注:kube-proxy 需要启用net.bridge.bridge-nf-call-iptables


cat <<EOF | tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

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

modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf

2.3 禁用 swap 分区

建议禁用并删除交换文件。

swapon -s
swapoff -a
sed -i ‘/swap/d‘ /etc/fstab
rm /swapfile

译者注:

Q:什么是 swap 分区?为什么要禁用 swap 分区?

A:swap 分区是将一部分磁盘空间用作内存使用,可以暂时解决内存不足的问题,Linux 系统默认会开启 swap 分区。

个人观点:swap 分区虽然能解决内存暂时不足的问题,但是与磁盘交互 IO 会影响应用程序的性能和稳定性,也不是长久之计。若考虑服务质量,服务提供商应该禁用 swap 分区。客户在内存资源不够时,可以临时申请更大的内存。

目前 K8s 版本是不支持 swap 的,经过漫长的讨论,最终 K8s 社区确实打算支持 swap,但还是实验版。

K8s 社区对开启 swap 功能的讨论: https://github.com/kubernetes/kubernetes/issues/53533

2.4 安装 containerd

wget https://github.com/containerd/containerd/releases/download/v1.5.7/containerd-1.5.7-linux-amd64.tar.gz
tar xvf containerd-1.5.7-linux-amd64.tar.gz -C /usr/local/

wget -O /etc/systemd/system/containerd.service https://raw.githubusercontent.com/containerd/containerd/v1.5.7/containerd.service

mkdir /etc/containerd

systemctl daemon-reload
systemctl start containerd
systemctl enable containerd

2.5 安装 CNI 插件

容器网络接口 (CNI) :大多数 pod 网络都需要。

cd
mkdir -p /etc/cni/net.d /opt/cni/bin
CNI_ARCH=amd64
CNI_VERSION=1.0.1
CNI_ARCHIVE=cni-plugins-linux-¥{CNI_ARCH}-v¥{CNI_VERSION}.tgz
wget https://github.com/containernetworking/plugins/releases/download/v¥{CNI_VERSION}/¥{CNI_ARCHIVE}
tar -xzf ¥CNI_ARCHIVE -C /opt/cni/bin

译者注:

CNI 作为容器网络的统一标准,可以让各个容器管理平台(k8s、mesos等)都可以通过相同的接口调用各式各样的网络插件(flannel,calico,weave 等)来为容器配置网络。

2.6 安装 crictl

Kubelet 容器运行时接口 (CRI) :kubeadm、kubelet 需要的。

INSTALL_DIR=/usr/local/bin
mkdir -p ¥INSTALL_DIR
CRICTL_VERSION="v1.22.0"
CRICTL_ARCHIVE="crictl-¥{CRICTL_VERSION}-linux-amd64.tar.gz"
wget "https://github.com/kubernetes-sigs/cri-tools/releases/download/¥{CRICTL_VERSION}/¥{CRICTL_ARCHIVE}"
tar -xzf ¥CRICTL_ARCHIVE -C ¥INSTALL_DIR
chown -Rh root:root ¥INSTALL_DIR

更新/etc/crictl.yaml 文件内容:


cat > /etc/crictl.yaml << ‘EOF‘
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
#debug: true
pull-image-on-create: true
disable-pull-on-run: false
EOF

2.7 安装 runc

runc 是非 Akash 部署使用的默认 OCF 运行时(即标准的 kubernetes 容器,如 kube、etcd、calico pods)。

apt install -y runc

译者注:

  • runc:是一个根据OCI标准创建并运行容器的 CLI 工具。简单地说,容器的创建、运行、销毁等操作最终都是通过调用 runc 完成的。

  • OFC:开放式计算设施。

2.8 (仅在 worker 节点上操作)安装 gVisor (runsc) 和 runc

gVisor (runsc) :是容器的应用程序内核,可在任何地方提供有效的纵深防御。 这里对比了几个容器运行时(Kata、gVisor、runc、rkt 等): https://gist.github.com/miguelmota/8082507590d55c400c5dc520a43e14a1

apt -y install software-properties-common
curl -fsSL https://gvisor.dev/archive.key | apt-key add -
add-apt-repository "deb [arch=amd64,arm64] https://storage.googleapis.com/gvisor/releases release main"
apt update
apt install -y runsc

2.9 配置 containerd 以使用 gVisor

现在 Kubernetes 将使用 containerd(稍后当我们使用 kubeadm 引导它时,您将看到这一点),我们需要将其配置为使用 gVisor 运行时。

删除 NoSchedule master 节点上的“runsc”(最后两行)。

更新/etc/containerd/config.toml

cat > /etc/containerd/config.toml << ‘EOF‘
# version MUST present, otherwise containerd won‘t pick the runsc !
version = 2

#disabled_plugins = ["cri"]

[plugins."io.containerd.runtime.v1.linux"]
shim_debug = true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
runtime_type = "io.containerd.runsc.v1"
EOF

并重启 containerd 服务:

systemctl restart containerd

gVisor (runsc) 还不能与 systemd-cgroup 或 cgroup v2 一起工作,如果您想跟进,这有两个未解决的问题: systemd-cgroup 支持 #193runc 中支持 cgroup v2 #3481

三、安装 Kubernetes

译者注:

Q:什么是 Kubernetes?

A:Kubernetes,也称为 K8s,是一个自动部署、扩展和管理容器化应用的开源系统。

安装最新稳定版 kubeadm、kubelet、kubectl 并添加 kubelet systemd 服务

INSTALL_DIR=/usr/local/bin
RELEASE="¥(curl -sSL https://dl.k8s.io/release/stable.txt)"
cd ¥INSTALL_DIR
curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/¥{RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
chmod +x {kubeadm,kubelet,kubectl}

RELEASE_VERSION="v0.9.0"
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/¥{RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:¥{INSTALL_DIR}:g" | tee /etc/systemd/system/kubelet.service
mkdir -p /etc/systemd/system/kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/¥{RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:¥{INSTALL_DIR}:g" | tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

cd
systemctl enable kubelet

3.2 使用 kubeadm 部署 Kubernetes 集群

您可以根据需要随意调整 pod 子网和 service 子网以及其他控制平面配置。 更多内容请参阅:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/control-plane-flags/

确保将 kubernetesVersion 环境变量设置为您下载的二进制文件的版本:https://dl.k8s.io/release/stable.txt

你只需要在 1 个 master 节点上运行kubeadm init 命令! 稍后您将使用 kubeadm join 加入其他 master 节点(控制平面)和 worker 节点。

如果你打算扩展你的 master 节点,取消多 master 部署的 controlPlaneEndpoint 注释。 把 controlPlaneEndpoint 设置为和 --cluster-public-hostname 相同的值。该主机名应解析为 Kubernetes 集群的公共 IP。

专业提示:您可以多次注册相同的 DNS A 记录,指向多个 Akash master 节点。然后设置 controlPlaneEndpoint 为该 DNS A 记录,这样它就能做到均衡的 DNS 轮询!


cat > kubeadm-config.yaml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: cgroupfs
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock # --cri-socket=unix:///run/containerd/containerd.sock
##kubeletExtraArgs:
##root-dir: /mnt/data/kubelet
imagePullPolicy: "Always"
localAPIEndpoint:
advertiseAddress: "0.0.0.0"
bindPort: 6443
---
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
kubernetesVersion: "stable"
#controlPlaneEndpoint: "akash-master-lb.domainXYZ.com:6443"
networking:
podSubnet: "10.233.64.0/18" # --pod-network-cidr, taken from kubespray
serviceSubnet: "10.233.0.0/18" # --service-cidr, taken from kubespray
EOF

在您的 master 节点(控制平面)上下载必要的依赖包,执行预检并预拉镜像:

apt -y install ethtool socat conntrack
kubeadm init phase preflight --config kubeadm-config.yaml
kubeadm config images pull --config kubeadm-config.yaml

现在,如果您准备好初始化单节点配置(您只有一个 master 节点也将运行 Pod):

kubeadm init --config kubeadm-config.yaml

如果您计划运行多 master 部署,请确保添加 --upload-certs 到 kubeadm init 命令,如下所示:

kubeadm init --config kubeadm-config.yaml --upload-certs

您可以先运行 kubeadm init phase upload-certs --upload-certs --config kubeadm-config.yaml,然后运行 kubeadm token create --config kubeadm-config.yaml --print-join-command 来获取 kubeadm join 命令!

单节点 master 部署不需要运行 upload-certs 命令。

如果您将看到“Your Kubernetes control-plane has initialized successfully! ”,则一切顺利,现在您的 Kubernetes 控制平面节点就在服务中了!

您还将看到 kubeadm 输出了带有 --tokenkubeadm join 命令。请妥善保管这条命令,因为如果您想根据您需要的架构类型来加入更多节点(worker 节点、数据节点),那么需要该命令。

通过多 master 节点部署,您将看到带有 --control-plane --certificate-key 额外参数的 kubeadm join 命令!确保在将更多 master 节点加入集群时使用它们!

3.3 检查您的节点

当你要使用 kubectl 命令与 Kubernetes 集群通信时,您可以设置 KUBECONFIG 变量,也可以创建指向 ~/.kube/config 的软链接。 确保您的 /etc/kubernetes/admin.conf 是安全的,因为它是您的 Kuberentes 管理密钥,可让您对 K8s 集群执行所有操作。

Akash Provider 服务将使用该配置,稍后您将看到如何使用。

(多 master 部署)新加入的 master 节点将自动从源 master 节点接收 admin.conf 文件。为您提供更多备份!

mkdir ~/.kube
ln -sv /etc/kubernetes/admin.conf ~/.kube/config
kubectl get nodes -o wide

3.4 安装 Calico 网络

缺少网络插件,Kubernetes 是无法使用的:

¥ kubectl describe node akash-single.domainXYZ.com | grep -w Ready
Ready False Wed, 28 Jul 2021 09:47:09 +0000 Wed, 28 Jul 2021 09:46:52 +0000 KubeletNotReady container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized

cd
curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yaml

译者注:

Q:什么是 Calico?

A:Calico 是一套开源的网络和网络安全方案,用于容器、虚拟机、宿主机之间的网络连接,可以用在kubernetes、OpenShift、DockerEE、OpenStrack等PaaS或IaaS平台上。

3.5 (可选)允许 master 节点调度 POD

默认情况下,出于安全原因,您的 K8s 集群不会在控制平面节点(master 节点)上调度 Pods。要么删除 master 节点上的 Taints(污点),以便您可以使用 kubectl taint nodes 命令在其上调度 pod,或者用 kubectl join 命令加入将运行 calico 的 worker 节点(但首先要确保执行了这些准备步骤:安装 CNI 插件、安装 crictl、配置 Kubernetes 以使用 gVisor)。

如果您正在运行单 master 部署,请删除 master 节点上的你 Taints:

¥ kubectl describe node akash-single.domainXYZ.com |grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule

¥ kubectl taint nodes --all node-role.kubernetes.io/master-

相关文章