kubernets学习结构
1. Architecture/Components
Master Node:
Work Node:
Workflow
① kubectl 发送部署请求到 API Server。
② API Server 通知 Controller Manager 创建一个 deployment 资源。
③ Scheduler 执行调度任务,将两个副本 Pod 分发到 k8s-node1 和 k8s-node2。
④ k8s-node1 和 k8s-node2 上的 kubelet 在各自的节点上创建并运行 Pod。
1.1.API Server
API Server 提供 HTTP/HTTPS RESTful API。
API Server是 Kubernetes Cluster 的前端接口,可以通过它管理 Cluster 的各种资源
2.2. Scheduler
Scheduler 负责决定将 Pod 放在哪个 Node 上运行。
Scheduler 在调度时会充分考虑 Cluster 的拓扑结构,当前各个节点的负载,
1.3.Controller Manager
Controller Manager 负责管理 Cluster 各种资源,保证资源处于预期的状态
1.4. kubelet
kubelet 是 work Node 的 agent,当 Scheduler 确定在某个 Node 上运行Pod 后,会将 Pod 的具体配置信息发送给该节点的 kubelet,kubelet 根据这些信息创建和运行容器,并向 Master 报告运行状态。
1.5.Proxy
它负责将访问 service 的 TCP/UDP 数据流转发到后端的容器。如果有多个副本,kube-proxy 会实现负载均衡。service的服务端口都是proxy这个进程起起来的
1.6. coredns
Kubernetes集群使用ServiceName作为服务的访问地址,因此需要一个集群范围的DNS服务实现从ServiceName到Cluster Ip的解析
通过配置kubelet服务参数,配置dns服务到每个pod. cluster.local为默认域名,服务名和namespace一起构成FQDN: <svc name>.<namespace>.svc.cluster.local
搜索服务时,同一个namespace,不需要加namespace,不同namespace需要加。参考https://hansedong.github.io/2018/11/20/9/
1.7.Container Network Interface(CNI)
标准的一个调用网络实现的接口
CNI plugin - 增删POD的时候,向CNI实例提供输入来配置容器网络,获取输出
IPAM plugin - CNI插件负责为接口配置和管理IP地址,容器的IP分配
1.7.1. 跨节点pod连接
容器的IP就是host网络里分配的IP,容器相当于host网络里的节点,那么就可以天然互访.
容器的IP与node的IP不属于同一个网段,node上配置个到各个网段的路由(指向对应容器网段所部属的node IP),通过路由实现互访[flannel,host-gw, calico bgp均是通过此方案实现];
容器的IP与node的IP不属于同一个网段,node上有服务对容器发出的包进行封装(UDP),对发给容器的包进行解封。封装后的包通过node所在的网络进行传输。解封后的包通过网桥或路由直接发给容器,即overlay网络[flannel udp/vxlan,calico ipip,openshift-sdn均通过此方案实现]
2. 安装
docker
etcd: etcd 负责保存 Kubernetes Cluster 的配置信息和各种资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件.
overlay网络插件: 需要用作服务发现和数据存储的backstore.overlay的网络插件遵循CNI规范. Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案,但不支持NetworkPolicy
kubelet: 是唯一需要安装的rpm,其他服务都是以pod的形式部署
3. Resource
3.1.Pod
Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器
3.1.1. 可管理性
有些容器天生就是需要紧密联系,一起工作。Pod提供了比容器更高层次的抽象,将它们封装到一个部署单元中。Kubernetes 以Pod 为最小单位进行调度、扩展、共享资源、管理生命周期
3.1.2. 通信和资源共享
Pod 中的所有容器使用同一个网络, PID namespace,即相同的 IP 地址和 Port空间。它们可以直接用 localhost 通信。同样的,这些容器可以共享存储,当Kubernetes 挂载 volume 到 Pod,本质上是将 volume 挂载到 Pod中的每一个容器
3.1.3. liveness
探测让用户可以自定义判断容器是否健康的条件。如果探测失败,Kubernetes就会重启容器
3.1.4. readiness
探测则是告诉 Kubernetes 什么时候可以将容器加入到 Service负载均衡池中,对外提供服务
3.2. Service
定义了外界访问一组特定 Pod 的方式。从逻辑上代表了一组Pod,具体是哪些 Pod 则是由 label 来挑选.Service 有自己的 IP 和端口,Service 为Pod 提供了负载均衡(通过iptables 将访问 Service 的流量转发到后端 Pod)
ClusterIP- Service 通过 Cluster 内部的 IP 对外提供服务,只有 Cluster内的节点和 Pod 可访
NodePort- Service 通过 Cluster 节点的静态端口对外提供服务。Cluster外部可以通过:访问 Service
LoadBalance- Service 利用 cloud provider 特有的 load balancer对外提供服务,cloud provider 负责将 load balancer 的流量导向 Service
3.3. Namespace
可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的
3.4.Deployment
是最常用的 Controller,可以管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。
1, 用户通过 kubectl 创建 Deployment。
2, Deployment 创建 ReplicaSet。
3, ReplicaSet 创建 Pod。
3.4.1. 伸缩
是指在线增加或减少 Pod 的副本数。
3.4.2. 滚动更新
一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新(增加一个新的,减少一个旧的)
3.4.3. 回滚
每次更新应用时 Kubernetes 都会记录下当前的配置,保存为一个revision,这样就可以回滚到某个特定 revision(回滚逻辑和滚动更新一致)
3.5. Job
用于运行结束就删除的应用。而其他 Controller 中的 Pod通常是长期持续运行
3.6. ReplicaSet
实现了 Pod 的多副本管理。使用 Deployment 时会自动创建ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod的多个副本,我们通常不需要直接使用 ReplicaSet。
3.7. DaemonSet
用于每个 Node 最多只运行一个 Pod副本的场景。正如其名称所揭示的,DaemonSet 通常用于运行 daemon
3.8. StatefuleSet
能够保证 Pod的每个副本在整个生命周期中名称是不变的。而其他 Controller不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod的名称会发生变化。同时 StatefuleSet会保证副本按照固定的顺序启动、更新或者删除。
3.9. Ingress and ingress controller
通过利用 Nginx负载均衡器暴露集群内服务的工具
解决NodePort 过多难以管理的问题8
通过配置ingress的yml文件代替nginx的配置文件来添加更新服务
ingress controller 是一个带有nginx的deployment,关联上service
ingress是一个配置的controller方向代理的工具,通过rules对controller里的方向代理进行配置支持http,和https(设置TLS)的访问
通过配置虚拟主机进行路由, 也可以通过URL进行路由通过annotation的指定rewrite、redirct等属性进行url从定向例如/testpath路由到A服务,但是A服务没有/testpath的资源所以要rewrite到准确的url
3.10. Volume
volume为容器提供持久化存储数据能力,生命周期独立于容器,Pod中的容器可能被销毁和重建,但 Volume 会被保留
3.10.1 emptyDir
是最基础的 Volume 类型。正如其名字所示,一个 emptyDirVolume 是 Host 上的一个空目录。emptyDir Volume对于容器来说是持久的,对于 Pod 则不是。当 Pod 从节点删除时,Volume的内容也会被删除。但如果只是容器被销毁而 Pod 还在,则 Volume 不受影响
3.10.2. hostPath
Volume 的作用是将 Docker Host 文件系统中已经存在的目录mount 给 Pod 的容器.大部分应用都不会使用 hostPath,因为这实际上增加了Pod 与节点的耦合,限制了 Pod 的使用。不过那些需要访问Kubernetes内部数据(配置文件和二进制库)的应用则需要使用 hostPath
3.10.3. 外部Storage Volume
AWS Azure, GCE, NFS, GlusterFS, Ceph
3.10.4. Persistent Volume
外部存储系统中的一块存储空间,由管理员创建和维护
3.10.4.1. Retain
当PV和PVCunbound后,需要管理员手工回收清理数据,并不能被PVC再次bound
3.10.4.2. Recycle
当PVC和PV unbound的时候清除 PV 中的数据,可以被pvc再次bound
3.10.4.3. Delete
删除 Storage Provider 上的对应存储资源,部分StorageProvider支持13
3.10.5. PVC
是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为Pod 分配存储资源时,用户可以创建一个PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes会查找并提供满足条件的 PV.
3.10.6. StorageClass
不需要提前创建PV,减少了管理员的工作量,效率高,如果没有满足 PVC 条件的PV,会动态创建 PV
3.11. Secret
Secret会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息
Volume形式引用-把secretmount到指定目录,默认key为文件名,value为文件内容。支持动态更新,Secret变,则pod里的文件内容变1
通过环境变量的形式引用- 不支持动态更新
3.12. ConfigMap
ConfigMap是数据以明文的形式存放,用于一些非敏感数据,比如应用的配置信息
Volume形式引用-把configmapmount到指定目录,默认key为文件名,value为文件内容。支持动态更新,configmap变,则pod里的文件内容变
通过环境变量的形式引用- 不支持动态更新
4. Pause容器
每个pod创建的第一个容器
与pod里其他容器共享网络namespace,pod里面所有容器共享网络,通过localhost访问,提高了网络访问效率
与pod里面其他容器共享PID namespace,pause容器的PID为1,其他容器的进程为子进程进程1的责任就是监控和处理僵尸子进程
pause 容器,因为for循环调用pause系统函数,所以顾名思义容器通过接收子进程信号来,pod容器进程进行监控和处理
5. RBAC
5.1.Role
只能用于授予对某一单一命名空间中资源的访问权限(rule是通过设定不同APIgroup的读,写,订阅的权限)
5.2.ClusterRole
可以授予与Role对象相同的权限,但由于它们属于集群范围对象,也可以使用它们授予对以下几种资源的访问权限:集群范围资源(例如节点,即node)非资源类型endpoint(例如”/healthz”)跨所有命名空间的命名空间范围资源(例如pod,需要运行命令kubectl get pods --all-namespaces来查询集群中所有的pod)
5.3.RoleBinding
可以引用在同一命名空间内定义的Role对象,也可以引用一个ClusterRole对象,在RoleBinding所在的命名空间内授予用户对所引用的ClusterRole中定义的命名空间资源的访问权限
5.4.ClusterRoleBinding
在集群级别和所有命名空间中授予权限
5.5.User
有外部独立服务(LDAP,AD)进行管理的用户,用户不能通过集群内部的 API来进行管理User 创建过程
1,创建一个RSA pair,和证书创建请求csr文件,以k8s的集群的CA.crt,CA.key为根证书,申请一个用户证书。
2,利用用户证书和私钥,设置一个用户的credential(k8s会生成一个user在配置文件里面)kubectl config set-credentials
3,利用这个用户的creduential,为用户设置一个contextkubectl config set-contexts
4, 绑定用户到指定role或者clusterrole
5.6.Group
这是用来关联多个账户的
5.7. ServiceAccount
通过Kubernetes API 来管理的一些用户帐号,和 namespace进行关联的,适用于集群内部运行的应用程序,需要通过 API来完成权限认证,可以在集群内部进行权限操作ServiceAccount的创建:
1,通过kubectl create serviceaccount 创建一个某个namespace下的SA
2,创建的serviceaccount的同时,会一起生成一个secret的resource与其对应,这个secret的包括一个token和根证书(CA.crt), token 用于k8s API对请求的认证,根证书用于请求端对k8s API的验证
3,生成这个SA所对应的role或者clusterrole(引用现有的也可以)
4,绑定到role或者clusterrole
查看token:kubectl get secret default-token-c87mr -o jsonpath={.data.token}
6. Tools
6.1.Helm
K8s的包管理工具, 类似于yum
Helm的架构图
6.1.1. Chart
创建一个应用的信息集合,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系、文档说明。类似于rpm包
chart是一个tgz包,解压后目录结构
mariadb
├── Chart.yaml
├── files
│ └── docker-entrypoint-initdb.d
│ └── README.md
├── OWNERS
├── README.md
├── templates
│ ├── _helpers.tpl
│ ├── initialization-configmap.yaml
│ ├── master-configmap.yaml
│ ├── master-pdb.yaml
│ ├── master-statefulset.yaml
│ ├── master-svc.yaml
│ ├── NOTES.txt
│ ├── rolebinding.yaml
│ ├── role.yaml
│ ├── secrets.yaml
│ ├── serviceaccount.yaml
│ ├── servicemonitor.yaml
│ ├── slave-configmap.yaml
│ ├── slave-pdb.yaml
│ ├── slave-statefulset.yaml
│ ├── slave-svc.yaml
│ ├── test-runner.yaml
│ └── tests.yaml
├── values-production.yaml
└── values.yaml
Chart.yaml-描述 chart 的概要信息
README.md-相当于 chart 的使用文档
Requirements.yaml-chart 可能依赖其他的 chart
在安装过程中,依赖的 chart 也会被一起安装
Values.yaml-chart 支持在安装的时根据参数进行定制化配置,而 values.yaml 则提供了这些配置参数的默认值
templates目录-各类 Kubernetes资源的配置模板都放置在这里(svc,deployment,secret,ConfigMap)。
Helm 会将 values.yaml 中的参数值注入到模板中生成标准的 YAML 配置文件
6.1.2. release
chart 的运行实例,代表了一个正在运行的应用。
当 chart 被安装到 Kubernetes 集群,就生成一个 release。
chart 能够多次安装到同一个集群,每次安装都是一个 release。
6.1.3. Tiller Sever
Pod/Service形式运行在cluster-管理release。负责监听helm客户端请求,调用k8s API。管理chart,包括记录, 安装, 升级,回滚
6.1.4. helm客户端工具
连接 Tiller Server对chart进行操作(查看,安装,卸载),本地开发chart, 管理chart仓库
6.1.5. helm repo
相当于yum 源。可以是官方的repo,也可以自己建立local的repo,任何 HTTP Server 都可以用作 chart 仓库
6.2.Prometheus Operator
对K8S进行监控,例如cluster,node,pod等,具体一下几个模块
Prometheus Server
ServiceMonitor
Prometheus Role
Alert Manager