Kubernetes资源对象
- 不能注释
- 可读性较差
- 语法严格
- 比较适用于API返回值,也可用于配置文件(但一般没有用json格式)
- json格式
{"人员名单":
{"张三":{"年龄":18,"爱好":["看书","学习"]},
"李四":{"年龄":20,"爱好":["旅游","运动"]}
}
}
-
yaml文件特点
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许tab键,只允许使用空格
- 缩进空格数目不重要,同级元素左对齐即可
- 使用#表示注释,从这个字符到行尾,都会被解释器忽略
- 比json更适合做配置文件
k8s的设计理念
分层架构

k8s系统:核心层--应用层--管理层--接口层
k8s扩展:
- 作用于k8s内部:CRI CNI CSI 镜像仓库
- 作用于k8s外部:监控、日志收集、CI/CD、配置管理(如配置中心)等
无状态应用:相互之间没有依赖关系的应用,不需要角色选举,没有先后启动顺序,如nginx
有状态应用:之间需要选举或有先后启动顺序,如:mysql主从,zookeeper等
API设计原则
1、所有API应该是声明式的
2、高层API以操作意图为基础设计
3、低层API根据高层API的控制需要设计
4、尽量避免简单封装,不要有在外部API无法显示知道的内部隐藏机制(多个k8s集群,在k8s的api外封装一个api,管理所有的k8s集群,在外层reset,同步到不同集群的k8s)
5、API操作复杂度与对象数量成正比
6、API对象状态不能依赖于网络连接状态(如:1000个pod,按顺序部署,而不是1000个都好了之后才返回结果)
7、尽量避免让操作机制依赖全局状态,因为再分布式系统中要保证全局状态的同步是非常困难的(有些有过半机制,集群中一半的机器同步成功,就当同步成功,后面其他机器再慢慢同步)
API简介
内置API:部署好K8s后内置的api
自定义资源:CRD(Custom Resource Definition),部署k8s之后通过安装其他组件扩展出来的api
命名方式:
/apis/myapi/v1/pods
/分类/API组/API版本/资源对象
显示当前的api
# curl -cacert /etc/kubernetes/ssl/ca.pem -H "Authorization: Bearer TOKEN" https://127.0.0.1:6443
# curl -cacert /etc/kubernetes/ssl/ca.pem -H "Authorization: Bearer TOKEN" https://127.0.0.1:6443/具体api 可显示具体api的信息

资源类型
资源对象: pod、ReplicaSet、Node...
存储对象:Volume、PersistentVolume、PersistentVolumtClaim、Secret、ConfigMap
策略对象:SecurityContext、ResourceQuota、LimitRange
身份对象:ServiceAccount、Role、ClusterRole

常用命令

