kubeadm部署k8s1.23.0单节点集群1


第一章:K8S介绍及集群部署

kubernetes(k8s)是2014年由Google公司基于Go语言编写的一款开源的容器集群编排系统,用于自动化容器的部署、扩缩容和管理;

kubernetes(k8s)是基于Google内部的Borg系统的特征开发的一个版本,集成了Borg系统大部分优势;

官方地址:https://Kubernetes.io

代码托管平台:https://github.com/Kubernetes

除了k8s还有哪些容器编排系统?如:docker swarm、Openshift、Rancher、Mesos等。

k8s具备的功能

  • 自我修复:k8s监控容器的运行状况,并在容器出现异常时自动对其重启;
  • 弹性伸缩:k8s可根据资源使用情况自动地调整容器的副本数。例如,在高峰时段,可自动增加容器的副本数以应对更多的流量;在低峰时段,减少容器的副本数节省资源;
  • 资源限额:通过对容器所需的CPU和内存资源设置上限,能够更好的管理容器的资源使用量;
  • 滚动升级:k8s可在不中断服务的情况下滚动升级应用版本,确保在整个过程中服务中断;
  • 负载均衡:k8s可根据应用的负载情况自动分配流量,确保各实例之间的负载均衡,避免某些实例过载导致性能下降;
  • 服务发现:通过为实例分配一个统一的访问地址,这样,用户只需要知道这个统一的地址,就可以访问到应用的任意实例,而无需关心具体的实例信息;
  • 存储管理:k8s可以自动管理应用的存储资源,为应用提供持久化的数据存储。这样,在应用实例发生变化时,用户数据仍能保持一致,确保数据的持久性;
  • 密钥与配置管理:Kubernetes 允许你存储和管理敏感信息,例如:密码、令牌、证书、ssh密钥等信息进行统一管理,并共享给多个容器复用;

k8s集群角色

k8s将多个节点组建成一个集群进⾏统⼀管理,但是在集群内部,这些节点⼜被划分成了两类⻆⾊:

  • Master管理节点:负责集群的所有管理工作;

  • Node工作节点:负责运行集群中的容器应用;

Master管理节点组件:

  • API Server:作为集群的管理入口,处理外部和内部通信,接收用户请求并处理集群内部组件之间的通信;
  • Scheduler:作为集群资源调度计算,根据调度策略,负责将待部署的 Pods 分配到合适的 Node 节点上;
  • Controller Manager:管理集群中的各种控制器,例如 Deployment、ReplicaSet、DaemonSet等,管理集群中的各种资源;
  • etcd:作为集群的数据存储,保存集群的配置信息和状态信息;

Node工作节点组件:

  • Kubelet:负责与 Master 节点通信,并根据 Master 节点的调度决策来创建、更新和删除 Pod,同时维护 Node 节点上的容器状态;
  • 容器运行时(如 Docker、containerd 等):负责运行和管理容器,提供容器生命周期管理功能。例如:创建、更新、删除容器等;
  • Kube-proxy:负责为集群内的服务实现网络代理和负载均衡,确保服务的访问性;

非必须的集群插件:

  • DNS服务:严格意义上的必须插件,在k8s中,很多功能都需要用到DNS服务,例如:服务发现、负载均衡、有状态应用的访问等;
  • Dashboard: 是k8s集群的Web管理界面;
  • 资源监控:例如metrics-server监视器,用于监控集群中资源利用率;

k8s集群类型

  • 一主多从集群:由一台Master管理节点和多台Node工作节点组成,生产环境下Master节点存在单点故障的风险,适合学习和测试环境使用;

  • 多主多从集群:由多台Master管理节点和多Node工作节点组成,安全性高,适合生产环境使用;

k8s集群规划

提示:系统尽量别带图形界面,图形比较吃内存。

主机名 IP地址 角色 操作系统 硬件最低配置
master01 192.168.0.30 管理节点 CentOS 7 2Core/4G内存/50G
node01 192.168.0.31 工作节点 CentOS 7 1Core/2G内存/50G
node02 192.168.0.32 工作节点 CentOS 7 1Core/2G内存/50G

