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
”
设置一个有意义的主机名:
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。在您的操作中,您需要将其替换为您的域名。
“注: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
建议禁用并删除交换文件。
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
”
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
“容器网络接口 (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 等)来为容器配置网络。
”
“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
“runc 是非 Akash 部署使用的默认 OCF 运行时(即标准的 kubernetes 容器,如 kube、etcd、calico pods)。
”
apt install -y runc
“译者注:
”
runc:是一个根据OCI标准创建并运行容器的 CLI 工具。简单地说,容器的创建、运行、销毁等操作最终都是通过调用 runc 完成的。
OFC:开放式计算设施。
“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
“现在 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 支持 #193 在 runc 中支持 cgroup v2 #3481
”
“译者注:
Q:什么是 Kubernetes?
A:Kubernetes,也称为 K8s,是一个自动部署、扩展和管理容器化应用的开源系统。
”
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
“您可以根据需要随意调整 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 输出了带有 --token 的 kubeadm join 命令。请妥善保管这条命令,因为如果您想根据您需要的架构类型来加入更多节点(worker 节点、数据节点),那么需要该命令。
通过多 master 节点部署,您将看到带有 --control-plane --certificate-key 额外参数的 kubeadm join 命令!确保在将更多 master 节点加入集群时使用它们!
“当你要使用
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
缺少网络插件,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平台上。
默认情况下,出于安全原因,您的 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-
“