资源对象详解
yaml文件必备字段
1、apiVersion:创建该对象所使用的Kubernetes API
2、kind:想要创建的对象类型
3、metadata:定义识别对象唯一的数据,包括一个name、可选namespace
4、spec:定义资源对象的详细规范信息
5、status:Pod创建完成后k8s自动生成status状态
spec:声明的状态
status:实际的状态
Pod
1、k8s最小调度单元
2、一个Pod中可以运行一个或多个容器(多个容器共享一个网络名称空间)
3、运行多个容器的话,这些容器是一起被调度的
4、Pod的生命周期是短暂的,不会自愈
5、一般都是通过controller来管理和创建pod
job与cronjob
-
job使用场景
如:当我们部署了mysql,需要去初始化mysql的数据库数据表。但是进去后动太麻烦。就可以使用job,连接到对应数据库,使用job已经准备好的脚本进行初始化
特点:只执行一次,用完之后退出,不会启动,一般用于初始化环境
-
cornjob
周期性任务,如备份等
每次启动创建一个新容器
默认保留三个记录,超过三个删除最远的一次(三次记录为kubectl get pod 显示的cornjob的pod的数量)
控制器
RC/RS
-
Replication Controller 副本控制器
第一代控制器
匹配Pod不是通过标签去匹配的,是根据selector = != 严格匹配或取反
https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicationcontroller/
https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/labels/
-
ReplicaSet
第二代控制器
对选择器的支持(selector 还支持in notin)
Deployment
比rs更高一级的控制器,除了有rs的功能之外,还有很多的高级功能,比如最重要的,滚动升级、回滚
但是deployment是管理replicaset控制器,再记录replicaset的版本
每次更新按25%当前pod数量更新pod
Service
解耦了宿主机到容器之间的关系
实现方式:通过label标签动态匹配后端的endpoint
ExternalName
将外部域名引入集群内部,而且可进行改名,让集群通过固定的service name访问集群外部的服务。有时也用于将不用namespace之间的pod通过该模式进行访问。en很少用到
ClusterIP
k8s集群内部能访问的ip
通过clusterip,内部服务需要调用时可访问clusterip,通过clusterip将请求转给自己负载的某个Pod
微服务常见手段:通过svc将pod全部注册到注册中心中,需要调用这个服务的服务,通过注册中心去获得需要提供服务的Pod地址
NodePort
将服务通过主机端口暴露,访问该暴露的主机端口去访问内部的服务
LoadBlance
通过lb类型的svc,与外部的负载均衡器进行关联,该负载均衡器有两个地址,公网地址和内网地址。由内网地址和k8s集群进行通信
跨节点nodePort转发路径
-
目前状态,nginx服务为nodeport类型端口30012,有6个节点,3master 3worker(172.31.7.111~192.168.1.113),nginx在 .113节点上。
此时:访问192.168.1.1:30098时,流量路径
1、172.31.7.112接收到请求
2、根据路由规则(ipvsadm查看转到哪个ip上 10.200.218.92:80)
3、根据路由表(route -n)查看这个到IP的网关为 172.31.7.113(即下一跳地址) 网卡为tunl0
4、再看192.168.1.6的路由表,这个ip通过calicoxx网卡转发,后真正到达后端Pod
-
112ipvsadm -Ln


-
112路由表


-
113路由表(到达Pod的网卡)


存储卷
Volume将容器中的指定数据和容器解耦,并将数据存储到指定位置,不同的存储卷功能不一样。如果是基于网络的存储卷可以实现容器的数据共享和持久化
静态存储卷需要在使用前手动创建PV和PVC,然后绑定至pod使用
-
常用存储卷
- emptyDir:本地临时卷,容器被删除就没了。一般用于同一个Pod的多个容器数据共享(有些也可能有日志共享需求)
- hostPath:本地存储卷(但是跨主机的话,数据无法同步,如需要最好配置pod亲和性)
- configmap:配置文件,将配置文件挂载到指定的pod的路径
- secret:包含敏感信息的数据。如密码、令牌、密钥等对象
- nfs等(NAS、Ceph)
emptydir
当Pod呗分配给节点时,首先会创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在,正如卷的名字所属,他最初是空的,Pod中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载在每个容器的相同或不同路径中,但当出于任何原因从节点中删除Pod时,emptydir中的数据将被永久删除。
路径:
/var/lib/kubelet/pods/$ID/volumes/kubernetes.io~empty-dir/cache-volume/$FILE


hotspath
将主机节点的文件系统中的文件或目录挂载到集群中,pod删除的时候,卷不会被删除。
但是当pod调度到另一主机的时候,数据无法跨主机同步,只存在第一次创建pod时调度的主机
NFS
nfs卷允许将现有的NFS共享挂载到容器中,不想emptyDir,当删除Pod时,nfs卷的内容将被保留,卷仅仅是被卸载,这意味着nfs卷可以预填充数据,并且可以在pod之间切换数据,nfs可以被多个写入者同时挂载
允许多个pod挂载一个nfs卷
允许一个pod挂载多个nfs卷
ubuntu下使用nfs协议挂载时,需要一个包:nfs-common 包含了一些nfs的lib库
没有的话:要么挂不上去,要么挂上去,传输速度会很慢
注意:
1、nfs共享时,配置文件写了一个目录,那么该目录下的所有子目录都可以单独挂载,不必子目录一个写一条配置
2、写nfs允许挂载的网段时,不要写pod的网段,否则宿主机是无法挂载的,那么容器也就无法挂载。
原因:pod的请求为了能原路返回,会以宿主机的ip去请求,并不会一pod的ip去请求
3、默认没有空间限制,需要去配置空间限制
PV/PVC
-
简介
PV: PersistenVolume
PVC: PersistentVolumeClaim
用于实现Pod和storage解耦,这样我们修改storage的时候就不需要修改Pod。
与NFS的区别,可以在PV和PVC层面实现对存储服务的分配,存储的访问权限管理等。
k8s从1.0开始支持pv/pvc
不同存储卷支持的访问模式:
存储类型
静态存储
static:静态存储卷,需要在使用前手动创建pv,然后创建pvc绑定到pv。然后挂载到pod去使用,适用于pv和pvc相对比较固定的业务场景
dynamin:动态存储卷,先创建一个storageclass,后期pod在使用pvc的时候,可以通过存储类动态创建pvc,适用于有状态服务集群和mysql一主多从,zookeeper集群等