集群环境部署

按照集群规划修改每个节点主机名

hostnamectl set-hostname 主机名

提示:以下前期环境准备需要在所有节点都执行

配置集群之间本地解析,集群在初始化时需要能够解析到每个节点的主机名

cat /etc/hosts 
192.168.0.10 master01
192.168.0.11 node01
192.168.0.12 node02

开启bridge网桥过滤功能

bridge (桥接网络) 是 Linux 系统中的一种虚拟网络设备,它充当一个虚拟的交换机,为集群内的容器提供网络通信功能,容器就可以通过这个 bridge 与其他容器或外部网络通信了。

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

参数解释:
net.bridge.bridge-nf-call-ip6tables = 1 //对网桥上的IPv6数据包通过iptables处理
net.bridge.bridge-nf-call-iptables = 1 //对网桥上的IPv4数据包通过iptables处理
net.ipv4.ip_forward = 1 //开启IPv4路由转发,来实现集群中的容器与外部网络的通信

由于开启 bridge 功能,需要加载 br_netfilter 模块来允许在 bridge 设备上的数据包经过 iptables 防火墙处理

modprobe br_netfilter && lsmod | grep br_netfilter

#...会输出以下内容
br_netfilter           22256  0
bridge                151336  1 br_netfilter

加载配置文件,使上述配置生效

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

配置ipvs代理功能

在k8s中 Service 有两种代理模式,一种是基于 iptables 的,一种是基于 ipvs ,两者对比 ipvs 负载均衡算法更加的灵活,且带有健康检查的功能,如果想要使用 ipvs 模式,需要手动载入 ipvs 模块。

ipsetipvsadm 是两个与网络管理和负载均衡相关的软件包,提供多种负载均衡算法,如轮询(Round Robin)、加权轮询(Weighted Round Robin)、最小连接(Least Connection)、加权最小连接(Weighted Least Connection)等;

yum -y install ipset ipvsadm

将需要加载的 ipvs 相关模块写入到文件中

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF

模块介绍:
ip_vs //提供负载均衡的模块
ip_vs_rr //轮询算法的模块(默认)
ip_vs_wrr //加权轮询算法的模块,根据后端服务器的权重值转发请求
ip_vs_sh //哈希算法的模块,同一客户端的请求始终被分发到相同的后端服务器,保证会话一致性
nf_conntrack //链接跟踪的模块,用于跟踪一个连接的状态,例如 TCP 握手、数据传输和连接关闭等

执行文件来加载模块

chmod +x /etc/sysconfig/modules/ipvs.modules
lsmod | grep ip_vs 

关闭SWAP分区

为了保证 kubelet 正常工作要求禁用SWAP,否则集群初始化失败

临时关闭

swapoff -a

永久关闭

sed -ri 's/.*swap.*/#&/' /etc/fstab

检查swap

free -h
...
Swap:            0B          0B          0B

安装Docker

安装 yum-utils 软件提供 yum-config-manager 命令

yum install -y yum-utils

添加阿里云 docker-ce 仓库

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 docker 软件包

yum -y install docker-ce-20.10.9-3.el7

启用 Cgroup 控制组,用于限制进程的资源使用量,如CPU、内存资源

mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
        "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

启动 docker

systemctl enable docker --now

集群部署方式

k8s集群有多种部署方式,目前常用的部署方式有如下两种:

  • kubeadm 部署方式:kubeadm是一个快速搭建kubernetes的集群工具;
  • 二进制包部署方式:从官网下载每个组件的二进制包,依次去安装,部署麻烦;
  • 其他方式:通过一些开源的工具搭建,例如:sealos;

通过 Kubeadm 方式部署k8s集群,需要配置k8s软件仓库来安装集群所需软件,本实验使用阿里云YUM源

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

