3.1 前情回顾1
之前是用二进制的方式部署K8S
没有配置iburst,同步就是一点点拉,因为配置了就是一下子拉满,有些程序可能崩溃,千禧年不是瑞年,所以在计算机里可能差一天,也是用iburst同步,一下子会要命
要做一些内核转发
Nexus3也可以做docker私服
不光cfssl这个工具可以用,还可以用openssl
如果内存不够大,小于64g,不然就建议开交换分区跑kubelet忽略swap分区,k8s官方建议kubelet运算节点关闭swap分区
8080其实走的是http协议和apiserver进行通信,跨网络就必须走6443通信,这三个组件部署在一台主机,就是为了scheduler和controller-manager 和apiserver走127.0.0.1进行通信。
etcd是https,集群内部通过2379端口,对外是2380提供服务,所以etcd物理部署,想部署哪里就部署哪里
etcd选举就是老大议员,写遗书,会根据其他议员的状态去调整这个遗书,谁来当主
运算节点两个,kubelet是干活的(启动容器,和容器引擎进行通信,监控容器运状态),apiserver只接受请求,该存etcd存etcd,该调度调度,该找controller-manager就找controller-manager。
kube-proxy,1.12开始建议使用ipvs流量调度算法,1.3 版本以前就是用userspaces来进行流量调度,造成大量用户空间和内核空间的交换,比较浪费资源。
如果用iptables规则,对操作系统资源就比较消耗大,所以建议使用kube-proxy的ipvs
3.2 前情回顾2–关于K8S证书
下载了cfssl(证书签发的主要工具)和cfssl-json(将cfssl生成的json文件变成文本文件,变为文件承载式证书,加-bare 加文件前缀),cfssl-json只是转化一下格式
issuer就是CA证书
签发的证书叫k8s-apiserver
sans就是在哪些节点上可以用,有可能部署的节点通通列到证书里,规划好
签发证书的时间和有效期,kubeadmin默认有效期是1年
还可以查domain
生产中先看证书什么时候过期
在kube/conf文件里有
看看两个节点一样不一样,可以算md5值出来
kubelet.kubeconfig有多套
通过四步,setcluster,setcredentials,3.setcontext,4.usecontext,把证书揉到配置文件里了
可以用 base64编码去反解
这个证书拿到后就可以输出重定向到
就可以用cfssl-certinfo,如果用阿里云的服务,是提供kubeconfig文件的,其实就拿到了k8s证书,就可以用base64反解
kubeconfig其实是一个k8s用户的配置文件,ca证书文件替换了,这个配置文件也要替换,kubelet.config,kube-proxy.config,要同步替换文件
3.2 前情回顾3–课程大纲
实战中,也可以有运维主机去管理生产和测试
之前是l4反代6443端口,nginx从1.8以后就可以提供4层反向代理了,两个6443都关联到vip的7443
k8s1.6以上可能会出问题安装 dashboard
3.4 kubectl详解–陈述式资源管理方法
对k8s集群的管理就是,对k8s集群里的各种资源,4组核心的概念,pod和pod控制器,name和namespace,label和label selector,ingress和service。
k8s集群真正抽象出来的各个概念都是不同的资源
陈述式就是CRUD,
这三种方法各有特点,属于互相依托,协同工作
查看名称空间,把所有名称空间给列出来了,这是自动生成的
其实有很多核心资源是有简称的,ns=namespace,其实查询资源的时候,应该都带上名称空间,名称空间同样类型的资源是有可能重名的
查询default名称空间里的所有资源
pod资源
service资源
pod控制器资源,daemonset
名称空间是 -n default的时候是默认不写的,否则必须显示-n 指定哪个名称空间
namespace可以简写成ns
也可以删除
现在需要去创建一个pod控制器,pod控制器就是来保证拉起一个pod的,使pod无限接近预期
之前的harbor
deployment简写使deploy
在kube-pulic名称空间申明创建了一个pod控制器,类型是deployment,使用的镜像是harbor仓库里的nginx,按照意愿吧容器发展起来
pod控制器名字
已经running起来了
用扩展的方式去显示资源
这是pod名字
一看这个ip就知道在哪台主机上
有nginx的镜像还有,pause镜像,这个pause镜像和业务镜像是side-car方式运行的,边车模式运行的,用途是先于业务容器,先起来把net,UTS,ipc空间站上
也就是docker容器,pause和nginx是UTS,NET,IPC是通用的。
扩展查看用-o wide是通用的
详细查看
用kubectl用任何命令都要-n 名称概念这个东西很重要
处在的名称空间
创建的时间
默认添加了一个label
注解,容器变更发版,就变成2了
seletor是标签选择器
replicas,有多少个副本集,desired渴望的,updated 到最新的状态了,total总共是一个,available一个存在,一个不存在unavailable
更新策略,k8s默认策略是滚动发布
容器用的什么镜像
kubectl命令下去,其实是先找apiserver,然后找scheduler,scheduler会在最恰当的节点帮你去启动容器,就算调度也是通过kubelet干活
apiserver,本机上有controller-manager和scheduler,一个请求时kubectl的请求,通过127.0.0.1找到apiserver,发送请求创建一个pod控制器,这个pod控制器名字就nginx-dp,这个pod控制器使用的容器镜像是harbor.od.com/public/nginx:v1.7.9,scheduler通过优选函数,找到启动pod的节点
21的apiserver要找kublet的时候,只能到10.4.7.10:7443
kubelet的server就是vip的7443,找kubelet就从这里开始找,因为配置文件写死了
然后找到kubelet去干活,kubelet也是自己去签发了一套server证书,apiserver是做为kubelet-client去找kubelet,kubelet就作为服务端,老实把活做了
跟docker exec是一样 的
kubectl exec是可以跨主机的
用docker exec是一模一样
用docker exec和kubectl exec 都可以,一般能用docker解决的用docker解决
有pause和nginx镜像
一般containerid是哈希码,手写前4个一般不重复
每一秒执行这个命令看一下
注意看events
把pod干掉
跟之前的名字已经改变了
现在调度到了172.7.21.3节点上
predicates预选策略,priorities优选策略
找到最大卷的方法
你把pod delete了,pod控制器没有delete ,pod控制器本身预期是有一个pod,由pod控制器来保证无论如何有一个pod
删除不掉pod的时候,可以加–force --grace-period=0
现在就把pod控制器删除了
service是核心资源之一,核心资源有pod,pod控制器,service,ingress
现在把deployment创建起来了,要给这个pod创建一个service资源,刚才删除pod,会自动起来一个,这样如何稳定对外提供服务,就需要service
多了一个service资源被列出来了,用的是cluster ip这个ip是192.168.27.1,这个ip就是port的一个接入点
现在是在22上
统一接入点是192.168.27.1
lvs前端,反代后端的172.7.22.3
把这个deployment扩容一下
代理后端两个真实服务器,service就是抽象一个具体的点,让服务有稳定的接入点
名字nginx-dp
标签 app=nginx-dp
service是如何找到pod的,就是用label selector,凡是在label app=nginx-dp,在一个名称空间内都加到serivice
采用集群ip的service
集群网络是一个虚的网络
只有在k8s集群里,这个ip才有意义,这个虚拟ip不对外提供服务,集群的网络是不直接暴露给k8s外面的。
*
ipvs默认调度是nq ,never queue 用不排队,后端调度的是pod的网络地址,kube-proxy技术把集群私有网络和pod网络做了关联
基本上已经覆盖了增删改查,覆盖三种核心资源,pods,name spaces,pod控制器,和service
k8s集群管理集群资源 唯一入口就是调用相应的apiserver方法。
kubectl是官方的命令行工具,用于和apiserver进行通信
node可以打污点
k8s中文社区
也就是手撕命令行的方法可以满足90%以上的工作需求了
daemonset这个pod控制器是让每个运算节点都要运行一份,所以现在想用daemonset暴露service
不能给daemonset控制器,用命令行的方式去创建一个service
使用patch,还要使用json字符串就比较痛苦
3.5 kubectl详解–声明式资源管理方法
陈述式有局限性,所以可以用声明式方法,声明式资源管理方法依赖于,资源配置清单yaml或json
就变成了yaml格式的统一配置清单
spec里指定了container用什么image,拉取策略
就把svc的统一配置清单拉回来了,主要的段,apiversion,kind,metadata,spec这4个段必须有的
下面的字段会有一些文档描述
学习yaml最有用的语句就是explain
资源配置清单贴进来
用陈述式命令用起来
现在就有两个
看一下yaml,就是按照资源清单的要求创的
可以用create也可以apply修改
对外暴露改成880,修改一下
出错了先把这个svc删除
再次apply,现在就是8080
修改资源清单分为在线修改或者离线修改
在线修改,默认在default名称空间,可以把8080改成801
离线修改试试
spec这里需要一个name
现在直接输出重定向
把一些删除,简化成一个非常简的svc
失败就换一下
换一个deployment镜像,换一个nginx curl镜像
打一个tag
push到harbor仓库里
资源配置镜像换掉
现在就修改了
daemonset简称ds
这里的image就改过来了,申明式修改资源依赖的是资源配置清单,然后去apply这个资源配置清单
直接describle历史指令
已经running
修改资源配置有两种,在线修改,一般用离线好点,在线修改(线上资源配置清单和线下的就有差异,真正要修改是资源清单的库)
删除有声明式删除,和陈述式删除
陈述式删除直接delete即可
声明式删除,-f指定文件
改用声明式比较好,增删用陈述式比较好
3.6 kubectl详解–学习小结
陈述式就是命令行,声明式就是yaml
声明式资源管理方法依赖于资源配置清单,可以式yaml或者json,是可以互相转换的
可以直接-o成json
yaml对人比较友好,json对api接口比较友好
声明式资源小结。管理资源就是增删改查,增删查用命令行比较好实现,改特别费劲,需要用到patch(json)
先定义yaml,然后把yaml应用到k8s集群
**1.资源配置清单学起来很难,可以多看看官方的写的
2.可以照着现在的改
3.善于explain查
**
3.7 flanneld安装部署详解
之前的集群两个节点间docker不能互相通信
在21和22上节点都有容器
在21节点ping21可以通,ping22通不了
这里根本ping不通
既然要组成集群,就要解决容器在不同节点上的互通。不互通是没办法使用的,所以离不开cni插件,就是解决容器在不同宿主机之间互通的
cni网络插件最主要的功能就是实现pod资源能够跨主机进行通信
canal类似把flannel和calico结合,前部分用flannel,后部分哟个calico,有一些限制网路的规则内容。
contiv是思科开源的网络插件。
NSX-T是vmware开源
kube-router是k8s自己弄的,试图取代kube-proxy
市场上的分布
部署flannel和部署k8s核心组件pod一样,(之前部署k8s包,是下载二进制包,然后解压出来,进行必要的配置和签订证书,启动脚本,创建目录,把需要的目录用户创建好,最后委托给supervisor管理。成为后台进程,比如你的进程异常退出了,supervisor可以拉起来)
做flannel也是这个套路
这是源码包的地址
现在21上安装
下载后,先创建flannel目录,弄了软连接,方便日后升级
flannel默认使用etcd作为存储和配置,需要让flannel能够链接etcd,需要把client.pem拿过来,作为etcd的客户端
目录结构
拷贝证书后,创建配置文件
定义了环境变量,flannel管理的网络(管理pod网络,能够让pod网络进行互通,本机的flannel子网是172.7.21.1/24,可以把容器的网络规划成一个大的网段)
创建好subnet就可以给flanneld创建启动脚本
public ip就是node节点
创建supervisor之前先去操作etcd,增加host-gw,flannel依赖etcd存储网络信息的,需要在etcd上去执行,set一下网络设置
用etcd去set一个节点,key是/coreos.com/network/config,值是{类型是host-gw}
看一下etcd谁是主,21是主
这里改成stdout
把标准的错误输出重定向到标准输出,2>&1
现在没有报错
现在是ping不通的
flannel已经running起来了
要到22上安装flannel
创建subnet.env
创建flanneld.sh
创建目录,加上执行权限
把证书复制过来
现在就通了
3.8 详解flanneld工作原理
容器跨主机能通信
这是在22主机上一个静态路由
flannel的host-gw模型,宿主机 是10.4.7网段,docker是172.7.21/22.0网段。docker的网络要找到对方的docker网络,是先经过宿主机的网关 ,然后再转发到172.7.22.0
宿主机网络本来就是互通的,host-gw就是添加gateway网关
实际上flannel起来就做了加路由这个事情
flannel host-gw模式就是添加路由,其他什么也没做,host-gw模型有很重要的前提条件,宿主机要在同一个2层网络下,也就是指向同一个网关设备,这样才能使用维护路由的方式,做到docker跨宿主机通信。
CNI网络插件,效率最高的就是flannel的host-gw模型,没有其他资源开销
flannel的 VxLan模型,两台宿主机分属不同的2层网络,10.4/5.7.1在两个不通的2层网络下。
在两台不同的宿主机上实例化两个虚拟的网路的设备,这个设备的名字就是flannel.1,虚拟网络设备,也就是网卡。
所以要经过封包,通过flannel隧道传送过去一层层解开。类似VPN,要装那个vpn包,走隧道
可以不做先看看,避免flannel瘫痪,先停了
没有关掉,就删除
虽然flannel停了,但是还需要把路由删除
修改flannel工作模式,先删除
修改成vxlan,只是做演示,并不是最终的
后端改成vxlan了
现在通了
ifconfig里有flannel.1网卡
现在是为flannel.1设备添加了路由
flannel用什么模式,完全取决于你宿主机用的网络规划,生产中,K8S主机不可能在不同的2层网络下
如果运算节点都在同一个2层网络下,应该毫不犹豫选择host-gw模型
直接路由模型,这是vxlan和directrouting直接路由的混合模型,当发现两个宿主机在同一个网络中,就走host-gw,这样就由flannel自行判定是否在同一个2层网络下
恢复成host-gw模型
先关闭flannel
调整etcd
启动flannel
通了
3.9 flannel之SNAT规则优化
把镜像改成curl
应用进去
默认就是default名称空间,delete之后,自己会把容器拉起来,因为pod控制器还在,pod控制器还在,只删除pod,相当于重启
两个都重新起来了
安装一下net-tools,这样就有ping
默认的nginx官方的容器,-f就是access.log
snat是在iptables的nat表的postrouting上做的,来源地址是172.7.21.0/24,-o 不是从docker0出网,才做masquerade,源地址转换,伪装宿主机ip出网,只规定了源地址,没有目标地址,现在希望的是,出网的地址是172.7.21.0/24,也不要做源地址ip转换,所以需要优化iptables规则
还需要优化,并不是安装了flannel,k8s集群就正常了
优化iptables规则
先把这个删除掉,源地址是172.7.21.0,不是从docker0出去的,才做源地址转换
再加一个不是去往172.7.0.0/16网络的,也不是从docker0出网的才去做snat转发
用iptable-save把当前规则保存
先删然后再优化,步骤不能错
优化snat规则,10.4.7.21主机上的,来源是172.7.21.0/24段的docker的ip,目标ip不是172.7.0.0/16段,网络发包不从docker0桥设备出站的,才进行SNAT转换
flannel干掉,重新再拉起来
这里有两个reject
删除reject
把forward也删除
通了
进入到21的容器,curl22容器
在k8s集群内部curl的应该看到的是真实ip,一定要优化,k8s内部的容器一定要做snat规则优化,让容器互相看到的是真实的ip,不能看到nodeip。
容器和容器之间通信,每一次都要做snat规则转换,有问题,优化snat就是为了让所有容器都坦诚相见
masquerade本意是伪装,面具是10.4.7.21,实际上是172.7.21.2,被flannel规划到一个容器网络里了,应该坦诚相见。我们要求k8s所有集群节点都是坦诚的,docke和docker之间,容器和容器之间一定要坦诚,不然有问题
现在要优化这条iptables规则
-I是insert,-A是append,来源是172.7.22.0的,目标地址不是172.7.0.0/16,不是容器的,才做转换,其实就是容器之间不要转换了
从宿主机上curl
是宿主机上的ip没有问题
没有问题,容器和容器间坦诚相见了