为什么要使用kubernetes?

(1)在使用docker或nerdctl创建容器时,都需要手动使用run命令去创建,那么假如生产环境中需要创建成千上万个容器时,手动创建就会大大影响效率

(2)若某台服务器宕机了,那么里面的容器也停止了,不具备高可用性

(3)若某个容器出现了问题,很难被发现,不便于管理

——所以为了更方便地管理容器,我们使用容器编排工具来对容器进行统一管理,kubernetes就是一种容器编排工具,除此之外还有:
docker swarm
mesos
openshift

有了k8s,就不需要我们一个一个手动创建了,k8s会帮我们去管理容器,k8s通过一个代理——kubelet,通过kubelet去访问一个个runtime(docker、containerd、rkt、cri-o…),从而进行管理容器,原先docker一家独大,但是随着各种容器客户端的发展,都想接入k8s作为runtime,但是若将每一个客户端产品都加进k8s,非常不利于维护,因此k8s制定了一个标准接口(CRI),只要符合这个标准,并提供CRI-shim(垫片,支持CRI标准的runtime),就可以接入k8s作为runtime,并且使用gPRC协议来互相通信

由于docker不支持CRI标准,因此1.24版本之后的k8s不支持docker,若还是想使用docker,则可以在中间增加一个转接头:cri-docker
在这里插入图片描述

kubernetes架构及组件介绍

以VMware的虚拟化架构来举例
在这里插入图片描述
如图,ESXi是专门用来运行虚拟机的,为了统一管理、统一调度这些ESXi及里面的虚拟机,需要安装一台vcenter,来作为一个控制台,通过 vsphere client 或 vsphere web client 连接到vcenter上,来对整个虚拟化架构进行管理

