k8s_day02_01

k8s_day02_01

​ apiserver 是整个k8s 系统的总线 ,是整个集群中唯一一个能存集群状态数据的位置。 但是apiserver 本身并不存,而是交给etcd 存储了。 所以etcd 在生产环境要做分布式冗余高可用,etcd 是基于go 语言、raft 协议研发的 强一致性分布式 的轻量级kv 存储系统

​ 分布式、强一致的系统在协同时可能会发生脑裂,因此为了避免脑裂,集群的节点一般是奇数个,所以etcd 最少3个节点。因为apiserver 与etcd 是通过https 协议通信的 ,相当于apiserver 是无状态的,apiserver 做冗余就不必要和ectd 节点数量保持一致取奇数个,一般2个就够了,当然这也取决于我们的业务系统。apiserver 本质是https 服务, 监听在6443 端口,当api有多个时 , 客户端选择任意一个都行,所以可以把api 防止负载均衡器上,但是负载均衡器也可能单点失败,所以可以再配keepalived。nginx 用4层负载就行

image-20211125201851003

而对于后端的server ,发生故障时,只要nginx 能探测到自己健康状态,并且摘除即可。

关于状态健康性检测,有2种,主动(AH)和被动(PH)检查

对于PH,通常叫做故障探测 或者叫异常值探测。nginx 做的探测 多数都是主动的,nginx 向后端发送请求,如果得到正常响应,就算健康。而被动检查 主要是观测 流量是否正常进行,如根据正常流量的响应码,是200还是502 判断。 还有就是根据相应时长,时间过长 大于正常平均时间就算有问题

​ controller manager 是控制器管理器,实现的作用是真正意义上是让k8s 所有功能得以实现的控制中心,k8s 有一个特点就是把运维日常工作代码化 ,代码化的集成位置就在controller 中。controller manager 中包含多个controller程序,把他们单个的controller 打包在一起成为一个组件,我们把它称为manager。

​ 每个controller内部都有一个叫controller loop 的控制循环,这个死循环 会一直监视着 k8s 上所管理的那个对象的数据,比如pod数量,一旦不满足就会增减。

Scheduler 没有太大作用,除了调度,主要是调度Pod[现在IT架构,都讲究以应用为中心] ,k8s 的核心作用就算运行应用。Scheduler 会时刻关注每个节点上的资源可用量, 以及能为了更好运行这个应用所需要的运行环境,让二者做最佳匹配。当然如果最佳匹配的节点不止一个,如何选择呢? 至上而下随便选一个就行。当然也可以选择一个合适的节点调度存储卷

​ node 的主要作用就是为了运行Pod, node 的三个组件 :

​ kubelet ,是 整个apiserver 或者控制节点的 运行在每一个工作节点的agent,控制节点的大多数任务都是kebelet 执行的。所以可以认为控制平面派出到每一个节点上的 去执行控制平面所需要执行的任务,尤其像是创建删除pod 都是kebelet 完成的。也就意味着调度器调度完了, kubelet 就会知道这是调度到自己机器上的,它负责把创建容器的配置拿过来,在本机上调用container engine,如dockers ,

​ kube-proxy :

​ service 就是由 kube-proxy在每个主机上生成的iptables 或者ipvs 规则。为什么service 能调度后端的pod呢, 创建的每一个service 都存到api server 上了 ,只要是创建或删除service 的操作, kube-proxy 就会在对应的节点上生成一些iptables规则,以便本地的pod能被负责均衡的规则所调度。service 内部用的是一种叫random 的算法,把请求随机分配到pod上。当然也可以用ipvs, ipvs支持更多的算法,sh 、dh、rr、wrr、wlc 等等。虽然说k8s 未必对ipvs中的每种算法都支持,但是好在多余iptables 的只有一个random 算法。二 、如果k8s 中跑了太多的service ,iptables 规则将会巨多,上万条,性能就会大受影响,但ipvs 就不会。

​ kube-proxy 就是一个确保 分散运行在各个节点的pod能够被正常调度一个daemon 守护进程

​ docker

运维工程师的三大核心职能:故障管理、资源管理、变更管理 k8s 对这些都有涉及:

  • 故障管理: k8s 要部署日志分析展示系统用于容器排障

  • 资源管理: 需要部署基础设施服务 kube-dns ,kubeadm启动时 会自动帮你运行一个附件 coredns

k8s 依赖的重要附件

