kubernetes架构原理与集群环境部署

发布于:2025-07-18 ⋅ 阅读:(24) ⋅ 点赞:(0)

概述

Kubernetes 是谷歌以 Borg 为前身,基于谷歌 15 年的生产环境经验开源的一个项目。Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 致力于提供跨主机集群的自动部署、扩展、高可用以及运行应用程序容器的平台,其遵循主从式架构设计、组件可以分为工作节点(Node)组件,和控制平面组件。Kubernetes Master 是集群的主要控制单元,用于管理工作负载并指导整个系统的通信。Kubernetes 控制平面由各自的进程组成,没个组件都可以在单个节点上运行,也可以在支持高可用集群的多个节点上运行。

为什么需要 Kubernetes

很多人会有疑问,有了 Docker 为什么还用 Kubernetes?

在业务开始进行容器化时,前期需要容器化的项目可能并不多,涉及的容器也并不多,此时基于Docker 容器直接部署至宿主机也能实现基本的需求。但是随着项目越来越多,管理的容器也会越来越多,此时使用“裸容器”部署的方式管理起来就显得很吃力,并且随着业务量的增加,会明显体会到“裸容器的不足。比如:

宿主机宕机造成该宿主机上的容器不可用,且无法自动恢复。
容器明明在运行,接口就是不通(健康检查做得不到位)
应用程序部署、回滚、扩缩容困难。
成百上千的容器和涉及的端口难以维护。

上面的问题知识做一个简单的罗列,真正使用时还有很多其他的问题。大家也可能使用过Docker-compose、Docker-swarm 等编排工具,但是这些工具的功能和 Kubernetes 比起来还是相差很多的。所以注定 Kubernetes 编排工具将成为主流的容器编排工具。

Kubernetes 带来的挑战

Kubernetes 从诞生至今,一路突飞猛进,在容器编排的领域过关斩将,最终拿下了容器编排的冠军宝座,成为最无可替代、不可撼动的佼佼者,但是针对 Kubernetes 的学习和使用始终是一个很大的难题。

首先,Kubernetes 本身的学习就很困难,因为Kubernetes 概念太多,涉及的知识面也非常广泛,可能学习了一个月也无法入门,甚至连集群也搭建不出来,使人望而却步。并且 Kubernetes 的技术能力要求也比较高,因为运维不仅仅均线于传统运维,有时候可能要修改业务代码、制定业务上线体系、给研发人员在开发应用中提供更好的建议等。需要掌握的知识也有很多,可能需要掌握公司内所有使用带的代码,比如代码如何进行编译、如何正确发布、如何修改代码配置文件等,这对于运维人员也是一种挑战。Kubernetes 的诞生把运维从传统的运维转变到了 Devops 方向,需要面临的问题更多,需要面临的新技术也很多,但是当真正掌握Kubernetes 的核心和涉及理念,就会收益终身。

kubernetes架构解析

在这里插入图片描述

由图可知,Kubernetes 架构可以简单分为主(master)节点,从(worker/node)节点和数据库 ETCD。其中主节点为集群的控制单元,一般不会运行业务应用程序,主要包含的组件 Kube-APIServer、Kube-ControllerManager、Kube-Scheduler。从节点为工作节点,也就是部署应用程序容器的节点,主要包含的组件有 Kubelet、Kube-Proxy,当然如果 master 节点也要部署容器,也会包含这两个组件

同时,可以看出一个集群中可以有多个 node 节点,用于保证集群容器的分布式部署,以保证业务的高可用性,也可以有很多的 master 节点,之后通过一个负载均衡保证集群控制节点的高可用。负载均衡可以使用软件负载均衡 Nginx、LVS、Haproxy+Keepalived 或者硬件负载均衡 F5 等,通过负载均衡对Kube-APIServer 提供的 VIP 即可实现 master 节点的高可用,其他组件通过该 VIP 连接至Kube-APIServer。ETCD 集群可以和 master 节点部署在同一个宿主机,也可以单独部署,生产环境建议部署大于3的奇数台 ETCD 节点用于实现 ETCD 集群的高可用。etcd 的 Leader 选举和数据写入都需要半数以上的成员投票通过确认,因此,集群最好由奇数个成员组成,以确保集群内部一定能够产生多数投票通过的场景。这也就是为什么etcd 集群至少需要3个以上的成员