动态存储
https://kubernetes.io/zh/docs/concepts/storage/storage-classes/
https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
过程:
1、创建账户:
a.创建命名空间,保留nfs驱动程序(当使用到nfs动态存储时,会在目录下创建一个目录,供当前的pvc去使用,这些都需要进行交互)
b.创建服务账号ServiceAccount
c.创建ClusterRole
d.创建ClusterRoleBonding
2、创建storageclass(确定你的后端类型):
例如:
apiVersion: stroage.k8s.io/v1
kind: StroageClass
metadata:
name: example-nfs
previsioner:
server: nfs-server.example.com
path: /share
readOnly: "false"
注意:杰哥上课时的vers=4.1这个参数去掉了
3、创建NFS驱动
4、创建PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myserver0myapp-dynamic-pvc
namespace: myserver
spec:
storageClassName: managed-nfs-storage ##调用指定storageclass
addceeModes
- ReadWriteMany
resource:
requests:
storage: 500Mi
5、创建web服务
ConfigMap
ConfigMap配置信息和镜像解耦,实现方式为将配置信息放到ConfigMap中,然后在Pod中以Volume的形式挂载,从而实现导入配置
使用场景:
- 通过ConfigMap给Pod定义全局环境变量
- 通过ConfigMap给Pod传递命令行参数,如mysql -u -p的账户名可以通过configmap进行传递
- 通过ConfigMap给Pod中的容器服务提供配置文件,配置文件以挂载到容器的形式使用
注意事项:
ConfigMap需要在Pod使用之前创建
pod只能使用位于一个namespace的ConfigMap,及ConfigMap不能跨namespace使用
通常用于非安全加密的配置场景
ConfigMap通常是小于1MB的配置


Secret
-
简介
功能类似于ConfigMap给Pod提供额外的配置信息,但是secret是一种包含少量敏感信息例如密码、令牌或密钥的对象
secret的名称必须是合法的DNS子域名
每个Secret的大小最多为1M,主要是为了避免用户创建非常大的Secret进而导致API服务器和kubelet内存耗尽,捕获创建很多小的secret也可能耗尽内存,可以使用资源配额来约束每个名称空间中的secret个数
再通过yaml文件创建secret时,可以设置data或stringData字段,data和stringData字段都是可选的,data字段中所有键值必须为base64编码的字符串,如果不希望执行这种base64字符串转换操作,也可以选择设置stringData字段,其中可以使用任何非加密字段的字符串作为其取值。
Pod可以用三种方式的任意一种来使用secret
作为挂载到一个或多个容器上的卷中文件(crt、key文件)
作为容器的环境变量
由kubelet在为Pod拉取镜像时使用(与镜像仓库的认证)
类型
| Secret类型 | 使用场景 |
|---|---|
| Opaque | 用户自定义数据 |
| kubernetes.io/service-account-token | ServiceAccount令牌 |
| kubernetes.io/dockercfg | ~/.dockercfg文件的序列化形式 |
| kubernetes.io/dockerconfigjson | ~/.docker/config.json文件的序列化形式 |
| kubernetes.io/basic-auth | 用于基本身份认证的凭据 |
| kubernetes.io/ssh-auth | 用于ssh身份认证的凭据 |
| kubernetes.io/tls | 用于TLS环境,保存crt证书和key证书 |
| bootstrap.kubernetes.io/token | 启动引导令牌数据 |
挂载流程
docker拉取镜像的secret
imagePullSecrets:
- name: 你创建的secret的名字
-
镜像拉取流程
kubectl 发送创建pod指令,apiserver接收,将其存入etcd... 被调度到的节点的kubelet接收到指令,将secret发送到docker,docker携带者这个secret去私有镜像仓库拉取镜像
动态存储实验
创建服务账号并绑定
apiVersion