安装集群软件,本实验安装k8s 1.23.0版本软件

  • kubeadm:用于初始化集群,并配置集群所需的组件并生成对应的安全证书和令牌;
  • kubelet:负责与 Master 节点通信,并根据 Master 节点的调度决策来创建、更新和删除 Pod,同时维护 Node 节点上的容器状态;
  • kubectl:用于管理k8集群的一个命令行工具;
yum install -y  kubeadm-1.23.0-0  kubelet-1.23.0-0 kubectl-1.23.0-0

配置 kubelet 启用 Cgroup 控制组,用于限制进程的资源使用量,如CPU、内存等

cat > /etc/sysconfig/kubelet <<EOF
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
EOF

设置 kubelet 开机自启动即可,集群初始化后自动启动

systemctl enable kubelet

集群初始化

在master01节点初始化集群:查看集群所需镜像文件

[root@master01 ~]# kubeadm config images list
#...以下是集群初始化所需的集群组件镜像
v1.27.1; falling back to: stable-1.23
k8s.gcr.io/kube-apiserver:v1.23.17
k8s.gcr.io/kube-controller-manager:v1.23.17
k8s.gcr.io/kube-scheduler:v1.23.17
k8s.gcr.io/kube-proxy:v1.23.17
k8s.gcr.io/pause:3.6
k8s.gcr.io/etcd:3.5.1-0
k8s.gcr.io/coredns/coredns:v1.8.6

需要创建集群初始化配置文件

[root@master01 ~]# kubeadm config print init-defaults > kubeadm-config.yml

配置文件需要修改如下内容

[root@master01 ~]# cat kubeadm-config.yml
#...以下是需要修改的内容

#本机IP地址
advertiseAddress: 192.168.0.10

#本机名称
name: master01

#集群镜像下载地址,修改为阿里云
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers

集群初始化

[root@master01 ~]# kubeadm init --config kubeadm-config.yml --upload-certs

选项说明:
–upload-certs //初始化过程将生成证书,并将其上传到etcd存储中,避免证书被移动或者删除,也不会影响集群。

根据集群初始化后的提示,执行以下命令生成集群管理员配置文件