Add-ons

  • kubedns: coredns k8s内部使用的域名解析系统可以统称为 kubedns

  • dashboard, web ui: 可以通过网页创建pod service,但是这个ui 目前不是特别好用而且我们特别依赖它😂

  • 监控系统:Prometheus cncf 毕业的第二个项目 本身也是用go 写的

  • 集群日志系统:
    ElastichSearch ,ElastichSearch 本身并不收集日志,而是借助客户端收集工具 Filebeat/Fluented/fluent-bit等等, 其实日志收集器做起来是很简单的,大公司为了装逼都自己开发 ,日志展示系统 叫kibana ,这套完整的系统就叫EFK

    k8s 为什么不用logstah ,是因为,logstash用的是一种叫 JRuby的语言开发【ruby是一种很小众的开发语言,类似csharp。python 的编译器是用C 开发的,所以python 可以叫做‘cpythjon’ 所以Jruby 是基于java 开发的,filebeat 收集日志只要占用大概2M内存,而logstash 需要占用2G,logstah 太吃资源显得太重量级,不适合在容器中收集日志】

    ​ 除了EFK外,第二种解决方案就是LOKI 。洛基, 是仿照普罗米修斯构建的一套日志收集系统,轻量级,是云原生应用。虽然功能没有EFK 多。它的日志展示系统就是Granfana

  • Ingress Controller:
    ingress 表示入站的意思。 k8s 内部可以愉快的交流,但是当我们想接入外部的流量时,可以使用node port 类型的service 。每一个nodeport 类型的service 就是相当于在集群的边界上挖了一个洞,作为集群管理者,很难知道哪里挖了洞,除非把所有的nodeport 类型的service 找出来。现在大多应用层都是走的https/hhtp 协议,为了方便统一管理,可以nginx 或者envoy 之类的应用做反向代理 来进行这些‘缺口/洞’。 Ingress Controller 就起着类似的功能 ,叫做 入站流量管理器,所有入站流量,都必须经过ingress 进行分派到后面需要与外部通讯的service

  • 除了上面之外的附件还有千千万,那就按需部署了 ,如Jenkins

    ==iaas : 按需创建主机 ==

    paas: 按需开发并且部署程序 ,所以为了运行业务应用,可能还需要部署其他的插件

image-20211126213422185

​ 控制平面组件 和 kubelet 是 k8s 的 非常重要组件,如果被入侵或者流量劫持了,会带来灾难性后果,所以组件间的安全通信非常重要,所以k8s 的组件都是基于https 协议进行的,ks 的一套系统中需要3个ca

  • 第一套 etcdca ,etcd 本身既支持http 又支持https, 为了避免被破环, 做了peer的通信认证,点对点的认证,所以用https

  • apiserver 肯定也需要一套ca 叫错kubernates ca, 用于给apiserver 的客户端和服务端各发证书

    【scheduler 、controller、proxy、kubectl 、kubelet】 都需要客户端证书, apiserver 要服务端证书

    它们彼此之间是双向认证的,kubelet连接到apiserver后 , 要验证它的域名和证书保持一致,反之apisever也要验证kubelet的身份信息 简称 mtls 【mute TLS 】

    ​ 如果手动部署k8s ,需要自己去建立这些证书密钥之类的,超麻烦。现在用的是kubeadm 部署的, kubeadm 已经GA ,可以在生产、和测试环境中使用。GA 叫做 genera availability 公共可用 。早2年,kubeadm 没有GA 是不敢在生产环境中部署的 ,用部署工具叫做github 上kubeeaz 的ansibe工具部署的,虽然部署效果一样。但是这个工具是k8s生态之外的一个工具,无法参与到k8s内生身的很多重要环节之中,而kubeadm 是ks SIG 【special instresting Groups 特殊兴趣小组】 提供的

  • front-proxy-ca 聚合器 和扩展 apiserver时用到的

  • 其实还有一个SA ,它不是证书,而是一个公钥私钥对

k8s 集群部署 和运行模型:3种

  • 二进制程序: 各个组件以二进制程序或rpm包手动管理
  • pod:
    • static pod 静态pod
    • pod : 常规pod 、控制器管理下的pod

image-20211126233128265

如图所示: 3种方式的附件都是 以pod 方式运行

第一种: master 、node 的所有组件 都可以以二进制程序部署的(左下第一个长方形图,cni flannel 除外),所有组件依靠init script 或者systenmd 管理

