【云原生训练营】模块四 Kubernetes 架构原则和对象设计

【云原生训练营】模块四 Kubernetes 架构原则和对象设计,第1张

Kubernetes 架构原则和对象设计 K8s安装K8s概念K8s架构控制器的工作流程了解KubectlKubernetes生态系统常用 Kubernetes 对象及其分组核心技术概念和 API 对象TypeMeta 核心对象概览课后练习

K8s安装

https://github.com/cncamp/101/tree/master/k8s-install/k8s-by-kubeadm

Install docker
apt install docker.io

Update cgroupdriver to systemd
vi /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
systemctl daemon-reload
systemctl restart docker
Letting iptables see bridged traffic
$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sudo sysctl --system

Update the apt package index and install packages needed to use the Kubernetes apt repository:
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl

Install kubeadm
$ sudo curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -

Add the Kubernetes apt repository
$ sudo tee /etc/apt/sources.list.d/kubernetes.list <<- EOF'
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
EOF


Update apt package index, install kubelet, kubeadm and kubectl
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl


kubeadm init
$ echo "10.0.100.141 cncamp.com" >> /etc/hosts
$ kubeadm init \
 --image-repository registry.aliyuncs.com/google_containers \
 --kubernetes-version v1.22.2 \
 --pod-network-cidr=10.0.100.0/16 \
 --apiserver-advertise-address=10.0.100.141

Copy kubeconfig
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config


Untaint master
$ kubectl taint nodes --all node-role.kubernetes.io/master-
K8s概念

Kubernetes 是谷歌开源的容器集群管理系统,是 Google 多年大规模容器管理技术 Borg 的开源版本,主要功能包括:

基于容器的应用部署、维护和滚动升级;负载均衡和服务发现;跨机器和跨地区的集群调度;自动伸缩;无状态服务和有状态服务;插件机制保证扩展性。

K8s架构

K8s Master:

API服务器:这是 Kubernetes 控制面板中唯一带有用户可访问 API 以及用户可交互的组件。API 服务器会暴露一个 RESTful 的 Kubernetes API 并使用 JSON 格式的清单文件(manifest files)。

etcd:etcd 是 CoreOS 基于 Raft 开发的分布式 key-value 存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)。

基本的key-value存储监听机制(数据发生变化watch API-Server,长连接)key 的过期及续约机制,用于监控和服务发现原子 CAS 和 CAD,用于分布式锁和 leader 选举

Controller Manager:它运行着所有处理集群日常任务的控制器。包括了节点控制器、副本控制器、端点(endpoint)控制器以及服务账户等。

Controller Manager 是多个控制器的组合,每个 Controller 事实上都是一个 control loop,负责侦听其管控的对象,当对象发生变更时完成配置;Controller 配置失败通常会触发自动重试,整个集群会在控制器不断重试的机制下确保最终一致性( Eventual Consistency)

调度器Scheduler:调度器会监控新建的pods(一组或一个容器)并将其分配给节点。

K8s Worker:

kubelet:负责调度到对应节点的 Pod 的生命周期管理,执行任务并将 Pod 状态报告给主节点的渠道,通过容器运行时(拉取镜像、启动和停止容器等)来运行这些容器。它还会定期执行被请求的容器的健康探测程序。kube-proxy:它负责节点的网络,在主机上维护网络规则并执行连接转发。它还负责对正在服务的 pods 进行负载平衡。

ETCD
直接访问etcd的数据
进入容器查询数据(获取etcd数据库里以斜杠开头的key)
get --keys-only --prefix

export ETCDCTL_API=3
etcdctl --endpoints https://localhost:2379 --cert /etc/kubernetes/pki/etcd/server.crt --key
/etc/kubernetes/pki/etcd/server.key --cacert /etc/kubernetes/pki/etcd/ca.crt get --keys-only --prefix /

监听对象变化(watch)
watch --prefix /registry/services/specs/default/mynginx

etcdctl --endpoints https://localhost:2379 --cert /etc/kubernetes/pki/etcd/server.crt --key
/etc/kubernetes/pki/etcd/server.key --cacert /etc/kubernetes/pki/etcd/ca.crt watch --prefix /registry/services/specs/default/mynginx

APIServer
Kube-APIServer 是 Kubernetes 最重要的核心组件之一,主要提供以下功能:

