Kubernetes第八篇:k8s启动、系统组件、APIServer与Scheduler

网友投稿 264 2022-09-10

Kubernetes第八篇:k8s启动、系统组件、APIServer与Scheduler

文章目录

​​一、前言​​​​二、k8s启动和系统组件​​

​​2.1 Master和Node功能分工​​​​2.2 kubeadm安装k8s的内部解析​​

​​2.2.1 master节点上执行 kubeadm init 内部九个步骤​​​​2.2.2 kubeadm join​​

​​2.3 支持一个k8s集群运行起来的核心组件汇总​​

​​01 kubectl​​​​02 kube-apiserver​​​​03 kube-scheduler​​​​04 kube-controller-manager​​​​05 kubelet​​​​06 kube-proxy​​​​07 DNS​​​​08 dashboard​​​​09 etcd​​

​​2.4 kubectl​​​​2.5 kubelet​​​​2.6 kube-proxy​​​​2.7 Kubernetes源码查看方式​​

​​三、API Server​​

​​3.1 kubectl与APIServer之间是REST调用​​​​3.2 集群安全机制之API Server​​

​​3.2.1 API Server认证(Authentication)​​​​3.2.2 API Server授权(Authorization)​​​​3.2.3 Admission Control(准入控制)​​

​​四、Scheduler​​

​​4.1 架构图​​​​4.2 流程描述​​​​4.3 预选策略和优选策略​​

​​4.3.1 预选策略​​​​4.3.2 优选策略​​

​​4.4 实战​​

​​4.4.1 Node​​​​4.4.2 Pod​​

​​五、尾声​​

一、前言

本文主要介绍:k8s启动、系统组件、APIServer与Scheduler。

二、k8s启动和系统组件

2.1 Master和Node功能分工

官网 :其中有一些关键的组件:比如API Server,Controller Manager,Scheduler等

Node Node会被Master分配一些工作负载,当某个Node不可用时,会将工作负载转移到其他Node节点上。 Node上有一些关键的进程:kubelet,kube-proxy,docker等

查看集群中的Node

kubectl get nodes kubectl describe node node-name

小结:一般来说,默认的程序员自己 通过 yaml 新建的 pod,会自动分配到 worker-node 节点上,不会被随机分配到 master 节点上。

2.2 kubeadm安装k8s的内部解析

2.2.1 master节点上执行 kubeadm init 内部九个步骤

master节点执行 kubeadm init 之后,内部执行了九个步骤。

第一步,检查:进行一系列检查[init之前的检查],以确定这台机器可以部署

kubernetes kubeadm init pre-flight check:

(1)kubeadm版本与要安装的kubernetes版本的检查 (2)kubernetes安装的系统需求检查[centos版本、cgroup、docker等] (3) 检查用户、主机、端口(如6443和8080端口是否被占用)、swap等

对应的日志如下:

