首页
Search
1
安装docker时报错container-selinux >= 2:2.74
125 阅读
2
rsync命令(可替代rm删除巨量文件)
102 阅读
3
docker 镜像加速器配置,daemon.json文件详解
90 阅读
4
使用国内镜像地址拉取k8s安装需要的images
79 阅读
5
Redhat 8版本安装ansible步骤
75 阅读
运维
自动化运维
数据库
容器与k8s
环境
云计算
脚本
登录
Search
标签搜索
命令
nginx
Mingrui
累计撰写
64
篇文章
累计收到
0
条评论
首页
栏目
运维
自动化运维
数据库
容器与k8s
环境
云计算
脚本
页面
搜索到
64
篇与
的结果
2025-04-18
容器的调度策略介绍
kubernetes scheduler是负责Pod调度的进程(组件),它的作用是先对等待调度的Pod通过一些复杂的调度流程计算出其最佳的目标Node,再將Pod绑定到目标Node上。随着kubernetes功能的不断增强和完善,Pod的调度也变得越来越复杂。Scheduler内部的实现机制也在不断优化,从最初的两阶段调度机制(Predicates&Priorities)发展到现在的调度框架(Scheduling Framework),以满足越来越复杂的调度场景。Pod调度复杂的原因:kubernetes要努力满足不同类型应用的不同需求并努力让大家和平相处。kubernetes集群里的Pod可以分为三类:无状态服务类,有状态集群类,批处理类。不同类型的Pod对资源占用的需求不同,对Node故障引发的中断/恢复及Node迁移方面的容忍度不同。调度流程kube-apiserver将待调度的Pod的信息发送给kube-scheduler,scheduler通过一系列的计算把Pod要绑定的最优Node(或者暂时不存在)信息返还返还给apiserver。调度流程过滤阶段(Filtering):遍历所有的Node,筛选出符合要求的候选Node。此阶段Scheduler会将不合适的Node全部过滤掉,只留下符合条件的候选Node。具体方式是通过一系列待定的Predicates对每个Node进行筛选,在筛选完成后通常会有多个候选Node供调度,从而进入打分阶段。如果筛选的结果集为空,则表示当前没有符合条件的Node,此时Pod会一直处于Pending状态。打分阶段(Scoring):在过滤阶段的基础上,采用优选策略计算出每个候选Node的积分,积分最高者胜出。在挑选出最佳Node后,Scheduler会把目标Pod安置到该Node上,完成调度。注:当Node处于以下状态时,Scheduler不在给它调度新的Pod。NotReadyUnschedulableMemoryPressure(不再调度新的BestEffort PodPod到这个Node)DiskPressure调度策略指定Node名称的定向调度策略Kubernetes支持在Pod的配置中通过指定nodeName字段的方式指定要调度的目标Node名称。这个字段的优先级高于nodeSelector和亲和性策略。设置了nodeName字段的Pod将不再参与调度器的调度过程,相当于已经完成了调度,apiserver将直接通知目标Node上的kubelet开始创建这个Pod。使用nodeName具有以下限制:如果指定的node不存在或者失联,则Pod将无法运行;如果指定的node资源不足,则pod可能会运行失败;在某些云环境下,node名称不一定是稳定的。验证一下污点策略的优先级示例:--- apiVersion: v1 kind: pod metadata: name: nginx spec: containers: - name: nginx image: nginx nodeName: 192.168.88.61基于Node Label的调度策略Node也是kubernetes管理的一种资源对象,可以为其设置多个Label。在Pod的配置中,可以方便的使用Label Selector来声明需要调度到具有指定Label的Node上,调度器会在具有这些Label的Node中进行选择。通过基于Node Label的调度方式,可以把集群中具有不同特点的Node都贴上不同的Label(如“role=frontend”,“role=backend”,“role=database”等),在部署应用时可以根据应用的需求设置NodeSelector来进行指定Node范围的调度。需要注意的是,如果指定了nodeselector条件,但是在集群中不存在包含相应Label的Node,那么集群中即便存在可供使用的Node,这个Pod也无法被成功调度。示例:--- apiVersion: v1 kind: pod metadata: name: pod-node-selector spec: nodeSelector: disk: ssd containers: - name: busybox image: busybox command: ['sh','-c','sleep 3600']亲和性调度策略亲和性和反亲和性的机制,扩展了Pod的调度能力,实现了更加灵活和精细的策略。其具有如下优点:更强的逻辑选择能力(不仅仅是“符合全部”的简单情况)可以设置为软性限制或优选,使得调度器在无法找到全部满足要求的Node时,也会寻找其他Node来调度Pod。除了基于Node上的Label,还可以依据Node上正在运行的其他Pod的Label来进行亲和性和反亲和性设置。这样可以定义一组规则来描述Pod间的亲和或者互斥关系。亲和性调度功能包括节点亲和性(NodeAffinity)和Pod亲和性(PodAffinity)两种类型。节点亲和性调度策略节点亲和性调度策略与NodeSelector类似,但表达能力更强,并且允许设置软性匹配规则。设置方法也是通过Node上的Label来设置Pod是否可以调度到目标Node上。节点亲和性的配置类型有以下两种:requiredDuringSchedulingIgnoredDuringExecution:必须满足指定的规则才可以调度Pod到Node上,是硬性要求,它的功能与nodeSelector相似,但是使用的是更加灵活的语法。preferredDuringSchedulingIgnoredDuringExecution:强调优先满足指定规则,调度器会尝试调度Pod到Node上,但并不强求,是软性限制。可以设置多个规则,还可以给每个规则设置权重值(weight),以定义判断的优先级顺序。权重 可以为每个规则设置一个1-100的权重值(weight),用于给调度器提供一个类似于优先级的分数,调度器会为满足条件的Node加上weight设置的值,以选出最终得分最高的Node。这两种策略中的IgnoredDuringExecution的意思是:如果一个Pod所在的节点在Pod运行期间其标签发生了变化,不再符合该Pod的亲和性需求,则系统将忽略Node上的Label变化,让Pod在原Node上继续运行。也就是说Pod正常运行后,不再对Node进行亲和性验证。在Label的匹配规则中,使用逻辑操作符(operator)进行设置,可用使用的操作符及其含义如下:In:Label的值(value)在给定的集合中。NotIn: Label的值(value)不在给定的集合中。Exists:需要具有此Label Key,此时不需要设置key的值。DoseNotExist:需要不存在此Label的值,此时不需要设置key的值。Gt;Label的值(Value)的整数值需要大于给定的值。Lt:Label的值(Value)的整数值需要小于给定的值。{callout color="#f75008"}NodeAffinity规则设置的注意事项如下:如果在Pod配置中同时使用了nodeSelector和nodeAffinity,那么必须两个条件都得到满足,才能将Pod调度到指定的Node上。(既要满足标签调度策略,又要满足亲和性调度策略。)如果nodeAffinity指定了多个nodeSelectorTerms,则则只需要其中一个条件能匹配成功就能完成Pod的调度,即多个条件之间是逻辑或(or)的关系。如果matchExperssions在nodeSelectorTerms中设置了多个条件表达式,那么必须满足所有的条件才能完成Pod的调度,即多个条件之间是逻辑与(and)的关系。{/callout}{tabs}{tabs-pane label="示例一"}#要求运行在具有标签“kubernetes.io/arch=amd64”的节点上。 #要求尽量运行在具有标签“disk-type=ssd”的节点上,如果没有,也可以运行在其他节点上。 --- apiVersion: v1 kind: Pod metadata: name: pod-with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: - amd64 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disk-type operator: In values: - ssd containers: - name: nginx image: nginx {/tabs-pane}{tabs-pane label="示例二"}对于具有zone=north标签的节点,系统会在调度算法的得分上加1(weigh=1),对于具有dis-type=ssd标签的节点,系统会在调度算法得分上加50(weight=50),然后综合其他条件计算出最终得分,并将pod调度到得分最高的Node上。apiVersion: v1 kind: Pod metadata: name: pod-with-node-affinity-weight spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: zone operator: In values: - north - weight: 50 preference: matchExpressions: - key: disk-type operator: In values: - ssd containers: - name: nginx image: nginx {/tabs-pane}{/tabs}Pod亲和性调度策略Pod亲和性:存在某些相互依赖,需要频繁互相调用的Pod,它们需要被尽可能地部署在同一个节点、机架、机房、网段或者区域(Zone)内。Pod反亲和性:处于避免竞争或者容错的需求,也可能使某些Pod尽可能地远离另外一些Pod。简单来说,某几个Pod可以在同一个拓扑域中共存,就是“Pod Affinity”,不能在同一个拓扑域中共存,就是“Pod Anti Affinity”。Pod亲和性与反亲和性调度的具体做法,就是通过在Pod的定义中增加topologyKey属性,来声明对应的目标拓扑域内几种相关联的Pod是“在一起还是不在一起”。需要注意的是,对于Pod的反亲和性策略,要求目标Node上需要存在相同的Label,实际上就是要求每个节点都具有相同的topologyKey指定的Label。如果某些Node不具有topologyKey指定的Label,则可能造成不可预估的调度结果。另外,设置Pod间的亲和性和反亲和性规则,会给调度器引入更多的计算量,在大规模集群中可能会造成性能问题,因此在配置Pod间的亲和性策略时需要谨慎。关于topoloygKey: 拓扑域:一个拓扑域由一些Node组成。这些Node通常具有相同的地理空间坐标。比如,在同一个机架、机房或地区。一般用Region表示机架、机房等的拓扑区域,用Zone表示地区这样跨度更大的拓扑区域。在某些情况下,可以认为一个Node就是一个拓扑区域。kubernetes为Node内置了一些常用的用于表示拓扑域概念的Label。kubernetes.io/hostnametopoloyg.kubernetes.io/regiontopoloyg.kubernetes.io/zone以上拓扑域是由kubernetes自己维护的。在node初始化时,Controller Manager会为Node设置许多标签。如,kubernetes.io/hostname这个标签的值会被设置为Node的hostname,云厂商会设置topoloyg.kubernetes.io/region和topoloyg.kubernetes.io/zone的值,以确定各个Node所属的拓扑域。{tabs}{tabs-pane label="参照Pod"}#带有两个Label --- apiVersion: v1 kind: Pod metadata: name: pod-flag labels: security: "S1" app: "nginx" spec: containers: - name: nginx image: nginx{/tabs-pane}{tabs-pane label="亲和性调度"}#亲和性Label是“security=S1” --- apiVersion: v1 kind: Pod metadata: name: pod-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: kubernetes.io/hostname containers: - name: pod-affinity image: nginx{/tabs-pane}{tabs-pane label="反亲和性调度1"}#新Pod与具有security=S1的Label的Pod在同一个zone的Node上运行 # 新Pod不能与具有app=nginx的Label的Pod在同一个Node上运行 --- apiVersion: v1 kind: Pod metadata: name: pod-anti-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: topology.kubernetes.io/zone podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: kubernetes.io/hostname containers: - name: pod-anti-affinity image: nginx{/tabs-pane}{tabs-pane label="反亲和性调度2"}#在同一个Node上不运行多个Pod副本。 --- apiVersion: apps/v1 kind: Deployment metadata: name: app-with-anti-affinity spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: "kubernetes.io/hostname" containers: - name: nginx image: nginx {/tabs-pane}{/tabs}污点和容忍度调度策略污点(Taint)配置在Node上,可以让Node拒绝一些具有某些特征的Pod在其上运行。容忍度(Toleration)配置在Pod中,用于高速系统允许调度到具有指定污点的节点上运行。默认情况下,在Node上设置一个或多个Taint后,除非Pod声明中明确能够容忍这些污点,否则无法在这些Node上运行。污点和容忍度的配合使用,可以避免将Pod调度到不合适的Node上。例如,某个Node存在问题(磁盘空间不足,计算资源不足,存在安全隐患等),希望新的Pod不要调度过来,就可以通过设置某些污点来实现。但设置了污点的Node并非不可用,仍是有效的Node。所以对于可用在这些Node上运行的Pod,可以给Pod设置与污点匹配的容忍度来实现调度。污点策略:PreferNoSchedule 尽量不调度,一个Pod如果没有声明容忍这个Taint,则系统会尽量避免把这个Pod调度到这一个Node上,但不保证一定能够避免NoScheduler 不被调度,除非Pod设置了与Taint匹配的容忍度。NoExecute 驱逐节点,不能在改node上运行,包括以下几种情况。对于正在该Node上运行的Pod,如果不能容忍指定的污点,则会被立刻从该Node驱逐。对于正在该Node上运行的Pod,如果能够容忍指定的污点,但未设置运行时限(tolerationSeconds),则会在该Pod上持续运行。对于正在该Node上运行的Pod,如果能够容忍指定的污点,但设置了运行时限(tolerationSeconds),则会在到达运行时限后从该Node上被驱逐。添加污点标签kubectl taint node node-0001 key=v1:PreferNoSchedule kubectl taint node node-0002 key=v2:NoScheduler容忍策略{tabs}{tabs-pane label="精确匹配"}…… spec: tolerations: - operator: "Equal" # 完全匹配键值对 key: "k" # 键 value: "v2" # 值 effect: "NoSchedule" # 污点标签 ……{/tabs-pane}{tabs-pane label="模糊匹配"}…… spec: tolerations: - operator: "Exists" # 部分匹配,存在即可 key: "k" # 键 effect: "NoSchedule" # 污点标签 ……{/tabs-pane}{tabs-pane label="所有污点标签"}…… spec: tolerations: - operator: "Exists" # 模糊匹配 key: "k" # 键 effect: # 没有设置污点标签代表所有 ……{/tabs-pane}{/tabs}优先级和抢占调度策略技术背景:对于运行各种负载(如Service,Job)的中等规模或者大规模的集群来说,需要尽可能提高集群的资源利用率。常规做法是采用优先级方案,即不同类型的负载对应不同的优先级,同时允许集群中的所有负载 所需要的资源总量超过集群可提供的资源。在这种情况下,当资源不足时,系统可以选择释放一些低优先级的负载,保障高优先级的负载获得足够的资源稳定运行。调度方式:由集群管理员创建priorityClass,Priority是不受限于命名空间的资源类型{tabs}{tabs-pane label="高优先级不抢占"}--- kind: PriorityClass apiVersion: scheduling.k8s.io/v1 metadata: name: high-non globalDefault: false preemptionPolicy: Never value: 1000 description: non-preemptive {/tabs-pane}{tabs-pane label="低优先级不抢占"}--- kind: PriorityClass apiVersion: scheduling.k8s.io/v1 metadata: name: low-non globalDefault: false preemptionPolicy: Never value: 500 description: non-preemptive{/tabs-pane}{tabs-pane label="高优先级抢占"}--- kind: PriorityClass apiVersion: scheduling.k8s.io/v1 metadata: name: high globalDefault: false preemptionPolicy: PreemptLowerPriority value: 1000 description: non-preemptive{/tabs-pane}{/tabs-pane}{tabs-pane label="低优先级抢占"}--- kind: PriorityClass apiVersion: scheduling.k8s.io/v1 metadata: name: low globalDefault: false preemptionPolicy: PreemptLowerPriority value: 500 description: non-preemptive{/tabs-pane}{/tabs-pane}{tabs-pane label="使用方式"}--- kind: Pod apiVersion: v1 metadata: name: php3 spec: nodeSelector: kubernetes.io/hostname: node-0002 priorityClassName: high-non # 优先级名称 containers: ……{/tabs-pane}{/tabs}其中,优先级的值越高,优先级越高,允许的设置范围是(-2147483648到1000000000),最大值是10亿,超过10亿的数字被系统保留,用于设置给系统组件。在上面的配置中,globalDefault设置为true表示这个优先级配置是全局默认配置,即对没有配置priorityCKassName的Pod都默认使用这个优先级设置。在系统没有设置全局默认优先级的情况下,对于没有配置priorityClassName的Pod,系统默认设置这些Pod的优先级为0。description字段用于设置一个说明,通常用来描述该priorityClass的用途。preemptionPolicy字段用于设置抢占策略。可用设置的策略有下面两个:PreemptLowerPriority:默认策略,表示允许具有该priorityClass优先级的Pod抢占较低优先级Pod的资源。Never:具有该优先级的Pod会被置于调度优先级队列中优先级数值更低的Pod之前,但不抢占其他Pod的资源,这些Pod将一直在调度列队中等待,知道有足够的可用资源后,才会被调度。抢占式调度的主要流程考察每个候选Node,找出为了满足新Pod的调度要求,需要释放的最少Pod实例;以抢占导致的代价最小原则,对筛查出来的所有候选Node进行考察,挑选出最优的候选Node作为最终被占用的目标Node;把目标Node与新Pod绑定,使得新Pod在下一轮的调度过程中可以使用这个目标Node来完成最终的调度流程,同时,调用APIServer删除目标Node上需要被释放的Pod以释放Node资源。最优Node选择规则拥有最小违反PodDisruptionBudget约束的Node;把Node上被释放的拥有最高优先级的Pod都找出来并进行比较,优先级排名垫底的Pod所在的Node;被释放的Pod的优先级之和(目标Pod需要的资源可能需要释放多个Pod才能满足)排名垫底的Node;被释放的Pod数量最少的Node;把Node上被释放的拥有最高优先级的Pod找出来,最晚启动的那个Pod所在的Node如果上述步骤还是无法选出最佳Node(可供选择的Node还有多个),就随机选择一个。注意事项如果目标Pod与候选Node上的某个优先级比它低的Pod之间有亲和性,则发生资源抢占后(这个低优先级的Pod被删除),目标pod不满足节点亲和性规则,此时该Node不符合抢占要求,Scheduler会考虑其他候选Node,无法保证目标Pod调度成功。要避免此类情况,要注意Pod亲和性和优先级的关系——具有亲和性关系的Pod不应该被设置为低优先级的。
2025年04月18日
33 阅读
0 评论
0 点赞
2025-04-10
kubernetes集群各配置文件解析
kubelet service文件在kubelet的service文件中,有下面两行配置信息:After=containerd.service Requires=containerd.service其中After确保kubelet在containerd启动后再启动,Requires确保containerd必须已经在正常运行了才能启动kubelet。配置这两行信息的原因是kubelet的启动时会根据kubelet的配置信息去找容器的sock借口,如果找不到借口就无法启动,会有如下报错。{callout color="#f70808"}4月 10 09:06:51 node002 kubelet[1537]: E0410 09:06:51.541944 1537 run.go:72] "command failed" err="failed to run Kubelet: validate service connection: validate CRI v1 runtime API for endpoint \"unix:///run/containerd/containerd.sock\": rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing: dial unix /run/containerd/containerd.sock: connect: no such file or directory\""4月 10 09:06:51 node002 systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE{/callout}因此,只有正确配置了上面两行内容,kubelet才能正常启动。配置的参数项是kubernetes集群所使用的容器运行时。(如docker,containerd,CRI-O等)集群中的地址分配相关集群中的地址分配主要是在kube-apiserver的配置文件中进行配置,核心配置是下面这个参数项--service-cluster-ip-range=10.245.0.0/16 \这个参数规定了集群中所有的service(服务)使用10.245地址段的ip地址。此外,service-node-port-range=30000-32767 是指创建NodePort类型的Service时,Kubernetes 会从 --service-node-port-range 指定的范围内自动分配一个端口。在kube-apiserver的配置配置文件中指定了IP地址段之后,还要在kube-controller-manger中进行对应的配置。核心参数是下面两项。--service-cluster-ip-range=10.245.0.0/16 \ --cluster-cidr=10.244.0.0/16 \其中,service-cluster-ip-range指定的是service服务所使用的IP地址段,与kube-apiserver中的配置应该相同。注意这个地址段不能与节点物理网络、Pod 网络或其他私有网络重叠cluster-cidr指定的是创建pod时,pod可以分配到的IP地址范围。注意这个地址段要与calico等网络插件的地址段配置一致,否则会造成pod间无法正常通信。calico网络插件对应的配置项- name: CALICO_IPV4POOL_CIDR value: "10.244.0.0/16"在kube-proxy中也有pod地址段相关的配置,需要确认与上面的配置相同。--cluster-cidr=10.244.0.0/16"
2025年04月10日
41 阅读
0 评论
0 点赞
2025-04-10
kubernetes集群各组件安装过程汇总
本文汇总了k8s集群所需要的各组件二进制安装配置过程,包括etcd、kubelet、kube-apiserver,kube-proxy,kube-controller-manager,kube-scheduler。{collapse}{collapse-item label="各组件详细安装步骤链接" open}containerd安装与配置etcd集群安装kube-apiserver部署配置kubeconfig并安装kube-controller-manager部署kube-scheduler服务HAProxy与keepalived部署node部署服务集群优化{/collapse-item}{/collapse}环境配置{tabs}{tabs-pane label="安装软件包"}dnf -y install iptables ipvsadm ipset nfs-utils{/tabs-pane}{tabs-pane label="安装模块"}cat /etc/modules-load.d/calico.conf ip_vs ip_vs_rr iptable_nat iptable_filter vxlan ipip cat /etc/modules-load.d/containerd.conf overlay br_netfilter nf_conntrack #确保机器上安装了以上模块 #创建了以上两个文件后使用systemctl命令来重新加载模块,使这些模块生效 systemctl restart systemd-modules-load{/tabs-pane}{tabs-pane label="环境配置"}#禁用selinux sed -i '/^SELINUX=/s//SELINUX=disabled/' /etc/selinux/config #禁用swap swapoff -a && sed -i '/swap/d' /etc/fstab #关掉防火墙 dnf -y remove firewalld #修改hosts文件 vim /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.88.51 master1 192.168.88.52 master2 192.168.88.53 master3 192.168.88.61 node001 192.168.88.62 node002 192.168.88.63 node003 {/tabs-pane}{/tabs}创建目录#创建存放根证书的目录 mkdir -p /etc/kubernetes/pki #创建存放etcd配置文件、CA证书,etcd数据的目录 mkdir -p /etc/etcd/{pki,data} #kubeconfig默认读取目录 mkdir -p $HOME/.kube # containerd cni插件目录 mkdir -p /opt/cni/bin/ # containerd cni插件配置文件目录 mkdir -p /etc/cni/net.d/ #containerd镜像加速存放加速地址配置文件的目录 mkdir -p /etc/containerd/certs.d/docker.ioCA证书制作证书所需要的配置文件{tabs}{tabs-pane label="etcd_ssl.cnf"}vim /etc/etcd/pki/etcd_ssl.cnf [ req ] req_extensions = v3_req distinguished_name = req_distinguished_name [ req_distinguished_name ] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [ alt_names ] IP.1 = 192.168.88.51 IP.2 = 192.168.88.52 IP.3 = 192.168.88.53{/tabs-pane}{tabs-pane label="master_ssl.cnf"}vim /etc/kubernetes/pki/master_ssl.cnf [req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = kubernetes DNS.2 = kubernetes.default DNS.3 = kubernetes.default.svc DNS.4 = kubernetes.default.svc.cluster.local DNS.5 = k8s-1 DNS.6 = k8s-2 DNS.7 = k8s-3 IP.1 = 10.245.0.1 IP.2 = 192.168.88.51 IP.3 = 192.168.88.52 IP.4 = 192.168.88.53 IP.5 = 192.168.18.100{/tabs-pane}{/tabs}创建证书{tabs}{tabs-pane label="CA根证书"}cd /etc/kubernetes/pki openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -subj "/CN=192.168.88.51" -days 36500 -out ca.crt{/tabs-pane}{tabs-pane label="etcd服务端证书"}etcd集群间相互认证所需证书cd /etc/etcd/pki/ openssl genrsa -out etcd_server.key 2048 openssl req -new -key etcd_server.key -config etcd_ssl.cnf -subj "/CN=etcd-server" -out etcd_server.csr openssl x509 -req -in etcd_server.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile etcd_ssl.cnf -out etcd_server.crt{/tabs-pane}{/tabs-pane}{tabs-pane label="etcd客户端证书"}kube-apiserver使用etcd数据库所需要证书cd /etc/etcd/pki/ openssl genrsa -out etcd_client.key 2048 openssl req -new -key etcd_client.key -config etcd_ssl.cnf -subj "/CN=etcd-client" -out etcd_client.csr openssl x509 -req -in etcd_client.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile etcd_ssl.cnf -out etcd_client.crt{/tabs-pane}{/tabs-pane}{tabs-pane label="kube-apiserver服务端证书"}cd /etc/kubernetes/pki openssl genrsa -out apiserver.key 2048 openssl req -new -key apiserver.key -config master_ssl.cnf -subj "/CN=192.168.88.51" -out apiserver.csr openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile master_ssl.cnf -out apiserver.crt cat ca.crt ca.key > ca.pem openssl x509 -in ca.crt -pubkey -noout > ca.pub{/tabs-pane}{/tabs-pane}{tabs-pane label="kube-apiserver客户端证书"}kube-controller-manager,kube-scheduler,kubelet,kube-proxy服务作为客户端连接kube-apiserver服务时,需要为它们创建客户端CA证书,使其能够正确访问kube-apiserver。cd /etc/kubernetes/pki openssl genrsa -out client.key 2048 openssl req -new -key client.key -subj "/CN=admin" -out client.csr openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 36500{/tabs-pane}{/tabs}制作kubeconfig配置文件kubeconfig 文件是 Kubernetes 的核心配置文件,用于管理和切换不同集群的访问配置。核心作用集群连接管理:存储多个 Kubernetes 集群的 API 服务器地址、CA 证书等信息,便于客户端(如 kubectl)安全连接。用户身份认证:保存用户凭据,例如客户端证书、Token、用户名/密码或 OAuth2 令牌,用于验证操作集群的权限。上下文切换:通过定义上下文(Context),将集群、用户和命名空间(Namespace)组合起来,快速切换不同环境(如开发、测试、生产)。多配置整合:支持通过环境变量 KUBECONFIG 合并多个配置文件,灵活管理不同项目或环境的配置。vim /etc/kubernetes/kubeconfig apiVersion: v1 kind: Config clusters: # 集群列表 - name: default cluster: server: https://192.168.88.100:9443 # 集群API地址 certificate-authority: /etc/kubernetes/pki/ca.crt # 验证集群的CA证书 users: - name: admin # 用户列表 user: client-certificate: /etc/kubernetes/pki/client.crt 用户身份证书 client-key: /etc/kubernetes/pki/client.key # 用户私钥 contexts: # 上下文列表 - context: cluster: default # 关联的集群 user: admin # 关联的用户 name: default # 默认命名空间 current-context: default # 当前生效的上下文配置service配置service文件,方便使用systemctl工具对各组件进行管理。{tabs}{tabs-pane label="apiserver"}vim /usr/lib/systemd/system/kube-apiserver.service [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=/etc/kubernetes/apiserver ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS Restart=always [Install] WantedBy=multi-user.target {/tabs-pane}{tabs-pane label="kubelet"}vim /usr/lib/systemd/system/kubelet.service [Unit] Description=Kubernetes Kubelet Server Documentation=https://github.com/kubernetes/kubernetes After=containerd.service Requires=containerd.service [Service] EnvironmentFile=/etc/kubernetes/kubelet ExecStart=/usr/bin/kubelet $KUBELET_ARGS Restart=always [Install] WantedBy=multi-user.target{/tabs-pane}{tabs-pane label="scheduler"}vim /usr/lib/systemd/system/kube-scheduler.service [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=/etc/kubernetes/scheduler ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS Restart=always [Install] WantedBy=multi-user.target {/tabs-pane}{tabs-pane label="controller-manager"}vim /usr/lib/systemd/system/kube-controller-manager.service [Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=/etc/kubernetes/controller-manager ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS Restart=always [Install] WantedBy=multi-user.target {/tabs-pane}{tabs-pane label="kube-proxy"}vim /usr/lib/systemd/system/kube-proxy.service [Unit] Description=Kubernetes Kube-Proxy Server Documentation=https://github.com/kubernetes/kubernetes After=network.target [Service] EnvironmentFile=/etc/kubernetes/proxy ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_ARGS Restart=always [Install] WantedBy=multi-user.target {/tabs-pane}{/tabs}创建各组件所需要的配置文件{tabs}{tabs-pane label="apiserver"}vim /etc/kubernetes/apiserver KUBE_API_ARGS="--secure-port=6443 \ --tls-cert-file=/etc/kubernetes/pki/apiserver.crt \ --tls-private-key-file=/etc/kubernetes/pki/apiserver.key \ --client-ca-file=/etc/kubernetes/pki/ca.crt \ --apiserver-count=3 --endpoint-reconciler-type=master-count \ --etcd-servers=https://192.168.88.51:2379,https://192.168.88.52:2379,https://192.168.88.53:2379 \ --etcd-cafile=/etc/kubernetes/pki/ca.crt \ --etcd-certfile=/etc/etcd/pki/etcd_client.crt \ --etcd-keyfile=/etc/etcd/pki/etcd_client.key \ --service-cluster-ip-range=10.245.0.0/16 \ --service-node-port-range=30000-32767 \ --allow-privileged=true \ --kubelet-client-certificate=/etc/kubernetes/pki/ca.crt \ --kubelet-client-key=/etc/kubernetes/pki/ca.key \ --service-account-key-file=/etc/kubernetes/pki/ca.pub \ --service-account-signing-key-file=/etc/kubernetes/pki/ca.pem \ --service-account-issuer=api" {/tabs-pane}{tabs-pane label="kubelet"}vim /etc/kubernetes/kubelet KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --config=/etc/kubernetes/kubelet.config \ --hostname-override=192.168.88.51" {/tabs-pane}{tabs-pane label="kubelet.config"}vim /etc/kubernetes/kubelet.config kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 0.0.0.0 port: 10250 cgroupDriver: systemd clusterDNS: ["10.245.0.100"] clusterDomain: cluster.local authentication: anonymous: enabled: false webhook: enabled: true x509: clientCAFile: /etc/kubernetes/pki/ca.crt {/tabs-pane}{tabs-pane label="scheduler"}vim /etc/kubernetes/scheduler KUBE_SCHEDULER_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig \ --leader-elect=true" {/tabs-pane}{tabs-pane label="controller-manager"}vim /etc/kubernetes/controller-manager KUBE_CONTROLLER_MANAGER_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig \ --leader-elect=true \ --service-cluster-ip-range=10.245.0.0/16 \ --cluster-cidr=10.244.0.0/16 \ --allocate-node-cidrs=true \ --service-account-private-key-file=/etc/kubernetes/pki/apiserver.key \ --root-ca-file=/etc/kubernetes/pki/ca.crt" {/tabs-pane}{tabs-pane label="proxy"} vim /etc/kubernetes/proxy KUBE_PROXY_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig \ --hostname-override=192.168.88.51 \ --proxy-mode=ipvs \ --ipvs-strict-arp=true \ --cluster-cidr=10.244.0.0/16"{/tabs-pane}{/tabs}启动服务systemctl enable --now kube-apiserver systemctl enable --now kube-proxy systemctl enable --now kubelet systemctl enable --now kube-scheduler systemctl enable --now kube-controller-manager配置文件下载etcd相关{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/etcd.conf" radius="" content="点击下载etcd.conf "/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_ssl.cnf" radius="" content="点击下载etcd_ssl.cnf "/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_server.crt" radius="" content="点击下载etcd_server.crt"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_server.csr" radius="" content="点击下载etcd_server.csr "/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_server.key" radius="" content="点击下载etcd_server.key"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_client.crt" radius="" content="点击下载etcd_client.crt"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_client.csr" radius="" content="点击下载etcd_client.csr"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_client.key" radius="" content="点击下载etcd_client.key"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/etcd/pki/etcd_client.pem" radius="" content="点击下载etcd_client.pem"/}kubernetes组件相关各组件配置文件{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/config/apiserver" radius="" content="点击下载apiserver"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/config/controller-manager" radius="" content="点击下载controller-manager"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/config/kubeconfig" radius="" content="点击下载kubeconfig"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/config/kubelet" radius="" content="点击下载kubelet"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/config/kubelet.config" radius="" content="点击下载kubelet.config"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/config/proxy" radius="" content="点击下载proxy"/}各组件service文件{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/service/kube-apiserver.service" radius="" content="点击下载apiserver"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/service/kube-controller-manager.service" radius="" content="点击下载controller-manager"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/service/kubelet.service" radius="" content="点击下载kubelet"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/service/kube-proxy.service" radius="" content="点击下载kube-proxy"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/service/kube-scheduler.service" radius="" content="点击下载kube-scheduler"/} CA认证文件{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/ master_ssl.cnf" radius="" content="点击下载master_ssl.cnf"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/apiserver.crt" radius="" content="点击下载apiserver.crt"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/apiserver.csr" radius="" content="点击下载apiserver.csr"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/apiserver.key" radius="" content="点击下载apiserver.key"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/ca.crt" radius="" content="点击下载ca.crt"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/ca.key" radius="" content="点击下载ca.key"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/ca.pem" radius="" content="点击下载ca.pem"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/ca.pub" radius="" content="点击下载ca.pub"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/ca.srl" radius="" content="点击下载ca.srl"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/client.crt" radius="" content="点击下载cclient.crt"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/client.csr" radius="" content="点击下载cclient.csr"/}{abtn icon="fa-cloud-download" color="#5698c3" href="https://doc.zhangmingrui.cool/usr/uploads/2025/04/k8s/pki/client.key" radius="" content="点击下载cclient.key"/}
2025年04月10日
37 阅读
0 评论
1 点赞
2025-04-09
解决kubectl exec Unauthorized报错问题
搭建kubernetes集群,最好的方式是使用kubeadm命令进行,使用二进制方式手动部署,步骤繁琐极易出错,使用过程中很容易出现一些问题。问题复现kubectl logs myhttp error: You must be logged in to the server (the server has asked for the client to provide credentials ( pods/log myhttp)) kubectl exec myhttp -- bash error: Internal error occurred: unable to upgrade connection: Unauthorized这个报错提示无法升级连接,未经授权。验证问题# 修改/etc/kubernetes/kubelet.config,启用匿名连接。 authentication.anonymous.enabled 的值设置为true #保存修改后重启集群内所有的kubelet。重启kubelet后会发现kubectl exec或者logs命令可以正常使用,这时就可以确认是kubelet与kube-apiserver之间通信时使用的认证相关配置出现了问题。解决报错在kube-apiserver的配置文件中,加入与kubelet通信相关的认证配置。这涉及到两条命令,分别是--kubelet-client-certificate和--kubelet-client-key。之后只需要根据kubelet配置文件中的认证文件来修改kube-apiserver相关参数即可。#查看kubelet使用的证书文件 grep client kubelet.config clientCAFile: /etc/kubernetes/pki/ca.crt #根据上面的证书文件对kube-apiserver配置进行修改 vim /etc/kubernetes/apiserver #添加下面两行内容 --kubelet-client-certificate=/etc/kubernetes/pki/ca.crt \ --kubelet-client-key=/etc/kubernetes/pki/ca.key \对集群内master节点上的所有kube-apiserver进行修改,然后重启kube-apiserver即可。kubectl exec -it myhttp -- bash root@myhttp:/usr/local/apache2# ls bin build cgi-bin conf error htdocs icons include logs modules root@myhttp:/usr/local/apache2# exit exit kubectl logs myhttp AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.244.61.131. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.244.61.131. Set the 'ServerName' directive globally to suppress this message [Wed Apr 09 11:57:48.855928 2025] [mpm_event:notice] [pid 1:tid 1] AH00489: Apache/2.4.63 (Unix) configured -- resuming normal operations [Wed Apr 09 11:57:49.254647 2025] [core:notice] [pid 1:tid 1] AH00094: Command line: 'httpd -D FOREGROUND'
2025年04月09日
31 阅读
0 评论
0 点赞
2025-04-08
二进制文件安装高可用k8s集群(七)集群优化
master主机安装containerd为方便主机与各node节点通信,安装containerd,kubelet与kube-proxy,以便于安装cni网络插件。具体安装方式详见 二进制文件安装高可用k8s集群(六)node部署服务 与 containerd安装与配置安装kubectl在master节点,主要通过kubectl命令行工具对k8s集群进行管理,因此需要将安装包中的kubectl可执行文件复制到/usr/bin目录下。cp /root/kubernetes/server/bin/kubelet /usr/bin/ 优化配置信息在集群的安装过程中,kubeconfig文件被存放在了/etc/kubernetes/目录下,这样就会导致每次使用kubectl命令时,需要搭配--kubeconfig参数指定kubeconfig的路径,比较麻烦。解决方案是把配置文件拷贝到k8s默认的配置目录下。mkdir -p $HOME/.kube cp -i /etc/kubernetes/kubeconfig $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config导入tab键方便使用tab键进行命令补全source <(kubectl completion bash|tee /etc/bash_completion.d/kubectl)安装网络插件calico插件的正常启用需要一些本地模块的支持,因此在安装calico插件前,需要先在本地安装一些calico可能会用到的模块#containerd需要的模块(安装containerd时已配置,此处仅展示) cat /etc/modules-load.d/containerd.conf overlay br_netfilter overlay br_netfilter nf_conntrack #配置calico需要用到的模块 vim /etc/modules-load.d/calico.conf #在文件中输入以下内容 ip_vs ip_vs_rr iptable_nat iptable_filter vxlan ipip tree /etc/modules-load.d/ /etc/modules-load.d/ ├── calico.conf └── containerd.conf #加载模块信息使生效 systemctl restart systemd-modules-load各模块作用说明ip_vs:IP 虚拟服务器(IP Virtual Server) 模块,用于实现传输层(L4)负载均衡,支持多种调度算法。ip_vs_rr:ip_vs 的调度算法之一,表示 轮询调度(Round Robin)。iptable_nat:支持 网络地址转换(NAT) 功能,用于实现 SNAT(源地址转换)和 DNAT(目标地址转换)。iptable_filter:支持 包过滤 功能,用于定义防火墙规则(如允许/拒绝特定流量)。vxlan:支持 VXLAN(Virtual Extensible LAN) 协议,用于在现有网络之上创建虚拟的 Overlay 网络,解决 VLAN ID 数量限制(支持 1600 万个虚拟网络)。ipip:支持 IP-in-IP 隧道协议,通过将原始 IP 数据包封装在另一个 IP 包中实现跨网络通信。模块在容器中的作用ip_vs/ip_vs_rr:Kubernetes Service 的负载均衡(IPVS 模式)。iptable_nat/iptable_filter:Service 流量转发和网络策略(iptables 模式)。vxlan/ipip:跨节点容器通信(Calico、Flannel 等插件的隧道封装)。calico模块依赖关系IPIP 模式:依赖 ipip 模块。VXLAN 模式:依赖 vxlan 模块。网络策略:依赖 iptable_filter 和 iptable_nat。kube-proxy IPVS 模式:依赖 ip_vs 和 ip_vs_rr安装calico插件calico插件官网: Calico Documentation calico插件安装教程: Calico Open Source 3.29 (latest) documentation calico官网提供了多种安装方式,简便起见这里选用Manifest(静态文件声明)模式进行安装。在这种模式下,calico根据k8s集群的规模提供了两个安装文件以供选择(以50个node节点规模为分界,)。本文选择选择小于50个节点规模的安装方式进行安装curl https://raw.githubusercontent.com/projectcalico/calico/v3.29.3/manifests/calico.yaml -O #因为集群指定的pod所使用的地址段为10.244.0.0/16,因此需要修改calico.yaml文件中pod地址段的默认值。 vim calico.yaml - name: CALICO_IPV4POOL_CIDR value: "10.244.0.0/16" #找到上面两行内容,大约在6291和6292行,去掉前面的#号和一个空格(yaml格式对缩进要求严格,缩进不对会报错),使得- name行的-号与上面一行的#号对齐,value行的value与name对齐。 kubectl apply -f calico.yaml #等待一段时间,待新生成的pod都是Running状态,即表示插件安装完成 kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-79949b87d-jn4mk 1/1 Running 0 3h11m calico-node-69plr 1/1 Running 0 3h11m calico-node-f6b5v 1/1 Running 0 3h11m calico-node-jsqt2 1/1 Running 0 3h11m calico-node-kwb46 1/1 Running 0 3h11m calico-node-m8ppg 1/1 Running 0 3h11m calico-node-z9rkj 1/1 Running 0 3h11m
2025年04月08日
46 阅读
0 评论
0 点赞
1
2
3
...
13