环境依赖
以下操作,无特殊说明,所有节点都需要执行
- 安装 ssh 服务
- 安装
openssh-server
shellsudo apt-get install openssh-server
- 修改配置文件
shellvim /etc/ssh/sshd_config
找到配置项
textLoginGraceTime 120 PermitRootLogin prohibit-password StrictModes yes
把
prohibit-password
改为yes
,如下:
shellLoginGraceTime 120 PermitRootLogin yes StrictModes yes
- 设置节点,
ssh
到其他节点免密
bash
ssh-keygen -t rsa
这将生成一个 RSA
密钥对。默认情况下,这些文件会存储在~/.ssh/
目录下,分别是id_rsa
(私钥)和id_rsa.pub
(公钥)。按提示操作,或者直接按回车键接受默认设置。如果已经存在密钥对,可以跳过此步。
复制公钥到远程主机 :使用 ssh-copy-id
命令来将你的公钥添加到远程主机的~/.ssh/authorized_keys
文件中。
bash
ssh-copy-id user@remote_host
- 设置主机名,保证每个节点名称都不相同
shell
hostnamectl set-hostname xxx
- 同步节点时间
- 安装 ntpdate
shellsudo apt-get -y install ntpdate
- 配置 crontab,添加定时任务
shellcrontab -e 0 */1 * * * ntpdate time1.aliyun.com
关闭防火墙
bash
systemctl stop firewalld && systemctl disable firewalld
or
ufw disable
iptables 配置
为了让 Kubernetes
能够检查、转发网络流量,需要修改 iptables
的配置,并启用 br_netfilter
模块。
bash
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1 # better than modify /etc/sysctl.conf
EOF
sudo sysctl --system # 手动加载所有的配置文件
关闭 swap 分区
关闭 Linux
的 swap
分区,提升 Kubernetes
的性能。
复制代码
bash
# 临时关闭
sudo swapoff -a
# 永久关闭:注释 swap 挂载,给 swap 这行开头加一下 "#" 注释
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
为什么要关闭 swap 交换分区?
Swap 交换分区,如果机器内存不够,会使用 swap 分区,但是 swap 分区的性能较低,k8s 设计的时候为了能提升性能,默认是不允许使用交换分区的。Kubeadm 初始化的时候会检测 swap 是否关闭,如果没关闭,那就初始化失败。如果不想要关闭交换分区,安装k8s 的时候可以指定 --ignore-preflight-errors=Swap 来解决。
集群规划
每台上都安装 docker-ce
、docker-ce-cli
、cri-docker
,使用 cri-docker
作为容器运行时,和 kubelet
交互。
所有节点都安装 kubelet
、kubeadm
、kubectl
软件包,都启动 kubelet.service
服务。
配置 docker
和 k8s
的 APT
源
(比如需要安装 1.29 版本,则需要将如下配置中的 v1.28 替换成 v1.29)
bash
apt-get update && apt-get install -y apt-transport-https
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/Release.key |
gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/ /" |
tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
旧版 kubernetes 源只更新到 1.28 部分版本,不过 docker 源部分可以用
bash
sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
sudo curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
sudo add-apt-repository "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"
apt update
在 Ubuntu 系统中,可以通过以下两个位置查看源列表:
/etc/apt/sources.list
文件:这是主要的源列表文件。你可以使用文本编辑器(如 vi
或 nano
)以管理员权限打开该文件,查看其中列出的软件源。
/etc/apt/sources.list.d/
目录:该目录包含额外的源列表文件。这些文件通常以 .list
扩展名结尾,并包含单独的软件源配置。
bash
apt-cache madison kubelet # 命令来列出可用的 kubelet 软件包版本。检查是否存在版本号为 '1.28.2-00' 的软件包。
/etc/apt/sources.list # apt软件系统源
安装docker
bash
apt install docker-ce docker-ce-cli
使用 apt
可以查看安装的 docker
两个软件。
bash
apt list --installed | grep -i -E 'docker'
启动 docker
相关服务
ubuntu
上的 dub
安装后,如果有服务,会被自动设置为开机自启动,且装完就会拉起,这里给出验证。
bash
systemctl list-unit-files | grep -E 'docker'
两个服务都应是 running
状态
bash
systemctl status docker.service
systemctl status docker.socket
配置 docker
容器引擎使用 systemd
作为 CGroup
的驱动
vim /etc/docker/daemon.json
bash
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
sudo systemctl enable docker # 配置Docker为开机自启动
sudo systemctl daemon-reload # 重新加载服务的配置文件
sudo systemctl restart docker # 重启Docker
配置cri-docker
https://github.com/Mirantis/cri-dockerd/releases
选择好适合自己的 docker
版本,进行安装
bash
sudo apt-get install ./cri-dockerd-<version>.deb
or
dpkg -i cri-dockerd-<version>.deb
验证 cri-dockerd
是否已安装并正在运行:
bash
systemctl status cri-docker
修改 cri-docker 配置文件
vim /usr/lib/systemd/system/cri-docker-service
修改第11行,增加 --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9
bash
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9
然后重载配置,设置开机自启,检查组件状态
bash
systemctl daemon-reload && systemctl enable cri-docker.socket && systemctl status cri-docker.socket cri-docker docker
安装Kubernetes
安装 Kubernetes
,以下需要在所有节点上进行。
列出可用的 kubelet 软件包版本。检查是否存在版本号为 1.28.2-00
的软件包。
bash
apt-cache madison kubelet
执行安装
bash
apt install kubelet kubeadm kubectl
# 如果需要指定安装1.28.2这个版本,则可以这样:
apt install kubelet=1.28.2-00 kubeadm=1.28.2-00 kubectl=1.28.2-00
配置 kubelet
为开机自启动
systemctl enable kubelet.service
版本锁定
锁定这三个软件的版本,避免意外升级导致版本错误。
bash
sudo apt-mark hold kubeadm kubelet kubectl
下载 Kubernetes 组件镜像
可以通过下面的命令看到 kubeadm
默认配置的 kubernetes
镜像,是外网的镜像
lua
kubeadm config images list
这里使用阿里的 kubernetes
镜像源,下载镜像
bash
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.28.2 --cri-socket unix:///var/run/cri-dockerd.sock
配置 kubelet
指定运行时
bash
vim /etc/sysconfig/kubelet
提示:如果没有 sysconfig
目录,请先创建,然后再创建 kubelet
文件;这一步就是告诉kubelet cri-dockerd
的接口在哪里;该配置不是必须的,我们也可以在初始化集群时在 kubeadm
命令上使用 --cri-socket unix:///run/cri-dockerd.sock
选项来告诉 kubelet cri-dockerd
的socket
文件路径。
kubeadm
初始化
bash
kubeadm init \
--apiserver-advertise-address=<自己本机的公网IP> \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.2 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket=unix:///var/run/cri-dockerd.sock
配置环境变量
bash
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
使用 Calico 网络插件
master
节点初始化后,可以使用 kubectl get node
来检查 kubernetes
集群节点状态,当前 master
节点的状态为 NotReady
,这是由于缺少网络插件,集群的内部网络还没有正常运作。
bash
kubectl create -f https://calico-v3-25.netlify.app/archive/v3.25/manifests/calico.yaml
Calico
使用的镜像较大,如果安装超时,可以考虑在每个节点上预先使用 docker pull
拉取镜像。
其他节点加入集群
主节点在初始化结束后,已经创建了临时 token
,但该临时 token
只有24小时有效期。
也可以重新在节点创建永久有效的 token
bash
kubeadm token create --print-join-command
worker
节点加入
bash
kubeadm join <master节点>:6443 --token oyl72q.dth6p8kwi7fopsd6 \
--discovery-token-ca-cert-hash sha256:b31bb54c63a550d287c89ddd0094e27ca680a6c3386a8630a75445de3c4d6e43 \
--cri-socket=unix:///var/run/cri-dockerd.sock
Nvidia 驱动安装
下载驱动:https://developer.nvidia.com/cuda-downloads
根据选项,选择好自己的系统配置
执行 CUDA Toolkit Installer,给出的安装命令
最后再执行 Driver Install,给出的命令,驱动安装成功
helm安装
使用脚本进行安装
bash
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
Nvidia vGPU 安装
添加 chart 仓库
bash
helm repo add hami-charts https://project-hami.github.io/HAMi/
根据 Kubernetes 版本,指定 imageTag
bash
helm install hami hami-charts/hami --set scheduler.kubeScheduler.imageTag=v1.16.8 -n kube-system
验证安装
bash
kubectl get pods -n kube-system
给节点打标签
通过添加标签 "gpu=on" 来为调度 HAMi 标记 GPU 节点
vGPU 设备配置
编辑 ConfigMap,更改后,重启相关的 HAMi 组件以应用更新的配置。
bash
kubectl edit configmap hami-scheduler-device -n <namespace>
ConfigMap 中的配置
nvidia.deviceMemoryScaling:
浮点类型,默认值:1。NVIDIA 设备内存缩放比例,可以大于 1(启用虚拟设备内存,实验性功能)。对于具有 M 内存的 NVIDIA GPU,如果我们将nvidia.deviceMemoryScaling
参数设置为 S ,则通过此 GPU 分割的 vGPU 在 Kubernetes 中将总共获得S * M
内存。nvidia.deviceSplitCount:
整数类型,默认值:10。分配给单个 GPU 设备的最大任务数。nvidia.migstrategy:
字符串类型,"none" 表示忽略 MIG 功能,"mixed" 表示通过独立资源分配 MIG 设备。默认值为 "none"。nvidia.disablecorelimit:
字符串类型,"true" 表示禁用核心限制,"false" 表示启用核心限制,默认值:false。nvidia.defaultMem:
整数类型,默认值:0。当前任务的默认设备内存,以 MB 为单位。'0' 表示使用 100% 设备内存。nvidia.defaultCores:
整数类型,默认值:0。为当前任务保留的 GPU 核心百分比。如果分配为 0,则可能适合任何具有足够设备内存的 GPU。如果分配为 100,则将独占使用整个 GPU 卡。nvidia.defaultGPUNum:
整数类型,默认值:1,如果配置值为 0,则配置值将不生效并被过滤。当用户未在 pod 资源中设置 nvidia.com/gpu 这个键时,webhook 应检查 nvidia.com/gpumem、resource-mem-percentage、nvidia.com/gpucores 这三个键,任意一个键有值,webhook 应将 nvidia.com/gpu 键和此默认值添加到资源限制映射中。nvidia.resourceCountName:
字符串类型,vgpu 数量资源名称,默认值:"nvidia.com/gpu"。nvidia.resourceMemoryName:
字符串类型,vgpu 内存大小资源名称,默认值:"nvidia.com/gpumem"。nvidia.resourceMemoryPercentageName:
字符串类型,vgpu 内存比例资源名称,默认值:"nvidia.com/gpumem-percentage"。nvidia.resourceCoreName:
字符串类型,vgpu 核心资源名称,默认值:"nvidia.com/cores"。nvidia.resourcePriorityName:
字符串类型,vgpu 任务优先级名称,默认值:"nvidia.com/priority"。