kubescheduler调度扩展

Kubernetes 自带了一个默认调度器kube-scheduler,其内置了很多节点预选和优选的调度算法,一般调度场景下可以满足要求。但是在一些特殊场景下,默认调度器不能满足我们复杂的调度需求。我们就需要对调度器进行扩展,以达到调度适合业务场景的目的。 背景 中间件redis容器化后,需要两主不能在同一个节点上,一对主从不能在同一节点上;elasticsearch容器化后,两个data实例不能在同一节点上。在这类场景下,默认调度器内置的预选、优选算法不能满足需求,我们有以下三种选择: 将新的调度算法添加到默认调度程序中,并重新编译镜像,最终该镜像运行的实例作为kubernetes集群调度器; 参考kube-scheduler实现满足自己业务场景的调度程序,并编译镜像,将该程序作为独立的调度器运行到kubernetes集群内,需要用该调度器调度的pod实例,在spec.schedulerName里指定该调度器; image实现“调度扩展程序“:默认调度器kube-scheduler在进行预选时会调用该扩展程序进行过滤节点;在优选时会调用该扩展程序进行给节点打分,或者在bind操作时,调用该扩展器进行bind操作。 对上述三种方式进行评估: 第一种:将自己的调度算法添加到默认调度器kube-scheduler中,对原生代码侵入性较高,而且随着kubernetes版本升级,维护成本也较高; 第二种:默认调度器里内置了很多优秀调度算法,如:检查节点资源是否充足;端口是否占用;volume是否被其他pod挂载;亲和性;均衡节点资源利用等,如果完全使用自己开发的调度器程序,可能在达到了实际场景调度需求同时,失去更佳的调度方案,除非集成默认调度器中的算法到自己独立调度程序中,但这无疑是不现实的; 第三种:通过启动参数的policy配置,选用某些默认调度器中的预选、优选调度算法的同时,也可以调用外部扩展调度程序的算法,计算得到最优的调度节点,无需修改kube-scheduler代码,只需要在启动参数中增加配置文件即可将默认调度程序和扩展调度程序相互关联。 可以参考: https://github.com/kubernetes... 故采用第三种:实现扩展调度程序的方案。 整体架构 imagekube-scheduler在调度pod实例时,首先获取到Node1、Node2、Node3三个节点信息,进行默认的预选阶段,筛选满足要求的节点,其次再调用扩展程序中的预选算法,选出剩下的节点,假设预选阶段Node3上资源不足被过滤掉,预选结束后只剩Node1和Node2;Node1和Node2进入kube-scheduler默认的优选阶段进行节点打分,其次再调用扩展调度程序中的优选算法进行打分,kube-scheduler会将所有算法的打分结果进行加权求和,获得分数最高的节点作为pod最终bind节点,然后kube-scheduler调用apiserver进行bind操作。 实现步骤 实现扩展调度程序代码 编写扩展调度器程序代码,根据实际业务调度场景编写预选逻辑、优选逻辑: image实现预选接口,入参为schedulerapi.ExtenderArgs,出参为schedulerapi.ExtenderFilterResult: image实现优选接口,入参为schedulerapi.ExtenderArgs,出参为schedulerapi.HostPriorityList: image暴露http接口: image参考: https://github.com/ll83744879... 默认调度器部署 由于kubernetes集群内已经有了一个名为default-scheduler的默认调度器,为了不影响集群正常调度功能,下面会创建一个名为my-kube-scheduler的调度器,这个调度器和default-scheduler除了启动参数不一样外,镜像无差别。 1、创建一个名为my-scheduler-config的configmaps,data下的config.yaml文件指定了调度器的一些参数,包括leader选举,调度算法策略的选择(指定另一个configmaps),以及指定调度器的名称为my-kube-scheduler。 相应的创建一个my-scheduler-policy的configmaps,里面指定了选择哪些预选、优选策略,以及外部扩展调度程序的urlPrefix、扩展预选URI、扩展优选URI、扩展pod优先级抢占URI、扩展bind URI、扩展优选算法的权重等。 以保证my-kube-scheduler和扩展调度程序的通信。 apiVersion: v1kind: ConfigMapmetadata: name: my-scheduler-config namespace: kube-systemdata: config.yaml: | apiVersion: kubescheduler.config.k8s.io/v1alpha1kind: KubeSchedulerConfigurationschedulerName: my-kube-scheduleralgorithmSource: policy: configMap: namespace: kube-system name: my-scheduler-policyleaderElection: leaderElect: false lockObjectName: my-kube-scheduler lockObjectNamespace: kube-systemapiVersion: v1kind: ConfigMapmetadata: name: my-scheduler-policy namespace: kube-systemdata: policy.cfg : | { "kind" : "Policy","apiVersion" : "v1","predicates" : [ {"name" : "PodFitsHostPorts"}, {"name" : "PodFitsResources"}, {"name" : "NoDiskConflict"}, {"name" : "MatchNodeSelector"}, {"name" : "HostName"}],"priorities" : [ {"name" : "LeastRequestedPriority", "weight" : 1}, {"name" : "BalancedResourceAllocation", "weight" : 1}, {"name" : "ServiceSpreadingPriority", "weight" : 1}, {"name" : "EqualPriority", "weight" : 1}],"extenders" : [{ "urlPrefix": "http://10.168.107.12:80/scheduler", "filterVerb": "predicates/always_true", "prioritizeVerb": "priorities/zero_score", "preemptVerb": "preemption", "bindVerb": "", "weight": 1, "enableHttps": false, "nodeCacheCapable": false}],"hardPodAffinitySymmetricWeight" : 10}2、在my-kube-scheduler yaml文件中将configmaps:my-scheduler-config以文件的形式挂载到容器内/my-scheduler目录下,并在启动参数中指定--config=/my-scheduler/config.yaml,使用和默认调度器一样的镜像。 ...