master 节点的组件

master 节点是 Kubernetes 集群的控制节点,在生产环境中不建议部署集群核心组件外的任何容器(在 kubeadm 安装方式下,系统组件以容器方式运行在 master 节点的宿主机上;二进制安装方式下,系统组件以守护进程的方式运行,master节点可以不运行任何容器),公司业务程序的容器是不建议部署在 master 节点上,以免升级或者维护时对业务在成影响。

(1)API server

API server 提供了集群网关,是整个集群的控制中枢,提供集群中各个模块之间的数据交换,并将集群信息存储到 ETCD 集群中。同时,它也是集群管理、资源配额、提供完备的集群安全机制的入口,为集群各类资源对象提供增删改査。API server 在客户端对集群进行访问,客户端需要通过认证,并使用
API server 作为访问节点和 pod(以及服务)的堡垒和代理/通道。

API 服务器公开 Kubernetes API。
REST/kubectl 的入口点–它是 Kubernetes 控制平面的前端。
它跟踪所有集群组件的状态并管理它们之间的交互。
它旨在水平扩展。
它使用 YAML/JSON manifest 文件。
它验证和处理通过 API 发出的请求。

(2)scheduler

Scheduler 主要功能是资源调度,将 pod 调度到对应的主机上。依据请求资源的可用性、服务请求的质量等约束条件,K8s也支持用户自己提供的调度器

它将 pod 调度到工作节点。
它监视 api-server 以查找没有分配节点的新创建的 Pod,并选择一个健康的节点让它们运行。
如果没有合适的节点,则Pod 将处于挂起状态,直到出现这样一个健康的节点。
它监视 API Server 的新工作任务。

(3)Controller Manager

Controller Manager 负责维护集群的状态,比如故障检测、内存垃圾回收、滚动更新等,也执行API 业务逻辑;K8s 默认提供 replication controller、replicaset controller、daemonsetcontroller 等控制器

它监视它管理的对象的期望状态并通过 API 服务器监视它们的当前状态。
采取纠正措施以确保当前状态与所需状态相同。
它是控制器的控制器。
它运行控制器进程。从逻辑上讲,每个控制器都是一个单独的进程,但为了降低复杂性,它们都被编译成一个二进制文件并在单个进程中运行。

(4)etcd

etcd 用于可靠的存储集群的配置数据,是一种持久性、轻量型、分布式的键值数据存储组件。可以理解为一种分布式的非关系型数据库。etcd 是集群的状态, K8s 默认使用分布式的 etcd 集群整体存储用来实现发现服务和共享配置集群的所有状态都存储在 etcd 实例中,并具有监控的能力,因此当 etcd中的信息发生变化时,能够快速地通知集群中相关的组件。

它是一个一致的、分布式的、高度可用的键值存储。
它是有状态的持久存储,用于存储所有 Kubernetes 集群数据(集群状态和配置)
它是集群的真相来源。
它可以是控制平面的一部分,也可以在外部进行配置。

etcd 集群最少3个节点,容错点才会有1个。3 个节点和4个节点的容错能力是一样的,所以有时候保持奇数节点更好,从这里可以判断出我们在部署k8s 的时候,至少有3个节点,才保证 etcd有1个节点容错性。

另外,etcd 的 Leader 选举和数据写入都需要半数以上的成员投票通过确认,因此,集群最好由奇数个成员组成,以确保集群内部一定能够产生多数投票通过的场景。所以etcd 集群至少需要 3个以上的奇数个成员。

如果使用偶数个节点,可能出现以下问题:

偶数个节点集群不可用风险更高,表现在选主(Leader 选举)过程中,有较大概率的等额选票从而触发下一轮选举。
偶数个节点集群在某些网络分割的场景下无法正常工作。当网络分割发生后,将集群节点对半分割开,形成脑裂。

Node 节点包含的组件

Node 节点也被成为 worker 节点,是主要负责部署容器的主机,集群中的每个节点都必须具备容器的Runtime(运行时),比如docker

kubelet 作为守护进程运行在 Node 节点上,负责监听该节点上所有的 pod,同时负责上报该节点上所有 pod 的运行状态,确保节点上的所有容器都能正常运行。当 Node 节点宕机或故障时,该节点上运行的 pod 会被自动转移到其他节点上。

(1)容器运行时