[root@master01 ~]# mkdir -p $HOME/.kube
[root@master01 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master01 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config

根据提示将 node 节点加入集群后,在master节点验证

[root@master01 ~]# kubectl get nodes
NAME       STATUS     ROLES                  
master01   NotReady   control-plane,master   
node01     NotReady   <none>               
node02     NotReady   <none>               

提示:如果哪个节点出现问题,可以使用下列命令重置当前节点

kubeadm  reset

部署Calico网络

CalicoFlannel 是两种流行的 k8s 网络插件,它们都为集群中的 Pod 提供网络功能。然而,它们在实现方式和功能上有一些重要区别:

网络模型的区别:

性能的区别:

master01 节点安装下载 Calico 的yaml文件

[root@master01 ~]# wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml 

创建calico网络

[root@master01 ~]# kubectl apply -f calico.yaml 

查看calico的Pod状态

[root@master01 ~]# kubectl get pod -n kube-system
NAME                                      READY   
calico-kube-controllers-66966888c4-whdkj   1/1    
calico-node-f4ghp                          1/1     
calico-node-sj88q                          1/1     
calico-node-vnj7f                          1/1     
calico-node-vwnw4                          1/1  

检查集群状态

[root@master01 ~]# kubectl get nodes
NAME     STATUS   ROLES                  
master   Ready    control-plane,master   
node01   Ready    <none>                 
node02   Ready    <none>               

部署Ingress-nginx代理

Ingress-nginx 相当于一个7层的负载均衡器,集群中的程序对外提供访问,需要通过Ingress代理发布域名。

资源清单文件下载地址:https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml

提示:由于网络原因可能无法下载,直接使用我给大家下载好的文件即可,文件名:ingress-nginx.yml

提前导入ingress-nginx 相关镜像,默认的镜像地址无法下载,导入后创建ingress-nginx.yaml文件

[root@master01 ~]# kubectl create -f ingress-nginx.yaml

查看 ingress-nginx 空间下的Pod状态

[root@master01 ~]# kubectl get pod -n ingress-nginx
NAME                                  READY   STATUS
ingress-nginx-admission-create-p2428  0/1     Completed 
ingress-nginx-admission-patch-w9tqj   0/1     Completed
ingress-nginx-controller-fbf8-s7sj9   1/1     Running

部署Harbor镜像仓库

搭建私有镜像仓库,用于存储自己构建的项目镜像。

主机名 IP地址 系统版本 硬件最低配置
harbor 192.168.0.7 CentOS 7 1Core/2G内存/20G磁盘

安装Docker软件包

安装 yum-utils 软件提供 yum-config-manager 命令

[root@harbor ~]# yum install yum-utils -y

添加阿里云 docker-ce 仓库

[root@harbor ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 docker 软件包

[root@harbor ~]# yum install docker-ce-20.10.9 -y

启动 docker

[root@harbor ~]# systemctl enable docker --now

上传 Docker Compose 程序文件并添加执行权限

[root@harbor ~]# chmod +x docker-compose
[root@harbor ~]# mv docker-compose /usr/bin
[root@harbor ~]# docker-compose --version

上传 harbor 离线包并解压

[root@harbor ~]# tar -xf harbor-v2.5.1.tgz

进入解压目录

[root@harbor ~]# cd harbor

导入Harbor 镜像文件

[root@harbor harbor]# docker load -i harbor.v2.5.1.tar.gz

修改配置文件名称

[root@harbor harbor]# mv harbor.yml.tmpl harbor.yml

修改配置文件中的如下内容

[root@harbor harbor]# vim harbor.yml
#上述内容省略...
hostname: 192.168.0.7		#Harbor主机IP地址

http:                     	#访问方式为http(不用修改)
  port: 80                	#默认端口(不用修改)

#https:                    	注释https访问方式(需要有效证书才可以使用)
# port: 443                	注释https端口
 
# certificate: /root/harbor/6864844_kubemsb.com.pem  注释证书文件
# private_key: /root/harbor/6864844_kubemsb.com.key  注释证书密钥文件
 
harbor_admin_password: 12345 #admin密码

执行 install.sh 安装脚本

[root@harbor harbor]# ./install.sh
#出现以下提示表示安装完成
...----Harbor has been installed and started successfully.----

本机指定 Harbor 仓库地址

[root@harbor harbor]# vim /etc/docker/daemon.json
{							
  "insecure-registries": ["http://192.168.0.7"]
}

重启 docker 使配置生效

[root@harbor harbor]# systemctl restart docker

重启 Harbor 仓库(docker 重启后,Harbor 相关组件并不会自动重启,需要手动重启)

[root@harbor harbor]# docker-compose down
[root@harbor harbor]# docker-compose up -d

浏览器访问Harbor页面:http://192.168.0.25/

部署NFS存储服务器

本案例基于NFS作为后端存储设备,来持久化保存k8s容器中的数据。

主机名 IP地址 操作系统 硬件配置
k8s-nfs 192.168.0.8 CentOS 7 1Core/2G内存/20G磁盘

安装NFS软件包

[root@k8s-nfs ~]# yum install nfs-utils -y

创建NFS共享目录

[root@k8s-nfs ~]# mkdir /wordpress-volume

修改NFS配置文件共享目录

[root@k8s-nfs ~]# vim /etc/exports
/wordpress-volume 192.168.0.0/24(rw,no_root_squash)

启动NFS

[root@k8s-nfs ~]# systemctl enable nfs --now

k8s集群节点也需要安装 nfs-utils 用于访问NFS服务端(不需要启动程序),否则无法访问NFS服务端。

node01node02 节点安装即可

[root@node01 ~]# yum install nfs-utils -y
[root@node02 ~]# yum install nfs-utils -y

node01node02 节点访问NFS服务端,查看共享信息

[root@node01 ~]# showmount -e 192.168.0.8
Export list for 192.168.0.8:
/wordpress-volume 192.168.0.0/24
[root@node02 ~]# showmount -e 192.168.0.8
Export list for 192.168.0.8:
/wordpress-volume 192.168.0.0/24

创建StorageClass动态存储

如果使用 StorageClass 结合NFS作为后端存储,需要一个 nfs-client-provisioner 程序, 用于与NFS集成。

需要先为 nfs-client-provisioner 程序提供访问集群的权限,文件下载地址(文件名:rbac.yaml ):https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/deploy

master 节点创建,文件内容如下,内容不需要修改

[root@master01 ~]# cat nfs-storage-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

创建文件

[root@master01 ~]# kubectl create -f nfs-storage-rbac.yaml

创建 nfs-client-provisioner 程序,文件下载地址(文件名:deployment.yaml ):https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/deploy

master 节点创建,文件内容如下,需要修改文件中的NFS地址及共享目录名称

[root@master01 ~]# cat nfs-client-provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.0.8             #传递NFS服务器IP地址
            - name: NFS_PATH
              value: /wordpress-volume       #传递NFS服务器共享路径
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.0.8              #后端NFS服务器IP地址
            path: /wordpress-volume          #后端NFS服务器共享路径

当 nfs-client-provisioner 创建 PV 时,它会生成这些配置文件,并将它们存储在 /persistentvolumes 目录中。PV 配置文件仅包含了 PV 的元数据和 NFS 服务器的连接信息,而不包括实际的数据。数据仍然存储在 NFS 服务器上的 /storageclass 目录中。

提示:该文件中的镜像默认无法下载,需提前导入到两台 node节点。

创建 nfs-provisioner

[root@master01 ~]# kubectl create -f nfs-client-provisioner.yaml

查看 nfs-provisioner 的Pod

[root@master01 ~]# kubectl get pod
NAME                                     READY  STATUS
nfs-client-provisioner-6cc8645fd5-gxmdw   1/1   Running

创建StorageClass动态存储,文件参考地址(文件名:class.yaml ):https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/deploy

master 节点创建,文件内容如下,内容不需要修改

[root@master01 ~]# cat nfs-storageclass.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:                     #向底层存储系统传递配置信息
  archiveOnDelete: "false"      #PV被删除时,false表示数据也会被删除,设定为true数据保留

提示:以上配置仅用于底层是NFS,其他存储设备还需要参考地址:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/

创建 storageclass

[root@master01 ~]# kubectl apply -f nfs-storageclass.yml

查看 storageclass 信息

[root@master01 ~]# kubectl get sc

字段说明:
NAME //存储名称。
PROVISIONER //对应的provisioner名称。
RECLAIMPOLICY //PV回收策略,通常是Delete(删除)或Retain(保留)。
VOLUMEBINDINGMODE //卷绑定模式,例如Immediate(无论是否有Pod使用该PVC,都会立即与合适的PVC绑定)或WaitForFirstConsumer(直到有Pod使用该PVC时,才会与PV绑定)。
ALLOWVOLUMEEXPANSION //是否允许对卷进行扩容,false不允许(NFS不支持扩容,云存储和分布式支持)


文章作者: HuanYue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 HuanYue !
 上一篇
CTF实战分享 | RWZIP CTF实战分享 | RWZIP
首先我们要了解,压缩包本身并不具备隐藏信息的功能,但由于在CTF竞赛中,经常出现压缩包与隐写术结合在一起的题目,所以我们需要掌握在CTF竞赛中有关 ZIP 压缩包题目的常见题型及分析手段。
2024-05-20
下一篇 
基于Hexo的hexo-theme-matery主题搭建之代码高亮坑点 基于Hexo的hexo-theme-matery主题搭建之代码高亮坑点
一个基于材料设计和响应式设计而成的全面、美观的Hexo主题。
2021-10-03
  目录