环境:1个Master,3个Node
k8s是一个容器编排工具,所以其核心功能就是容器编排。
在Master上,有三大组件
APIServer :
Master主机地址的6443端口来进行交互。
用户认证:双向的认证。不但要求APIServer向客户端发送证书,也要求客户端向APIServer发送客户端证书,并且CA是要APIService认可的。任何需要接入APIServer或者说是接入K8s的资源都必须通过APIServer来进行操作
Scheduler:通过Scheduler来进行调度
Controller:通过Pod Controller来进行创建Pod并进行管理
Service:客户端访问Pod需要通过Service来进行代理。service需要手动创建
由此可以得出k8s中最为重要的几个组件:Pod,Pod Controller,Service ……
Pod Controller:这是一类控制器的总称,最常用的叫做deployment。他是一个类型,需要向此类型赋值之后,创建出真正的控制器,然后此控制器来帮我们创建Pod
大致流程:Deployment—–> xxx-deploy——–> xxx Pod
Service:也是一种资源类型,需要进行赋值进行实例化,创建出一个特殊的service实例。例如
Service ——->nginx svc ——-关联——->pod
k8s使用Node来运行Pod,并且通过kube-proxy来将Pod相关的service转换为当前节点的iptables或者ipvs规则
kube-proxy也是APIServer的一个客户端,它随时监视着APIServer上的资源变动,尤其是service的变动。
基本操作:
展示pods的详细信息:
在创建pods的时候若没有指定namespace,则默认会在default中。
通过kubectl api-resources来查看可以创建的资源类型,可以使用全称或者简写
创建名称空间:kubectl create namespace develop
删除资源:kubectl delete namespaces develop
或者 kubectl delete ns/develop ns/prod
(删除该名称空间下的所有资源)
查看资源信息:kubectl get ns/default
或者 kubectl get ns/default -o wide
或者 kubectl get ns/default -o yaml
或者kubectl get ns/default -o json
资源的描述信息(状态等):kubectl describe ns/default
创建控制器:kubectl create deployment
kubectl create deploy ngx-dep –image=nginx:1.14-alpine
直接访问Pod
删除Pod : kubectl delete pods/POD_NAME
因为Pod由控制器管理,所以当我们删除Pod之后,控制器会自动再重建一个Pod
使用命令查询:kubectl get pods -o wide
但是ip地址的变动,需要对客户端透明。所以就需要使用到service来做一个类似代理的工作
创建service:kubelet create service clusterip -h
这里的5678就是service(本地)的端口,8080就是远程端口,相当于pod的端口
kubectl create service clusterip ngx-svc --tcp=80:80
但是这种情况并没有指定对应的哪一个pod
删除: kubectl delete svc/ngx-svc
重新创建:kubectl create service clusterip ngx-dep --tcp=80:80
这里的dep要和deployment同名,这样就会自动关联此deployment下的Pod
这时候访问service的ip,得到的返回就是Pod的内容
此时再把Pod 删除
此时控制器会重建一个Pod,这时候Pod的主机可能就会发生变化
此时这个service就会关联到新的主机地址上。所以客户端访问service地址就可以访问到Pod,无需关注Pod的ip变化
但是service的ip可能也会有变动。(删除再重建)
这个时候就可以使用service的名称来访问
开始可以看到,无法解析这个ngx-svc这个名称,原因就是本地默认情况下使用的DNS服务地址是
而在k8s上默认使用的DNS地址是:
所以需要将10.96.0.10作为DNS服务器,才可以进行解析
但是改完ip地址后仍然报错,访问不到,这是因为我们使用的是相对路径
ngx-dep:service的名称
default:service所在的名称空间
svc:固定字符串
cluster.local:k8s所在域的域名,这个是在配置集群的时候,有一个命令:kubeadm init -h
所以这个时候如果把service删了,但是只要service的名称没有变,就可以这样去访问。
deployment还有一个功能,就是按需伸缩Pod规模
再创建一个Deployment:kubectl create deploy myapp --image=xxxxxx(镜像)
为这个myapp也创建一个service:
kubectl create service clusterip myapp --tcp=80:80
扩缩容:现在myapp只有一个Pod,现在想要他扩缩容一下
命令:kubectl scale --replicas=3 deployment myapp
扩容为3个副本
这个改动也会自动的关联到service上
kubectl describe svc/myapp
此时service做了一个类似负载均衡的效果,但是这里默认是随机调度的。
缩容:
使用nodeport来创建service
命令:kubectl create service nodeport myapp --tcp=80:80
这时候会发现多了一个31996的端口,但是这个端口不是pod的端口,而是宿主机的端口,这样就可以在外部访问了。。
为什么是31996端口呢。。这是一个端口内外映射的问题。这是反应在每一个宿主机的iptables的规则里,每个service创建完之后都会立即在每一个宿主机的iptables上建立规则。这是由kube-proxy进程来完成的
总结
客户端所有操作都只能且必须经过APIServer。
这时候再来看这张图,controller-mamager,scheduler,kubectl,kube-proxy这些都是APIServer的客户端,他们只能和APIServer交互,且必须认证到APIServer。APIServer是唯一一个etcd的客户端,只有APIServer才能访问etcd。所以etcd被叫做集群存储,整个集群所有的资源状态信息都保存在etcd中。所以要定时对etcd进行备份。并且etcd必须是要高可用。
在APIServer中,支持很多种不同类型的资源。例如pod,控制器,service等。当service发生改变的时候, 如果所有东西都打包在一起,那所有版本都会随之变动。
所以APIServer把他api接口中的资源分为了多个逻辑组合,每个组合通常都是一组相关的类型,每个组合称之为 API Group,api群组
v1叫核心群组,所有核心资源都在这个群组中
deployment就在apps这个群组中
所以每一个资源,一定是某一个群组下的某一个类型的资源。
在v1beta1下定义的deployment在v1beta2下未必会起作用
后续创建deployment就不会像上述的那样使用命令的方式来创建,太low了。。后续会写一个类似上图的文件来进行创建。
控制器会周期性的比对资源的期望状态和实际状态
ps:集群内部的Pod要被集群外的客户端访问,有三种方式:
1、service,Nodeport
2、hostPort
3、hostNetwork
本文地址:https://blog.csdn.net/weixin_38147296/article/details/109614444