第二步,生成 /etc/kubernetes/pki/ 目录下一系列证书:生成kubernetes对外提供服务所需要的各种证书可对应目录,也就是生成私钥和数字证书 /etc/kubernetes/pki/*

(1)自建ca,生成ca.key和ca.crt (2)apiserver的私钥与公钥证书 (3)apiserver访问kubelet使用的客户端私钥与证书 (4)sa.key和sa.pub (5)etcd相关私钥和数字证书

第三步:生成 /etc/kubernetes/ 目录下,一系列为其他组件访问kube-ApiServer所需的配置文件xxx.conf

ls /etc/kubernetes/ admin.conf controller-manager.conf kubelet.conf scheduler.conf

对于 /etc/kubernetes/ 目录下的四个文件,其作用是:

admin.conf kubectl与apiServer打交道的文件 controller-manager.conf controllerManager与apiServer打交道的文件 kubelet.conf kubelet与apiServer打交道的文件 scheduler.conf scheduler与apiServer打交道的文件

(1) 有了$HOME/.kube/config就可以使用kubectl和K8s集群打交道了,这个文件是来自于 /etc/kubernetes/admin.conf,就是将 /etc/kubernetes/admin.conf 这个拷贝到 $HOME/.kube/config ,如下:

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

(2)kubeconfig中包含了cluster、user和context信息:kubectl config view

(3)允许kubectl快速切换context,管理多集群

第四步,生成 /etc/kubernetes/manifests 目录下一系列yaml文件:为master生成Pod配置文件,这些组件会被master节点上的kubelet读取到,并且创建对应资源

ls /etc/kubernetes/manifests/*.yaml kube-apiserver.yamlkube-controller-manager.yaml kube-scheduler.yaml

这些pod由kubelet直接管理,是静态pod,直接使用主机网络 kubelet读取manifests目录并管理各控制平台组件pod的启动与停止 要想修改这些pod,直接修改manifests下的yaml文件即可

05-下载镜像

下载镜像,等待控制平面启动,k8s.gcr.io下载不了,所以我们先提前下载并且tag好了

06-启动/etc/kubernetes/manifests/目录下的静态Pod

一旦这些 YAML 文件出现在被 kubelet 监视的/etc/kubernetes/manifests/目录下,kubelet就会自动创建这些yaml文件定义的pod,即master组件的容器。master容器启动后,kubeadm会通过检查localhost: 6443/healthz这个master组件的健康状态检查URL,等待master组件完全运行起来

cat /etc/kubernetes/manifests/kube-apiserver.yaml里面有健康检查的配置

07-安装默认插件,kubernetes默认kube-proxy和DNS两个插件是必须安装的,dns插件安装了会出于pending状态,要等网络插件安装完成,比如calico

【 kubectl get daemonset -n kube-system 可以看到kube-proxy和calico[或者其他网络插件] 】

08-将ca.crt等 Master节点的重要信息,通过ConfigMap的方式保存在etcd中,工后续部署node节点使用

09-设定当前node为master,master节点将不承担工作负载,为集群生成一个bootstrap token,包括token和sha256,如下

2.2.2 kubeadm join

kubeadm join 192.168.0.51:6443 --token yu1ak0.2dcecvmpozsy8loh \ --discovery-token-ca-cert-hash sha256:5c4a69b3bb05b81b675db5559b0e4d7972f1d0a61195f217161522f464c307b0

kubeadm join 三个变量 = masterIp + token + hash(即sha256)

01 join前检查

02 discovery-token-ca-cert-hash用于验证master身份

# 可以计算出来,在w节点上执行 openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -pubkey | openssl rsa -pubin - outform DER 2>/dev/null | sha256sum | cut -d' ' -f1 # 最终hash的值 909adc03d6e4bd676cfc4e04b864530dd19927d8ed9d84e224101ef38ed0bb96

03 token用于master验证node

# 在master上节点上,可以查看对应的token kubectl get secret -n kube-system | grep bootstrap-token # 得到token的值 kubectl get secret/bootstrap-token-kggzhc -n kube-system -o yaml # 对token的值进行解码 echo NHRzZHp0Y2RidDRmd2U5dw==|base64 -d --->4tsdztcdbt4fwe9w # 最终token的值 kggzhc.4tsdztcdbt4fwe9w

04 实在忘了怎么办?​​​ 支持一个k8s集群运行起来的核心组件汇总

kubectl 是客户端,任何一个机器有了 kubectl 和 .kube/config 就可以任意操作 k8s-cluster apiServer是中枢纽带,/etc/kubernetes/xxx.conf admin.conf(kubectl) controller-manager.conf kubelet.conf scheduler.conf scheduler是调度策略,就是哪个pod需要随机放到哪个node上(一般放到node上,master不放业务pod) controller Manager 创建真正的资源的工具人,不同的Controller Manager创建不同的资源,包括Deployment StatefulSet Service ServiceAccout NameSpace kubelet 运行和管理Pod,可以认为是kubernetes服务端,运行在所有节点中(包括master和node),将所在节点的Pod的信息汇报给apiServer kube-proxy 所有节点都运行,作用集群内节点之间的通信,serviceName.namespace 这样集群内的调用是需要 kube-proxy 底层来完成的(常用的在另一个Deployment的env中通过 serviceName.namespace 调用上一个Service,还有就是 Service 负载均衡到各个Pod) dns将域名解析为ip dashboard只是控制面板 etcd 整个集群的配置中心,所有集群的系统配置、系统状态都存储在etcd kubeadm 安装工具,仅仅只是kubernetes的安装工具

01 kubectl

总得要有一个操作集群的客户端,也就是和集群打交道

02 kube-apiserver

整个集群的中枢纽带,负责的事情很多

(1)/etc/kubernetes/manifests/kube-apiserver.yaml # kubelet管理的静态pod (2)--insecure-port=0 # 默认使用(3)安全验证的一些文件 (4)准入策略的拦截器 (5)--authorization-mode=Node,RBAC (6)--etcd # 配置apiserver与etcd通信

03 kube-scheduler

单纯地调度pod,按照特定的调度算法和策略,将待调度Pod绑定到集群中某个适合的Node,并写入绑定信息,由对应节点的kubelet服务创建pod。

(1)/etc/kubernetes/manifests/kube-scheduler.yaml # kubelet管理的静态pod (2)--address表示只在master节点上提供服务,不对外 (3)kubeconfig表示

04 kube-controller-manager

负责集群中Node、Pod副本、服务的endpoint、命名空间、Service Account、资源配合等管理

会划分成不同类型的controller,每个controller都是一个死循环,在循环中controller通过apiserver监视自 己控制资源的状态,一旦状态发生变化就会努力改变状态,直到变成期望状态

(1)/etc/kubernetes/manifests/kube-controller-manager.yaml # kubelet管理的静态pod (2)参数设置ca-file (3)多个manager,是否需要进行leader选举

05 kubelet

集群中的所有节点都有运行,用于管理pod和container,每个kubelet会向apiserver注册本节点的信息,并向master节点上报本节点资源使用的情况

(1)kubelet由操作系统init[systemd]进行启动 (2)ls /lib/systemd/system/kubelet.service (3)systemctl daemon-reload & systemctl restart kubelet

06 kube-proxy

集群中的所有节点都有运行,像service的操作都是由kube-proxy代理的,对于客户端是透明的

(1)kube-proxy由daemonset控制器在各个节点上启动唯一实例 (2)配置参数:/var/lib/kube-proxy/config.conf(pod内) # 不是静态pod (3)kubectl get pods -n kube-system (4)kubectl exec kube-proxy-jt9n4 -n kube-system -- cat /var/lib/kube-proxy/config.conf (5)mode:"" ---># iptables

07 DNS

域名解析的问题

08 dashboard

需要有监控面板能够监测整个集群的状态

09 etcd

整个集群的配置中心,所有集群的状态数据,对象数据都存储在etcd中 kubeadm引导启动的K8s集群,默认只启动一个etcd节点

(1)/etc/kubernetes/manifests/etcd.yaml # kubelet管理的静态pod (2)etcd所使用的相关秘钥在/etc/kubernetes/pki/etcd里面 (3)etcd挂载master节点本地路径/var/lib/etcd用于运行时数据存储,tree

2.4 kubectl

语法 :kubectl [command] [TYPE] [NAME] [flag] 官网 :动词,用于操作k8s集资源对象的命令,比如apply、delete、describe、get等 TYPE: 类型,要操作资源对象的类型,区分大小写,比如pod[pods/po]、deployment NAME: 具体名称,要操作对象的具体名称,若不指定,则返回该资源类型的全部对象[是默认命名空间下的] flags: 可选

查看集群信息

# 查看集群的信息 kubectl config view # 查看cluster的信息 kubectl config get-clusters

创建资源,name可以是文件名,也可以是目录名

kubectl apply -f xxx.yamlkubectl apply -f

查看资源对象

# 查看Pod kubectl get pods # 查看Service kubectl get svc

问题查看调试

# 启动日志调试kubectl describe pod pod-name # 运行日志调试kubectl logs -f pod-name # 进入容器调试kubectl exec -it pod-name kubectl attach

2.5 kubelet

官网 :在k8s集群中,每个Node上都会启动一个kubelet服务进程,用于处理master节点下发到本节点的任务。 管理Pod及Pod中的容器,每个kubelet进程会在API Server上注册节点自身信息,定期向Master节点汇报节点资源的使用情况,并通过cAdvisor监控容器和节点资源。

2.6 kube-proxy

官网 :在k8s集群中,每个Node上都会运行一个kube-proxy进行,它是Service的透明代理兼负载均衡器,核心功能是将某个Service的访问请求转发到后端的多个Pod实例上。

2.7 Kubernetes源码查看方式

Kubernetes是Go语言写的,如下:

源码地址 :Server

3.1 kubectl与APIServer之间是REST调用

官网 :Kubernetes API server validates and configures data for the api objects which include pods, services, replicationcontrollers, and others. The API Server services REST operations and provides the frontend to the cluster’s shared state through which all other components interact.

(1) 查看yaml文件中的apiVersion

grep -r “apiVersion” .

./pod_nginx.yaml:apiVersion: apps/v1 ./my-tomcat.yaml:apiVersion: apps/v1 ./my-tomcat.yaml:apiVersion: v1 ./mandatory.yaml:apiVersion: v1 ./mandatory.yaml:apiVersion: v1 ./mandatory.yaml:apiVersion: v1 ./mandatory.yaml:apiVersion: v1 ./mandatory.yaml:apiVersion: v1 ./mandatory.yaml:apiVersion: rbac.authorization.k8s.io/v1beta1 ./mandatory.yaml:apiVersion: rbac.authorization.k8s.io/v1beta1 ./mandatory.yaml:apiVersion: rbac.authorization.k8s.io/v1beta1 ...

效果如下:

(2) REST API设计

api官网 :v1.19 :localhost:8080/api/v1/namespaces/wordpress/podscurl 127.0.0.1:8080/api/v1/namespaces/wordpress/pods

(4)kube-apiserver

把 8080 端口暴露出来,就可以用restful 接口操作了

# 默认8080端口是没有打开的lsof -i tcp:8080 vi /etc/kubernetes/manifests/kube-apiserver.yaml [kubeadm安装方式] # 查询insecure-port,并将修改端口为8080 insecure-port=8080 # kubect apply生效,需要等待一会 kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml

效果如下:

(5)查看端口以及访问测试 可以发现结果和kubectl使用一样

lsof -i tcp:8080 curl localhost:8080 curl localhost:8080/api curl localhost:8080/api/v1 curl localhost:8080/api/v1/pods curl localhost:8080/api/v1/services

(6)设计一个Pod的url请求​​​ -core-strong-

(7)这种操作还是相对比较麻烦的,哪怕使用kubectl,怎么办?其实已经有开源的kubernetes-client

小结:apiServer打开8080端口,提供了一个restful风格出来了。

3.2 集群安全机制之API Server

官网 :server的rest api来实现的,难道所有的操作都允许吗?当然不行,这里就涉及到认证、授权和准入等操作。

传输安全 Transport Security 认证 Authentication 授权 Authorization 准入控制 Admission Control IP和端口 API Server Ports and IPs

3.2.1 API Server认证(Authentication)

官网:​​​ HTTPS证书认证:基于CA根证书签名的双向数字证书认证方式 HTTP Token认证:通过一个Token来识别合法用户 HTTP Base认证:通过用户名+密码的方式认证

中文社区(中文写的,界面跳转快):- 认证 - 授权 - 准入控制 - Port和Ip的操作 传输安全:客户端和服务端之间安全通道,实现数据的加密传输 认证:说白了,就是要识别客户端的身份,认证分为两个维度 认证的第一个维度(三种方式有其一就可以了):HTTPS证书认证、token、用户名和密码 HTTPS证书认证就是ca认证

对于master节点的 /etc/kubernetes/pki 目录下的一系列证书,就是如下图:

认证分为两类(即两个维度)

认证的第一个维度:外部客户端(系统外部组件)要想和apiServer的认证,通过三种方式有其一就可以了:HTTPS证书认证、token、用户名和密码

认证的第二个维度:系统内部组件要想和apiServer的认证,通过serviceAccount实现

serviceAccount简称为sa,主节点上默认就有一个serviceAccount,使用 kubectl get sa 查看,使用 kubectl describe sa 查看详细信息;每一个pod也会有serviceAccount,进入pod里面的容器,存放在 /run/secrets/kubernetes.io/serviceaccount 目录下。

系统内部组件 serviceAccount 默认有一个serviceAccount,可以直接使用默认的 serviceAccount,也可以用户自己新建 serviceAccount ,授予权限。

3.2.2 API Server授权(Authorization)

官网:ABAC授权模式(已过时):基于属性的访问控制 (2) Webhook授权模式(已过时) (3) RBRC授权模式(推荐使用):基于角色的访问控制

常见的资源是Role、ClusterRole、RoleBinding和ClusterRoleBinding,用户可以使用kubectl或者API调用等方式操作这些资源对象,如下图:

Role与ClusterRole的区别(RoleBinding与ClusterRoleBinding的区别) 没有Cluster,Role和RoleBinding,表示某个局部的权限 有Cluster,ClusterRole和ClusterRoleBinding,表示整个集群的权限

(1) 定义一个ServiceAccount (2) 定义一个Role,角色关联的权限 (3) 最后定义RoleBinding,直接把 ServiceAccount 和 Role 都绑定起来

3.2.3 Admission Control(准入控制)

官网 :AlwaysPullImages:在启动容器之前总是尝试重新下载镜像 AlwaysDeny:禁止所有请求

Admission Control 是准入控制,类似于 filter 拦截器,可以修改或拒绝请求(modify or reject requests),准入控制通俗易懂的来说就是 一组强大的拦截器给你拦着,只要有一个拦截器你没有通过,整个请求就失败了。

最后,过三关(认证、授权、准入控制)之后,用户就可以操作具体资源,并将操作的相关信息写入到etcd的持久化存储里面。

四、Scheduler

官网 :,如下:

通过调度算法,为待调度Pod列表的每个Pod,从Node列表中选择一个最合适的Node。 然后,目标节点上的kubelet通过API Server监听到Kubernetes Scheduler产生的Pod绑定事件,获取对应的Pod清单,下载Image镜像,并启动容器。

4.1 架构图

In Kubernetes, scheduling refers to making sure that Pods are matched to Nodes so that Kubelet can run them

4.2 流程描述

​​(1)预选调度策略:遍历所有目标Node,刷选出符合Pod要求的候选节点 (2)优选调度策略:在(1)的基础上,采用优选策略算法计算出每个候选节点的积分,积分最高者胜出

4.3 预选策略和优选策略

4.3.1 预选策略

​​PodFitsHostPorts PodFitsHost PodFitsResources

4.3.2 优选策略

SelectorSpreadPriority InterPodAffinityPriority

4.4 实战

4.4.1 Node

(1)正常创建pod,网盘/课堂源码/scheduler-node-origin.yaml

kubectl apply -f scheduler-node-origin.yaml kubectl get pods kubectl describe pod pod-name

主要是体现node的调度

kubectl get nodes m -o yaml

找到labels,如下:

4.4.2 Pod

上面是node亲和力,也可以有Pod亲和力,如下:

affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - k8s topologyKey: kubernetes.io/hostname

表示的含义是:required当前的pod创建,要能够找到有另外的pod app=k8s 和它在同一个node上。

五、尾声

Kubernetes第八篇:k8s启动、系统组件、APIServer与Scheduler,完成了。

天天打码,天天进步!!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【云原生 | Kubernetes篇】Kubernetes简介(一)
下一篇:Kubernetes第七篇:Pod进阶、Controller进阶、Resource和Dashboard
相关文章

 发表评论

暂时没有评论,来抢沙发吧~