开发者学堂课程【企业级运维之云原生与 Kubernets 实战课程:kubectl 客户端使用方法+如何创建应用和暴露服务 】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/913/detail/14499
kubectl 客户端使用方法+如何创建应用和暴露服务
摘要:本小节主要内容为 K8s 核心概念,包括声明式 API、K8s 组件控制器、SVC 创建及使用、Pod 生命周期管理及 Kubectl 常用命令和使用技巧。
目录
Ÿ 声明式 API
Ÿ 创建 Deployment
Ÿ 创建 service 服务
Ÿ Kubectl 常用命令和使用技巧
一、声明式 API
1. 什么是声明式 API
声明式 API:提交的API对象不再是一个单体应用的描述,而是一个完整的分布式应用集群的描述。
2. 命令式 API 与生命式 API
Ÿ 命令式 API:命令“机器”如何去做事情( how ),这样不管你想要的是什么( what ),它都会按照你的命令实现。
Ÿ 声明式 API:告诉“机器”你想要的是什么,让机器想出如何去做。
3. 声明式 API 核心原理
Ÿ 当用户向 Kubernetes 提交了一个 API 对象的描述之后,Kubernetes 会负责保障整个集群里各项资源的状态,确保与 API 对象描述的需求相一致;
Ÿ 更重要的是,这个保证是一项“无条件的”、“没有期限”的承诺:对于每个保存在 etcd 里的 API 对象,Kubernetes 都通过启动一种叫做“控制器模式”( Controller Pattern ) 的无限循环,不断检查,然后调谐,最后确保整个集群的状态与这个 API 对象的描述一致;
Ÿ 简单理解就是对象的声明与对象的创建互相解耦,在普通程序中创建对象需要向操作系统申请资源,相似的在容器云平台上创建对象,需要向 K8s 申请资源;
Ÿ 在 K8s 环境中,只需要提交一个申请单,然后由K8s系统完成对象的创建。
4. 声明式 API 与控制器总结
二、创建 Deployment
1. 什么是 Deployment
简单来说,Deployment 是管理无状态应用部署发布的控制器,相当于管理 Pod 的经理人。
在 K8s 中,组件控制器 controller 包括:
Ÿ Deployment:无状态
Ÿ Statefulset:有状态
Ÿ Job:运行一个任务
Ÿ Cronjob:周期性运行
Ÿ Daemonset:在指定的 node 或者所有的 node 上运行一个 pod
Ÿ HPA :根据资源使用状况,来维持扩容/缩容副本数(客户自定义的资源维度)。
如图,通过 Deployment 将应用 A、B、C 分别规划到不同的容器组中,每个 Deployment 其实是管理的一组相同的应用 Pod,这组 Pod 我们认为它是相同的一个副本。
2. Deployment 功能
Ÿ 定义一组 Pod 的期望数量,Deployment 控制器会维持 Pod 数量与期望数量一致;
Ÿ 配置 Pod 发布方式,Deployment 控制器会按照给定策略更新 Pod,保证更新过程中不可用的 Pod 数量在限定范围内;
Ÿ 如果发布有问题,支持“一键”回滚。
比如说应用 A 期望的 Pod 数量是 4个,controller 就会持续维持 Pod 数量为期望的数量,当 Pod 出现了网络问题或者宿主机问题,controller 能将其恢复,也就是新扩出来对应的 Pod,来保证可用 Pod 数量与期望数量一致。
3. Deployment 语法
Ÿ Metadata:Deployment 元信息;
Ÿ Replicas:Pod 的最终数量;
Ÿ Selector:Pod 的选择器;
Ÿ Template:Pod 模板;
Ÿ Pod image:镜像版本;
Ÿ Labels:标签
在容器更新镜像时,Deployment 要通过新建 Pod 更新容器镜像,可以通过maxsurge 和 maxUnavailable 来保证副本数一致,如:
Ÿ replicas:4
Ÿ maxSurge: 25%,那么 4*1.25=5(最多 5 个 running 的副本)
Ÿ maxUnavailable: 25%,那么 4*0.75=3(最小 3 个不可用)
亦即,在滚动更新时,最多 5 个 running 的副本,最小 3 个不可用副本。
在 Deployment 中,revisionHistory 可以设置保持历史版本的个数,在Deployment 创建 Pod 时,会通过 replicaset 来拉起 Pod,Deployment 与 Pod 之间无直接联系,而是通过 replicaset 来管理 Pod。
4. Deployment 相关操作
a. Deployment 创建无状态服务:
Ÿ kubectl rollout history deployment
:查看历史 Pod 版本;
Ÿ kubectl rollout undo deployment
:回滚发布;
Ÿ kubectl scale deployment/xxx
(xxx为容器名) --replicas=n
( n 为副本数):进行副本的扩缩容;
Ÿ kubectl get pod -owide
:查看 Pod 所运行的节点信息。
b. Statefulset:创建有状态服务(略);
c. Job 会创建一个或者多个 Pod ,直到运行成功为止,运行成功后正常退出;
kubectl get job
:查看 job 类型的 Pod;
kubectl describe job xxx
( job 服务名):查看 job 的运行信息;
Parallelism
:Job 运行时并行数;
Completions
:Job 运行成功数;
backoffLimit (失败阀值):设置 activeDeadlinesSeconds 时间,一旦 job 运行时间达到这个设置值,终止所有的 pod。可以编写 yaml 文件设置每次启动一个 job 运行五次和设置并行启动两个 job 运行六次,通过命令watch -d kubectl get
监控 job 创建的次数发现,job 的启动是按照并行数启动,然后正常退出,直到完成所有运行次数。
d. CronJob:周期性的执行 job 类似 Linux 下 crontab;
设置方式:Schedule:"*/1 * * * *
"表示每分钟都运行1次
Ÿ startingDeadlineSeconds
如果 startingDeadlineSeconds 字段非空,则控制器会统计从startingDeadlineSeconds 设置的值到现在、而不是从上一个计划时间到现在错过了多少次 Job。例如,如果 startingDeadlineSeconds 是 200,则控制器会统计在过去 200 秒中错过了多少次 Job。
Ÿ concurrencyPolicy,共同运行的 policy(allow,forbid)
如果未能在调度时间内创建 CronJob ,则计为错过。例如,如果 concurrencyPolicy 被设置为 Forbid ,并且当前有一个调度仍在运行的情况下,试图调度的 CronJob 将被计算为错过。
ž 情况1:concurrencyPolicy=forbidstartingDeadlineSeconds
默认,CronJob 被设置为从08:30:00开始每隔一分钟创建一个新的 Job;如果 CronJob 控制器从 08:29:00 到 10:21:00 终止运行,则该 Job 将不会启动,因为其错过的调度次数超过了 100。
ž 情况2:concurrencyPolicy=forbidstartingDeadlineSeconds=200
,如果CronJob 控制器恰好在与上一个示例相同的时间段( 08:29:00 到 10:21:00 )终止运行,则 Job 仍将从 10:22:00 开始。造成这种情况的原因是控制器现在检查在最近 200 秒(即 3 个错过的调度)中发生了多少次错过的 Job 调度,而不是从现在为止的最后一个调度时间开始。
e. Daemonset 的 Pod 会在指定的 node 或者所有的 node 上运行。
三、创建 Service 暴露服务
1. 什么是 service(SVC)
Service 是 Kubernetes 中的服务发现与负载均衡。
为什么需要服务发现?Kubernetes 应用应如何相互调用?Kubernetes 应用应如何相互调用?
Ÿ Pod 生命周期短暂,IP 地址随时变化;
Ÿ Deployment 等的 Pod 组需要统一访问入口和做负载均衡;
Ÿ 应用间在不同环境部署时保持同样的部署拓扑和访问方式;
Ÿ 集群内可以通过 service name 直接访问
2. Service 语法
3. Service 类型
a. ClusterIP:分配一个集群内部的 IP 地址,只能在集群内部访问。
Ÿ kubectl get svc:查看创建了哪些 SVC;
Ÿ kubectl get ep xxx( svc 的名字):查看 svc 后端挂载的服务;
Ÿ curl 命令:访问该服务。
Ÿ 流量流转:从 client 访问 SVC,SVC 通过 iptables 或 Ipvs 转发到后端 Pod,SVC 通过 Lable 选择 Pod,ClusterIP 暴露的 SVC 可以通过集群内部访问或 Pod 访问;
Ÿ 无头 Service 指定 clusterlP: None
ž Pod 通过 service_name 方式访问时可以获取到所有后端 Pod IP;
ž 客户端应用自主选择需要访问的 Pod。
b. NodePort:分配一个集群内部的 IP 地址,并在每个节点上启用一个端口来暴露服务,可以在集群外部被访问。
c. Loadblalancer:分配一个集群内部的 IP 地址,并在每个节点上启用一个端口来暴露服务,除此之外,kubernetes 会请求底层云平台上的负载均衡器,把 Node 节点作为后端添加进去。
Ÿ 通过 NodePort 与 SLB 配合的方式,创建 NodePort 模式的 SVC 并在前面加上负载均衡,通过 NodePort 把节点暴露出来,客户端可以访问节点端口就是访问了 SVC 进而访问了后端 Pod;
Ÿ 可以通过命令 kubectl describe svc xxx ( svc 服务名),查看 NodePort 暴露的端口;
Ÿ Loadblalancer 的 SVC,在 master 节点上有组件 CCM (c1ond contro11er mannger )去创建/复用已经存在的 SLB 的设备,并把这些集群节点加到 SLB 上,外部客户端访问 SLB(ip) 就会被转发到后端节点 SVC 上再转发到 Pod,而 SLB 一般都是多可用区容灾,不存在单点故障。
d. Externalname:把外部相关域名或 IP 引入到集群内部;
Ÿ <svc name>.<ns>.svc.cluster.local
:集群内部访问外部域名访问方式;
Ÿ 好处:内部代码不必写死外部的 IP,如果外部 IP 改变,只需要变更 SVC 即可,不需要改动代码。
本讲小结
1. Deployment、daemonset、job、cronjob、svc 等内容。
2. Kubectl 的相关命令,Pod 滚动更新等内容。
3. SVC。