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

kubernetes(k8s)是2014年由Google公司基于Go语言编写的一款开源的容器集群编排系统,用于自动化容器的部署、扩缩容和管理;
kubernetes(k8s)是基于Google内部的Borg系统的特征开发的一个版本,集成了Borg系统大部分优势;
代码托管平台: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
模块。
ipset
和 ipvsadm
是两个与网络管理和负载均衡相关的软件包,提供多种负载均衡算法,如轮询(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网络
Calico
和 Flannel
是两种流行的 k8s 网络插件,它们都为集群中的 Pod 提供网络功能。然而,它们在实现方式和功能上有一些重要区别:
网络模型的区别:
- Calico 使用 BGP(边界网关协议)作为其底层网络模型。它利用 BGP 为每个 Pod 分配一个唯一的 IP 地址,并在集群内部进行路由。Calico 支持网络策略,可以对流量进行精细控制,允许或拒绝特定的通信。
- Flannel 则采用了一个简化的覆盖网络模型。它为每个节点分配一个 IP 地址子网,然后在这些子网之间建立覆盖网络。Flannel 将 Pod 的数据包封装到一个更大的网络数据包中,并在节点之间进行转发。Flannel 更注重简单和易用性,不提供与 Calico 类似的网络策略功能。
性能的区别:
- 由于 Calico 使用 BGP 进行路由,其性能通常优于 Flannel。Calico 可以实现直接的 Pod 到 Pod 通信,而无需在节点之间进行额外的封装和解封装操作。这使得 Calico 在大型或高度动态的集群中具有更好的性能。
- Flannel 的覆盖网络模型会导致额外的封装和解封装开销,从而影响网络性能。对于较小的集群或对性能要求不高的场景,这可能并不是一个严重的问题。
在 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代理发布域名。
提示:由于网络原因可能无法下载,直接使用我给大家下载好的文件即可,文件名: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服务端。
node01
与 node02
节点安装即可
[root@node01 ~]# yum install nfs-utils -y
[root@node02 ~]# yum install nfs-utils -y
node01
与 node02
节点访问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不支持扩容,云存储和分布式支持)