设为首页 收藏本站
查看: 732|回复: 0

[经验分享] Kubernetes 简介

[复制链接]

尚未签到

发表于 2018-9-15 12:24:41 | 显示全部楼层 |阅读模式
  https://www.cnblogs.com/zhenyuyaodidiao/p/6500720.html

简介
  Kubernetes作为时下最火的容器编排工具,不用多说。架构图如下:
  !()[https://images2015.cnblogs.com/blog/704717/201703/704717-20170304103633345-155330022.png

节点
  k8s集群中,存在两种性质的物理节点,一种是master,一种是node节点


  • master:简单的说,master节点就是管理节点,负责整个集群的资源调度;
  • node: 工作节点,执行启动容器的节点;
Master
  Master节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd。


  •   APIServer:APIServer负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。如架构图中所示,kubectl(Kubernetes提供的客户端工具,该工具内部就是对Kubernetes API的调用)是直接和APIServer交互的。

  •   schedule:scheduler的职责很明确,就是负责调度pod到合适的Node上。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定,即将这个pod部署到这个Node上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。

  •   controller manager:如果说APIServer做的是“前台”的工作的话,那controller manager就是负责“后台”的。每个资源一般都对应有一个控制器,而controller manager就是负责管理这些控制器的。比如我们通过APIServer创建一个pod,当这个pod创建成功后,APIServer的任务就算完成了。而后面保证Pod的状态始终和我们预期的一样的重任就由controller manager去保证了。

  • etcd:etcd是一个高可用的键值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。
Node
  每个Node节点主要由三个模块组成:kubelet、kube-proxy、runtime。


  •   runtime:runtime指的是容器运行环境,目前Kubernetes支持docker和rkt两种容器。

  •   kube-proxy:该模块实现了Kubernetes中的服务发现和反向代理功能。反向代理方面:kube-proxy支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。另外kube-proxy还支持session affinity。

  • kubelet:Kubelet是Master在每个Node节点上面的agent,是Node节点上面最重要的模块,它负责维护和管理该Node上面的所有容器,但是如果容器不是通过Kubernetes创建的,它并不会管理。本质上,它负责使Pod得运行状态与期望的状态一致。
Pod
  Pod 是Kubernetes的基本操作单元,也是应用运行的载体。整个Kubernetes系统都是围绕着Pod展开的,比如如何部署运行Pod、如何保证Pod的数量、如何访问Pod等。另外,Pod是一个或多个机关容器的集合,这可以说是一大创新点,提供了一种容器的组合的模型。

Pod与容器
  在Docker中,容器是最小的处理单元,增删改查的对象是容器,容器是一种虚拟化技术,容器之间是隔离的,隔离是基于Linux Namespace实现的。而在Kubernetes中,Pod包含一个或者多个相关的容器,Pod可以认为是容器的一种延伸扩展,一个Pod也是一个隔离体,而Pod内部包含的一组容器又是共享的(包括PID、Network、IPC、UTS)。除此之外,Pod中的容器可以访问共同的数据卷来实现文件系统的共享。
  

## 镜像  

  在kubernetes中,镜像的下载策略为:


  • Always:每次都下载最新的镜像
  • Never:只使用本地镜像,从不下载
  • IfNotPresent:只有当本地没有的时候才下载镜像
  Pod被分配到Node之后会根据镜像下载策略进行镜像下载,可以根据自身集群的特点来决定采用何种下载策略。无论何种策略,都要确保Node上有正确的镜像可用。

Pod的一些设置
  可以在yaml文件中设置
  

启动命令,如:spec-->containers-->command;  

  
环境变量,如:spec-->containers-->env-->name/value;
  

  
端口桥接,如:spec-->containers-->ports-->containerPort/protocol/hostIP/hostPort(使用hostPort时需要注意端口冲突的问题,不过Kubernetes在调度Pod的时候会检查宿主机端口是否冲突,比如当两个Pod均要求绑定宿主机的80端口,Kubernetes将会将这两个Pod分别调度到不同的机器上);
  

  
Host网络,一些特殊场景下,容器必须要以host方式进行网络设置(如接收物理机网络才能够接收到的组播流),在Pod中也支持host网络的设置,如:spec-->hostNetwork=true;
  

  
数据持久化,如:spec-->containers-->volumeMounts-->mountPath;
  

  
重启策略,当Pod中的容器终止退出后,重启容器的策略。这里的所谓Pod的重启,实际上的做法是容器的重建,之前容器中的数据将会丢失,如果需要持久化数据,那么需要使用数据卷进行持久化设置。Pod支持三种重启策略:Always(默认策略,当容器终止退出后,总是重启容器)、OnFailure(当容器终止且异常退出时,重启)、Never(从不重启);
  

Pod生命周期
  Pod被分配到一个Node上之后,就不会离开这个Node,直到被删除。当某个Pod失败,首先会被Kubernetes清理掉,之后ReplicationController将会在其它机器上(或本机)重建Pod,重建之后Pod的ID发生了变化,那将会是一个新的Pod。所以,Kubernetes中Pod的迁移,实际指的是在新Node上重建Pod。以下给出Pod的生命周期图。
  https://images2015.cnblogs.com/blog/704717/201703/704717-20170304103856954-1091445106.png
  生命周期回调函数:PostStart(容器创建成功后调研该回调函数)、PreStop(在容器被终止前调用该回调函数)。以下示例中,定义了一个Pod,包含一个JAVA的web应用容器,其中设置了PostStart和PreStop回调函数。即在容器创建成功后,复制/sample.war到/app文件夹中。而在容器终止之前,发送HTTP请求到http://monitor.com:8080/waring,即向监控系统发送警告。具体示例如下:
  

………..  
containers:
  
- image: sample:v2
  name: war
  lifecycle:
  posrStart:
  exec:
  command:
  - “cp”
  - “/sample.war”
  - “/app”
  prestop:
  httpGet:
  host: monitor.com
  psth: /waring
  port: 8080
  scheme: HTTP
  

Replication Controller
  Replication Controller(RC)是Kubernetes中的另一个核心概念,应用托管在Kubernetes之后,Kubernetes需要保证应用能够持续运行,这是RC的工作内容,它会确保任何时间Kubernetes中都有指定数量的Pod在运行。在此基础上,RC还提供了一些更高级的特性,比如滚动升级、升级回滚等。

Label
  RC与Pod的关联是通过Label来实现的。Label机制是Kubernetes中的一个重要设计,通过Label进行对象的弱关联,可以灵活地进行分类和选择。对于Pod,需要设置其自身的Label来进行标识,Label是一系列的Key/value对,在Pod-->metadata-->labeks中进行设置。
  Label的定义是任一的,但是Label必须具有可标识性,比如设置Pod的应用名称和版本号等。另外Lable是不具有唯一性的,为了更准确的标识一个Pod,应该为Pod设置多个维度的label。如下:
  

    "release" : "stable", "release" : "canary"  

  
    "environment" : "dev", "environment" : "qa", "environment" : "production"
  

  
    "tier" : "frontend", "tier" : "backend", "tier" : "cache"
  

  
    "partition" : "customerA", "partition" : "customerB"
  

  
    "track" : "daily", "track" : "weekly"
  

  举例,当你在RC的yaml文件中定义了该RC的selector中的label为app:my-web,那么这个RC就会去关注Pod-->metadata-->labeks中label为app:my-web的Pod。修改了对应Pod的Label,就会使Pod脱离RC的控制。同样,在RC运行正常的时候,若试图继续创建同样Label的Pod,是创建不出来的。因为RC认为副本数已经正常了,再多起的话会被RC删掉的。

弹性伸缩
  弹性伸缩是指适应负载变化,以弹性可伸缩的方式提供资源。反映到Kubernetes中,指的是可根据负载的高低动态调整Pod的副本数量。调整Pod的副本数是通过修改RC中Pod的副本是来实现的,示例命令如下:
  扩容Pod的副本数目到10
  

$ kubectl scale>  

  缩容Pod的副本数目到1
  

$ kubectl scale>  

滚动升级
  滚动升级是一种平滑过渡的升级方式,通过逐步替换的策略,保证整体系统的稳定,在初始升级的时候就可以及时发现、调整问题,以保证问题影响度不会扩大。Kubernetes中滚动升级的命令如下:
  

$ kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s  

  升级开始后,首先依据提供的定义文件创建V2版本的RC,然后每隔10s(--update-period=10s)逐步的增加V2版本的Pod副本数,逐步减少V1版本Pod的副本数。升级完成之后,删除V1版本的RC,保留V2版本的RC,及实现滚动升级。
  升级过程中,发生了错误中途退出时,可以选择继续升级。Kubernetes能够智能的判断升级中断之前的状态,然后紧接着继续执行升级。当然,也可以进行回退,命令如下:
  

$ kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s --rollback      

  回退的方式实际就是升级的逆操作,逐步增加V1.0版本Pod的副本数,逐步减少V2版本Pod的副本数。

Job
  从程序的运行形态上来区分,我们可以将Pod分为两类:长时运行服务(jboss、mysql等)和一次性任务(数据计算、测试)。RC创建的Pod都是长时运行的服务,而Job创建的Pod都是一次性任务。
  在Job的定义中,restartPolicy(重启策略)只能是Never和OnFailure。Job可以控制一次性任务的Pod的完成次数(Job-->spec-->completions)和并发执行数(Job-->spec-->parallelism),当Pod成功执行指定次数后,即认为Job执行完毕。

Service
  如果Pods是短暂的,那么重启时IP地址可能会改变,怎么才能从前端容器正确可靠地指向后台容器呢?
  Service是定义一系列Pod以及访问这些Pod的策略的一层抽象。Service通过Label找到Pod组.
  在Kubernetes中,在受到RC调控的时候,Pod副本是变化的,对于的虚拟IP也是变化的,比如发生迁移或者伸缩的时候。这对于Pod的访问者来说是不可接受的。Kubernetes中的Service是一种抽象概念,它定义了一个Pod逻辑集合以及访问它们的策略,Service同Pod的关联同样是居于Label来完成的。Service的目标是提供一种桥梁, 它会为访问者提供一个固定访问地址,用于在访问时重定向到相应的后端,这使得非 Kubernetes原生应用程序,在无须为Kubemces编写特定代码的前提下,轻松访问后端。
  Service同RC一样,都是通过Label来关联Pod的。当你在Service的yaml文件中定义了该Service的selector中的label为app:my-web,那么这个Service会将Pod-->metadata-->labeks中label为app:my-web的Pod作为分发请求的后端。当Pod发生变化时(增加、减少、重建等),Service会及时更新。这样一来,Service就可以作为Pod的访问入口,起到代理服务器的作用,而对于访问者来说,通过Service进行访问,无需直接感知Pod。
  需要注意的是,Kubernetes分配给Service的固定IP是一个虚拟IP,并不是一个真实的IP,在外部是无法寻址的。真实的系统实现上,Kubernetes是通过Kube-proxy组件来实现的虚拟IP路由及转发。所以在之前集群部署的环节上,我们在每个Node上均部署了Proxy这个组件,从而实现了Kubernetes层级的虚拟转发网络。

Service代理外部服务
  Service不仅可以代理Pod,还可以代理任意其他后端,比如运行在Kubernetes外部Mysql、Oracle等。这是通过定义两个同名的service和endPoints来实现的。示例如下:
  redis-service.yaml
  

apiVersion: v1  
kind: Service
  
metadata:
  name: redis-service
  
spec:
  ports:
  - port: 6379
  targetPort: 6379
  protocol: TCP
  

  redis-endpoints.yaml
  

apiVersion: v1  
kind: Endpoints
  
metadata:
  name: redis-service
  
subsets:
  - addresses:
  - ip: 10.0.251.145
  ports:
  - port: 6379
  protocol: TCP
  

  基于文件创建完Service和Endpoints之后,在Kubernetes的Service中即可查询到自定义的Endpoints。
  

[root@k8s-master demon]# kubectl describe service redis-service  
Name:            redis-service
  
Namespace:        default
  
Labels:            
  
Selector:        
  
Type:            ClusterIP
  
IP:            10.254.52.88
  
Port:                6379/TCP
  
Endpoints:        10.0.251.145:6379
  
Session Affinity:    None
  
No events.
  
[root@k8s-master demon]# etcdctl get /skydns/sky/default/redis-service
  
{"host":"10.254.52.88","priority":10,"weight":10,"ttl":30,"targetstrip":0}
  

Service内部负载均衡
  当Service的Endpoints包含多个IP的时候,及服务代理存在多个后端,将进行请求的负载均衡。默认的负载均衡策略是轮训或者随机(有kube-proxy的模式决定)。同时,Service上通过设置Service-->spec-->sessionAffinity=ClientIP,来实现基于源IP地址的会话保持。

发布Service
  Service的虚拟IP是由Kubernetes虚拟出来的内部网络,外部是无法寻址到的。但是有些服务又需要被外部访问到,例如web前段。这时候就需要加一层网络转发,即外网到内网的转发。Kubernetes提供了NodePort、LoadBalancer、Ingress三种方式。


  •   NodePort:在之前的Guestbook示例中,已经延时了NodePort的用法。NodePort的原理是,Kubernetes会在每一个Node上暴露出一个端口:nodePort,外部网络可以通过(任一Node)[NodeIP]:[NodePort]访问到后端的Service。

  •   LoadBalancer:在NodePort基础上,Kubernetes可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发。该模式需要底层云平台(例如GCE)支持。

  • Ingress:是一种HTTP方式的路由转发机制,由Ingress Controller和HTTP代理服务器组合而成。Ingress Controller实时监控Kubernetes API,实时更新HTTP代理服务器的转发规则。HTTP代理服务器有GCE Load-Balancer、HaProxy、Nginx等开源方案。
service的自发性机制
  Kubernetes中有一个很重要的服务自发现特性。一旦一个service被创建,该service的service IP和service port等信息都可以被注入到pod中供它们使用。Kubernetes主要支持两种service发现 机制:环境变量和DNS。

环境变量方式
  Kubernetes创建Pod时会自动添加所有可用的service环境变量到该Pod中,如有需要.这些环境变量就被注入Pod内的容器里。需要注意的是,环境变量的注入只发送在Pod创建时,且不会被自动更新。这个特点暗含了service和访问该service的Pod的创建时间的先后顺序,即任何想要访问service的pod都需要在service已经存在后创建,否则与service相关的环境变量就无法注入该Pod的容器中,这样先创建的容器就无法发现后创建的service。

DNS方式
  Kubernetes集群现在支持增加一个可选的组件——DNS服务器。这个DNS服务器使用Kubernetes的watchAPI,不间断的监测新的service的创建并为每个service新建一个DNS记录。如果DNS在整个集群范围内都可用,那么所有的Pod都能够自动解析service的域名。

多个service如何避免地址和端口冲突
  此处设计思想是,Kubernetes通过为每个service分配一个唯一的ClusterIP,所以当使用ClusterIP:port的组合访问一个service的时候,不管port是什么,这个组合是一定不会发生重复的。另一方面,kube-proxy为每个service真正打开的是一个绝对不会重复的随机端口,用户在service描述文件中指定的访问端口会被映射到这个随机端口上。这就是为什么用户可以在创建service时随意指定访问端口。

Deployment
  Kubernetes提供了一种更加简单的更新RC和Pod的机制,叫做Deployment。通过在Deployment中描述你所期望的集群状态,Deployment Controller会将现在的集群状态在一个可控的速度下逐步更新成你所期望的集群状态。Deployment主要职责同样是为了保证pod的数量和健康,90%的功能与Replication Controller完全一样,可以看做新一代的Replication Controller。但是,它又具备了Replication Controller之外的新特性:


  •   Replication Controller全部功能:Deployment继承了上面描述的Replication Controller全部功能。

  •   事件和状态查看:可以查看Deployment的升级详细进度和状态。

  •   回滚:当升级pod镜像或者相关参数的时候发现问题,可以使用回滚操作回滚到上一个稳定的版本或者指定的版本。

  •   版本记录: 每一次对Deployment的操作,都能保存下来,给予后续可能的回滚使用。

  •   暂停和启动:对于每一次升级,都能够随时暂停和启动。

  • 多种升级方案:Recreate----删除所有已存在的pod,重新创建新的; RollingUpdate----滚动升级,逐步替换的策略,同时滚动升级时,支持更多的附加参数,例如设置最大不可用pod数量,最小升级间隔时间等等。
滚动升级
  相比于RC,Deployment直接使用kubectl edit deployment/deploymentName 或者kubectl set方法就可以直接升级(原理是Pod的template发生变化,例如更新label、更新镜像版本等操作会触发Deployment的滚动升级)。操作示例——首先 我们同样定义一个nginx-deploy-v1.yaml的文件,副本数量为2:
  

apiVersion: extensions/v1beta1  
kind: Deployment
  
metadata:
  name: nginx-deployment
  
spec:
  replicas: 3
  template:
  metadata:
  labels:
  app: nginx
  spec:
  containers:
  - name: nginx
  image: nginx:1.7.9
  ports:
  - containerPort: 80
  

  创建deployment:
  

$ kubectl create -f nginx-deploy-v1.yaml --record  
deployment "nginx-deployment" created
  
$ kubectl get deployments
  
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
  
nginx-deployment   3         0         0            0           1s
  
$ kubectl get deployments
  
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
  
nginx-deployment   3         3         3            3           18s
  

  正常之后,将nginx的版本进行升级,从1.7升级到1.9。第一种方法,直接set镜像:
  

$ kubectl set image deployment/nginx-deployment2 nginx=nginx:1.9  
deployment "nginx-deployment2" image updated
  

  第二种方法,直接edit:
  

$ kubectl edit deployment/nginx-deployment  
deployment "nginx-deployment2" edited
  

  查看Deployment的变更信息(以下信息得以保存,是创建时候加的“--record”这个选项起的作用)
  

$ kubectl rollout history deployment/nginx-deployment  
deployments "nginx-deployment":
  
REVISION    CHANGE-CAUSE
  
1           kubectl create -f docs/user-guide/nginx-deployment.yaml --record
  
2           kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  
3           kubectl set image deployment/nginx-deployment nginx=nginx:1.91
  

  
$ kubectl rollout history deployment/nginx-deployment --revision=2
  
deployments "nginx-deployment" revision 2
  Labels:       app=nginx
  pod-template-hash=1159050644
  Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  Containers:
  nginx:
  Image:      nginx:1.9.1
  Port:       80/TCP
  QoS Tier:
  cpu:      BestEffort
  memory:   BestEffort
  Environment Variables:      
  No volumes.



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-583542-1-1.html 上篇帖子: 为kubernetes手动生成证书 下篇帖子: [Kubernetes] 国内获取 Kubernetes 镜像的方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表