kubernetes base
kubernetes提供了资源调度,扩容缩容,服务发现,存储编排,自动部署和回滚,并且具有天生高可用,负载均衡,故障自动恢复
架构
master
主节点生产环境推荐三个起步
kube-ApiServer
无状态服务,状态存储到etcd当中
集群的控制中枢
提供集群各个模块之间的数据交换
将集群状态和信息存储到etcd集群中
只有kube-ApiServer和etcd进行通信,其他节点基本不通信
ControllerManager
有状态组件
集群状态管理器
保证Pod或其他资源达到期望值
Scheduler
有状态组件
集群Pod的调度中心
通过调度算法将Pod分配到最佳Node
通过Kube-ApiServer监听所有Pod状态
可选
kubelet
Kube-proxy
node
从节点部署Pod
kubelet
负责与master通信
管理该节点上的Pod
对容器进行健康检查及监控
负责上报节点和节点上面Pod的状态
kube-proxy
负责各pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器上
runtime
负责容器管理
coredns
用于kubernetes集群内部Service的解析
可以让Pod把service名称解析成Service的ip
通过service的ip地址进行连结到对应的应用上
calico
cni标准的网络插件
负责给每个pod分配一个不会重复的ip
并且把每一个节点当作一个路由器
这样一个节点的pod就可以通过ip地址访问到其他节点pod
查看路由规则 route -n
kubectl
在哪里都可以,只要和集群进行通信就可以
在config里面进行配置操作kubernetes集群
etcd
3个起步,奇数个,不能是偶数,会有脑裂的风险
Pod
一组一个或多个容器构成,每个pod还包含一个Pause容器
pause容器是pod的父容器,主要负责僵尸进程的回收管理
通过Pause容器可以使同一个Pod里面的不同容器共享存储,网络,pid,ipc等
容器之间可以通过localhost:port相互访问
可以使用volume等实现数据共享
pod可被建模为一组具有共享命令空间,卷,ip地址和port端口的容器
containerd的命令
ctr相关
创建pod
文件形式创建
# vim nginx.yaml
apiVersion : v1 # pod的版本号 使用kubectl api-resources查看
kind: Pod # 类型pod
metadata: # 元数据
name: nginx # pod名称
spec: # Pod详细信息
containers: # 容器列表
- name: nginx # 容器名称
image: nginx:1.15.12 # 容器镜像
ports :
` containerPort: 80 # 端口号
kubectl create -f nginx.yaml
查看pod状态
kubectl get pod nginx
使用kubectl run
kubectl run nginx-run --image=nginx:1.15.12
apiVersion: v1 # API的版本号
kind: Pod # 类型pod
metadata: # 元数据
name: nginx # pod名称
spec: # 定义pod的详细信息
containers: # 容器列表
- name : nginx # 容器名称
image: nginx:1.15.12 # 容器所用的镜像地址
ports: # 容器暴露的端口号
- containerPort: 80 # 端口号
# 创建pod
kubectl create -f nginx.yaml
# 查看pod状态
kubectl get pod nginx
# 使用kubectl run 创建一个pod
kubectl run nginx-run --image=nginx:1.15.12
更改Pod的启动命令和参数
# vim nginx.yaml
apiVersion: v1 # api的版本号
kind: Pod # 类型pod
metadata: # 元数据
name: nginx # pod的名称
spec: # Pod的详细信息
containers: #容器列表
- name: nginx # 容器名称
image: nginx:1.15.12 # 镜像地址
command:# 容器启动执行的命令
-sleep
- "10"
ports:# 端口号
- containerPort: 80
Pod状态以及Pod故障排查命令
Pod的Phase字段只有Pending,Running,Succeeded,Failed,UnKnown,其余的为处于上述状态的原因
kubectl get pod xxx -o yaml查看,这个要指定命名空间
Pod镜像拉取策略
spec.containers.imagePullPolicy指定镜像拉去策略
always(默认)
never
ifnotpresent
# vim nginx.yaml
apiVersion: v1 # api的版本
kind: Pod
metadata:
name: nginx
spec:
containers:
-name: nginx
image: nginx:1.15.12
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
``
### pod重启策略
spec.restartPolicy指定容器的重启策略
always
onfailure
never
```python
# vim nginx.yaml
# 指定重启策略为never
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
-image: nginx:1.15.12
imagePullPolicy: IfNotPresent
command:
-sleep
- "10"
ports:
-containerPort:80
restartPolicy:Never
Pod的三种探针:检测容器是否正常
三种健康检查方式只能使用一种
startupProbe 只探测一次,先进行startupProbe的探测,探测完才会调用其他探针
livenessProbe 循环探测
readlinessProbe 判断容器内的程序是否正常
grpc(1.24版本开启)
探针的实现方式
execaction
Tcpsocketaction
httpgetaction
没有配置探针检查
容器启动慢,没有配置监控检查,访问的时候会出现错误
创建完成之后立马变成了runnning状态,ready会立马变为满额
加健康检查后,前面的ready会有延迟
livenessProbe和readinessProbe
startupProbe
启动进程特别特别慢,健康检查如何配置?
保证不能重启,等这么长时间在检查
程序需要90秒才能启动,没有startupPorbe的时候要干等这么长时间
k8s>1.16,程序大于30,需要配置StartupProbe,让startupProbe去等待延迟时间,不能让livenetssProbe和readlinessProbe,因为她两故障恢复时间长,业务上无法忍受
pod启动过程
pod启动和删除属于pod的生命周期
pod创建的时候,apiserver收到指令,处于pending状态
确定节点之后,变为containercreating状态,开始拉镜像
镜像啦下来之后变为runnning状态
先初始化容器操作
然后在启动主容器container
健康检查
pod退出过程
preStop和postStart
poststart:容器创建完成后执行的指令
apiVersion:v1
kind: pod
metadata:
name: nginx
spec:
containers:
-name: nginx
image: nginx:1.15.12
imagePullPolicy: IfNotPresent
command:
-sh
--c
-sleep 10;nginx -g "daemon off;"
ports:
- containerPort:80
restartPolicy:never
# 配置健康检查
apiversion:v1
kind:pod
metadata:
name:nginx
spec:
containers:
- name: nginx
image: nginx:1.15.12
imagePullPolicy:IfNotPresent
command:
- sh
- -c
- sleep 10; nginx -g "daemon off;"
readlinessProbe:
httpGet:
path:/index.html
port:80
scheme:http
httpHeaders:
-name : end-user
value : jason
initialDelaySeconds:10
timeoutSeconds:2
periodSeconds:5
periodSeconds:5
successThreshold:1
failureThreshold:2
livenessProbe:
tcpscoket:
part:80
initialDelaySeconds:10
timeoutSeconds:2
periodSeconds:5
successThreshold:1
failureThreeshold:2
ports:
- containerPort:80
-restartPolicy:Never
k8s资源调度
pod不会经常单独操作
ReplicaSet和Replication Controller
Replication Controller:rc,复制控制器
replicaset:复制集,rs
rc
rc可确保pod副本数达到期望值,也就是tc定义的数量
用rc维护的pod在失败,删除或终止时会自动替换
类似于进程管理程序
监视多个节点上的pod
rs
支持基于集合的标签选择器的下一代rc
用作deployment协调创建,删除和更新pod
与rc的区别是,rs支持标签选择器
虽然rs可以单独使用,但是一般建议使用deployment来自动管理rs
deployment
用于部署无状态服务i
deployment首先创建rs,然后由rs去创建pod
deployment具有命名空间隔离性
创建deployemnt
apiversion: apps/v1
kind: deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas:3
selector:
matchLabels:
app:nginx
template:
metadata:
labels:
app:nginx
spec:
containers:
-name : nginx
image:nginx:1.15.12
ports:
-containerPort:80
spec:deployment自己的配置
template是关于pod的定义
kubectl create deployment nginx --image= --replicas=3 -oyaml --dry-run=client
属于一个yaml格式的文件,–dry-run发给apiserver不创建,返回一个数组,转成yaml格式
# 创建deployment
kubectl create -f nginx-deploy.yaml
# 查看
kubectl get deploy
# 查看rs
kubectl get rs
# 查看pod部署在哪个节点
kubectl get po -owide
# 删除Pod
kubectl delete pod pod-name
ready:pod就绪个数和总副本数
Up-to-date:显示已达到期望状态的被更新的副本数
available:显示用户可以使用的副本数
age:显示应用程序运行的时间
rollout
使用rollout查看整个deployment创建的状态
kubectl rollout status deployment/nginx-deployment
查看deployment当前对应的rs
kubectl get rs -l app=nginx
当deployment有过更新,对应的rs可能不止一个,可以通过-o yaml获取当前对应的rs是哪个,其余的rs为保留的历史版本,用于回滚操作
更新deployment
当且仅当deployment的Pod模板更改时,才会触发deployment更新
更新的时候会创新一个新的rs,新rs变为1,旧rs减1,然后新rs会启动pod
当新rs变为就绪,他就会把之前的旧的接着减1,最后把新的全部其出来,老的变为0
更新过程为新旧交替更新
# 更新nginx pod的image使用nginx:latest,并使用--record记录当前更改的参数
kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record
kubectl edit deployment.v1.apps/nginx-deployment
# 查看更新过程
kubectl rollout status deployment.v1.apps/nginx-deployment
# 通过describe查看deployment的详细信息
kubectl describe deploy nginx-deployment
看到整个部署的流程
回滚deployment
版本不稳定或配置不合理时,对其进行回滚操作
kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record
kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v2 --record
使用kubectl rollout history
kubectl rollout history deployment/nginx-deployment
kubectl rollout history deployment/nginx-deployment --revision=3
kubectl rollout undo deployment/nginx-deployment
kubectl rollout history deployment/nginx-deployment
回滚到指定版本 --to-revision
扩容deployment
使用kubectl scale动态调整
kubectl scale deployment.v1.apps/nginx-deployment --replicas=5
查看pod
kubectl get pod
暂停和恢复deployment更新
多次修改,更新一次,使用deployment暂停功能
kubectl roolot pause deployment/nginx-deployment
kubectl rollout history deployment.v1.apps/nginx-deployment
使用kubectl rollout resume恢复deployment更新
kubectl rollout resume deployment.v1.apps/nginx-deployment
kubectl get rs
kubectl describe deploy nginx-deployment
更新deployment的注意事项
默认情况下,revision保留10个旧的replicaset,其余的将在后台进行垃圾回收,可以在spec.revisionHistoryLimit设置保留replicaset的个数,当设置为0时,不保留历史记录
本地文件改了不一定会改,需要手动更新
Statefulset:sts
有状态的资源管理,程序需要持久化一些数据,或者有一个固定的标识符
命名空间限制
有序
需要稳定的独一无二的网络标识符
需要持久化数据
需要有有序的,优雅的部署和扩展
需要有序的自动滚动更新
headless service
statefulset为每个pod维护了一个粘性标识
statefulset创建pod一般使用headless service(headless service)没有clusterip,使用的是endpoint进行互相通信
headless一般的格式为:statefulsetname-{0…N-1}.serviceName.namespace.svc.cluster.local
headless service需要提前创建
定义一个statrfulset资源文件
apiversion:vi
kind:service
metadata:
name:nginx
labels:
app:nginx
spec:
ports:
-port: 80
name:web
clusterIp: None
selector:
app:nginx
apiversion: apps/v1
kind: statefulset
metadata:
name:web
spec:
serviceNmae:"nginx"
replicas:2
selector:
matchLabels:
app:nginx
template:
metadata:
labels:
app:nginx
spec:
containers:
-name: nginx
image: nginx
ports:
-containerPort: 80
name: web
创建statefulset
kubectl create -f sts-web.yaml
kubectl get sts
kubectl get svc
kubectl get po -l app=nginx
statefulset创建pod流程
一直查看状态
kubectl get pod -w
headless service通信原理
statefulset扩容缩容
statefulset更新策略
statefulset灰度发布 分段更新
statefulset级联删除和非级联删除
daemonset 守护进程
创建一个daemonset
daemonset的更新和回滚
最好先测试一个,成功后在更新多个
保存在controllerrevision
自动扩缩容 hpa
水平自动扩缩,不推荐垂直自动扩缩
k8s发布服务
东西流量
南北流量
label和selector
kubectl get pod -l app=nginx
kubectl get node -l disktype=ssd
kubectl get pod --show-labels
pod标签改的少,node标签改的多
kubectl label node k8s-node02 region=subnet7
kubectl get po -l region=subnet7
selector选择器
–show-labels查看指定资源目前已有的Label
service 东西流量
service代理pod,非要南北流量,需要使用nodeport,为了不麻烦,使用Ingress
定义service
kind: service
apiversion:v1
metadata:
name:my-service
spec:
selector:
app:nginx
ports:
-protocol:tcp
port:80
targetPart:80
# 创建服务
apiversion:apps/v1
kind:deployment
metadata:
name: nginx-deployment
labels:
app:nginx
spec:
replicas:3
selector:
matchlabels:
app:nginx
template:
metadata:
labels:
app:nginx
spec:
containers:
-name:nginx
image:nginx:1.15.12
ports:
-containerPort:80
service类型
clusterip
nodeport
loadbalancer
externalname
多端口service
ingress
通过域名的方式发布服务
ingress是配置
ingress controller是服务
ingress controller安装
使用域名发布k8s的服务
不配置域名发布服务
ingress 接口变化解析
k8s新版本Ingressv1配置 1.19之后
configmap
创建configmap的几种形式
做配置文件,环境变量
看官网
使用valuefrom定义环境变量
使用envfrom批量生成环境变量
以文件形式挂载configmap
自定义挂载权限及名称
secret
创建secret
使用secret拉取私有仓库镜像
使用secret管理http证书
使用subpath解决挂载覆盖
configmap&secret热更新
configmap&secret使用限制
不可变secret和configmap
volumes
volumes介绍
volumes emptydir实现数据共享
volumes hostpath挂载宿主机路径
挂载nfs至容器
为什么要引入pv和pvc
volume无法满足生产需求
无法知道每个资源德存储细节,所以需要引入pv和pvc
pv访问和回收策略
文件存储,块存储,对象存储
创建nas或nfs类型的pv
pv的状态
创建hostpath类型的pv
pvc如何绑定到pv
pvc挂载实例
pvc创建和挂载处于pending的原因
job
什么是job
标签和选择运算符 labels和selector
labels是附加到kubernetes对象上的键值对
标签能够支持高效的查询和监听操作,对于用户界面和命令行是很理想的
名词解释
有状态组件
选主机制,如果同时去恢复某些资源,这样会产生浪费和问题,这个时候让一个去操作即可
kubernetes版本是1.20以下
kubernetes1.20以后
同时工作的只有一个节点
kube-apiserver不是,可以同时工作