提供集群管理的 REST API 接口,包括: 认证 Authentication;授权 Authorization;准入 Admission(Mutating & Valiating)。 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 APIServer 查询或修改数据,只有 APIServer 才直接 *** 作 etcd)。APIServer 提供 etcd 数据缓存以减少集群对 etcd 的访问。

Scheduler
特殊的 Controller,工作原理与其他控制器无差别。
Scheduler 的特殊职责在于监控当前集群所有未调度的 Pod,并且获取当前集群所有节点的健康状况和资源使用情况,为待调度 Pod 选择最佳计算节点,完成调度。

调度阶段分为:

Predict:过滤不能满足业务需求的节点,如资源不足、端口冲突等。Priority:按既定要素将满足调度需求的节点评分,选择最佳节点。Bind:将计算节点与 Pod 绑定,完成调度。

kubelet
Kubernetes 的初始化系统(init system)

从不同源获取 Pod 清单,并按需求启停 Pod 的核心组件: Pod 清单可从本地文件目录,给定的 HTTPServer 或 Kube-APIServer 等源头获取;Kubelet 将运行时,网络和存储抽象成了 CRI,CNI,CSI。 负责汇报当前节点的资源信息和健康状态;负责 Pod 的健康检查和状态汇报。

kube-proxy

监控集群中用户发布的服务,并完成负载均衡配置。每个节点的 Kube-Proxy 都会配置相同的负载均衡策略,使得整个集群的服务发现建立在分布式负载
均衡器之上,服务调用无需经过额外的网络跳转(Network Hop)。负载均衡配置基于不同插件实现: userspace。 *** 作系统网络协议栈不同的 Hooks 点和插件: iptables;ipvs。 控制器的工作流程

实际上就是个生产者消费者,把控制器放在消息队列里,等待worker去消费

Informer的内部机制
Reflector会解析对象的key。
代码本地的Thread Safe Store会存储对象和键值,

控制器的协同工作原理
Controller Manager
把结果写到API Server

了解Kubectl

kubectl 是一个 Kubernetes 的命令行工具,它允许Kubernetes 用户以命令行的方式与 Kubernetes 交
互,其默认读取配置文件 ~/.kube/config。kubectl 会将接收到的用户请求转化为 rest 调用以rest client 的形式与 apiserver 通讯。apiserver 的地址,用户信息等配置在 kubeconfig。

kubectl手册:
kubectl logs 可查看 pod 的标准输入(stdout, stderr),与 tail 用法类似
kubectl exec 提供进入运行容器的通道,可以进入容器进行 debug *** 作。
kubectl describe 展示资源的详细信息和相关 Event。
kubectl get po -oyaml -w
kubectl 可查看对象。

-oyaml
输出详细信息为 yaml 格式。-w watch
该对象的后续变化。-owide
以详细列表的格式查看对象。 Kubernetes生态系统


分层架构

核心层:Kubernetes 最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境。应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析
等)。管理层:系统度量(如基础设施、容器和网络的度量)、自动化(如自动扩展、动态 Provision 等)、
策略管理(RBAC、Quota、PSP、NetworkPolicy 等)。接口层:Kubectl 命令行工具、客户端 SDK 以及集群联邦。生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴: Kubernetes 外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS 应用、
ChatOps 等;Kubernetes 内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等。

Kubernetes 如何通过对象的组合完成业务描述

架构设计原则

只有 APIServer 可以直接访问 etcd 存储,其他服务必须通过 Kubernetes
API 来访问集群状态;单节点故障不应该影响集群的状态;在没有新请求的情况下,所有组件应该在故障恢复后继续执行上次最后收到的请求
(比如网络分区或服务重启等);所有组件都应该在内存中保持所需要的状态,APIServer 将状态写入 etcd 存储,而其
他组件则通过 APIServer 更新并监听所有的变化;优先使用事件监听而不是轮询。 常用 Kubernetes 对象及其分组

核心技术概念和 API 对象

API 对象是 Kubernetes 集群中的管理 *** 作单元。
Kubernetes 集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的 API 对象,支持对该功能的管理 *** 作。

每个 API 对象都有四大类属性:

TypeMetaMetaDataSpecStatus TypeMeta

Kubernetes对象的最基本定义,它通过引入GKV(Group,Kind,Version)模型定义了一个对象的类型。