第二种: master 和node 的组件中,kubelet 和docker 仍然以二进制方式靠 init script 或者systenmd 管理(中间的正方形图),其他组件仍然以Pod方式运行 ,但是 master中的这些pod 是不受控制器管理的,而是受kubelet 直接借助一个叫配置清单的文件(manifest)管理 , kubelet 会监视某个目录是否有某个应用的清单,如果有就创建起来,而且只要发现那个pod 不在会自动创建起来,这叫静态pod。 以kubeadm 为代表

第三种: 相对于第二种来说 ,区别就是 , master上控制平面组件pod 是受控于自己专门的控制器管理,而不是kubelet. 应用场景就是共有云的kaas 服务 (阿里云亚马逊) ,只要你提供 master 和node 的数量,就能拉起一个集群,因为把拉起的过程全部代码化了,缺点就是贵,以动态pod的方式来运行这些控制组件pod

image-20211127000218276

​ 如果用kubeadm 来管理k8s ,它做不到以下事:它不会帮你创建主机,不会帮你管理主机,所以对于Laye1 基础设施层它管理不到 ,无法通过api 创建主机

​ kubeadm 主要在第二层实现了2个功能 bootstrapping(拉起引导)一个集群 ,并且提供一个基本的功能api

​ kubeadm 除了提供了coredns ,在第三层,并没有提供其他的附件

下图蓝色的部分是kubeadm 可以完成的任务,运行蓝色组件。(通常不认为kube-proxy是附件,但是有些机构认为)

image-20211127002348734

k8s 没有实现网络插件,太复杂了,而是交给专业的网络公司。只留了一个容器网络接口

CNI:

​ Container Network Interface。 目前CNI 的解决方案 海了去,有几十种之多,但目前最流行的只有两个

  • flannel
    coreos 这家组织研发的,只实现了网络,而没有实现网络策略 , 简单易学 , 叠加和承载模型都支持, 性能也不差 hostgw 的机制 ,支持directRouting Vxlan 三种
  • Project Calico
    既实现了网络,又实现了网络策略 , 生产环境使用居多,而且支持BGP协议的underlay network 性能更强大
  • Cannel:
    网络功能用flannel 实现 , 策略用Calico 实现 , 现在已经废弃不再更新(因为作者后发现 相当于又实现了一遍Calico)

​ CNI通常要求组件有2个功能:第一网络解决方案,underlay 和overlay 都行. 第二, 网络策略:控制通信的 ,两个pod之间能不能通信 k8s并没有做任何限制,只要能部署就能通信.但是 如果是一个多租户环境 ,如公司里有多个团队,每个团队要独立隔离, 可认为每个团队就是一个租户,租户与租户之间要隔离, 但是就算是用名称空间隔离 起来, A租户去访问 B租户是没有任何问题的,

CRI : R untime 容器运行时

CSI: Storage 存储

flannel 是如何工作的?

image-20211127010330576

节点网络: 各个物理节点 的网卡接口 真正通信的地方(无论是叠加还是承载网络模型 都必须有). 可以认为是是虚拟机Ip 所组成的, 172.29…0.0/16 自己规划

Pod 网络: flannel 用的是10.244.0.0/16 网段 , 会给每个物理节点分配一个子网 如10.244.1.0/24 .这个可以自己设置划分,若想运行最大数量pod,可以网段设置为8位,如10.0.0.0/8…通常一个节点主机 运行256 容器撑死 , 所以每个主机可以分配到一个C类子网(24 位掩码,1个255). 这样就可以支持256*256 台主机 可以自己选择,适配网络插件默认设定 会减少很多麻烦, 除非我们有特殊需要

service 网络: 默认flannel 用的是 10.96.0.0/12 地址 . 所以service 可用的地址为 10.96.0.1 ~10.111.255.255

[root@master01 ~]# kubectl  get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
demoapp      ClusterIP   10.107.176.51   <none>        80/TCP    2d7h
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   2d9h
[root@master01 ~]# 

service 是一个虚假网络 , service 地址不会设置在任何网卡或网络接口上,只是会出现在service相关的iptables或者ipvs 规则中做为服务访问入口或者端点 , 也会出现在dns解析记录中把service对应名称解析为对应ip service 网络 是由kube-proxy 管理 , 在哪里指定的呢,用 kubeadm 部署时, service-cidr参数 指定

–service-cidr string Use alternative range of IP address for service VIPs. (default “10.96.0.0/12”)

kubeadm 拉起一个集群的流程

image-20211127014600068

kubecofig 介绍

