Kubernetes入门
了解Kubernetes
什么是Kubernetes?
Kubernetes(简称 K8s)是一个容器编排系统,可以把它当成一个应用管理平台,专门帮忙解决我们平时在传统服务维护中遇到的痛点。比如:我的应用应该跑在哪台机器上?如果某个应用挂了,怎么自动恢复?如果访问量突然变大,我们要怎么快速扩容服务?外部用户怎么访问我们的应用?等问题。
个人理解:
可以把Kubernetes当成Docker-Compose和Docker-Swarm的升级版并结合在一起构成了一个大型的容器管理的平台服务。
K8S的功能特点
1.数据卷
Pod中容器之间共享数据,可以使用数据卷
2.应用程序健康检查
容器内服务可能进程阻塞无法处理请求,可以设置监控检查策略保证应用健壮性
3.自我修复
控制器维护pod副本数量,保证一个pod或一组同类的pod数量始终可用,如果某个容器宕机了,K8S 可以快速重新启动新的的容器,替换旧的容器
4.弹性伸缩
根据设定的指标(CPU利用率)自动缩放pod副本数
5.服务发现
使用环境变量或DNS服务插件保证容器中程序发现pod入口访问地址。
6.负载均衡
一组pod副本分配一个私有的集群ip地址,负载均衡转发请求到后端容器。在集群内部其他pod可通过这个clusterIP访问应用
7.滚动更新
更新服务不中断,一次更新一个pod,而不是同时删除整个服务。
8.服务编排
通过文件描述部署服务,使得应用程序部署变得更高效
9.资源监控
Node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDB时序数据库,再由Grafana展示
10.提供认证和授权
支持角色访问控制(RBAC)认证授权等策略
K8S常见概念
Master:
- 指的是集群控制节点(相当于整个集群的指挥中心),在每个Kubernetes集群里都需要有一个Master来负责整个集群的管理和控制。
Node:
- 除了master,k8s集群中的其他机器被称为Node节点, Node节点才是kubernetes集群中的工作负载节点。
- 每个Node节点都会被master分配一些工作负载(docker容器),node节点上的docker负责容器的运行。
Pod:
- Pod是一组容器, 在K8S中,最小的单位是Pod, 一个Pod可以包含多个容器,但通常情况下我们在每个Pod中仅使用一个容器。
- 创建分类:
1.自主创建:直接创建出来的Pod,这种pod删除后就没有了,也不会自动重建。
2.控制器创建:通过控制器创建的pod,这类Pod删除了之后还会自动重建。
Pod Controller:
- 控制器是管理pod的中间层,只需要告诉Pod控制器,想要创建多少个什么样的Pod,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod在运行中出现故障,它会基于指定策略重新编排Pod,通过它来实现对pod的管理,比如启动pod、停止pod、扩展pod的数量等等。
- 它的类型有:ReplicaSet、Deployment、Horizontal Pod Autoscaler、DaemonSet等
Service:
- 在k8s里面,每个Pod都会被分配一个单独的IP地址,但这个IP地址会随着Pod的销毁而消失。
- Service (服务)就是用来解决这个问题的, 对外服务的统一入口,用于为一组提供服务的Pod 抽象一个稳定的网络访问地址。
- 一个Service可以看作一组提供相同服务的Pod的对外访问接口,作用于哪些Pod是通过标签选择器来定义的。
Label:
- K8S提供了一种机制来为Pod进行分类,那就是Label(标签),同一类pod会拥有相同的标签
- Label的具体形式是key-value的标记对,可以在创建资源的时候设置,也可以在后期添加和修改
- 给某个资源对象定义一个Label,就相当于给它打了一个标签,可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,K8S通过这种方式实现了类似SQL的对象查询机制
Label选择器: - 对应的资源打上标签后,可以使用标签选择器过滤指定的标
签 - 标签选择器目前有两个:
1.基于等值关系(等于、不等于)
2.基于集合关系(属于、不属于、存在)
NameSpace:
- 可以在一个物理集群上运行多个虚拟集群,这种虚拟集群被称作 命名空间,用来隔离pod的运行环境
- 同一个名字空间中的资源名称必须唯一,而不同名字空间之间则没有这个要求 NameSpace是不能嵌套的,每一个 Kubernetes 的资源都只能在一个NameSpace内名字空间是在多个用户之间划分集群资源的一种方法(通过资源配额)
- 不必使用多个名字空间来分隔轻微不同的资源,例如同一软件的不同版本: 应该使用标签 来区分同一名字空间中的不同资源
- Kubernetes会创建四个初始NameSpace名称空间:
1.default:没有指明使用其它名字空间的对象所使用的默认名字空间
2.kube-system:系统创建对象所使用的名字空间
3.kube-public:让所有具有或不具有身份验证的用户都能全局可读,这对于公开bootstrap组件所需的集群信息非常有用
4.kube-node-leas:该命名空间含有与每个节点关联的Lease对象,节点租用允许kubelet发送heartbeat(心跳),以便控制平面能检测节点故障
应用分类:
- 有状态应用(Stateless Service):该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一个请求响应的结果是完全一致的,比如前面我们讲解的 WordPress 实例,我们是不是可以同时启动多个实例,但是我们访问任意一个实例得到的结果都是一样的吧?因为他唯一需要持久化的数据是存储在MySQL数据库中的,所以我们可以说 WordPress 这个应用是无状态服务,但是 MySQL 数据库就不是了,因为他需要把数据持久化到本地。
- 无状态应用(Stateful Service):就和上面的概念是对立的了,该服务运行的实例需要在本地存储持久化数据,比如上面的 MySQL 数据库,你现在运行在节点 A,那么他的数据就存储在节点 A 上面的,如果这个时候你把该服务迁移到节点 B 去的话,那么就没有之前的数据了,因为他需要去对应的数据目录里面恢复数据,而此时没有任何数据。
K8S组件介绍
Master节点(控制节点):
apiserver:
提供操作【k8s集群资源】的唯一入口,RESTful方式请求,并提供认证、授权、访问控制、API注册和发现等。
以HTTP API提供接口服务,所有对象资源的增删改查和监听操作都交给APIService处理后再提交给Etcd存储。
scheduler:
负责资源的调度计算,按照预定的调度策略,为新建的Pod选择调度到相应的Node节点。
controller-manager:
处理集群中常规后台任务,一个资源对应一个控制器,而controllerManager就是负责管理这些控制器的,也负责维护集群的状态,比如故障检测、滚动更新等,根据调度器的安排通知对应的节点创建pod。
etcd:
存储中心,是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据信息的后台数据库。
Node(工作节点):
kubelet:
相当于主节点派到工作节点的一个代表,用于管理本机容器(相当于master节点的化身)并接收Master节点的指令,负责维护容器的生命周期也负责Volume(CVI)和网络(CNI)的管理。
kube-proxy:
负责为Service提供cluster内部的服务发现、网络代理、负载均衡等操作,为部署的应用程序提供访问入口,和apiserver是不一样的,后者是操作k8s集群内部的。
☆K8S架构图以及工作详细流程