Group
Kubernetes 定义了非常多的对象,如何将这些对象进行归类是一门学问,将对象依据其功能范围归入不同的分组,
比如把支撑最基本功能的对象归入 core 组,把与应用部署有关的对象归入 apps 组,会使这些对象的可维护性和可
理解性更高。Kind
定义一个对象的基本类型,比如 Node、Pod、Deployment 等。Version
与软件版本类似,通常社区提出一个模型定义以后,随着该对象不断成熟,其版本可能会
从 v1alpha1 到 v1alpha2,或者到 v1beta1,最终变成生产就绪版本 v1。

Metadata 中有两个最重要的属性:Namespace和Name,分别定义了对象的
Namespace 归属及名字,这两个属性唯一定义了某个对象实例。

Label

顾名思义就是给对象打标签,一个对象可以有任意对标签,其存在形式是键值对。
Label 定义了对象的可识别属性,Kubernetes API 支持以 Label 作为过滤条件
查询对象。Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象Label Selector 支持以下几种方式:等式,如 app=nginx 和 env!=production;集合,如 env in (production, qa);多个 label(它们之间是 AND 关系),如 app=nginx,env=test。

Annotation
Annotation 与 Label 一样用键值对来定义,但 Annotation 是作为属性扩展,

Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象,Annotations 则是用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。比如 deployment 使用 annotations 来记录 rolling update 的状态。 Finalizer
Finalizer 本质上是一个资源锁,Kubernetes 在接收某对象的删除请求时,会检
查 Finalizer 是否为空,如果不为空则只对其做逻辑删除(pod会处于terminating状态),即只会更新对象中的
metadata.deletionTimestamp 字段。ResourceVersion
ResourceVersion 可以被看作一种乐观锁,每个对象在任意时刻都有其
ResourceVersion,当 Kubernetes 对象被客户端读取以后,ResourceVersion
信息也被一并读取。此机制确保了分布式系统中任意多线程能够无锁并发访问对
象,极大提升了系统的整体效率

Spec 和 Status 才是对象的核心。

Spec 是用户的期望状态,由创建对象的用户端来定义。Status 是对象的实际状态,由对应的控制器收集实际状态并更新。与 TypeMeta 和 Metadata 等通用属性不同,Spec 和 Status 是每个对象独有的。 核心对象概览

Node

Node 是 Pod 真正运行的主机,可以物理机,也可以是虚拟机。为了管理 Pod,每个 Node 节点上至少要运行 container runtime(比如 Docker 或者 Rkt)、Kubelet 和 Kube-proxy 服务。

Namespace

Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, replication controllers 和 deployments 等都是属于某一个 Namespace 的(默认是 default),而 Node, persistentVolumes
等则不属于任何 Namespace。

Pod

Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace,是 Kubernetes
调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。同一个 Pod 中的不同容器可共享资源: 共享网络 Namespace;可通过挂载存储卷共享存储;共享 Security Context。

存储卷

通过存储卷可以将外挂存储挂载到 Pod 内部使用。存储卷定义包括两个部分: Volume 和 VolumeMounts。 Volume:定义 Pod 可以使用的存储卷来源;VolumeMounts:定义存储卷如何 Mount 到容器内部。
apiVersion: v1
kind: Pod
metadata:
  name: hello-volume
spec:
  containers:
  - image: nginx:1.15
    name: nginx
    volumeMounts:
	- name: data
	  mountPath: /data
  volumes:
  - name: data
    emptyDir: {}

资源限制
Kubernetes 通过 Cgroups 提供容器资源管理的功能,可以限制每个容器的CPU 和内存使用,比如对于刚才创建的 deployment,可以通过下面的命令限制nginx 容器最多只用 50% 的 CPU 和 128MB 的内存:

$ kubectl set resources deployment nginx-app -c=nginx --limits=cpu=500m,memory=128Mi
deployment "nginx" resource requirements updated

等同于在每个 Pod 中设置 resources limits

健康检查
Kubernetes 作为一个面向应用的集群管理工具,需要确保容器在部署后确实处在正常的运行状态。

探针类型: LivenessProbe 探测应用是否处于健康状态,如果不健康则删除并重新创建容器。 ReadinessProbe 探测应用是否就绪并且处于正常服务状态,如果不正常则不会接收来自 Kubernetes Service 的流量。 StartupProbe 探测应用是否启动完成,如果在failureThreshold*periodSeconds 周期内未就绪,则会应用进程会被重启。 探活方式: ExecTCP socketHTTP