April 30, 2019 · 1 min · jiezi

覆盖网络 Flannel 0.7

资源https://github.com/coreos/fla… 官方资源https://github.com/coreos/fla… 下载地址特性概念Flannel会修改Docker的启动参数,限制指定每台节点使用的子网不重复数据请求会从 docker0虚拟网卡转发到flannel0虚拟网卡 再将数据封包之后通过路由或者隧道发送到对应节点解包,再从flannel0虚拟网发送到docker0虚拟网卡可以使用etcd的最新版本3.x,但flannel使用的还是2.x的数据保存格式,和v2的api使用中间网络会有网络延迟,大概比使用路由器性能下降了2倍路由器平均内网请求0.2ms左右 使用中间网络内网平均0.4ms使用vxlan backend时,数据是由Kernel转发的,Flannel不转发数据,仅仅动态设置ARP entryFlannel中有多种backend,其中vxlan backend通过内核转发数据,而udp backend通过用户态进程中的proxy转发数据0.7.0中刚刚加入,即VTEP的IP加上了/32位的掩码避免了广播,此前的版本都是/16掩码,解决了VXLAN网络中由于广播导致的“网络风暴”的问题。Flannel在使用vxlan backend的时候,短暂启停flanneld不会造成网络中断,而udp backend会可以重启flanneld来更新网络配置;然后flannel每24h会自动重新分配集群内的网络flanneld挂掉会导致本地的ARP entry无法自动更新,但是已经生成的网络环境还是可用的安装mkdir /opt/flanneld-v0.8.0wget https://github.com/coreos/flannel/releases/download/v0.8.0/flannel-v0.8.0-linux-amd64.tar.gztar -xzvf flannel-v0.8.0-linux-amd64.tar.gz -C /opt/flanneld-v0.8.0ln -sf /opt/flanneld-v0.8.0/flanneld /usr/bin/flanneldrm -f flannel-v0.8.0-linux-amd64.tar.gzmkdir -p /var/log/k8s/flanneld#配置配置文件vim /etc/sysconfig/flanneldFLANNEL_ETCD=“http://10.31.75.198:2379,http://10.29.164.118:2379"FLANNEL_ETCD_KEY="/dudu_flannel/network"FLANNEL_OPTIONS="-ip-masq=true -v=0"FLANNEL_IFACE=“eth0"网卡 eth0 或IP-ip-masq=true 这个参数的目的是让flannel进行ip伪装,而不让docker进行ip伪装。这么做的原因是如果docker进行ip伪装,流量再从flannel出去,其他host上看到的source ip就是flannel的网关ip,而不是docker容器的ip#配置系统启动vim /usr/lib/systemd/system/flanneld.service [Unit]Description=Flanneld serverAfter=network.targetAfter=network-online.targetWants=network-online.targetBefore=docker.service[Service]Type=notifyEnvironmentFile=/etc/sysconfig/flanneldExecStart=/usr/bin/flanneld -etcd-endpoints=${FLANNEL_ETCD} -iface=${FLANNEL_IFACE} -etcd-prefix=${FLANNEL_ETCD_KEY} $FLANNEL_OPTIONSRestart=on-failure[Install]WantedBy=multi-user.target#向etcd 写入网段配置export ETCDCTL_API=3etcdctl put /dudu_flannel/network/config ‘{“Network”: “172.17.0.1/16”,“SubnetMin”: “172.17.0.0”, “SubnetMax”: “172.17.254.0”,“Backend”:{“Type”:“vxlan”}}’ –endpoints=10.30.187.25:2379查看etcdctl –endpoints=10.30.187.25:2379 get /dudu_flannel/network/config 删除etcdctl –endpoints=10.30.187.25:2379 del –prefix=true “/dudu_flannel"或rest接口curl -X PUT http://10.30.187.25:2379/v2/keys/dudu_flannel/network/config -d value=’{“Network”: “172.17.0.1/16”,“SubnetLen”:24,“Backend”:{“Type”:“vxlan”}}‘curl http://localhost:2379/v2/keys/dudu_flannel/network/config#删除配置curl http://localhost:2379/v2/keys/dudu_flannel/network/config -XDELETEcurl http://localhost:2379/v2/keys/dudu_flannel?recursive=true -XDELETE#关闭防火墙 flanneldsystemctl stop firewalldsystemctl disable firewalld#清理防火墙到默认规则#没有任何参数的 -F 命令在当前表中刷新所有链。同样的, -X 命令删除表中所有非默认链。 iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -t raw -F iptables -t raw -X iptables -t security -F iptables -t security -X iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT 保存规则 iptables-save #查看规则 iptables -t filter –list iptables -t mangle –list iptables -t nat –list iptables -t raw –list #清理网卡ip link delete docker0ip link delete flannel.1#停止docker 启动flannelsystemctl daemon-reloadsystemctl stop dockersystemctl stop flanneldsystemctl enable flanneld systemctl start flanneldsystemctl status -l flanneldsystemctl restart flanneld#命令行启动/usr/local/bin/flanneld -etcd-endpoints=http://10.29.167.233:2379 -etcd-prefix=/dudu_flannel/network -iface=eth0 -log_dir=/var/log/k8s/flanneld#启动flannel之后从etcd中获取network的配置信息划分本机subnet子网络,#并在etcd中进行注册本机的IP已经对应的子网。#Flannel守护程序将子网配置信息记录到/run/flannel/subnet.env文件中#Flannel守护进程还创建/run/flannel/docker文件记录docker的守护进程启动需要的环境变量信息#按照生成的docker环境变量配置docker的启动参数启动docker#如果没有/run/flannel/docker 文件手动生成/opt/flanneld-v0.8.0/mk-docker-opts.sh -icat /run/docker_opts.env#例子:cat /run/flannel/subnet.envFLANNEL_NETWORK=172.17.0.0/16FLANNEL_SUBNET=172.17.31.1/24FLANNEL_MTU=1450FLANNEL_IPMASQ=falsecat /run/flannel/dockerDOCKER_OPT_BIP=”–bip=172.17.31.1/24"DOCKER_OPT_IPMASQ=”–ip-masq=true"DOCKER_OPT_MTU=”–mtu=1450"DOCKER_NETWORK_OPTIONS=" –bip=172.17.31.1/24 –ip-masq=true –mtu=1450 “#修改 docker的启动参数 按照/run/flannel/docker 文件中的配置 ip-masq表示IP伪装vim /etc/docker/daemon.json { “registry-mirrors”: [“https://mb4qkfnx.mirror.aliyuncs.com”], “insecure-registries”:[“dudureg.xip.io:5000”], “bip”:“172.17.0.1/24”, “ip-masq”: false, “mtu”: 1450, “iptables”:false }#重启dockersystemctl restart docker#查看路由,查看网卡route -n ifconfig#查看成员curl http://localhost:2379/v2/keys/dudu_flannel/network/subnets#PublicIP配置的地址是外网地址,不是内网地址#测试docker run -d -it –name ip_test alpine:3.5 ashdocker inspect ip_testdocker exec -ti ip_test ash #进入容器中互pingdocker run -it –rm busybox shdocker logs -f -t –tail=100 ip_test#查看系统日志journalctl -fu docker.service journalctl –no-pager -l -u flanneld#监控包tcpdump -i flannel.1 tcpdump host 10.29.168.24 and 10.29.167.186 -w /var/log/001.captcpdump -i flannel.1 -w /var/log/001.cap#防火墙Nat转发规则iptables -t filter -L -v#查看封包地址bridge fdb show dev flannel.1删除bridge fdb del xx:xx:xx:cc:dd:a7 dev flannel.1 添加bridge fdb add xx:xx:xx:cc:dd:a7 dev flannel.1 dst 192.168.110.18 self permanent常用操作命令配置配置使用Vxlan 重启需要在几秒钟内完成此操作,因为ARP条目可能会开始超时,需要法兰绒守护程序刷新它们为了避免重新启动过程中的中断,不能更改配置(例如,VNI,-iface值)vxlan将具有较低的延迟开销和原生网络一样的带宽,性能基本和原生一样cat /boot/config-uname -r | grep CONFIG_VXLAN 检查主机内核是否支持VXLAN 返回 CONFIG_VXLAN=m支持cat flannel-config.json { “Network”: “172.17.0.0/16”, “SubnetLen”: 24, “Backend”: { “Type”: “vxlan”, “VNI”: 1 }}在backend中还可以配置 Port 默认为内核默认端口8472 是发送UDP封包的端口号#保存到etcd etcdctl set /dudu_flannel/network/config < flannel-config.json使用udp 作为后端 flanneld可以重新启动 甚至进行升级而不会影响现有的流量cat flannel-config.json{ “Network”: “172.17.0.0/16”, “SubnetLen”: 24, “SubnetMin”: “172.17.0.0”, “SubnetMax”: “172.17.254.0”, “Backend”: { “Type”: “udp”, “Port”: 7890 }}使用 host-gw 作为后端etcdctl set /dudu_flannel/network/config ‘{“Network”: “192.168.0.1/16”,“SubnetLen”: 24,“Backend”: {“Type”: “host-gw”}}‘curl http://10.99.132.22:2379/v2/keys/dudu_flannel/network/config flanneld -etcd-endpoints=http://10.99.132.21:2379 -etcd-prefix=/dudu_flannel/network -logtostderr=true -v=3 -iface=eth0 &>> /var/log/flanneld &子节点启动网桥模式docker run –net=bridge -itd –name=‘vm2’ sshd:1.0 测试联通 docker exec vm1 ping -c 3 192.168.1.194测试路由docker exec vm1 traceroute 192.168.1.194–iface 启动参数默认使用的系统的默认路由网卡 route -n 排在第一个的就是默认路由,在阿里云默认路由就是etch1 为外网路由内网路由是eth0 需要手动配置–iface=“eth0” 才能让flannel使用内网路由内网IP通信功能功能1功能2调试优化常见问题实际应用 ...

December 18, 2018 · 2 min · jiezi