Back to prev

k8s 安装记录

May 25, 2023
Linkang Chan
@Jesse Chan

本文记录使用 kubeadm 安装 k8s 的大致过程。 在此之前需要确认一下系统上的相关环境。以下搭建是在ubuntu20.04上,使用 containerd 作为容器运行时。

kubeadm 安装

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
sudo tee /etc/apt/sources.list.d/kubernetes.list <<-'EOF'
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
EOF
sudo apt-get update
sudo apt install -y kubeadm kubelet kubectl kubernetes-cni

正常情况下相关的工具就安装完成了。就下来,我们需要配置一下containerd的相关内容

containerd 配置

$ sudo apt install -y containerd.io
$ sudo systemctl enable containerd
$ sudo systemctl status containerd # 查看状态

接下来生成一份 containerd 的配置,运行如下命令:

$ sudo containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1

我们需要将cgroup开启, 进入config.toml文件中,将SystemdCgroup的值改为 True。

NVIDIA GPU 支持

首先我们需要安装 Nvidia runtime, 具体可以参考链接

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
      && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
      && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
            sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
            sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

$ sudo apt-get update
$ sudo apt-get install -y nvidia-container-toolkit

安装成功后,nvidia-container-runtime的命令便会出现, 接下来配置config.toml以支持 Nvidia runtime

version = 2
[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "nvidia"

      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]
          privileged_without_host_devices = false
          runtime_engine = ""
          runtime_root = ""
          runtime_type = "io.containerd.runc.v2"
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options]
            BinaryName = "/usr/bin/nvidia-container-runtime"

配置完成后,我们需要重启一下containerd

$ sudo systemctl restart containerd

其他配置

关闭 swap

$ sudo swapoff -a

网络配置

/etc/hosts中增加 master 节点的名称, 同时修改桥接配置

$ sudo modprobe br_netfilter

创建集群

运行如下的命令,来创建我们的集群:

$ sudo kubeadm init --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --control-plane-endpoint=172.21.0.16 --pod-network-cidr=10.244.0.0/16

相关说明:

  • --image-repository国内加速镜像源
  • --control-plane-endpoint指定控制面地址,一般指定为 master 节点的 ip/
  • --pod-network-cidr用于后续安装网络插件使用,如果是 flannel, 设置固定值10.244.0.0/16

在 init 过程中如果提示sandbox的镜像需要更换时,可以修改/etc/containerd/config.toml中的sandbox_image为提示的那个镜像,比如registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9

如果遇到失败后,可以使用会退方式清理 init

$ sudo kubeadm reset

单节点使用

正常情况下,master 节点不接受 pod 的调度,当我们有需求时,可以将 master 节点支持调度 pod 。

$ kubectl taint nodes --all node-role.kubernetes.io/control-plane-

如果想还原回来,可以使用如下命令

$ kubectl get node # 查看 master 节点名称
$ kubectl taint node [nodename] node-role.kubernetes.io/control-plane:NoSchedule

安装完成后,会提示我们如下的三个操作,执行后:

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

GPU 的插件支持

$ kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml

安装 flannel 网络

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

查看

  • daemonset
$ kubectl get daemonset -n kube-system
  • pods
$ kubectl get pods -A

自动补齐

$ kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
$ sudo chmod a+r /etc/bash_completion.d/kubectl
$ . ~/.bashrc

生成 token

kubectl create serviceaccount admin-user
kubectl create clusterrolebinding admin-user-binding \
  --clusterrole cluster-admin \
  --serviceaccount default:admin-user

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Secret
metadata:
  name: admin-user-token
  annotations:
    secret.ttl: "94608000"
    kubernetes.io/service-account.name: admin-user
type: kubernetes.io/service-account-token
EOF

SECRET_NAME="admin-user-token"
TOKEN=$(kubectl get secret ${SECRET_NAME} -o jsonpath='{$.data.token}' | base64 -d | sed $'s/$/\\\n/g')
echo $TOKEN

将上述内容保存成 bash 脚本后执行即可。

配置 registry

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."carbonsilicon-ai-registry.cn-hangzhou.cr.aliyuncs.com"]
      endpoint = ["https://carbonsilicon-ai-registry.cn-hangzhou.cr.aliyuncs.com"]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
    [plugins."io.containerd.grpc.v1.cri".registry.configs."carbonsilicon-ai-registry.cn-hangzhou.cr.aliyuncs.com".auth]
      username="xxxx"
      password="xxx"

注意,registry 的名称需要是完整的名称,否则无法鉴权成功。比如这边的carbonsilicon-ai-registry.cn-hangzhou.cr.aliyuncs.com, 需要完整写入。

containerd documentation

metric-server

需要修改部分内容:

image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.6.4
spec:
  containers:
  - args:
    - --cert-dir=/tmp
    - --secure-port=4443
    - --kubelet-insecure-tls  # 新增
    - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
## crictl 无法使用

需要在 `/etc/crictl.yaml` 中写入如下内容:

```bash
runtime-endpoint: "unix:///run/containerd/containerd.sock"
image-endpoint: "unix:///run/containerd/containerd.sock"
timeout: 0
debug: false
pull-image-on-create: false
disable-pull-on-run: false

创建加入节点的 token

$ kubeadm token create --print-join-command

安全移除节点

$ kubectl drain nodename --ignore-daemonsets
$ kubectl delete node node-name 

恢复节点使用

$ kubectl uncordon node-name

dns 配置

当前遇到一个问题,在字节点上,无法访问外部服务。可以查看/var/lib/kubelet/config.yaml文件,修改相关的内容 DNS 内容。 但是这个问题不是最终的解决办法。

同时也可以修改/etc/resolv.conf中的配置。

DNS debug

reset network

kubeadm reset
systemctl stop kubelet
systemctl stop docker
rm -rf /var/lib/cni/
rm -rf /var/lib/kubelet/*
rm -rf /etc/cni/
ifconfig cni0 down
ifconfig flannel.1 down
ifconfig docker0 down
ip link delete cni0
ip link delete flannel.1
systemctl start docker
systemctl start kubelet

查看指定节点上的 pod 情况

$ kubectl get pods --all-namespaces --field-selector spec.nodeName=your-node-name