ConfigMap

ConfigMap 用来将非机密性的数据保存到键值对中。使用时, Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。ConfigMap 将环境配置信息和 容器镜像解耦,便于应用配置的修改。

Secret

Secret 是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。使用 Secret 的好处是可以避免把敏感信息明文写在配置文件里。

用户帐户和服务帐户的一个区别是作用范围:

用户帐户对应的是人的身份,人的身份与服务的 Namespace 无关,所以用户账户是跨Namespace 的;而服务帐户对应的是一个运行中程序的身份,与特定 Namespace 是相关的。

Service
Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹
配 labels 的 Pod IP 和端口列表组成 endpoints,由 Kube-proxy 负责将服务
IP 负载均衡到这些 endpoints 上。

每个 Service 都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)
和 DNS 名,其他容器可以通过该地址或 DNS 来访问服务,而不需要了解后端
容器的运行。

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 8078 # the port that this service should serve on
    name: http
    # the container on each pod to connect to, can be a name
    # (e.g. 'www') or a number (e.g. 80)
    targetPort: 80
    protocol: TCP
  selector:
    app: nginx

有状态服务集(StatefulSet)

对于 StatefulSet 中的 Pod,每个 Pod 挂载自己独立的存储,如果一个 Pod 出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来 Pod 的存储继续以它的状态提供服务。适合于 StatefulSet 的业务包括数据库服务 MySQL 和 PostgreSQL,集群化管理服务 ZooKeeper、etcd 等有状态服务。使用 StatefulSet,Pod 仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,StatefulSet 做的只是将确定的 Pod 与确定的存储关联起来保证状态的连续性

Statefulset 与 Deployment 的差异

身份标识 StatefulSet Controller 为每个 Pod 编号,序号从0开始。 数据存储 StatefulSet 允许用户定义 volumeClaimTemplates,Pod 被创建的同时,Kubernetes 会以volumeClaimTemplates 中定义的模板创建存储卷,并挂载给 Pod。

StatefulSet 的升级策略不同

onDelete滚动升级分片升级

任务(Job)

Job 是 Kubernetes 用来控制批处理型任务的 API 对象。Job 管理的 Pod 根据用户的设置把任务成功完成后就自动退出。成功完成的标志根据不同的 spec.completions 策略而不同: 单 Pod 型任务有一个 Pod 成功就标志完成;定数成功型任务保证有 N 个任务全部成功;工作队列型任务根据应用确认的全局成功而标志成功。

后台支撑服务集(DaemonSet)

长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类业务的 Pod,有些节点上又没有这类 Pod 运行;而后台支撑型服务的核心关注点在 Kubernetes 集群中的节点(物理机或虚拟机),要保证每个节点上都有一个此类 Pod 运行。节点可能是所有集群节点也可能是通过 nodeSelector 选定的一些特定节点。典型的后台支撑型服务包括存储、日志和监控等在每个节点上支撑 Kubernetes 集群运行的服务。

存储PV和PVC

PersistentVolume(PV)是集群中的一块存储卷,可以由管理员手动设置,或当用户创建 PersistentVolumeClaim(PVC)时根据 StorageClass 动态设置。PV 和 PVC 与 Pod 生命周期无关。也就是说,当 Pod 中的容器重新启动、
Pod 重新调度或者删除时,PV 和 PVC 不会受到影响,Pod 存储于 PV 里
的数据得以保留。对于不同的使用场景,用户通常需要不同属性(例如性能、访问模式等)
的 PV。 课后练习 启动一个 Envoy Deployment。要求 Envoy 的启动配置从外部的配置文件 Mount 进 Pod。进入 Pod 查看 Envoy 进程和配置。更改配置的监听端口并测试访问入口的变化。通过非级联删除的方法逐个删除对象。
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: envoy
  name: envoy
spec:
  replicas: 1
  selector:
    matchLabels:
      run: envoy
  template:
    metadata:
      labels:
        run: envoy
    spec:
      containers:
      - image: envoyproxy/envoy-dev
        name: envoy
        volumeMounts:
        - name: envoy-config
          mountPath: "/etc/envoy"
          readOnly: true
      volumes:
      - name: envoy-config
        configMap:
          name: envoy-config

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/927334.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存