01. kube-scheduler 启动及前期调试准备

01. kube-scheduler 启动及前期调试准备

kube-scheduler (调度器)是控制平面的组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。 调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。

kube-scheduler 启动的参数可以参考:https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-scheduler/

我们知道 kube-scheduler 本质上是利用 client-go 和 kube-apiserver 交互,监听 Pod 资源的创建,并为其调度到相应的 Node 上。

因此,kube-scheduler 启动的关键就是为其配置 kubeconfig ,使其可以连接上 kube-apiserver 。在我们之前两回讲 client-go 的使用时,其实一直使用到了 kubeconfig ,但我们并没有讲这个配置文件是哪来的。

实际在我们配置 kubectl 的时候:

# 添加新集群(apiserver地址和ca证书)
kubectl config set-cluster devk8s --server=https://127.0.0.1:6443 --certificate-authority=cert/ca.crt
# 添加用户(客户端证书)
kubectl config set-credentials devk8s --client-certificate=cert/client.crt --client-key=cert/client.key
# 添加上下文(绑定集群和用户)
kubectl config set-context devk8s --user=devk8s --cluster=devk8s
# 切换当前上下文
kubectl config use-context devk8s

就会在 ~/.kube/config 生成 kubeconfig ,或者也可以通过 kubectl config view 查看该配置。对于我们本地启动,可以直接复用该 kubeconfig 。

也就是说,我们的 kube-scheduler 启动参数可以配置为(这里我配置了完整路径,并且将日志等级设为 4 ,方便调试观察):

--kubeconfig=/root/.kube/config -v=4

Untitled

启动 kube-scheduler :

Untitled

查看组件状态,scheduler 已正常运行:

$ kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS      MESSAGE                                                                                        ERROR
controller-manager   Unhealthy   Get "https://127.0.0.1:10257/healthz": dial tcp 127.0.0.1:10257: connect: connection refused
scheduler            Healthy     ok                                                                                     
etcd-0               Healthy     {"health":"true","reason":""}

当创建一个 Pod 时:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80
EOF

kube-scheduler 日志:

Untitled

Pod 事件:

$ kubectl describe pod nginx
Name:             nginx
Namespace:        default
......
Status:           Pending
......
Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  32s  default-scheduler  no nodes available to schedule pods

可以看到,因为没有 Node ,kube-scheduler 无法调度 Pod 。

因为我们是本地调试,如果额外部署 kubelet 来注册 Node ,就比较麻烦了。

有一个简单的办法,我们可以直接利用 https://github.com/kubernetes-sigs/kwok 来模拟一些 Nodes 。

首先启动 kwok ,管理集群的所有 Node :

$ kwok --kubeconfig=/root/.kube/config --manage-all-nodes=true
Watch all nodes

创建 1 个 Node :

kubectl apply -f - <<EOF
apiVersion: v1
kind: Node
metadata:
  annotations:
    node.alpha.kubernetes.io/ttl: "0"
    kwok.x-k8s.io/node: fake
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: kwok-node-0
    kubernetes.io/os: linux
    kubernetes.io/role: agent
    node-role.kubernetes.io/agent: ""
    type: kwok
  name: kwok-node-0
spec: {}
status:
  allocatable:
    cpu: 32
    memory: 256Gi
    pods: 110
  capacity:
    cpu: 32
    memory: 256Gi
    pods: 110
  nodeInfo:
    architecture: amd64
    bootID: ""
    containerRuntimeVersion: ""
    kernelVersion: ""
    kubeProxyVersion: fake
    kubeletVersion: fake
    machineID: ""
    operatingSystem: linux
    osImage: ""
    systemUUID: ""
  phase: Running
EOF

kwok 会监听到 Node 资源的创建,并将其设置成 Ready 状态:

$ kubectl get node
NAME          STATUS   ROLES   AGE   VERSION
kwok-node-0   Ready    agent   15s   fake

但此时我们的 kwok-node-0 还存在 污点(Taint),我们需要手动删除该污点,使 Pod 可以调度到该 Node 上:

kubectl edit node kwok-node-0

删除污点后保存:

spec:
  taints:
  - effect: NoSchedule
    key: node.kubernetes.io/not-ready
# 将以上内容改为以下内容
spec: {}

此时,Pod 可以正常调度到虚拟的 kwok-node-0 节点:

$ kubectl get pod -owide
NAME    READY   STATUS    RESTARTS   AGE   IP         NODE          NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          30m   10.0.0.1   kwok-node-0   <none>           <none>

$ kubectl describe pod nginx
Name:             nginx
Namespace:        default
......
Node:             kwok-node-0/
......
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  30m                default-scheduler  no nodes available to schedule pods
  Normal   Scheduled         43s                default-scheduler  Successfully assigned default/nginx to kwok-node-0

kube-scheduler 日志就不贴出了。

这样,我们前期的准备工作就完成了,利用 kwok 创建 Node,后续我们就可以更方便地调试 kube-scheduler 。

微信公众号

更多内容请关注微信公众号:gopher云原生