kubernetes入门
基于容器技术来实现资源管理的自动化
跨多个数据中心的资源利用率的最大化
kubernetes是一个全新的基于容器技术的分布式架构解决方案
容器云平台的选型方案
基于容器技术的paas平台的重要底层框架
云原生技术生态圈的核心
service mesh,serverless等新一代分布式架构框架及技术基于Kubernetes来实现
不必在飞信与负载均衡器和部署实施问题,不必在考虑引入或自己开发一个复杂的服务治理框架
不必在头疼于服务监控和故障处理模块的开发
任何语言编写的服务,都可以映射为kubernetes的service,并通过标准的tcp通信协议进行交互
kubernetes平台对现有的编程语言,编程框架,中间件没有任何侵入性
kubernetes中,service是分布式集群架构的核心
拥有唯一指定的名称
拥有一个虚拟ip地址(clusterip地址)和端口号
能够提供某种远程服务能力
能够将客户端对服务的访问请求转发到一组容器应用上
service的服务进程通常基于socket通信方式对外提供服务
一个service通常由多个相关的服务进程提供服务,每个服务进程都有一个独立的endpoint(ip+port)访问点
kubernetes能够让我们通过service(clusterip+service port)连接指定的服务
kubernetes内建的透明负载均衡和故障恢复机制,不会影响服务的正常调用
service一旦被创建就不在变化
容器提供了强大的隔离功能,把service提供服务的这组进程放入容器中进行隔离
kubernetes设计了pod对象,每个服务进程都包装到相应的pod中,使其成为在pod中运行的一个容器(container)
service和pod之间的联系:给pod贴上label,给相应的service定义标签选择器(label selector)
pod运行在node环境中,每个Node上运行多个pod
每个pod中都运行一个特殊的pause容器,其他容器为业务容器,共享pause容器的网络栈和volume挂在卷
所以pod中的容器通信和数据交换更为高效
设计时将一组密切相关的服务进程放入同一个pod中
并不是每个pod和它里面运行的容器都被映射到一个service上,只有提供服务(无论内外)的那组pod才会被映射为一个服务
集群:master+node
master:资源管理,pod调度,弹性伸缩,安全机制,系统监控,纠错
kube-apiserver
kube-controller-manager
kube-scheduler
node:负责pod的创建,启动,监控,重启,销毁
集群中的工作节点,运行这真正的应用程序
node上,kubernetes管理的最小单元是pod
kubelet
kube-proxy
deployment
目标pod的定义
目标pod需要运行的副本数量(replicas)
要监控的目标pod的标签
创建好deployment之后,kubernetes会根据这一定义创建符合要求的pod
通过deployment中定义的label筛选出对应的pod实例并实时监控状态和数量
有了deployment,服务扩容只需要修改deployment中的副本数量即可
微服务架构的核心是将一个巨大的单体应用分解为很多小的互相连接的微服务
一个微服务可能由多个实例副本支撑,副本的数量可以随着系统的负荷变化进行调整
helloworld
Tomcat运行的webapp,使用Mysql保存数据
启动两个容器:webapp容器和mysql容器
webapp容器需要访问mysql容器
如果使用docker启动这两个容器,需要通过docker network或者端口映射的方式实现容器间的网络互访
mysql
https://github.com/kubeguide/K8sDefinitiveGuide-V5-Sourcecode
1. 使用deployment创建一个定义文件:mysql-deploy.yaml
apiVersion: apps/v1 # api版本
kind: Deployment # 副本控制器RC
metadata:
labels: # 标签
app: mysql
name: mysql # 对象名称,全局唯一
spec: # deployment的相关属性定义
replicas: 1 # 预期的副本数量,确保在当前集群中始终有replicas个pod实例在运行。
selector: # deployment的pod选择器,符合条件的pod实例受到该deployment的管理
matchLabels:
app: mysql
template: # pod模板
metadata:
labels: # 该pod的标签,labels必须匹配之前的spec.selector
app: mysql
spec:
containers: # 定义容器
- image: mysql:5.7
name: mysql
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
2. 为了将1发布到kubernetes集群中,在master上运行
kubectl apply -f mysql-deploy.yaml
3. 查看刚刚创建的deployment
kubectl get deploy
4. 查看pod的运行情况
kubectl get pods
pod一开始的状态为pending,创建成功启动完成后是running
使用docker ps查看正在运行的容器
创建pod与之关联的service
mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql # service的全局唯一名称
spec:
ports:
- port: 3306 # service提供服务的端口号
selector:
app: mysql # service对应的pod拥有这里定义的标签
5. 创建service
kubectl create -f mysql-svc.yaml
6. 查看刚创建的service对象
kubectl svc mysql
kubernetes使用了linux的环境变量来解决发现服务的问题
根据service的唯一名称,容器可以从环境变量中获取service对应的clusterip地址和端口号,从而发起tcp/ip请求
启动tomcat服务
7. myweb-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myweb
name: myweb
spec:
replicas: 2
selector:
matchLabels:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- image: kubeguide/tomcat-app:v1
name: myweb
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
value: 10.245.161.22
# 应用使用环境变量的值连接Mysql服务
没有注册环境变量的原因是kubernetes会自动将已存在的service对象以环境变量的形式展现在新生的pod中
更安全可靠的方法是使用服务的名称mysql,要求集群内的DNS服务(kube-dns)正常运行
8. kubectl apply -f myweb-deploy.yaml
9. kubectl get pods
10.创建service
基本概念
概念和术语是基于resource object
与某种资源的对象
与资源对象相关的事物与动作
资源对象:node,pod,service,volume
与资源对象相关的事物与动作:label,annotation,namespace,deployment,hap,pvc
通用属性:版本,kind,名称,标签,注解
版本信息包括了对象所属的资源组,一些资源对象的属性会随着版本的升级而变化
类别属性用于定义资源对象的类型
资源对象的名称,标签,注解这三个属性属于资源对象的元数据
资源对象的名称唯一
资源对象的标签来表明资源对象的特征,类别,以及通过标签筛选不同的资源对象并实现对象之间的关联,控制或协作功能
注解是一种特殊的标签,与程序挂钩,实现资源对象属性的自定义扩展
每个资源对象都有自己的特定结构的定义,可以理解为数据库中一个特定的表,并且统一保存在etcd非关系型数据库中
所有资源都可以通过kubectl工具执行增删改查等操作
集群类
cluster是由master和node组成的
master:集群的控制节点,负责集群的管理和控制
整个集群的大脑,如果发生宕机或不可用,集群内容器应用的管路都无法实施
kubernetes api server(kube-apiserver):提供http restful api接口的主要服务
是kubernetes里对所有资源进行增删改查等操作的唯一入口,集群控制的入口进程
kuec-controller-manager:kubernetes里所有资源对象的自动化控制中心,资源对象的大总管
kube-scheduler:资源调度(pod调度)的进程,公交公司的调度室
master上通常部署etcd服务,也可单独部署
node
除了master之外都被称为node
node是集群中的负载节点
每个node都会被Master分配一些工作负载(docker)
当某个node宕机时,其上的工作负载就会被master自动转移到其他node上
kubelet:负责pod对应容器的创建,启动,停止等任务,与Master密切协作,实现集群管理的基本功能
kube-proxy:实现service的通信与负载均衡机制
容器运行时:负责本机的容器创建和管理
node动态加载到集群中
kubelet会自动向Master注册自己
master能不能直到pod的详细信息,全靠kubelet
kubectl get nodes
kubectl describe node <node_name>
node出现问题会打标签:taint->污点,避免新容器调度到该node上
某些Pod可以短期容忍(toleration)某种污点的存在,可以继续调度到该node上
namespace:实现多租户的资源隔离
属于不同命名空间的资源对象从逻辑上相互隔离
master默认命名空间:default,kube-system
用户创建的资源对象如果没有指定命名空间,会被存在default中
系统相关的资源对象:网络组件,DNS组件,监控类组件,都被安装在kube-system
·kubectl get pods --namespace=development
应用类
service与pod
service指的是无状态服务,一般由多个副本提供服务
特殊情况下是有状态的单实例服务
拥有全局唯一clusterip,创建成功后不会改变,客户端通过clusterip + port直接访问,
部署DNS服务,实现了service name(域名)到clusterip地址的DNS映射功能->服务发现
mysql存储类服务:
系统由多个提供不同业务能力而又独立的微服务单元组成,服务之间通过TCP/IP通信
拥有强大的分布式能力,弹性扩容能力,容错能力
pod:
为进程之间的协作提供一个抽象模型,使用pod作为基本的调度,复制等管理工作的最小单位,让多个应用进程能一起有效的调度和伸缩
pod里的多个业务容器共享pause容器的ip,共享pause容器挂载的volume
每个pod有唯一的pod ip,一个pod里的多个pod容器共享pod ip地址
任意两个pod可以直接使用TCP/IP通信->虚拟二层网络技术
flannel
一个pod里的容器能跟另一个pod里的容器直接进行通信
static pod:没有存放在etcd,存放在某个具体的node上的具体文件中,并且只能在该node上启动运行
普通pod一旦被创建,就被kubernetes master调度到某个具体的node上并绑定
该pod被对应的node上的kubelet进程实例化一组相关的docker容器并启动
pod里的某个容器停止时,kubernetes会自动检测到这个问题并且重新启动这个pod(重启Pod里的所有容器)
如果pod所在的node宕机,node上的所有pod都重新调度到其他节点上
endpoint:pod的ip和容器端口
代表此pod里的一个服务进程的对外通信地址
一个pod存在多个endpoint的情况
tomcat:对外暴露管理端口和服务端口
pod volume是被定义在Pod上,被各个容器挂载到自己的文件系统中的
volume简单来说就是被挂载到pod里的文件目录
event:事件的记录,记录了事件最早产生的时间,最后重现时间,重复次数,发起者,类型,以及导致此事件的原因
event通常会被关联到某个具体的资源对象上,排查故障的重要参考信息
发现某个pod迟迟无法创建时,kubectl describe pod xxx
来查看它的描述信息
label
一个资源对象可以定义任意数量的label
同一个label也可也被添加到任意数量的资源对象上
label通常在资源对象定义时确定,在对象创建后动态添加或删除
通过给指定的资源对象空帮一个或多个label来实现多维度的资源分组管理功能
方便灵活的进行资源的分配,调度,配置,部署等管理工作
通过label selector查询和筛选某些label资源对象
label和label selector共同构成了kubernetes系统中核心的应用模型
可以被管理对象进行精细的分组管理,同时实现了整个集群的高可用性
pod与deployment
大部分service都是无状态的服务,由多个pod副本实例提供服务
每个service对应的pod服务实例都是固定的
deployment负责指定数量自动创建pod实例
replicas:pod的副本数量
selector:目标pod的标签选择器
template:用于自动创建新pod副本的模板
deployment的另一个特性:自动控制
如果pod所在的节点发生宕机事件,kubernetes就会观察到这个故障,自动创建一个新的pod对象,将其调度到其他合适的节点
kubernetes会实时监控集群中目标pod的副本数量,尽力与deployment中声明的replicas数量保持一致
desired:pod副本数量的期望值,deployment里定义的replicas
current:当前replicas的值,不断增加直到desired为止,表示部署成功
up-to-date:最新版本的pod副本数量,在滚动升级的过程中,有多少个pod副本已经成功升级
available:当前集群中可用的副本数量
kubernetes会根据deployment自动创建关联的replicaset对象
kubectl get replicaset
service的clusterip地址
每个pod都提供了endpoint(pod ip + containerport)
kubernetes内部在每个node上都运行了一套全局的虚拟负载均衡器,自动注入并自动实时更新集群中所有service的路由表,通过iptables或者ipvs机制,把对service的请求转发到其后端实时对应的某个pod实例上,并在内部实现服务的负载均衡与会话保持机制
clusterip:pod的endpoint地址会随着pod的销毁和重新创建而产生改变,因为新的pod的ip与之前的旧的pod不同
service一旦被创建,在kubernetes生命周期中就不会被更改,每个服务旧变成了唯一ip地址的通信节点,远程服务之间的通信问题就变成了基础的TCP网络通信问题
服务发现:service的name与clusterip地址做一个dns域名映射
clusterip与node和master所在的物理网络完全无关
单独的clusterip不具备tcp/ip通信的基础
clusterip属于Kubernetes集群的这个封闭的空间,集群外的节点要访问这个通信端口,需要做一些额外的工作
kubectl get endpoints
查看clusterip地址
kubectl get svc <servicename> -o yaml
targetport属性用来确定该服务的容器所暴露的端口号
具体的业务进程在容器内的targetport上提供tcp/ip接入
port属性则定义了service的端口
不指定targetport的时候,默认与port相同
headless service clusterIP:None
:与普通service的区别是有没有cluster ip地址
如果解析headless service的DNS域名,则返回的是该service对应的全部pod的endpoint列表
客户端是直接与后端的pod建立tcp/ip连接进行通信的
没有通过虚拟clusterip地址进行转发,因此通信性能最高,等同于原生网络通信
service的多端口要求每个endpoint定义一个名称进行区分
clusterip外网访问:
nodeip:物理网卡Ip,访问kubernetes中的某个节点或tcp/ip服务,必须通过node ip通信
pod ip:
使用docker作为容器支持引擎,docker engine根据docker0网桥的ip地址段进行分配的,通常是一个虚拟二层网络
pod相互访问就是通过虚拟二层网络进行通信的,真实的tcp/ip流量是通过node ip所在的物理网卡流出的
service ip:集群内的地址,无法直接在外部使用
采用了nodeport来解决集群外的应用访问集群内的服务
type:NodePort nodePort:31002
在kubernetes集群的每个Node上都需要为外部访问的service开启一个对应的TCP监听端口,外部系统只要用任意一个Node的ip地址+nodeport端口号即可访问此服务
任意node上运行netstat命令,就可以看到有nodeport端口被监听
netstat -tlp | grep 31002
nodeport最好的解决方案是在其上加一个负载均衡器
云 type=NodePort改为type=LoadBalancer
NodePort的升级版:ingress
ingress的实现机制理解为基于nginx的支持虚拟主机的http代理
有状态的应用集群
deployment用来实现无状态服务的多副本自动控制功能
deployment创建的pod名称是随机的
有状态的应用被比为宠物,无状态的应用被比为牛羊
有状态的应用:
每个阶段都有固定的身份ID,通过这个ID,集群中的成员可以互相发现并通信
集群的规模是比较固定的,集群规模不能随意变动
集群中的每个节点都是有状态的,通常会持久化数据到永久存储中,每个节点重启后都需要使用原有的持久化数据
集群中成员的启动关闭顺序也是确定的
如果磁盘损坏,集群里的某个节点无法正常运行,集群功能受损
集群中的pod需要挂接某种共享存储
statefulset:
deploymet/rc的一个特殊变种
每个pod都有稳定,唯一的标识,用来发现集群内的其他成员
pod副本的启停顺序是受控制的
pod采用稳定的持久化存储卷,通过pv或pvc来实现
删除pod时默认不会删除与statefulset相关的存储卷
statefulset与pv空帮使用,与headless service配合使用
每个在statefulset定义中都要声明它属于哪个headless service
statefulset在headless service的基础上又创建了一个dns域名
kubernetes operator是api,开发一个类似statefulset的控制器
主流有状态集群都会以operator方式部署到kubernetes cluster中
批处理应用
批处理应用的特点是一个或多个进程处理一组数据(图像,文件,视频等)
采用job
两个控制并发数的参数:completions和parallelism
completions表示运行任务数的总数
parallelism表示并发运行的个数
job所控制的pod副本是短暂运行的,将其视为一组容器
其中的每个容器都仅运行一次
当job控制的所有pod副本运行都结束时,对应的job也就结束了
job生成的pod副本是不能自动重启的
restartpolicy=Never
cronjob可以周期性的执行某个任务
应用配置
如何解决应用需要在不同的环境中的修改配置问题
configmap:
保存配置项的一个map,分布式系统中配置中心的独特实现之一
几乎所有应用都需要一个静态的配置文件来提供启动参数
当一个应用是分布式应用,配置分发需要一个配置中心组件
应用应用的时候,将configmap定义为特殊的volume进行挂载
pod被调度到某个Node上时,configmap里的配置文件会被自动还原到本地目录下,然后映射到pod里指定的配置目录下
configmap修改后,kubernetes会自动获取内容并在目标节点进行更新
secret:
解决应用配置的问题,对敏感信息的配置问题
被pod引用
HPA
horizontal pod autoscaler
用deployment来控制pod的副本数量,可以手工实现pod的扩容缩容
hpa:pod横向自动扩容
通过追踪分析指定deployment控制的所有目标pod负载变化情况,来确定是否需要有针对性地修改pod地副本数量
kubernetes内置基于cpu利用率进行自动扩缩容地机制
vpa
垂直pod自动扩缩容
根据容器资源使用率自动推测并设置pod合理地cpu和内存地需求指标
存储类
存储类地对象:volume,persistent volume,pvc,storageclass
volume是pod中能够被多个容器访问地共享目录
kubernetes中地volume被定义在pod上,被一个pod里地多个容器挂载到具体地文件目录下
kubernetes中地volume与pod地生命周期相同,但与容器地生命周期不相关
当容器终止或者重启时,volume中地数据不会丢失
pod上声明一个volume,在容器中引用该volume并将其挂载(mount)到容器里地某个目录下
emptydir
pod分配到Node地时候创建emptydir
初始内容为空,无需指定宿主机上对应地目录文件
kubernetes自动分配目录
pod从Node上移除时,emptydir中地数据也被永久删除
临时空间
长时间任务执行过程中使用地临时目录
一个容器需要从另一个容器中获取数据地目录(多容器共享目录)
emptydir使用地是节点地存储介质
hostpath
在pod上挂载宿主机地文件或目录
在容器应用程序生成地日志文件需要永久保存时,可以使用宿主机地高速文件系统对其进行存储
需要访问宿主机上docker引擎内部数据结构地容器应用时
通过定义hostpath为宿主机/var/lib/docker目录,使得容器内部地应用直接访问docker地文件系统
不同地Node上具有相同配置地pod,可能会因为宿主机上地目录和文件不同而导致volume上目录和文件地访问结果不一致
如果使用了资源配额管理,则kubernetes无法将hostpath在宿主机上使用地资源纳入管理
公有云volume
volume属于静态管理地存储
需要事先定义每个volume,然后将其挂载到pod中去用
配置参数繁琐,存在大量手工操作
预定义地静态volume可能不符合目标应用地需求,比如容量问题,性能问题
动态化存储:persistent volume,storageclass,pvc
pv表示由系统创建地一个存储卷,某个网络存储对应地一块存储
pv不是被定义在pod上地,而是独立于pod之外定义地
storageclass用来描述和定义某种存储系统地特征
previsioner:创建pv地第三方存储插件
parameters创建pv时地必要参数
reclaimpolicy代表声明了pv回收策略
回收策略包括删除或者保留
storageclass会在pvc中出现
pvc表示应用申请地pv规格
重要地属性包括accessmodes,storageclassname,resources
安全类
多用户共享资源地资源管理系统
service account
rbac
在每个命名空间都会创建一个默认名称为default地service account
service account是不能全局使用地
只能被他所在地命名空间中使用
kubectl get sa --all-namespaces
service account是通过secret来保存对应地用户身份凭证信息地
凭证信息有ca根证书数据和签名后地token信息
默认情况下,创建一个pod,会绑定对应命名空间中地default
当pod容器被创建时,kubernetes会把对应地secret对象中地身份信息持久化保存到容器里固定位置地本地文件中
role和clusterrole
group,user,service account
不同厂商地时候用networkpolicy
kubernetes入门
kubernetes是一个全新的基于容器技术得分布式架构领先方案
新一代得基于容器技术得pass平台得重要底层框架
service mesh,serverless等新一代分布式架构框架技术纷纷基于Kubernetes实现
任何语言写得service都可以映射为kubernetes得service,并通过标准得tcp通信协议进行交互
kubernetes对现有得编程语言,编程框架,中间件没有任何侵入性
kubernetes具有完备得集群管理能力,多层次得安全防护和准入机制,多租户应用承受能力,透明的服务注册和服务发现机制,内建的智能负载均衡器,服务滚动升级和在线扩容能力。
service是分布式集群架构的核心
拥有唯一指定的名称(mysql)
拥有一个虚拟ip地址(clusterip)和端口号
能够提供某种远程服务能力
能够讲客户端对服务的访问请求转发到一组容器应用上
service的服务进程通常基于socket通信方式对外提供服务
一个service通常由多个相关的服务进程提供服务,每个服务进程都有一个独立的endpoint(ip+port)访问点,但kubernetes能够让我们通过service(clusterip+service port)连接指定的服务
service本身一旦创建就不在发生变化
容器提供了强大的隔离功能,所以要把为service提供服务的这组进程放入容器中进行隔离
将每个服务进程放到相应的pod中,使其成为在pod中运行的一个container
建立service和pod之间的关联关系,kubernetes给每个pod都设置了一个标签,给相应的service定义label selector
pod运行在Node的环境中,这个node既可以是物理机,也可以是云上的虚拟机,在一个node上可以运行多个pod
每个pod都运行这一个pause的container,其他容器为业务容器,这些业务容器共享pause容器的网络栈和volume挂在卷
并不是每个Pod和它里面运行的container都会被映射到一个service上,只有提供服务的那组Pod才会被映射为一个服务
master:kube-apiserver,scheduler,controller manager
实现了集群的资源管理,pod调度,弹性伸缩,安全机制,系统监控和纠错
node:kubelet,kube-proxy
集群中的工作节点,其上运行这真正的应用程序.
kubernetes在node上管理的最小运行单元是pod
实现了pod的创建,启动,监控,重启,销毁,以及实现软件模式的负载均衡器
云平台将kubernetes作为底层平台
微服务架构的核心是将一个巨大的单体应用分解为很多小的互相连接的微服务,一个微服务可能由多个实例副本支撑,副本的数量可以随着系统的负荷变化进行调整
微服务架构使得每个服务都可以独立开发,副本的数量可以随着系统的负荷变化进行调整,一个微服务可能由多个实例副本支撑,副本的数量可以随着系统的负荷变化进行调整
hello world
-
创建deployment定义文件mysql-deploy.yaml
-
将yaml发送到集群中,在master运行
kubectl apply -f mysql-deploy.yaml
-
查看刚创建的deployment
kubectl get deploy
-
查看pod的创建情况
kubectl get pods
- 创建的pod一开始是pending,创建成功后是running
-
在kubernetes节点的服务器上通过docker ps查看正在运行的容器
docker ps | grep mysql
-
创建一个与之关联的kubernetes service:mysql-svc.yaml
-
通过kubectl create创建service对象
kubectl create -f mysql-svc.yaml
-
查看刚创建的service对象
kubectl get svc mysql
-
clusterip地址是在service创建后由kubernetes系统自动分配的,其他pod无法预知某个service的clusterip地址,需要一个服务发现机制来找到这个服务
kubernetes使用了linux环境变量(environment variable)来解决这个问题
根据service的唯一名称,容器可以从环境变量中获取service对应的clusterip地址和端口号,从而发起tcp/ip连接请求
tomcat
-
创建myweb-deploy.yaml
- tomcat内应用使用环境变量mysql_service_host连接mysql服务
- 为什么不需要注册该环境变量?
- kubernetes会自动将已存在的service对象以环境变量的形式展现在新生的pod中
- 更安全更可靠的方法是使用服务名称mysql,这就要求dsn(kube-dns)正常运行
-
将yaml发送到集群中,在master运行
kubectl apply -f myweb-deploy.yaml
-
查看刚创建的deployment
kubectl get deploy
-
查看pod的创建情况
kubectl get pods
-
在kubernetes节点的服务器上通过docker ps查看正在运行的容器
docker ps | grep mysql
-
创建一个与之关联的kubernetes service:myweb-svc.yaml
- 通过kubectl create创建service对象
- kubectl create -f myweb-svc.yaml
- 查看刚创建的service对象
kubectl get svc myweb
- 通过kubectl create创建service对象
资源对象有自己的生命周期及其相应的状态
资源按照功能或用途分为:集群类,应用类,存储类,安全类
集群类:由master和node组成的kubernetes集群
master指的是集群的控制节点,每个集群中都需要一个或一组被称为master的节点,来负责整个集群的管理和控制。
master通常占据一个独立的服务器,在高可用部署种至少使用3台服务器,是整个集群的大脑
如果发生宕机或不可用,对集群内容器应用的管理都无法实施
master上运行这这些关键进程
kubernetes api server(kube-apiserver):提供http restful api接口的主要服务,是kubernetes里对所有资源进行增删改查等操作的唯一入口,也是集群控制的入口进程。
kubernetes controller manager(kube-controller-manager):kubernetes里所有资源对象的自动化控制中心,将其理解为资源对象的大总管
kubernetes scheduler(kube-scheduler):负责资源调度(pod)的进程,相当于公交公司的调度室
master通常还需要部署etcd服务
node:除了master之外的服务器
node可以是一台物理主机,一台虚拟机
node是kubernetes集群种的负载节点,每个node都会被master分配一些工作负载(docker)
当某个Node宕机时,其上的工作负载会被master自动转移到其他node上
每个node上运行这这些关键进程
kubelet:负责pod对应容器的创建,启动,停止等任务,与master密切协作,实现集群管理的基本功能
kube-proxy:实现kubernetes service的通信与负载均衡机制的服务
容器运行时(docker):负责本机的容器创建和管理
node可以在运行期间动态加载到kubernetes集群种,前提是这个Node已正确安装配置和启动了上述关键进程
默认情况下,kubelet进程会定时向master汇报自身的情报,例如操作系统,主机cpu和内存使用情况,以及当前有哪些pod在运行等,这样master就可以获知每个node的资源使用情况,并实现高效均衡的资源调度策略
某个Node在超过指定时间不上报信息时,会被master判定为失联的node,状态被标记为不可用(not ready),master随后会触发工作负载大转移的自动流程
查看多少node:get nodes
查看某个node的详细信息:kubectl describe node nodename
如果node存在问题,就给node打上一种特殊的标签-污点(taint),避免新的容器被调度到该node上。
而如果某些pod短期可以容忍toleration某种污点的存在,就可以继续将其调度到该node上
命名空间:实现多租户的资源隔离,给每个租户都分配一个命名空间
命名空间属于kubernetes集群范畴的资源对象,在一个集群里可以创建多个命名空间,每个命名空间都是相互独立的存在,属于不同命名空间的资源对象从逻辑上互相隔离
在每个kubernetes集群安装完成且正常运行后,master会自动创建两个命名空间,一个是default,一个是系统级的(kube-system)
用户创建的资源对象如果没有指定命名空间,则被默认存放在default命名空间种
而系统相关资源如网络挂件,DNS组件,监控类组件等,被安装在kube-system命名空间种
我们可以通过命名空间将集群内部的资源对象分配到不同的命名空间种,形成逻辑上分组的不同项目,小组或用户组,便于不同的分组在共享使用整个集群的资源的同时能被分别管理
当给每个租户都创建一个命名空间来实现多租户的资源隔离时,还能结合kubernetes的资源配额管理,限定不同的租户能占用的资源,如:cpu使用量,内存使用量
一旦创建了命名空间,我们在创建资源的时候就可以指定这个资源对象属于哪个命名空间
kubectl get pods --namespace=
应用类
service与pod
应用类主要围绕service和pod
service指的是无状态服务,通常由多个程序副本提供服务,在特殊情况下也是由状态的单实例服务
与常规理解的服务不同,kubernetes里的service具有一个全局唯一的虚拟clusterip地址
service一旦被创建,kubernetes就会自动分配一个可用的clusterip地址,而且在service的整个生命周期种,clusterip地址不会改变,客户端可以通过clusterip直接访问该服务,在通过部署kubernetes的dns服务,就可以实现service name(域名)到clusterip地址的DNS映射功能,只要使用服务的名称(DNS名称)即可完成目标服务的访问请求
凭借clusterip的独特设计,kubernetes进一步实现了service的透明负载均衡和故障自动恢复的高级特性
系统最终由多个提供不同业务能力而又彼此独立的微服务单元组成,服务之间通过TCP/IP进行通信,从而形成强大又灵活的弹性网格,拥有强大的分布式能力,弹性扩展力,容错能力,程序架构也变得简单和直观许多
每个pod都有一个特殊的根容器pause
pause容器对应的镜像属于Kubernetes平台的一部分
除了pause容器,每个pod都还包括一个或多个紧密相关的用户业务容器
在kubernetes里面,一个pod里的容器与另外主机上的pod容器能够直接通信
pod分为两种:普通pod和静态pod
static pod并没有保存在etcd中,而是保存在某个具体的node上的一个具体文件中,并且只能在此node启动,运行
普通pod一旦被创建,就保存在etcd,随后被Kubernetes master调度到具体的node上并绑定,该pod对应的node上的kubelet进程实例化成一组相关的docker容器并启动
默认情况下,当pod里的某个容器停止时,kubernetes会自动检测到这个问题并且重新启动这个pod(重启pod里的所有容器),如果pod所在的Node宕机,就会将这个Node上的所有pod都重新调度到其他节点上。
endpoint:pod的ip加上这里的容器端口(container port)组成,代表此pod里的一个服务进程的对外通信地址
一个pod也存在具有多个endpoint的情况
pod volume被定义在pod上,然后被各个容器挂载到自己的文件系统中
volume简单来说就是挂载到Pod里的文件目录
event:事件记录,记录了事件的最早发生时间,最后重现时间,重复次数,发起者,类型,以及导致此事件的原因等众多信息
event通常会被关联到某个具体的资源对象上,是排查故障的重要参考信息
当我们发现某个pod迟迟无法创建时,可以使用kubectl describe pod xxx
来查看他的描述信息
label与标签选择器
一个资源对象可以定义任意数量的label,同一个label也可也被添加到任意数量的资源对象上
label通常在资源对象定义时确定,也可也在对象创建后动态添加或删除。
给指定的资源对象绑定一个或多个不同的label来实现多维度的资源分组管理功能
部署不同版本的应用到不同的环境中,以及监控,分析应用等
通过label selector查询和筛选拥有某些label的资源对象
kubernetes通过这种方式实现了类似sql的简单查询机制
大部分service都是无状态服务,可以由多个pod副本实例提供服务
每个service对应的pod服务实例数量都是固定的
deployment有一个重要的特性自动控制
kubectl create -f deployment.yaml
查看deployment的信息
kubectl get deployment
服务发现:用service的name与clusterip地址做一个DNS域名映射
node ip
pod ip
service ip
nodeport
page 35
kubeadm一般安装的是测试环境,生产环境用kuberadm装全部宕机重新启动之后会比较慢,因为kubeadm是容器里面装容器。生产环境用二进制装会比较快
cat /proc/cpuinfo | grep process
kubectl debug 设置一个临时容器
sidecar:先启动sidecar还是先启动容器?需要设置,1.8已搞定。1.8之前没有搞定
volume:更改目录权限。fsgroup
configmap和secret
负载均衡:nginx+?
uname -a :查看内核,一定要升级内核,不然会出现莫名其妙的问题
宿主机挂了,docker无法自动恢复
java程序端口启动,但是docker无法访问,程序假死
高可用,负载均衡,自动扩缩容
load Balancer:虚拟vip,master节点高可用,负载均衡
硬件负载均衡?
master节点:整个集群的控制中枢
kube-apiserver:集群的控制中枢,各个模块之间信息交互都需要,同时也是集群管理,资源配置,整个集群安全机制的入口
kubectl:k8s控制端工具,请求都发送道了kube-apiserver
controller-manager:集群的状态管理器,保证pod或其他资源得到期望值。需要和kube-apiserver进行通信,在需要的时候创建,更新或删除它所管理的资源
scheduler:集群的调度中心。它会根据指定的一系列条件选择一个或一批最佳的节点,然后部署我们的pod
etcd:键值数据库,保存一些集群的信息,一般生产环境部署三个以上,一般奇数个,不建议偶数个。一定要使用ssd硬盘,使用普通硬盘越往后性能越差
node节点:工作节点:
worker节点,node节点,minion节点
kubelet:master节点也有可能会部署。get node
查看节点。负责监听节点上po的状态,同时负责上报节点和节点上面pod的状态。负责与master节点通信并管理节点上面的pod
kube-proxy:负责pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器上。
``netstat -lntp | grep kube-proxy
查看kube-proxy的工作模式:curl:127.0.0.1:10249/proxyMode
ipvs:监听master节点,增加和删除service以及endpoint的消息,调用netlink接口,创建相应的ipvs规则。通过ipvs规则,将流量转发到相应的pod上
ipvsadm -ln
kubectl get svc -n kubernetes-dashboard
kubectl get po -n kubernetes-dashboard -owide
iptables:监听master节点增加和删除service以及endpoint的消息,对于每一个service,它都会创建一个iptables规则,将service的clusterip代理到后端对应的pod上。(tptables多的时候性能下降)
kubectl get po -n kube-sysytem kubectl get po -n kube-system -owide
需要指定命名空间,因为是互相隔离的。如果不指定,查看的就是default命名空间
kubectl get po
calico:符合cni标准的网络插件,给每个pod生成一个唯一的ip地址。并且把每个节点当作一个路由器。跨节点通信就可以通信。
route -n :查看节点路由信息
cilium:有可能替代kube-proxy。成千上万扛不住,使用cilium ebpf替代kube-proxy,原生支持ebpf
coredns:用于kubernetes集群内部service的解析,可以让pod把service名称解析成ip地址,然后通过service的ip地址进行连接到对应的应用上
kubectl get svc:查看网段
生产环境中coredns会启动多个:什么时候启动几个?
docker:容器引擎,负责对容器的管理
metrics-server:
kubectl top po -n kube-sysytem
pod
哪些是namespace隔离,哪些不是?
kubectl get ns:查看namespace
kubectl get po -n kube-sysytem
kubectl get clusterrole
kubectl get clusterrole -n kube-system
kubectl get storageclass
kubectl get ingressclass
kubectl get secret
kubectl get secret -n kube-system
pod是kubernetes中最小的单元,它由一组,一个或多个容器组成,每个pod还包含了一个pause容器
kubectl get po -n kube-sysytem
docker ps
发现启动的时候带了一个pause容器
pause容器是pod的父容器,主要负责僵尸进程的回收管理,同时通过pause容器可以使同一个pod里面的多个容器共享存储,网络,pid,ipc等
一个container里面最多启动一个进程。
为什么要引入pod?
当容器之间需要互相引用的时候,docker无法保证在同一个pod里面,无法共享内存,无法以特别小的方式取访问
yaml以空格分隔
get node --show-labels
kubectl create -f pod-yam -n kube-public
kubectl create ns ns_name
kubectl get po -n kube-public
kubectl apply -f pod.yaml
pod在生产环境中很少单独创建,pod无法进行弹性升级回滚。
kubectl logs -f nginx
管理Pod使用depeloment,statefult,daemonset
探针:
startupprobe:k8s1.16版本后新加得探测方式,用于判断容器内应用程序是否已经启动。如果配置了startupprobe就会先禁止其他得探测,直到它成功为止。成功后将不在进行探测。
零宕机必备
kubectl get deployment -n kube-system
kubectl edit deploy -n kube-system
livenessprobe:用于探测容器是否运行,如果探测失败,kubelet会根据配置得重启策略进行相应得处理。如果没有配置该探针,默认就是success
readinessprobe:用于探测容器内得程序是否健康。如果为success,那么就代表这个容器已经完全启动,并且程序已经完全接受流量得状态。
pod探针得检测方式:
execaction:在容器内执行一个命令,如果返回值为0,则认为容器健康
tcpsocketaction:通过tcp连接检查容器内得端口是否是通得,如果是通得,就认为容器健康。
telnet 127.0.0.1:2379
Httpgetaction:生产用得最多。通过应用程序暴露得api地址来检测程序是否是正常得。如果http状态码为200~400之间,则认为容器健康
kubectl create -f pod.yaml
kubectl get po
不论何种语言编写的服务,都可以被映射为kubernetes的service,通过标准的Tcp通信协议进行交互
在kubernetes中,service是分布式集群架构的核心,一个service对象拥有如下关键特征
拥有唯一指定的名称
拥有一个虚拟IP地址(clusterip)和端口号
能够提供某种远程服务能力
能够将客户端对服务的访问请求转发到一组容器应用上
service的服务进程通常通过socket通信方式对外提供服务
每个service进程都有一个独立的endpoint访问点
kubernetes通过service链接指定的服务
kubernetes内建的透明负载均衡和故障恢复机制
service一旦被创建就不能被改变
每个service都包装到相应的pod,使service成为pod中的一个container
为了给service和pod建立链接,给pod添加了一个Lable
pod被运行在一个被称为节点的环境中
每个pod中都运行这一个特殊的被称为pause的容器,其他容器为业务容器
这些业务容器共享pause容器的网络栈和volume挂载卷,因此他们之间的通信和数据交换更为高效
只有提供服务的那组pod才会被映射为一个服务
集群管理
kubernetes将集群中的机器划分为Master和node
master上运行这集群管理相关的一些进程:
kube-apiserver
kube-controller-manager
kube-scheduler
这些进程实现了集群的资源管理,pod调度,弹性伸缩,安全控制,系统监控和纠错,都是自动完成的
node:集群中的工作节点,其上运行这真正的应用程序
在Node上,kubernetes管理的最小运行单元是pod,在Node上运行这kubernetes的kubelet,kube-proxy服务进程,这些服务进程负责pod的创建,启动,监控,重启,销毁以及实现软件模式的负载均衡器
在kubernetes中只需要为需要扩容的service关联的pod创建一个deployment对象,服务扩容及服务升级就解决了
deployment
目标pod的定义
目标pod需要运行的副本数量
要监控的目标pod标签
kubernetes根据目标pod需要运行的副本数量来自动创建,如果需要扩容,只需要修改此项即可。
docker network
使用deployment来定义需要启动的服务
将deployment的yaml文件发布到kubernetes集群中使用
kubectl apply -f *.yaml
查看刚创建的deployment
kubectl get deploy
查看pod的创建情况
kubectl get pods
status:pending->running
使用docker ps
查看运行的容器
创建kubernetes service与pod关联
kubectl create -f *.yaml
查看刚创建的service
kubectl get svc mysql
clusterup是在service创建后由kubernetes系统自动分配的,其他pod无法预先知道某个service的clusterip地址
因此需要一个服务发现机制:使用linux环境变量来解决
通用属性:版本,标签,类别,名称,注解
每个资源对象保存在etcd这种非关系型数据库中
所有资源都可以通过kubectl工具执行增删改查操作
查看集群中有多少个Node
get nodes
查看某个node的详细信息
kubectl describe node <node_name>
video
参考资料
kubernetes权威指南