docker 引擎是本地的容器运行时环境,负责镜像管理以及 pod 和容器的真正运行。K8s 本身并不提供容器运行时环境,但提供了接口,可以插入所选择的容器运行时环境,目前支持 Docker 和 rkt。容器运行时是负责运行容器(在 Pod 中)的软件,为了运行容器,每个工作节点都有一个容器运行时引擎,它从容器镜像注册表(container image registry)中提取镜像并启动和停止容器。

Kubernetes 支持多种容器运行时:

Docker
containerd
CRI-0
Kubernetes CRI(Container Runtime Interface,容器运行时接口)的任何实现

(2)kubelet

kubelet 是 node 节点上最主要的工作代理,用于汇报节点状态并负责维护 pod 的生命周期,也负责volume(CVI)和网络(CNI)的管理。kubelet 是 pod 和节点 API 的主要实现者,负责驱动容器执行层。作为基本的执行单元,pod 可以拥有多个容器和存储卷,能够方便地在每个容器中打包一个单一的应用,从而解耦了应用构建时和部署时所关心的事项,方便在物理机或虚拟机之间进行迁移。

它是在集群中的每个节点上运行的代理。
它充当 API 服务器和节点之间的管道。
它确保容器在 Pod 中运行并且它们是健康的。
它实例化并执行 Pod。
它监视 API Server 的工作任务!
它从主节点那里得到指令并报告给主节点

(3)kube-proxy代理

kube-proxy 代理对抽象的应用地址的访问,服务提供了一种访问一群 pod 的途径, kube-proxy 负责为服务提供集群内部的服务发现和应用的负载均衡(通常利用 iptables 规则),实现服务到 pod 的路由和转发。此方式通过创建一个虚拟的 IP 来实现,客户端能够访问此 IP,并能够将服务透明地代理至 pod.

它是网络组件,在网络中起着至关重要的作用。
它管理 IP 转换和路由。
它是运行在集群中每个节点上的网络代理。
它维护节点上的网络规则。这些网络规则允许从集群内部或外部与Pod进行网络通信。
它确保每个 Pod 获得唯一的 IP 地址。
这使得 pod 中的所有容器共享一个 IP 成为可能。
它促进了 Kubernetes 网络服务和服务中所有 pod 的负载平衡。
它处理单个主机子网并确保服务可供外部各方使用。

kubernetes 网络插件

CNI(容器网络接口)是一个云原生计算基金会项目,它包含了一些规范和库,用于编写在 Linux容器中配置网络接口的一系列插件。CNI 只关注容器的网络连接,并在容器被删除时移除所分配的资源。

Kubernetes 使用 CNI 作为网络提供商和 Kubernetes Pod 网络之间的接口。

在这里插入图片描述

(1)Flannel 网络

由 Coreosk 开发的一个项目,很多部署工具或者 k8s 的发行版都是默认安装,flannel 是可以用集群现有的 etcd,利用 api 方式存储自身状态信息,不需要专门的数据存储,是配置第三层的 ipv4 0verlay网络,在此网络内,每个节点一个子网,用于分配 ip 地址,配置 pod 时候,节点上的网桥接口会为每个新容器分配一个地址,同一主机中的 pod 可以使用网桥通信,不同主机的 pod 流量封装在 udp 数据包中,路由到目的地。

Flannel 通过每个节点上启动一个 flnnel 的进程,负责给每一个节点上的子网划分、将子网网段等信息保存至 etcd,具体的报文转发是后端实现,在启动时可以通过配置文件指定不同的后端进行通信,目前有 UDP、VXLAN、host-gateway 三种,VXLAN 是官方推荐,因为性能良好,不需人工干预。UDP、VXLAN是基于三层网络即可实现,host-gateway 模式需要集群所有机器都在同一个广播域、就是需要在二层网络在同一个交换机下才能实现,host-gateway 用于对网络性能要求较高的常见,需要基础网络架构支持,UDP 用于测试或者不支持 VXLAN 的 linux 内核。反正一般小规模集群是完全够用的,直到很多功能无法提供时在考虑其他插件。

在这里插入图片描述

(2)calico 网络

