K8S学习笔记
K8S概述
简介
k8s是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。
核心特点:自主管理容器,保证云平台的容器按照用户的期望状态运行,管理员记载一个微型服务,让规划器找到合适的位置,并让用户方便的部署自己的应用。
网络特点:支持一种特殊的网络模型,k8s创建了一个地址空间,并且不动态的分配端口,它可以允许用户选择任何想使用的端口,为实现这一功能,为每个pod分配IP地址。
入门
此处以一个java web应用为例,帮助理解k8s。
一个运行在Tomcat里的Web App。此应用需要启动两个容器:Web App容器和MySQL容器,并且Web App容器需要访问MySQL容器。在Docker时代,假设在一个宿主机上启动了两个容器,需要把MySQL容器的IP地址通过环境变量注入Web App容器里;同时,需要将Web App容器的8080端口映射到宿主机的8080端口,以便外部访问。
启动MySQL服务
首先,为MySQL服务创建一个RC定义文件mysql-rc.yaml,文件内容如下:
apiVersion: v1
kind: ReplicationController #副本控制器RC
metadata:
name: mysql #RC的名称,全局唯一
spec:
replicas: 1 #Pod副本的期待数
selector: 1 #符合目标的Pod拥有此标签
app: mysql
template: #根据此模板创建Pod的副本
metadate:
labels:
app: mysql
spec:
containers: #pod内容器的定义部分
- name: mysql #容器的名称
image: mysql #容器对应的镜像
ports:
- containerPort: 3306 #容器应用监听的端口号
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
K8S的基本概念和术语
在声明一个kubernetes资源对象时,需要一个关键属性:apiVersion。k8s大部分常见的核心资源对象都归属于v1这个核心API,比如Node、Pod、Service、Endpoints、Namespace、RC、Persistent Volume等。
Master
Master通常会占用一个独立的服务器。在Master上运行以下进程:
1、api server:提供了HTTP Rest接口的关键服务进程,是k8s里所有资源的增、删、改、查等操作的唯一入口。也是集群控制的入口进程;
2、kube-controller-manager:所有资源对象的自动化控制中心;
3、kube-secheduler:负责资源调度的进程。
Node
每个Node会被Master分配一些工作负载,当某个Node宕机时,其上的工作负载会被Master自动转移到其它节点上。每个Node上都运行着以下进程:
1、kubelet:负责Pod对应的容器创建、启停等任务,同时与master密切协作,实现集群管理的基本功能;
2、kube-proxy:实现k8s service的通信与负载均衡机制的重要组件;
3、Docker Engine:Docker引擎,负责本机的容器创建和管理工作。
默认情况下,kubelet会向Master注册自己。
#查看集群中有多少个Node
$kubectl get nodes
#查看某个Node的详细信息
$kubectl describe node <node_name>
Pod
每个Pod都有一个被称为"根容器"的pause容器,还有一个或多个业务容器。每个Pod都有一个Pod IP,Pod内的容器共享该IP。K8s要求底层网络支持集群内任意两个Pod之间的TCP/IP直接通信,采用虚拟二层网络技术来实现,例如Flannel、open vSwitch等。因此我们需要牢记一点:在k8s里,一个Pod里的容器与另一个主机上的Pod容器能够直接通信。
Pod有两种类型:普通的Pod及静态Pod。
namespace
作用:实现多租户的资源隔离。
常用操作:
#查看集群中namespace
$kubectl get namespaces
#创建命名空间
$kubectl create namespace <name>
Label
label是一个key=value的键值对,其中key和value由用户自己指定。label和资源对象是多对多的关系。label通常是在资源对象定义时添加,也可以在创建后动态添加或删除。node的label选择器为NodeSelector,pod的标签选择器为selector。
Replication Controller
RC定义包括以下几个部分:
1、Pod期待的副本数;
2、用于筛选目标Pod的Label selector;
3、当Pod的副本数量少于预期数量时,用于创建新Pod的Pod模板。
#修改RC的副本数量,来实现Pod的动态缩放
$kubectl scale rc <pod-name> --replicas=3
需要注意,删除RC并不会影响已经通过该RC创建好的Pod。为了删除所有的Pod,可以设置replicas的值为0,然后更新该RC。另外,kubectl提供了stop和delete命令来一次性删除RC和RC控制的全部Pod。
总结一下RC的一些特性与作用:
通过定义一个RC实现Pod的创建及副本数量的自动控制 |
---|
在RC中包括完整的Pod定义模板 |
通过Label Select机制实现对Pod副本的自动控制 |
通过改变RC里Pod副本的数量,实现Pod的扩容和缩容 |
通过改变RC里Pod模板中的镜像版本,可以实现Pod的滚动升级 |
Deployment
Deployment的典型使用场景有以下几个:
1、创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建;
2、检查Deployment的状态来看部署动作是否完成;
3、更新Deployment以创建新的Pod;
4、如果当前Deployment不稳定,则回滚一个早先的Deployment版本;
5、暂停Deployment以便一次性修改多个PodTemplateSpec的配置选项,之后再恢复Deployment,进行新的发布。
6、扩展Deployment以应对高负载;
7、查看Deployment的状态,以此作为发布是否成功的指标;
8、清理不再需要的旧版本ReplicaSets。
Horizontal Pod Autoscale
HPA的实现原理:通过追踪分析指定RC控制的所有目标Pod的负载变化情况,来确定是否需要有针对性地调整目标Pod的副本数量。度量指标:
1、CPUUtilizationPercentage;
2、应用程序自定义的度量指标,比如服务在每秒内的相应请求数(TPS或QPS)。
创建HPA对象:
$ kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10
StatefulSet
有状态的服务:
(1)每个节点都有固定的身份ID,通过这个ID,集群中的成员可以相互发现并通信;
(2)集群的规模是比较固定的,集群规模不能随意变动;
(3)集群中的每个节点都是有状态的,通常会持久化数据到永久存储中;
(4)如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。
如果通过RC或Deployment控制pod副本数量来实现上述有状态的集群,就会发现(1)是无法满足的,因为Pod名称是随机产生的,Pod的IP地址也是在运行期间才确定并且有可能变动,我们事先无法为每个Pod都确定唯一不变的ID。另外,为了能够在其他节点恢复某个失败的节点,这种集群的Pod需要挂接某种共享存储。
StatefulSet的特性:
(1)StatefulSet里的每一个Pod都有唯一且稳定的网络标识,可以用来发现集群内其他成员;
(2)StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态;
(3)StatefulSet里的Pod采用稳定的持久化存储卷,通过PV或PVC来实现,删除Pod时,默认不会删除相应的卷。
Stateful需要与Headless Service配合使用,即每个StatefulSet都要声明它属于哪一个Headless Service。
Service
K8S的服务发现机制
首先,每个k8s中的Service都有唯一的Cluster IP及唯一的名称,而名称是由开发者自己定义的,部署时也没有必要改变,所以完全可以被固定在配置中。接下来为如何通过Service名称找到Cluster IP,起初是采用Linux环境变量解决该问题,后来通过Add-On增值包引入DNS系统。
参考:kubernetes权威指南