k8s的架构就类似这种虚拟化架构类似
![![在这里插入图片描述](https://img-blog.csdnimg.cn/1e0a64b04eeb493eb879538a7bb9ccf7.png](https://img-blog.csdnimg.cn/008438950c4943aca38af98630c7495e.png

master(控制台)——就相当于vcenter作为一个控制台,也称 control plane node(控制平面节点)
worker(节点)——就相当于ESXi,专门用于运行pod

pod(豆荚)
在docker、nerdctl中,直接管理容器,容器是最小的调度单位,而在k8s中,直接管理的是pod,pod是最小的调度单位,pod与容器的关系就好比豆荚与豆子的关系,pod是豆荚,容器就是豆荚里一粒粒的豆子,而kubernetes就好比豆荚藤
在这里插入图片描述

一个pod里可以有多个容器,但一般我们只会在一个pod里设计一个容器,那既然只有一个容器,为什么还要在外面加个pod这层壳呢,因为在pod里有各种策略、各种网络设置,加强了功能
在这里插入图片描述

kubernetes中的组件
master上运行的组件
kubectl:客户端命令行工具,为整个系统的操作入口,将命令发送给api-server
api-server:REST接口,接收客户端请求,为整个系统的控制入口
scheduler:调度器,节点资源管理,创建pod时,判断并分配到某个worker来创建
controller-manager:整个系统的大管家,执行整个系统中的后台任务,监控节点状况、pod个数、pod和service的关联等
kubelet:运行在master和每个节点上,作为代理,接受master分配过来的任务,周期性获取容器状态,反馈给master上的api-server
kube-proxy:运行在master和每个节点上,作为代理,用于把发送给service的请求转发给后端pod,做相应策略,模式有iptables和ipvs

worker上运行的组件
kubelet:略
kube-proxy:略
calico网络:使得各个节点中的pod能够互相通信,集群安装好一定要安装这个组件,docker都是在单机上配置的,不同主机若想要通信,一是通过端口映射,要不就是安装calico网络来实现,k8s是多主机的环境,pod可能分布在各个不同的机器上,因此各个pod若想互相通信,则需要在k8s环境中安装calico网络

在这里插入图片描述

(docker中我们手动run命令来创建容器,k8s中,客户端连接到master,发出一个创建pod请求,master里的调度器来判定由worker来创建)
——api-server接收用户请求,验证用户身份、权限,当接收到了创建pod请求,就会通过scheduler来调度由哪个节点来创建,当然也可以自己指定,每个节点上都有一个kubelet,kubelet中可以进行一些配置,如使用哪个厂商的runtime(containerd、docker…)、kubelet接收到了创建pod请求后,调用相应的runtime去创建容器,每一次kubelet与api-server的通信,都需要TLS证书认证,controller-manager是整个系统的大管家,会实时监控系统运行状态,当监测到kubelet证书过期了,controller-manager会重新给它颁发证书,当监测到某个pod宕机了,会重新生成一个这样的pod,但是pod的IP地址会改变, 因此用户直接访问这个pod并不方便,所以设置了一个service-svc的服务,它实际上实现了负载均衡的功能,用户访问service-sve,然后由service-sve通过kube-proxy这个组件来转发到后端的pod,转发时kube-proxy通过iptables或者ipvs这两种模式来实现
——可以通过BGP、vxlan、openswitch等技术在各个节点之间建立通道,例如calico工具封装了这些协议,使得各个节点内的pod可以跨节点通信
——用户所有的创建、删除等操作及一些配置信息,都会记录到etcd数据库里去

安装K8S集群环境

前置准备(所有节点上都需要操作)

实验中准备3台centos虚拟机,一台作为master(192.168.26.21),两台作为worker(192.168.26.22、192.168.26.23)

以下为所有节点上都需要操作的步骤:

(1)同步/etc/hosts,使所有节点都能互相解析

#1.编辑/etc/hosts文件
vim /etc/hosts
#2.都同步为如下
192.168.26.21 vms21.rhce.cc vms21
192.168.26.22 vms22.rhce.cc vms22
192.168.26.23 vms23.rhce.cc vms23
#修改好master上的后,可以拷贝到其他节点上
scp /etc/hosts vms22:/etc
scp /etc/hosts vms23:/etc

(2)所有节点关闭selinux

#编辑/etc/selinux/config文件,将SELINUX值设为disabled
vim /etc/selinux/config
#修改为
SELINUX=disabled

重启后生效
输入getenforce,显示 “Disabled” 则表示已关闭
(3)所有节点关闭swap交互分区

#关闭swap,并设置机器重启时不在开启swap(set -i '/swap/d' /etc/fstab)
swapoff -a ; sed -i '/swap/d' /etc/fstab

(4)设置防火墙

firewall-cmd --set-default-zone=trusted

(5)添加k8s的国内加速yum源k8s.repo,放入/etc/yum.repos.d/下
若是阿里云的,则会有些问题,需要将gpgcheck与repo_gpgcheck的值改为0

#配置yum源
rm -rf /etc/yum.repos.d/* ; wget ftp://ftp.rhce.cc/k8s/* -P /etc/yum.repos.d/

vim /etc/yum.repos.d/k8s.repo
#修改为
gpgcheck=0
repo_gpgcheck=0
#修改完其中一台后,同步到其他节点上
scp /etc/yum.repos.d/k8s.repo vms22:/etc/yum.repos.d
scp /etc/yum.repos.d/k8s.repo vms23:/etc/yum.repos.d
#所有节点上清楚yum缓存
yum clean all

(6)加载内核所需模块
每个节点上手动加载模块

modprobe overlay
modprobe br_netfilter

设置开机时能够自动加载模块

cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

(7)修改内核参数

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

使设置立即生效

sysctl -p /etc/sysctl.d/k8s.conf

(8)安装runtime
所有节点上安装containerd
安装好后,生成containerd的默认配置文件,并作相关配置,(参考上一篇文章内容)

containerd config default > /etc/containerd/config.toml

同时将crictl工具runtime-endpoint指定为containerd.sock

crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock

启动containerd并开机自启动

systemctl enable containerd --now

安装并启动nerdctl(可选,为了便于管理容器)(参考上一篇文章)
安装nerdctl后,修改配置文件如下,namespace设为k8s.io

mkdir /etc/nerdctl

cat > /etc/nerdctl/nerdctl.toml <<EOF
debug          = false
debug_full     = false
address        = "unix:///var/run/containerd/containerd.sock"
namespace      = "k8s.io"
#snapshotter   = "stargz"
cgroup_manager = "systemd"
hosts_dir     = ["/etc/containerd/certs.d"]
insecure_registry = false
EOF

安装k8s(所有节点上都需要操作)

以下为所有节点上都需要进行的操作:

(1)可以先查看当前k8s最新版本号

yum list --showduplicates kubeadm --disableexcludes=kubernetes

(2)在线安装1.24.2版

#--disableexcludes=kubernetes:防止包冲突
yum install -y kubelet-1.24.2-0 kubeadm-1.24.2-0 kubectl-1.24.2-0 --disableexcludes=kubernetes

(10)开启kubelet并设置开机自启动

systemctl enable kubelet --now

初始化集群(master上进行操作)

以下为在master上要做的操作:

(1)初始化集群

#直接使用kubeadm init命令时,会默认从k8s.gcr.io拉取镜像,但是在国内访问不了这个地址
#因此这里我们使用阿里云作为镜像源
#同时给pod分配网段cidr=xx.xx.xx.xx,这里为10.244.0.0/16
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.24.2 --pod-network-cidr=10.244.0.0/16  
#拉取完成之后,可以通过nerdctl images查看,大概有七个镜像

初始化完成后,会出现如下提示:

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.26.21:6443 --token azcfgb.x6ddnmtchvbl7bzp \
	--discovery-token-ca-cert-hash sha256:a56481720586f286a229eeef8c4edb6cf0c6697136f2c04321da521ef8eb5e62

(2)根据提示创建.kube/config认证文件

#(方式1与方式2二选一,不要两个都做)
#方式1
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config  
#方式2
export KUBECONFIG=/etc/kubernetes/admin.conf

初始化集群完成之后,可以通过kubectl get nodes查看当前所有节点,可以看到已经有了一个节点,即master

加入集群(所有worker上进行操作)

以下为所有worker上要做的操作:
初始化集群完成后,将所有worker加入集群

#1.获取加入集群的命令,加入集群的命令在初始化集群后提示中有,或者使用以下命令重新生成
kubeadm token create --print-join-command
#2.将生成类似如下命令,复制并输入执行
kubeadm join 192.168.26.21:6443 --token [xxx...]\--discovery-token-ca-cert-hash sha256:[xxx...]
#若命令执行过程中遇到某个报错了,则将报错解决后,这时直接执行加入集群的命令会报错,需要输入kubeadm reset恢复出厂设置(哪个节点上出错就哪个节点上reset),然后再重新输入命令加入集群
kubeadm reset

加入成功:
在这里插入图片描述

安装calico网络环境

(1)来到master上,查看当前所有节点

kubectl get nodes

在这里插入图片描述

此时可以看到 “STATUS” 都是 “NotReady”,是因为还需要准备CNI的网络环境,这里我们使用calico

(2)安装calico网络
1.master上下载配置calico网络的yaml(只在master上存在calico.yaml文件)

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

若出现以下错误
在这里插入图片描述
则需要安装ca-certificates

yum install -y ca-certificates

2.修改calico.yaml文件

vim calico.yaml
#1.修改pod网段
#将name为 “CALICO_IPV4POOL_CIDR” 处的属性注释去掉,并将值设置为 “初始化集群时给pod设置的网段”(即这里的值要与初始化集群时设置的pod的网段保持一致)
#要注意缩进关系
- name: CALICO_IPV4POOL_CIDR
  value: 10.244.0.0/16

#2.添加IP_AUTODETECTION_METHOD参数
#在CALICO_IPV6POOL_VXLAN这项下添加一个参数————IP_AUTODETECTION_METHOD,值为interface=ens32
#意为所有节点之间相互通信的时候,通过ens32这个物理网络来进行通信(各节点之间通过calico这个通道来通信的时候,底层还是走物理线路),特别是在多网卡的情况下,可能还有ens35、ens36等,若不指定则会报错
#要注意缩进关系
- name: IP_AUTODETECTION_METHOD
  value: "interface=ens32"

4.下载calico所需镜像(所有节点上都要下载)

#可以在master中根据calico.yaml可查看需要哪些镜像
grep image calico.yaml

在这里插入图片描述
所有节点上都下载这些镜像

for i in docker.io/calico/cni:v3.23.1 docker.io/calico/node:v3.23.1 docker.io docker.io/calico/kube-controllers:v3.23.1 ; do nerdctl pull $i ; done

若下载速度太慢,也可以提前下载离线镜像,打包成calico-img-3.23.tar,上传到所有节点中,然后导入到所有镜像

#将calico-img-3.23.tar上传到master中,然后拷贝至所有节点
scp calico-img-3.23.tar vms22:~
scp calico-img-3.23.tar vms23:~
#在所有节点中导入镜像
nerdctl load -i calico-img-3.23.tar

5.master上加载calico.yaml文件,执行安装(只在master上执行)

kubectl apply -f calico.yaml

注:calico.yaml可根据自己需要重命名

安装完成后,这时输入kubectl get nodes,当前所有的节点的 “STATUS” 变为 “Ready” 了,整个k8s环境部署完成

若遇到如下报错

Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")

可以删除/root/.kube/config文件,然后在所有节点上reset一下,并在master上重新初始化集群

rm -rf /root/.kube/config
kubeadm reset
#然后重新初始化集群...

安装metrics-server

若想监测节点的负载、pod的负载,就先要安装metrics-server

步骤一:master中下载metrics-server的yaml文件(只在master上操作)
进入https://github.com/kubernetes-sigs/metrics-server,找到installarion,找到metricserver的yaml文件,复制链接,并wget

wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

步骤二:查看需要哪些镜像

grep image components.yaml
#输出:
image: k8s.gcr.io/metrics-server/metrics-server:v0.6.1
imagePullPolicy: IfNotPresent

步骤三:所有节点上都下载这些镜像,k8s.gcr.io国内访问不了,因此将k8s.gcr.io/metrics-server改成registry.aliyuncs.com/google_containers

for i in registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 ; do nerdctl pull $i ; done

步骤四:然后进行tag镜像名,将主机地址改回k8s.gcr.io,库地址改回metrics-server,形成一个新镜像

nerdctl tag registry.aliyuncs.com/google_containers/metrics-server:v0.6.1 k8s.gcr.io/metrics-server/metrics-server:v0.6.1

步骤五:master中修改components.yaml文件(只在master上操作)

vim components.yaml
#显示所有行号
:set nu
#

修改1:98行左右,kind为Service的这项中,将下面原先的targetPort: https 改为 targetPort: 4443
在这里插入图片描述
修改2:115行左右,kind为Deployment的这项,在下面的containers中:
(1)先前的版本中要将–secure-port=4443注释,现在不能注释它
(2)在–secure-port=4443这项下增加 --kubelet-insecure-tls
(3)将livenessProbe这几行全部注释
(4)将containerdPort值改为4443
(5)将readinessProbe这几行全部注释
在这里插入图片描述
在这里插入图片描述
注:可以看到这里的image镜像名k8s.gcr.io/metrics-server/metrics-server:v0.6.1
也要与本地中的metrics-server镜像名对应

步骤六:
master中加载components.yaml文件,执行安装(只在master上操作)

kubectl apply -f components.yaml

安装完成
在这里插入图片描述

查看节点的负载

kubectl top nodes

查看pod的负载

# -n 指定命名空间
kubectl top pods -n kube-system

1core = 1000m(1核=1000微核心)
双核既2core=2000m,若某个node占用cpu383m,则cpu使用率为383/2000=19%

设置kubectl子命令可以使用tab键

前提:操作系统中安装有 “bash-completion-2.1-6.el7.noarch” 这个包
编辑 /etc/profile 文件(对所有用户生效)

vim /etc/profile

#在注释“/etc/profile”下增加
source <(kubectl completon bash)
Logo

开源、云原生的融合云平台

更多推荐