虽然 fa1nnel 很好,但是 calico 因为其性能、灵活性都好而备受欢迎,calico 的功能更加全面不但具有提供主机和 pod 间网络通信的功能,还有网络安全和管理的功能,而且在 CNI 框架之内封装了calico 的功能,calico 还能与服务网络技术 Istio 集成,不但能够更加清楚的看到网络架构也能进行灵活的网络策略的配置,calico 不使用 overlay 网络,配置在第三层网络,使用 BGP 路由协议在主机之间路由数据包,意味着不需要包装额外的封装层。主要点在网络策略配置这一点,可以提高安全性和网络环境的控制。

如果集群规模较大,选择 calico 没错,当然 calico 提供长期支持,对于一次配置长期使用的目的来说,是个很好的选择。

在这里插入图片描述

kubeadm快速安装kubernetes集群

确保可连接互联网,推荐虚拟机使用 NAT 模式。k8s-master 主机最小建议配置为 2 核 4G,k8s-node 节点最小建议配置 为 2 核 2G。

Kubernetes v1.23 支持高达 5008 节点。更准备地说,在使用 Kubernetes 时,应当遵循以下所有准则:

每个节点不要超过 110个 Pod,
集群不要超过 5000 节点,
集群不要超过 150000 个 Pod,
不要超过 300000个Container。

部署docker环境

(这一步可以看我之前的文章配置,此处不进行详解)

基础环境配置

systemctl stop firewalld
setenforce 0
systemctl disabled firewalld
sed -i '^SELINUX=/s/enforcing/disabled/' /etc/selinux/config

时间同步(若同步可省略)

确保三台时间同步(可与宿主机不同步,但三台主机必须一致)

(1)将虚拟机工具的离线包(linux.iso)添加至虚拟机的虚拟光驱

(2)挂载此光盘

mount /dev/cdrom /mnt

(3)将光盘里的文件拷贝出来

cp VMwareTools-10.3.26-22085142.tar.gz /root

(4)解压

cd
tar zxvf VMwareTools-10.3.26-22085142.tar.gz

(5)进入解压目录

cd vmware-tools-distrib/

(6)安装虚拟机工具

./vmware-install.pl
然后一直按回车

下载repo文件

此处用的旧版本

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

想找新版可以去阿里的仓库找https://developer.aliyun.com/mirror/

dnf clean all
dnf makecache
dnf -y install kubelet-1.23.0 kubeadm-1.23.0 kubectl-1.23.0

如果在命令执行过程中出现索引 gpg 检査失败的情况,请使用 yum insta11 -y --nogpgcheckkubelet-1.23.0 kubeadm-1.23,0 kubect1-1.23.0 来安装,或者将gpgcheck=1和repo gpgcheck=1设置为 0

kubelet设置开机启动

三台节点都需要做
systemctl enable kubelet

生成初始化配置文件

master节点做
kubeadm config print init-defaults > init-config.yaml

Kubeadm 提供了很多配置项,Kubeadm 配置在 Kubernetes 集群中是存储在 ConfigMap 中的,也可将这些配置写入配置文件,方便管理复杂的配置项。Kubeadm 配置内容是通过 kubeadm config 命令写入配置文件的。
其中,kubeadm config 除了用于输出配置项到文件中,还提供了其他一些常用功能,如下所示。

kubeadm config view:查看当前集群中的配置值
kubeadm config print join-defaults:输出 kubeadm join 默认参数文件的内容。
kubeadm config images list:列出所需的镜像列表。
kubeadm config images pull:拉取镜像到本地。
kubeadm config upload from-flags: 由配置参数生成 ConfigMap

修改初始化配置文件

master节点

vim init-config.yaml

修改以下内容

advertiseAddress: 192.168.10.101(master节点IP)
name: k8s-master
imageRepository: registry.aliyuncs.com/google_containers
podSubnet: 10.244.0.0/16

注意:1.24.8 的版本中 apiVersion:kubeadm.k8s.io/v1beta2 被弃用,
servicesubnet:指定使用 ipvs 网络进行通信,ipvs 称之为 IP 虚拟服务器(IP Virtual Server,简写为IPVS)。是运行在 LVS下的提供负载平衡功能的一种技术。含义 IPVS基本上是一种高效的Layer-4交换机

podsubnet 10.244.0.0/16 参数需要和后文中 kube-flannel.yml 中的保持一致,否则,可能会使得 Node 间 cluster IP 不通