[root@master01 ~]# cd /etc/kubernetes/
[root@master01 kubernetes]# ls
admin.conf  controller-manager.conf  kubelet.conf  manifests  pki  scheduler.conf
[root@master01 kubernetes]# 

kubecofig 就是/etc/kubernetes/目录下的文件

[root@master01 kubernetes]# cat admin.conf 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZyT3NqRERsYWtLQgpjcEJmbTZFbjRRSERPVE03aWxHdWZNck9OZ2MrbFpUZlgvY3B1elVvOUxwS0Z6eE5pT2RiNUFzeCtiTmk1bFg0CjQvQjNMbnBqN2tmZzF4bG1EY1Q1VVllMjhsNnRZQUxCQmszTAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://kubeapi.magedu.com:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lJT0F5T2o1c2NRMk13RFFZSktvWklnQwpR2kzWEZ5d09ZZVBwYXdYMGZOdXlGNE5BdFpmWHYvS3JRY1hiY1pQazU0eWsKcjRjbXVmSXJGb1EwbWNSSkNyazFBWU1qMmVOQUJjcz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBNlB3cnFoK0lLeFRnWkliczJEZndRT1bHVHVFdEYWh6WXR3MUdwL05EK0dNSE9yLwpHUFNjVDlEcjdoVWdza29BMWVTM2owbS9hRjlQQVpCK0NKOGR3amJKOXVlOGhyY3YrRU9LQjdzPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
[root@master01 kubernetes]# 

主要就是集群的地址端口 , 集群的名称, 访问集群时用的用户名称以及相关证书,私钥信息.

为什么要写在配置文件中?https 是无状态协议, 每一次访问都要认证 ,不这样就要以命令行的方式指定认证信息. 特麻烦. admin.conf 是 kubectl 客户端以超级管理员(相当于root)的身份连接到apiserver 上时使用的

controller-manager.conf : 控制平面组件除了 apiserver 都是apiserver的客户端,都需要认证 , scheduler.conf也是同理

真正的证书都在/etc/kubernetes/pki/ 目录下

[root@master01 kubernetes]# ll /etc/kubernetes/pki/
total 56
-rw-r--r-- 1 root root 1298 Nov 25 00:26 apiserver.crt
-rw-r--r-- 1 root root 1135 Nov 25 00:26 apiserver-etcd-client.crt
-rw------- 1 root root 1675 Nov 25 00:26 apiserver-etcd-client.key
-rw------- 1 root root 1679 Nov 25 00:26 apiserver.key
-rw-r--r-- 1 root root 1143 Nov 25 00:26 apiserver-kubelet-client.crt
-rw------- 1 root root 1675 Nov 25 00:26 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1066 Nov 25 00:26 ca.crt
-rw------- 1 root root 1679 Nov 25 00:26 ca.key
drwxr-xr-x 2 root root  162 Nov 25 00:26 etcd
-rw-r--r-- 1 root root 1078 Nov 25 00:26 front-proxy-ca.crt
-rw------- 1 root root 1679 Nov 25 00:26 front-proxy-ca.key
-rw-r--r-- 1 root root 1103 Nov 25 00:26 front-proxy-client.crt
-rw------- 1 root root 1679 Nov 25 00:26 front-proxy-client.key
-rw------- 1 root root 1675 Nov 25 00:26 sa.key
-rw------- 1 root root  451 Nov 25 00:26 sa.pub
[root@master01 kubernetes]# 

静态pod 清单文件

[root@master01 kubernetes]#  ll /etc/kubernetes/manifests/
total 16
-rw------- 1 root root 2118 Nov 25 00:26 etcd.yaml
-rw------- 1 root root 3176 Nov 25 00:26 kube-apiserver.yaml
-rw------- 1 root root 2858 Nov 25 00:26 kube-controller-manager.yaml
-rw------- 1 root root 1413 Nov 25 00:26 kube-scheduler.yaml
[root@master01 kubernetes]# 

Taint and the label master : 给master 节点打污点,污点是高级调度策略的一种 ,pod 不会调度到有污点的机器上,所以新建的pod 不会在master 上

Bootstrap Token: 生成一个引导令牌 : 也就是生成一个随机字符串当密码. 这个令牌是会过期的,且符合CA的签名

kubeadm join kubeapi.magedu.com:6443 --token sjh4s0.lsj3y7swfjpf9d2g
–discovery-token-ca-cert-hash sha256:f65cce015ac254b3e7c3a0cac59ac031079d9c31ffac12f31940a57d15c30764

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值