K8S是一个容器编排工具,其实也是管理应用的全生命周期的一个工具。从创建应用,应用的部署,应用提供服务,扩容收缩应用,应用更新都非常的方便。而且可以做到故障自愈,例如一个服务器挂了,可以自动将这个服务器上的应用调度到另外一个主机上运行,无需人工干预。
k8s的全生命周期管理:在k8s进行管理应用的时候,基本步骤是:创建集群,部署应用,发布应用,扩展应用,更新应用。
k8s集群: k8s在物理上进行划分的时候,划分了两种类型的主机,一个是master节点:主要用来调度,控制集群的资源等,另外是node节点:主要用来运行容器的节点,也就是运行服务的节点。
其实集群都差不多,master用来控制,存储各种元数据,node节点是一个工作节点,真正来干活的。node节点定时与master进行通讯,通过kubectl进程进行汇报信息。
创建集群的目的是为了提供服务,让应用程序能够在集群上运行。
有了image之后,一条指令就能运行一个应用。所以在开发完应用之后,需要程序打包成image,然后放到registry中,然后能够运行应用了。
kubectl run key --image=nginx:1.79 --port=80
kubectl get deployments/kel
在完成应用部署之后,就可以看到应用的名称,期望状态是运行一个pod,当前有一个pod,活动的也是一个。
那么什么是pod呢? 在k8s里面,集群调度的最小单元就是一个pod,一个pod可以是一个容器,也可以是多个容器,例如你使用一个程序,其中使用了nginx,使用了mysql,使用了jetty,那么可以将这三个使用在同一个pod中,对他们提供统一的调配能力,一个pod只能运行在一个主机上,而一个主机可以运行多个pod。
为什么要使用pod,为什么不能直接使用容器呢?使用pod相当于一个逻辑主机,还记得创建一个VM,在VM上运行几个进程么,道理是一样的。pod的存在主要是让几个紧密链接的几个容器直接共享,例如ip地址,共享存储信息。如果直接调度容器的话,那么几个容器可能运行在不同的主机上,这样就增加了系统的复杂性。
发布应用
发布应用就是为对外提供服务,可能会有人提出疑问,我都运行了服务为什还不能提供服务,这是因为在集群中,创建的IP地址等资源,只有在同一个集群中才能访问,每个pod都会有唯一的ip地址。当有多个pod提供相同的服务的时候,就需要有负载均衡的能力。从而这里涉及到的一个概念就是service,专门用来提供服务。
基于pod创建一个service:
kubectl expose deployment kel --type="NodePort" --port=80
kubectl get services/kel
服务主要用来提供对外访问的接口,服务可以关联一组pod,这些pod的ip地址各不相同。而service相当于一个负载均衡的vip,用来指向各个pod。当pod的ip地址发生变化的时候,也能做到自动化负载均衡,在关联的时候,service与pod直接主要通过label来关联,也就是标签(-l表示label)
kubectl get services -l run=kel
kubectl get pods -l run=kel
kubectl describe service/kel
容器扩容:
在业务上线之后,怎样进行动态的扩容和收缩呢? 只要有一个pod,那么就可以产生无数个pod。这样就具备了横行扩展的能力
kubectl scale deployments/kel --replicas=3
应用更新:
有新版本了,需要发布。滚动更新,根据新的image创建一个pod,分配各种资源。然后自动负载均衡,删除老的pod,然后继续更新,不会中断服务。
kubectl set image deployments/kel kel=nginx:1.8
滚动更新:根据新的image创建一个pod,分配各种资源,然后自动负载均衡,删除老的pod,然后继续更新。不会出现中断服务。
kubectl rollout undo deployments/kel
DashBoard
1.创建dashboard服务
kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml
2. 生成登陆token
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
3. 启动API Server
kubectl proxy
4.访问dashboard 本地访问URL
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview?namespace=default
基于k8s部署的应用如何访问:
首先了解kubernate 网络模型设计的基础原则:每个pod拥有一个独立的ip地址,并且假定所有的pod都在一个直接连通的,扁平的网络空间中。
1.集群内部访问:
1.1 通过pod的ip访问 这种方式是不可靠的,当pod重启后,它的IP会重新分配。
不同的pod的访问方式可以用endpoint方式:pod的IP+容器的端口
1.2 通过服务访问 通过创建service,可以为一组具有相同功能的容器应用提供统一的入口地址,这个地址不会因为pod的重启而发生变化。
访问方式:clusterIp+containerPort
2.集群外表访问
2.1 直接访问容器
在启动pod的rc/deployment中指定容器的hostport,并设置pod级别的hostwork=true,这样直接通过主机ip+hostport就可以实现访问
2.2 通过service访问。
2.2.1 NodePort方式
在service的yaml中配置nodePort参数。这一集群会在每一个node上为需要外部访问的service开启一个TCP监听端口,外部系统只需要用任意一个Node的ip地址+具体的NodePort端口号就可以访问此服务。不过这种方式没有解决node层负载均衡问题。(pod层kube-proxy会自动实现负载均衡分发到多个pod上,但是node层不能负载分发到多个node)
2.2.2 如果使用外部公有云平台,如aws,azure部署时,可以使用 loadbalance方式,配置外部负载均衡器,对service的请求
2.3 Ingress
Ingress是k8s单独定义的对象,它的作用就是单独对外暴露负载访问的均衡,它和service的本身的loadbalance区别在于:
Ingress支持L4,L7负载均衡,LoadBalance设计上支持L4.
Ingress基于pod部署 ,并将pod设置为external network。
Ingress controller支持nginx,Haproxy,GCE-L7,能够满足企业内部使用。