默认情况下,每个节点会从 Podsubnet 中注册一个掩码长度为 24 的子网,然后该节点的所有 podip 地址都会从该子网中分配。

拉取所需镜像

master节点
操作节点:k8s-master
如果地址无法解析,可以使用阿里的公共 DNS:223.5.5.5或223.6.6.6

kubeadm config images list --config init-config.yaml
kubeadm config images pull--config=init-config.yaml

此步骤是拉取 k8s 所需的镜像,如果已经有离线镜像,可以直接导入,这一步就不需要了

初始化 k8s-master

操作节点:k8s-master
注意:master节点最少需要2个CPU

kubeadm init --config=init-config.yaml

执行完该命令后一定记下最后生成的 token:

kubeadm join 192.168.10.101:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash
sha256:8b17b7d607ab7f79c2249c58d74525368bbb15ad884c365aaa1a968b9833d107

Kubeadm 通过初始化安装是不包括网络插件的,也就是说初始化之后是不具备相关网络功能的,比如k8s-master 节点上査看节点信息都是“Not Ready”状态、Pod 的 CoreDNS 无法提供服务等。

复制配置文件到用户的 home 目录

操作节点:k8s-master

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

node 节点加入集群

操作节点:k8s-node01、k8s-node02
将 master 中生成的 token,直接复制过来即可

在k8s-master节点设置环境变量并查看节点信息

echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
kubectl get nodes
kubectl get pod -A

因为此时还没安装网络插件,coredns 无法获得解析的 IP,就会使得 coredns 处于 pending 状态。
各个节点的状态也处于 NotReady 的状态,这些异常情况待安装过网络插件后都会自行解决。

部署Calico网络插件

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

也可以提前下载好 calica 的资源清单直接部署
[root@k8s-master ~]# kubectl create -f calico.yaml

kubectl get nodes
kubectl get pod --all-namespaces

Metrics-server部署

Metrics Server 是一种可扩展、高效的容器资源指标来源,适用于Kubernetes 内置的自动缩放管道。Metrics Server 从 Kubelets 收集资源指标,并通过 Metrics API 将它们暴露在 Kubernetesapiserver 中,供Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。指标 API 也可以通过 访问 kubectl top,从而更容易调试自动缩放管道。

Metrics server 对集群和网络配置有特定的要求。这些要求并不是所有集群分布的默认要求。在使用 Metrics Server 之前,请确保您的集群分布支持这些要求:

kube-apiserver 必须启用聚合层。
节点必须启用 Webhook 身份验证和授权。
Kubelet 证书需要由集群证书颁发机构签名(或通过传递–kubelet-insecure-tls 给Metrics Server 来禁用证书验证)注意这里是重点,如果本地没有签名需要传递 args:"–kubelet-insecure-tls"给Metrics Server
容器运行时必须实现容器指标RPC(或具有cAdvisor 支持)

网络应支持以下通信:

(1)控制平面到指标服务器。控制平面节点需要到达 Metrics Server 的 pod IP 和端口10250(或节点 IP 和自定义端口,如果 hostNetwork 已启用)
(2)所有节点上的 Kubelet 的指标服务器。指标服务器需要到达节点地址和 Kubelet 端口。地址和端口在 Kubelet 中配置并作为 Node 对象的一部分发布。字段中的地址.status.daemonEndpoints.kubeletEndpoint.port(默认 10250)。Metrics Server 将根据 kubelet-preferred-address-types 命令行标志(InternalIP,ExternalIP,Hostname 清单中的默认值) 提供的列表选择第一个节点地址

源码位置:
matrics-server的github地址:https://github.com/kubernetes-sigs/metrcs-server

kubectl create -f components.yaml
kubectl top node
kubectl top pod -A

安装helm客户端

(1)下载安装包

wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz

(2)解压

tar zxvf helm-v3.9.4-linux-amd64.tar.gz

(3)安装

mv linux-amd64/helm /usr/local/bin/

(4)查看版本

helm version

在使用 kubectl命令的时候,如果觉得单词不好打,可以设置一个别名:
vim ~/.bashrc
添加

alias ku='kubectl'

测试

vim nginx-service.yaml

在这里插入图片描述

kubectl create -f nginx-service.yaml
kubectl get pod
kubectl get service

在这里插入图片描述

用宿主机浏览器访问
http://192.168.10.101:32362

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到