Kubernetes的基础概念
Kubernetes是谷歌以Borg为前身,基于谷歌15年的生产环境经验开源的一个项目。
Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes致力于提供跨主机集群的自动部署、扩展、高可用以及运行应用程序容器的平台,其遵循主从式架构设计、
组件可以分为工作节点(Node)组件,和控制平面组件。Kubernetes Master是集群的主要控制单元,用于管理工作负载并指导整个系统的通信。Kubernetes控制平面由各自的进程组成,每个组件都可以在单个节点上运行,也可以在支持高可用集群的多个节点上运行。
为什么需要Kubernetes
在业务开始进行容器化时,前期需要容器化的项目可能并不多,涉及的容器也并不多,此时基于Docker容器直接部署至宿主机也能实现基本的需求。但是随着项目越来越多,管理的容器也会越来越多,此时使用“裸容器”部署的方式管理起来就显得很吃力,并且随着业务量的增加,会明显体会到“裸容器”的不足。比如:
- 宿主机宕机造成该宿主机上的容器不可用,且无法自动恢复。
- 容器明明在运行,接口就是不通(健康检查做得不到位)
- 应用程序部署、回滚、扩缩容困难。
- 成百上千的容器和涉及的端口难以维护。
对于运维人员
对于运维人员,可能经常因为一些重复、烦琐的工作感到厌倦,比如一个项目需要一套新的测
试环境。另一个项目需要迁移测试环境至其他平台。传统架构可能需要装系统、装依赖环境、部署
域名、开通权限等,这一套下来,不仅耗时,而且可能会因为有某些遗漏而造成诸多问题。而如今,可以直接使用Kubernetes包管理工具,一键式部署一套新的测试环境,甚至全程无须自己干预,开发人员通过jenkins或者自动化运维平台即可一键式创建,大大降低了运维成本。
在传统架构体系下,公司业务故障可能是因为基础环境不一致、依赖不一致、端口冲突等问题,而现在使用docker镜像部署,Kubernetes进行编排,所有的依赖、基础都是一样的,并且环境的自动化扩容、健康检查、容灾、恢复都是自动的,大大减少了因为这类基础问题引发的故障。另外,也有可能公司业务由于服务器宕机、网络等问题造成服务不可用,此类情况均需要运维人员及时去修复,而在Kubernetes中,可能在收到严重告警信息时,Kubernetes已经自动恢复完成了。
在没有使用Kubernetes时,业务应用的扩容和缩容需要人工去处理,从采购服务器、上架到部署依赖环境,不仅需要大量的人力物力,而且非常容易在中间过程出现问题,又要花大量的时间去查找问题。成功上架后,还需要在前端负载均衡添加该服务器,而如今,可以利用Kubernetes的弹性计算一键式扩容和缩容,不仅大大提高了运维效率,而且还节省了不少的服务器资源,提高了资源利用率。
在反向代理配置方面,可能对nginx的配置规则并不熟悉,一些高级的功能也很难实现,但是在Kubernetes上,利用Kubernetes的ingress即可简单的实现那些复杂的逻辑,并且不会再遇到nginx少加一个斜杠和多加一个斜杠的问题。
在负载均衡方面,之前负载均衡可能是nginx、LVS、Haproxy、F5等,云上可能是云服务商
提供的负载均衡机制。每次添加和删除节点时,都需要手动去配置前端负载均衡,手动去匹配后端
节点。在使用Kubernetes进行编排服务时,使用Kubernetes内部的Service即可实现自动管理
节点,并且支持自动扩容、缩容。
在高可用方面,Kubernetes天生的高可用功能让运维人员彻底释放了双手,无需再去创建各类高可用工具,以及检测脚本。Kubernetes支持进程、接口级别的健康检查,如果发现接口超时或者返回值不正确,会自动处理该问题。
在中间件搭建方面,根据定义好的资源文件,可以实现秒级搭建各类中间件高可用集群,且支持一键式扩容、缩容,如Redis、RabbitMQ、Zookeeper等,并且大大减少了出错的概率。
在应用端口方面,传统架构中,一台服务器可能跑了很多进程,每个进程都有一个端口,要认为的去配置端口,并且还需要考虑端口冲突的问题,如果有防火墙的话,还需要配置防火墙,在 Kubernetes中,端口统一管理、统一配置,每个应用的端口都可以设置成一样的,之后通过Service进行负载均衡,大大降低了端口管理的复杂度和端口冲突。
无论是对于开发人员、测试人员还是运维人员,Kubernetes的诞生不仅减少了工作的复杂度,
还减少了各种运维成本。
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、controller、daemonset、controller等控制器。
- 它监视它管理的对象的期望状态并通过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-O
- Kubernetes CRI(Container Runtime Interface,容器运行时接口)的任何实现。
(2)kubelet
kubelet是node节点上最主要的工作代理,用于汇报节点状态并负责维护pod的生命周期,也负责volume(CVI)和网络(CNI)的管理。kubelet是pod和节点API的主要实现者,负责驱动容器执行层。作为基本的执行单元,pod可以拥有多个容器和存储卷,能够方便地在每个容器中打包一个单一的应用,从而解耦了应用构建时和部署时所关心的事项,方便在物理机或虚拟机之间进行迁移。
- 它是在集群中的每个节点上运行的代理。
- 它充当API服务器和节点之间的管道。
- 它确保容器在Pod中运行并且它们是健康的。
- 它实例化并执行Pod。
- 它监视API Server的工作任务。
- 它从主节点那里得到指令并报告给主节点。
(3)kube-proy代理
kube-proy代理对抽象的应用地址的访问,服务提供了一种访问一群pod的途径,kube-proy负责为服务提供集群内部的服务发现和应用的负载均衡(通常利用ptab1es规则),实现服务到pod的路由和转发。此方式通过创建一个虚拟的IP来实现,客户端能够访问此IP,并能够将服务透明地代理至pod。
- 它是网络组件,在网络中起着至关重要的作用。
- 它管理IP转换和路由。
- 它是运行在集群中每个节点上的网络代理。
- 它维护节点上的网络规则。这些网络规则允许从集群内部或外部与Pod进行网络通信。
- 它确保每个Pod获得唯一的IP地址。
- 这使得pod中的所有容器共享一个IP成为可能。
- 它促进了Kubernetes网络服务和服务中所有pod的负载平衡。
- 它处理单个主机子网并确保服务可供外部各方使用。
kubernetes网络插件
CN工(容器网络接口)是一个云原生计算基金会项目,它包含了一些规范和库,用于编写在Linux容器中配置网络接口的一系列插件。CNI只关注容器的网络连接,并在容器被删除时移除所分配的资源。
Kubernetes使用CNI作为网络提供商和Kubernetes Pod网络之间的接口。
(1)Flannel网络
由CoreoSk开发的一个项目,很多部署工具或者k8s的发行版都是默认安装,flannel是可以
用集群现有的etcd,利用api方式存储自身状态信息,不需要专门的数据存储,是配置第三层的
ipv4 Overlay网络,在此网络内,每个节点一个子网,用于分配ip地址,配置pod时候,节点上
的网桥接口会为每个新容器分配一个地址,同一主机中的pod可以使用网桥通信,不同主机的pod流量封装在udp数据包中,路由到目的地。
Flannel通过每个节点上启动一个f1nne1的进程,负责给每一个节点上的子网划分、将子网网段等信息保存至etcd,具体的报文转发是后端实现,在启动时可以通过配置文件指定不同的后端进行通信,目前有UDP、VXLAN、host-gatway三种,VXLAN是官方推荐,因为性能良好,不需人工干预。UDP、VXLAN是基于三层网络即可实现,host-gatway模式需要集群所有机器都在同一个广播域、就是需要在二层网络在同一个交换机下才能实现,host-gateway用于对网络性能要求较高的常见,需要基础网络架构支持,UDP用于测试或者不支持VXLAN的1iuX内核。反正一般小规模集群是完全够用的,直到很多功能无法提供时在考虑其他插件。
(2)Calico网络
虽然falnnel很好,但是calico因为其性能、灵活性都好而备受欢迎,calico的功能更加全面,不但具有提供主机和pod间网络通信的功能,还有网络安全和管理的功能,而且在CN工框架之内封装了calico的功能,calico还能与服务网络技术Istio集成,不但能够更加清楚的看到网络架构也能进行灵活的网络策略的配置,calico不使用Overlay网络,配置在第三层网络,使用BGP路由协议在主机之间路由数据包,意味着不需要包装额外的封装层。主要点在网络策略配置这一点,可以提高安全性和网络环境的控制。
如果集群规模较大,选择ca1ico没错,当然ca1ico提供长期支持,对于一次配置长期使用的目的来说,是个很好的选择。
Kubeadm快速安装Kubernetes集群
本节采用Kubeadm方式来安装Kubernetes集群,实验环境包括一台master节点,两台node节点。
实现思路
- 部署三台主机的基础环境。
- 部署三台主机的Docker环境。
- 通过Kubeadm快速部署Kubernetes集群。
基础环境准备
正式开始部署kubernetes集群之前,先要进行如下准备工作。基础环境相关配置操作在三台主机
k8s-master、k8s-node01、k8s-node02上都需要执行,下面以k8s-master主机为例进行操作演示。
基础网络信息配置要求
依据案例环境为三台主机配置IP地址、网关、DS等基础信息,确保可连接互联网,推荐虚拟机
使用NAT模式。k8s-master主机最小配置为2核2G,k8s-node节点最小配置为1核1G。
升级内核
如果使用自己的私有仓库,此步骤替换成如下操作
部署docker环境(此步骤在三个节点都执行)
关闭防火墙
禁用SELinux
安装Docker(用阿里云仓库安装)
(4)配置加速器
很多镜像都是在国外的服务器上,由于网络上存在的问题,经常导致无法拉取镜像的错误,所以最
好将镜像拉取地址设置成国内的。
(5)设置内核参数
部署Kubernetes集群(注意命令执行的节点)
(1)配置三台主机的主机名
主机一
主机二
主机三
(2)在三台主机上绑定hosts
(3)关闭交换分区
(4)在三台主机上安装常用软件
(5)配置Kubernetes的YUM源
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
yum clean all
(6)安装Kubelet、.Kubeadm和Kubectl
操作节点:k8s-master,k8s-node01,k8s-node02
(7)Kubelet设置开机启动
操作节点:k8s-master,k8s-node0:1,k8s-node02
(8)生成初始化配置文件
操作节点:k8s-master 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。
(9)修改初始化配置文件
操作节点:k8s-master
vim init-config.yaml
apiVersion:kubeadm.k8s.io/v1beta3
bootstrapTokens:
groups:
system:bootstrappers:kubeadm:default-node-token
token:abcdef.0123456789abcdef
ttl:24h0m0s
usages:
signing
authentication
kind:InitConfiguration
localAPIEndpoint:
advertiseAddress:192.168.10.101
bindPort:6443
nodeRegistration:
criSocket:/var/run/dockershim.sock
name:k8s-master
taints:null
apiserver:
timeoutForControlPlane:4m0s
apiVersion:kubeadm.k8s.io/v1beta2
certificatesDir:/etc/kubernetes/pki
clusterName:kubernetes
controllerManager:{
dns
type:CoreDNS
etcd:
local:
dataDir:/var/lib/etcd
imageRepository:registry.aliyuncs.com/google_containers
kind:ClusterConfiguration
kubernetesVersion:v1.23.0
networking:
dnsDomain:cluster.local
servicesubnet:10.96.0.0/12
podSubnet:10.244.0.0/16
scheduler:{}
修改advertiseAddressIP地址为master主机地址以及name为k8s-master
修改imageRepository为registry.aliyuncs.com/google_containers,podSubnet为10.244.0.0/16
(10)拉取所需镜像
操作节点:k8s-master
(11)初始化k8s-master
操作节点:k8s-master
注意:master节点最少需要2个CPU
执行完该命令后一定记下最后生成的token:
kubeadm join 192.168.10.101:6443 --token abcdef.0123456789abcdef\--discovery-token-ca-cert-hash sha256:8b17b7d607ab7f79c2249c58d74525368bbb15ad884c365aaa1a968b9833d107
(12)复制配置文件到用户的home目录
操作节点:k8s-master
(13)node节点加入集群
操作节点:k8s-node01、k8s-node02
注意:在master中生成的token,直接在master主机中复制过来即可
(14)在k8s-master查看节点
(15)安装flannel网络
hnttps://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-fla nnel.yml
[root@k8s-master ~]sed -i 's/quay.io/quay-mirror.qiniu.com/g'kube-flannel.yml
/文件内quay.io国内无法访问,替换为国内地址
[root@k8s-master ~]kubectl apply -f kube-flannel.yml
/运行开启f1anne1网络Pod
(16)查看节点状态
kubectl get nodes -o wide
(17)部署Calico网络插件
Metrics-server部署
Metrics Server是一种可扩展、高效的容器资源指标来源,适用于Kubernetes内置的自动缩放管道。Metrics Server从Kubelets收集资源指标,并通过Metrics API将它们暴露在 Kubernetes apiserver中,供Horizontal Pod Autoscaler和Vertical Pod Autoscaler使用。指标API也可以通过访问kubectl top,从而更容易调试自动缩放管道。
下载Metrics-server的yaml文件
修改yaml文件并安装
测试安装结果
Dashboard部署
在k8s工作目录中创建dashborad工作目录
上传所需的yaml文件并部署dashboard:
修改谷歌浏览器
修改方法如下:
在桌面找到谷歌浏览器的快捷方式右键属性找到“快捷方式”选项卡在目标栏添加参数:-test-type-ignore-certificate-errors(注意--前有空格)
查看端口号
查看token
登录dashboard