一、Kubernetes的基础概念

Kubernetes(简称K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。Kubernetes的基础概念主要包括以下几个部分:

1.集群(Cluster)

  • Kubernetes集群由一组节点(Node)组成,这些节点可以是物理服务器或虚拟机。
  • 集群分为控制平面(Control Plane)和工作节点(Worker Nodes)。

2.控制平面(Control Plane)

  • 控制平面管理集群的工作节点和Pod。
  • 它包括API服务器、etcd存储、kube-scheduler、kube-controller-manager和cloud-controller-manager等组件。


3.节点(Node)

  • 节点是集群中的工作机器,可以是物理机或虚拟机。
  • 每个节点由主节点管理,节点上运行的应用程序在容器中运行。


4.Pod

  • Pod是Kubernetes中最小的部署单元,一个Pod代表集群中运行的一个进程。
  • Pod封装了一个或多个紧密相关的容器,这些容器共享存储和网络资源。


5.服务(Service):

  • Service是一个抽象层,它定义了一种访问Pod的逻辑集合的方式。
  • Service通过标签选择器来确定要访问的Pod集合。


6.标签(Label)

  • 标签是用于组织和选择集群中对象的键值对。
  • 可以将标签附加到各种资源上,如Pod、Service等,然后通过标签选择器进行资源选择。


7.命名空间(Namespace)

  • 命名空间是将集群资源逻辑上划分为多个虚拟集群的一种机制。
  • 每个命名空间都是一个完全独立的逻辑环境,可以有自己的Pod、Service等资源。


8.控制器(Controller)

  • 控制器是Kubernetes中用于管理Pod的中间层。
  • 常见的控制器包括ReplicationController、ReplicaSet、Deployment、StatefulSet等。


9.卷(Volume)

  • 卷是集群中由Pod使用的存储资源。
  • 可以是集群内的存储(如emptyDir)或集群外的存储(如NFS、Ceph等)。


10.持久卷(PersistentVolume)和持久卷申请(PersistentVolumeClaim)

  • PersistentVolume是集群中的一块存储,由管理员提供。
  • PersistentVolumeClaim是用户存储的请求,Kubernetes会尝试将PersistentVolumeClaim与合适的PersistentVolume进行绑定。


这些基础概念构成了Kubernetes的核心,使得它能够有效地管理和编排容器化应用程序。


二、Kubernetes架构解析

Kubeadm 快速安装 Kubernetes 集群_ico

由图可知,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 个以上的成员。


1.master节点的组件

(1)kube-apiserver(Kubernetes API Server)

功能:kube-apiserver是Kubernetes集群的核心组件之一,它提供了Kubernetes API的服务,是集群内各个组件之间相互通信的枢纽。所有的操作都通过kube-apiserver进行,如创建、更新、删除资源对象等。同时,它也提供了认证、授权、访问控制等安全机制。

作用:作为集群的统一入口,处理来自用户的请求,如通过kubectl命令行工具发起的请求,并将这些请求转发给相应的组件进行处理。


(2)kube-controller-manager(Kubernetes Controller Manager)

功能:kube-controller-manager负责管理集群中的各种控制器,这些控制器是Kubernetes自动化操作的核心。控制器负责监听集群状态,并确保集群状态符合预期。

包含的控制器:包括Node Controller、Replication Controller、Deployment Controller等,它们分别负责节点的健康状态管理、Pod副本数量的控制、部署管理等不同功能。


(3)kube-scheduler(Kubernetes Scheduler)

功能:kube-scheduler负责调度集群中的Pod资源到合适的Worker节点上运行。它会根据Pod的资源需求和节点的容量情况来做出调度决策,确保集群的负载均衡和资源高效利用。

工作原理:监听API Server上的Pod创建事件,根据预设的调度策略和算法,选择最合适的节点来绑定Pod,并通过API Server更新Pod的绑定信息。


(4)etcd

功能:etcd是一个高可用的键值存储数据库,用于保存集群的状态和元数据。Kubernetes的各个组件通过etcd进行数据同步和共享,确保集群的一致性和可靠性。

作用:作为集群的数据中心,存储集群的配置信息、状态信息以及用户数据等关键信息。通过Raft一致性算法处理日志复制,保证数据的强一致性。

备注:

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

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

偶数个节点集群不可用风险更高,表现在选主(Leader 选举)过程中,有较大概率的等额选票,从而触发下一轮选举。

偶数个节点集群在某些网络分割的场景下无法正常工作。当网络分割发生后,将集群节点对半分割开,形成脑裂。


2.node节点包含的组件

(1)kubelet

功能:kubelet是Node节点上的主要“节点代理”,负责维护容器的生命周期。它从Master节点中的Kubernetes API Server接收Pod的创建、更新、删除等请求,并相应地启动、停止或更新容器。kubelet还负责监控容器的运行状态,并在必要时重启失败的容器。

通信方式:kubelet通过API Server与Master节点进行通信,并与其他Node节点上的kubelet协同工作,以确保集群中的Pod按预期运行。


(2)kube-proxy

功能:kube-proxy负责实现Kubernetes服务的负载均衡和网络代理功能。它监听API Server中Service和Endpoint对象的变化,并根据这些变化更新Node节点上的网络规则,以确保集群内部的网络流量能够正确路由到相应的Pod。

实现方式:kube-proxy通常通过iptables或IPVS等工具来实现网络代理和负载均衡。它会为Service创建相应的iptables规则或IPVS配置,将访问Service的流量转发到后端的Pod上。


(3)容器运行时(Container Runtime)

功能:容器运行时是负责运行容器的底层引擎。Node节点上需要安装一个容器运行时来运行Pod中的容器。Docker是最常用的容器运行时之一,但Kubernetes也支持其他容器运行时,如containerd、CRI-O等。

工作方式:kubelet通过容器运行时接口(CRI)与容器运行时进行通信,以启动、停止和管理容器。容器运行时负责解析容器镜像、创建容器进程、管理容器资源等。


3.Kubernetes网络插件

(1)Flannel

特点:

Flannel是一个简单易用的Kubernetes网络插件,主要用于创建一个扁平的网络,使得集群中的每个节点和Pod都可以互相通信。

支持多种网络后端,包括VXLAN、UDP、Host-GW等。

VXLAN是Flannel的默认模式,通过在UDP包中封装以太网帧来创建覆盖网络,支持跨子网通信。

Host-GW模式使用主机的路由表来实现跨节点的Pod通信,性能较高,但要求所有节点在同一二层网络中。


适用场景:

适用于大多数Kubernetes集群环境,特别是当节点分布在多个子网时。


(2)Calico

特点:

Calico是一种基于BGP的网络插件,使用路由表来路由容器之间的流量。

支持多种网络拓扑结构,并提供了安全性和网络策略功能。

纯IP模式是Calico最基本的模式,直接使用路由表进行Pod间的通信,不进行任何封装,性能高。

Calico还提供了丰富的网络策略功能,可以细粒度地控制Pod间的网络通信。


适用场景:

适用于中大型集群,特别是需要高性能、灵活网络策略和良好安全支持的环境。


三、Kubeadm 快速安装 Kubernetes 集群

Kubeadm 是官方社区推出的一个用于快速部署 Kubernetes 集群的工具。以下是使用 kubeadm 快速安装 Kubernetes 集群的步骤:

1.安装要求

在开始之前,部署 Kubernetes 集群的机器需要满足以下几个条件:

  • 一台或多台机器,操作系统推荐 CentOS 7.x 或更高版本的 86_x64 位系统。
  • 硬件配置:2GB 或更多 RAM,2 个 CPU 或更多,硬盘 30GB 或更多。
  • 集群中所有机器之间网络互通。
  • 可以访问外网,以便拉取镜像。
  • 禁止 swap 分区,因为 Kubernetes 不支持在启用 swap 的节点上运行。


2.准备环境

(1)关闭防火墙:

systemctl stop firewalld  
 
 systemctl disable firewalld


(2)关闭 SELinux:

sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久关闭  
 
 setenforce 0  # 临时关闭  
 
 getenforce  # 查看 SELinux 状态


(3)关闭 swap:

swapoff -a  # 临时关闭  
 
 sed -ri 's/.*swap.*/#&/' /etc/fstab  # 永久关闭


(4)设置主机名:

hostnamectl set-hostname <hostname>


(5)配置 hosts 文件:

在 master 节点上添加 hosts,以便节点间可以通过主机名相互访问。

cat >> /etc/hosts <<EOF  
 
 192.168.x.x k8s-master  
 
 192.168.x.y k8s-node1  
 
 192.168.x.z k8s-node2  
 
 EOF


(6)配置桥接流量:

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


(7)时间同步:

yum install ntpdate -y  
 
 ntpdate time.windows.com


3.安装 Docker

Kubernetes 默认 CRI(容器运行时)为 Docker,因此需要先安装 Docker。

(1)添加 Docker 镜像源:

cat > /etc/yum.repos.d/docker-ce.repo << EOF  
 
 [docker-ce-stable]  
 
 name=Docker CE Stable - $basearch  
 
 baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/$releasever/$basearch/stable  
 
 enabled=1  
 
 gpgcheck=1  
 
 gpgkey=https://mirrors.aliyun.com/docker-ce/gpg  
 
 EOF

(2)安装 Docker:

yum install docker-ce docker-ce-cli containerd.io -y  
 
 systemctl start docker  
 
 systemctl enable docker  
 
 docker info

(3)配置 Docker 镜像加速器(可选):

cat > /etc/docker/daemon.json << EOF  
 
 {  
 
   "registry-mirrors": ["https://<your-mirror-url>"]  
 
 }  
 
 EOF  
 
 systemctl daemon-reload  
 
 systemctl restart docker


4.安装 kubeadm、kubelet、kubectl

(1)添加 Kubernetes YUM 源:

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

(2)安装 kubeadm、kubelet、kubectl:

yum install -y kubelet-<version> kubeadm-<version> kubectl-<version>  
 
 systemctl enable kubelet

注意:<version> 需要替换为实际的版本号,并且确保所有组件的版本一致。


5.部署 Kubernetes Master

(1)初始化 Master 节点:

kubeadm init \  
 
   --apiserver-advertise-address=<master-ip> \  
 
   --image-


(2)拷贝授权文件,用于管理K8S集群:

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


6.配置worker节点加入集群 

kubeadm join 10.0.0.231:6443 --token jkopy0.4fnwsu5zzoeb0kq2 \

	--discovery-token-ca-cert-hash sha256:3a3bbdfd8e696a93639754fbc053b84f6821e46acfdc83a31e9215212df7f76b


7.部署容器网络(CNI)

当我们把node节点加入集群后会发现他的状态时NotReady(不可用),那是因为网络插件还没有部署;接下来部署网络插件calico

(1)下载YAML:

wget https://docs.projectcalico.org/manifests/calico.yaml

下载完之后还需要修改里面定义的pod网络(CALICO_IPV4POOL_CIDR),与前面kubeadm

init初始化的–pod-network-cdir(pod所使用的网络)指定的一样;

[root@k8s-master ~]#vim calico.yaml
- name: CALICO_IPV4POOL_CIDR 
  value: "10.244.0.0/16"
...

#如果有多个网卡的话,可以选择指定的网卡进行绑定

- name: IP_AUTODETECTION_METHOD
  value: interface=ens33
# Auto-detect the BGP IP address.


(2)部署calico pod:

[root@k8s-master ~]# kubectl apply -f calico.yaml 
[root@k8s-master ~]# kubectl get pods -n kube-system
calico-kube-controllers-56fcbf9d6b-qtxch   1/1     Running   0             6m49s
calico-node-2mw65                          1/1     Running   0             6m49s
calico-node-sl2t6                          1/1     Running   0             6m49s
calico-node-zbd49                          1/1     Running   0             6m49s
coredns-6d8c4cb4d-4lfn6                    1/1     Running   0             41m
coredns-6d8c4cb4d-9zfg2                    1/1     Running   0             41m
etcd-k8s-master                            1/1     Running   0             42m
kube-apiserver-k8s-master                  1/1     Running   0             42m
kube-controller-manager-k8s-master         1/1     Running   0             42m
kube-proxy-5c2w6                           1/1     Running   0             23m
kube-proxy-h42w8                           1/1     Running   0             41m
kube-proxy-hcn58                           1/1     Running   0             23m
kube-scheduler-k8s-master                  1/1     Running   1             42m


等calico pod都Running之后,node节点也会准备就绪

[root@k8s-master ~]# kubectl get nodes 
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   42m   v1.23.0
k8s-node1    Ready    <none>                 23m   v1.23.0
k8s-node2    Ready    <none>                 23m   v1.23.0