第一步:kubectl命令
使用kubect客户端命令执行需要执行创建pod的命令,kubectl会调用apiserver接口进行请求
第二步:apiserver认证
apiserver收到请求,对发出请求的用户进行认证,认证通过后将命令以及文件信息写入保存到etcd中
第三步:controller manager
创建pod的信息交给controller manager,controller manager根据配置信息将要创建的资源对象放在等待队列中
第四步:scheduler计算调度
scheduler会对节点资源以及要部署的pod信息进行计算,找到到合适的节点进行调度,并将调度的最终信息写入保存到etcd
第五步:kubelet创建pod
apiserver与被调度节点上的kubelet通信,kubelet获取要部署的pod清单信息,进行创建pod
第六步:controller manager监控pod状态
controller manager会通过apiserver提供的接口实时监控资源对象的当前状态,让pod保持良好的状态
☆部署一个K8S应用实例
一、使用命令部署
1.使用deployment控制器创建一个Pod(deployment是Pod控制器的一种, 直接删除pod后,会自动创建新的,需要删除deployment)
kubectl create deployment app-nginx --image=nginx:1.23.1
2.创建service来暴露端口(不暴露的话只能通过ClusterIP在内部访问,不能通过节点ip加端口访问)
kubectl expose deployment app-nginx --port=80 --type=NodePort
注意:这里会暴露服务的80端口到本机随机从30000~32767中选择的端口上
二、使用yaml文件部署
nginx-1.23.1.yaml内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-1.23.1
spec:
selector:
matchLabels:
app: nginx-1.23.1
replicas: 2
template:
metadata:
labels:
app: nginx-1.23.1
spec:
containers:
- name: nginx
image: nginx:1.23.1
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
spec:
selector:
app: nginx-1.23.1
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
name: mynginx-http
使用apply命令部署,并通过curl命令查看网页测试
kubectl apply -f nginx-1.23.1.yaml
#查看部署的运行状态,并使用curl命令测试
[root@master ~]# kubectl get deployment nginx-1.23.1
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-1.23.1 2/2 2 2 165m
[root@master ~]# kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx NodePort 10.97.171.41 <none> 80:30080/TCP 165m
[root@master ~]# curl 192.168.31.101:30080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>