一、环境准备

0)、生产环境云服务器防火墙配置

1、配置安全组,保证即便没有配置各个机器之间的端口,也能保证机器之间是互通的

在这里插入图片描述

2、各个机器内部额外配置端口,保证外部可以访问使用

在这里插入图片描述

3、k8s集群自动在机器上暴露节点设置

配置个起始端口的区间,30000-32767之间,以后未来k8s部署应用,那么就不需要配置其它端口了,比如nginx的8端口,因为nginx会以service的形式统一管理,而service的端口可以分配在30000-32767之间,直接请求serveice的端口,k8s会以负载均衡的方式分配给nginx,这样就不需要配置那么多端口了
在这里插入图片描述

1)、环境准备

分别修改三台机器的主机名称(所有节点执行),注意是各自改各自机器上的hostname,别搞错了

hostnamectl set-hostname k8s-node1 && bash

hostnamectl set-hostname k8s-node2 && bash

hostnamectl set-hostname k8s-node3 && bash

配置主机hosts文件,相互之间通过主机名互相访问
修改每台服务器的/etc/hosts文件,文件最后增加如下内容:
ps. 文件里原有的配置不要动(所有节点执行)

## 192.168.10.100节点
192.168.10.100   k8s-node1
192.168.10.101   k8s-node2 
192.168.10.102   k8s-node3

## 192.168.10.101节点
192.168.10.100   k8s-node1
192.168.10.101   k8s-node2 
192.168.10.102   k8s-node3

## 192.168.10.102节点
192.168.10.100   k8s-node1
192.168.10.101   k8s-node2 
192.168.10.102   k8s-node3

关闭交换分区swap,建议永久关闭(所有节点执行)

#临时关闭
swapoff -a

永久关闭:注释swap挂载,给swap这行开头加一下注释。为什么要关闭swap交换分区?
Swap是交换分区,如果机器内存不够,会使用swap分区,但是swap分区的性能较低,k8s设计的时候为了能提升性能,默认是不允许使用交换分区的。Kubeadm初始化的时候会检测swap是否关闭,如果没关闭,那就初始化失败。如果不想要关闭交换分区,安装k8s的时候可以指定–ignore-preflight-errors=Swap来解决

#永久关闭
vi /etc/fstab
#或者使用二选一
sed -ri 's/.*swap.*/#&/' /etc/fstab
free -g #验证,swap 必须为 0;

在这里插入图片描述
关闭防火墙 生产环境不能关闭,要配置防火墙规则,允许kubelet端口通过

systemctl stop firewalld
#关闭防火墙开机自启
systemctl disable firewalld

关闭selinux,不关闭配置集群会有问题

#临时关闭
sudo setenforce 0

#永久关闭
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

配置集群时间同步(所有节点执行)

#安装日期软件(所有节点都执行)
yum install -y chrony

如果使用yum出现以下异常:

已加载插件:fastestmirror, langpacks
Determining fastest mirrors
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 未知的错误"


 One of the configured repositories failed (未知),
 and yum doesn't have enough cached data to continue. At this point the only
 safe thing yum can do is fail. There are a few ways to work "fix" this:

     1. Contact the upstream for the repository and get them to fix the problem.

     2. Reconfigure the baseurl/etc. for the repository, to point to a working
        upstream. This is most often useful if you are using a newer
        distribution release than is supported by the repository (and the
        packages for the previous distribution release still work).

     3. Run the command with the repository temporarily disabled
            yum --disablerepo=<repoid> ...

     4. Disable the repository permanently, so yum won't use it by default. Yum
        will then just ignore the repository until you permanently enable it
        again or use --enablerepo for temporary usage:

            yum-config-manager --disable <repoid>
        or
            subscription-manager repos --disable=<repoid>

     5. Configure the failing repository to be skipped, if it is unavailable.
        Note that yum will try to contact the repo. when it runs most commands,
        so will have to try and fail each time (and thus. yum will be be much
        slower). If it is a very temporary problem though, this is often a nice
        compromise:

            yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true

Cannot find a valid baseurl for repo: base/7/x86_64

解决办法:
1.下载阿里云 CentOS 7 镜像源

curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

2.清除缓存并生成新缓存

yum clean all
yum makecache
#修改配置文件(master节点)
vim /etc/chrony.conf

# 配置上游NTP服务器(从互联网获取时间)
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst

# 允许本地网络设备同步时间(根据实际网络调整)
allow 192.168.0.0/16  # 允许192.168.0.0/16网段的客户端
# allow 10.0.0.0/8     # 取消注释以允许10.0.0.0/8网段(示例)

# 本地时钟作为备用时间源(当无法访问上游服务器时使用)
local stratum 10

# 指定存放时间数据的目录
driftfile /var/lib/chrony/drift

# 启用RTCCLOCK内核模块(硬件时钟同步)
rtcsync

# 保存频率,减少系统崩溃时的时间损失
makestep 1.0 3

# 指定日志文件位置
logdir /var/log/chrony
# 配置防火墙(如启用),没有启动防火墙就不需要配置这一步
firewall-cmd --add-service=ntp --permanent
firewall-cmd --reload
# 启动并验证 chrony 服务
# 启动chrony服务
systemctl start chronyd

# 设置开机自启
systemctl enable chronyd

# 检查服务状态
systemctl status chronyd

# 验证时间同步状态
chronyc sources -v
# 正常输出示例
210 Number of sources = 4
.-- Source mode  '^' = server, '=' = peer, '#' = local clock
/ .- Source state '*' = current synced, '+' = combined, '-' = not combined,
| /   '?' = unreachable, 'x' = time may be in error, '~' = time too variable
||                                                 .- xxxx [ yyyy ] +/- zzzz
||                                                 .- Reachability register (octal)
||                                                 |  .- xxxx [ yyyy ] +/- zzzz
||                                                 |  |   .- xxxx = adjusted offset, yyyy = measured offset, zzzz = estimated error
||                                                 |  |   |
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 2.pool.ntp.org               2   6   377    12   -12us[ -12us] +/-  12ms
^+ 3.pool.ntp.org               2   6   377    11   +33us[ +33us] +/-  11ms
^+ 0.pool.ntp.org               2   6   377    12   -15us[ -15us] +/-  11ms
^+ 1.pool.ntp.org               2   6   377    12   +23us[ +23us] +/-  11ms

从节点配置,如果从节点没有安装chrony,就需要先安装yum install -y chrony

vim /etc/chrony.conf

# 注释掉原有服务器配置
# server 0.centos.pool.ntp.org iburst
# server 1.centos.pool.ntp.org iburst
# server 2.centos.pool.ntp.org iburst
# server 3.centos.pool.ntp.org iburst

# 添加你的chrony服务器
server 192.168.10.100 iburst
allow 192.168.10.0/24  # 允许192.168.10.0/24网段的客户端
#配置防火墙(如启用),没有启用防火墙不需要配置这一步
firewall-cmd --permanent --add-service=ntp
firewall-cmd --reload
# 重启chrony服务
systemctl restart chronyd

# 设置开机自启
systemctl enable chronyd

# 检查服务状态
systemctl status chronyd

验证时间同步状态

chronyc sources -v
210 Number of sources = 1
.-- Source mode  '^' = server, '=' = peer, '#' = local clock
/ .- Source state '*' = current synced, '+' = combined, '-' = not combined,
| /   '?' = unreachable, 'x' = time may be in error, '~' = time too variable
||                                                 .- xxxx [ yyyy ] +/- zzzz
||                                                 .- Reachability register (octal)
||                                                 |  .- xxxx [ yyyy ] +/- zzzz
||                                                 |  |   .- xxxx = adjusted offset, yyyy = measured offset, zzzz = estimated error
||                                                 |  |   |
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 192.168.10.100             3   6   377    10    -6us[  -6us] +/-  25ms

在这里插入图片描述
将桥接的IPv4流量传递到iptables的链(所有节点执行):

cat << EOF | sudo tee /etc/modules-load.d/k8s.conf 
br_netfilter
EOF

cat << EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
 
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

设置镜像加速地址(所有节点执行)

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

配置ssh免密登录(master节点)
先生成密钥,再复制到所有节点

ssh-keygen
#hosts配置的
ssh-copy-id k8s-node1
ssh-copy-id k8s-node2
ssh-copy-id k8s-node3
#测试连接
ssh k8s-node3

二、docker20.10.7版本安装

1)、安装docker(所有节点都执行)

sudo yum remove docker*

yum install docker-ce-20.10.7 docker-ce-cli-20.10.7  containerd.io-1.4.6

2)、配置 docker 加速(所有节点都执行)

vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://shj9hb93.mirror.aliyuncs.com","https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
		"max-size": "100m"
	},
"storage-driver": "overlay2"
}

3)、启动 docker & 设置 docker 开机自启(所有节点都执行)

sudo systemctl daemon-reload

systemctl start docker
systemctl enable docker

4)、添加阿里云 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
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

如果有安装最新版本docker需求或者docker往下降版本

1)、要下载最新版本的docker命令,升级docker版本可以直接执行

sudo yum install -y docker-ce docker-ce-cli containerd.io

2)、高版本docker需要降级安装旧版本docker,新版本往下降,需要执行下面命令,如果是旧版本往上升级,直接执行下载安装docker的命令就可以了

sudo yum remove docker-buildx-plugin

执行安装命令

#将版本改成你需要的旧版本
yum install docker-ce-20.10.9-3.el7 docker-ce-cli-20.10.9-3.el7 docker-compose-plugin containerd.io

#启动docker
systemctl start docker
 
#设置开机自启
systemctl enable docker

在这里插入图片描述
可以看到,我这里docker启动失败了

排查docker启动失败几种方式
1)、检查 containerd 服务状态
systemctl status containerd.service

在这里插入图片描述我这里是正常启动的,如果没有启动,则启动它

systemctl start containerd.service
2)、设置 containerd 服务开机自启
systemctl enable containerd.service
3)、检查 Docker 配置文件,Docker 的配置文件(通常为 /etc/docker/daemon.json)可能存在语法错误或不兼容的配置项,从而导致 Docker 守护进程启动失败
sudo mv /etc/docker/daemon.json /etc/docker/daemon.json.bak

这一步是为了在修改配置文件出现问题时可以恢复。重新启动 Docker 服务:

sudo systemctl start docker.service

若 Docker 服务能够正常启动,说明原配置文件存在问题。你可以逐步将原配置项添加回新的 daemon.json 文件中,每次添加后都重启 Docker 服务,以确定具体是哪个配置项导致的问题。我这里就是daemon.json格式有问题,修复完以后

在这里插入图片描述

3)、再次启动docker,然后使用systemctl status docker,就可以看到启动成功了

在这里插入图片描述

5)、docker配置镜像下载加速器,添加/修改了镜像加速器,记得让docker重新加载一下,先执行加速器地址配置命名,后执行docker加载命令,位置在/etc/docker/daemon.josn(所有节点执行)

vi /etc/docker/daemon.josn
{
  "registry-mirrors": ["https://shj9hb93.mirror.aliyuncs.com","https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"],
"exec-opts": ["native.cgroupdriver=systemd"]
}

重新加载配置,重启docker

sudo systemctl daemon-reload
#重启docker
systemctl restart docker

三、安装kubelet(主节点,我这里是三台机器,任选一个作为主节点)

1)、下载kubelet前,要先配置它的加速器地址,不然下载的时候就会去kubelet官网地址下载。(所有节点都执行)

sudo vi /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

2)、安装kubelet,版本是1.22.12(所有节点都执行)

kubeadm:用来初始化k8s集群的指令。
kubelet:在集群的每个节点上用来启动 Pod 和容器等。
kubectl:用来与k8s集群通信的命令行工具,查看、创建、更新和删除各种资源

mkdir /root/k8s/kubernetesv1.22.12/

cd /root/k8s/kubernetesv1.22.12/

yum install -y kubelet-1.22.12 kubeadm-1.22.12 kubectl-1.22.12

#设置开机自启,必须要设置
sudo systemctl enable kubelet
#启动kubelet
sudo systemctl start kubelet

3)、初始化kubeadm(只在master节点执行)

sudo kubeadm init \
--apiserver-advertise-address=192.168.10.100 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version v1.22.12 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16

在这里插入图片描述

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

也可以使用这个命令查看所有yum安装的应用

yum list|grep kube

在这里插入图片描述

4)、安装网络插件Calico(主节点执行)

这个是安装在 Kubernetes 集群中部署 网络插件,我在根目录创建了一个k8s的目录,进入该目录执行命令下载calico.yml,执行完该命令后就会看到k8s目录里多个文件。注意,安装网络插件一定要在初始化kubeadm后

mkdir /root/k8s/calicov3.15/
cd /root/k8s/calicov3.15/

下载calico.yml保存
curl https://docs.projectcalico.org/v3.15/manifests/calico.yaml -O
#或者使用
wget https://docs.projectcalico.org/v3.15/manifests/calico.yaml

修改配置,显示文件内容行数,进入文件后不要按i,直接输入冒号:set number,就会显示行数
如果文件内容很多,想快速定位到3727行,按一下ESC,然后直接输入3727G点回车(注意,linux界面,输入

修改配置
3727行             - name: CALICO_IPV4POOL_CIDR
3728行               value: "10.244.0.0/16"  # 与 kubeadm init 时的 --pod-network-cidr 一致
 
安装至kubectl
kubectl apply -f calico.yaml

验证是否成功
kubectl get pod -A | grep calico

5)、前面初始化kubelet控制台出现的token,这个token是会过期的,只有24小时有效,再执行上面的命令会有问题,可以执行一个命令再生成一个永不过期的token,(而且只能在从节点执行),如果在24小时内执行从节点加入主节点命令,则第五步可以跳过不需要执行。

该命令用于创建一个新的令牌(token),此令牌在节点加入集群时会被使用,作为身份验证的凭证。打印的一长串,kubeadm join …这个命令是可以直接执行的,作用是在节点加入集群时会被使用,简单点说就是让其他节点,都加入主节点进来
–ttl 0:ttl 是 “Time To Live” 的缩写,代表令牌的有效期。将其设置为 0,意味着生成的令牌永不过期。在实际使用时,如果不确定新节点何时加入集群,设置为永不过期是比较方便的做法。

kubeadm token create --ttl 0 --print-join-command

执行完上面这个重新生成token的命令后,控制台会继续打印出这个token,注意,直接复制控制台这个token,第二行calico.yaml --discovery-token-ca-cert-hash sha256:bb481e918e79f2de49519209cffcba81fb41b4702dea705c2d0a8178a1c06f14 ,一定要删除calico.yaml,不然执行从节点加入主节点会报错
在这里插入图片描述 kubeadm join <主节点 IP>:<端口> --token <令牌> --discovery-token-ca-cert-hash sha256:<哈希值>

kubeadm join 你的主机ip:端口号--token 1xt7bj.r3vzi4l0vzdq4ary \
    --discovery-token-ca-cert-hash sha256:d5450edfa03899712abb11e2a95cb4c6867b56e9f6edfaf7cdc06d1646090f59 

6)、查看所有的节点信息命令

kubectl get nodes

可以看到我这里不是Ready状态,需要等待一会
在这里插入图片描述
在这里插入图片描述
我这里目前只有一个节点,就是master节点,一定要等master节点的状态是Ready

7)、部署kubelet从节点

1)、两台机器执行加入主节点命令

注意啊,直接从控制台复制,第二行会多出来一个calico.yaml,记得删除它

kubeadm join 你的主机ip:端口号--token elkh0e.y76q4glo87dkkpim \
    --discovery-token-ca-cert-hash sha256:5ba04add15ccbe3fcf61eae1de00412bb2eeae21610ab7b47608205a8e21e9b3 

在这里插入图片描述

3)、两台机器都加入集群后,在主节点查看一下从节点状态

kubectl get nodes

在这里插入图片描述
可以看到,两个从节点也加入到集群中了,k8s-node1是master节点,但是另外两个节点的状态是NotReady的,这是因为,从节点还正在初始化中

8)、master监控Node各节点

当这各个节点状态都是Running了,再去查看从节点的状态

watch kubectl get pod -n kube-system -o wide

在这里插入图片描述
在这里插入图片描述可以看到,集群所有的节点状态都是Ready了

四、存储抽象NFS(网络文件系统)

在docker中,以前是将docker内部目录挂载到机器上,但是在k8s中如果将目录挂载到机器上,如果某个节点的容器挂了,比如MySQL,k8s的自愈机制会在其它节点再拉起一份,那就会导致原来的数据丢失了,所以在k8s中需要应用到存储层:比如NFS、OpenEBS,k8s会将这些容器的数据全部存在存储层,而这个存储层会在所有节点都有一份

方式一:使用openEBS(推荐这个)

0、为什么推荐openEBS

我前面是使用nfs做存储系统的,但是到了部署MySQL的时候,看部署日志kubectl logs -n <名称空间> 发现mysql初始化很慢(下面贴图展示)初始化半天,等很久后初始化完成,mysql也会有各种各样的问题,比如无法使用DNS域名访问,提示没有权限,是因为在初始化MySQL的时候,少了很多东西。而且opendEBS是块存储,这种类型的比NFS存储性能更高,效率更快。MySQL、redis这种中间件也是集群部署的,也不用担心数据丢失问题
在这里插入图片描述

1、下载helm

curl -fsSL -o helm-v3.12.3-linux-amd64.tar.gz https://get.helm.sh/helm-v3.12.3-linux-amd64.tar.gz

2、解压并且验证安装

# 解压文件
tar -zxvf helm-v3.12.3-linux-amd64.tar.gz

# 移动二进制文件到PATH路径
sudo mv linux-amd64/helm /usr/local/bin/helm

# 验证安装
helm version

在这里插入图片描述

3、添加仓库

# 添加官方稳定仓库
helm repo add stable https://charts.helm.sh/stable

helm repo add openebs https://openebs.github.io/charts

# 更新仓库索引
helm repo update

在这里插入图片描述

5、安装opendEBS

helm install openebs openebs/openebs \
  --namespace openebs \
  --create-namespace \
  --version 2.10.0

查看安装的openebs的pod

kubectl get pods -n openebs

在这里插入图片描述

6、查看存储类

等待openebs所有的pod都是Running状态后,查看存储类,可以使用linux系统自带的每秒输出指令的内容,用来监控openebs是否都是Running

watch -n 1 kubectl get pod -n openebs
#查看openebs的存储类
kubectl get sc

在这里插入图片描述

7、设置默认存储类

必须要设置默认存储类,不然安装kubesphere的时候,会报错,找不到默认存储类

kubectl patch storageclass openebs-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

在这里插入图片描述

方式二:安装nfs

1、所有节点都执行

yum install -y nfs-utils

2、master节点执行

#在master节点暴露/nfs/data/这个目录
#*:所有人都能同步这个目录,以非安全、读写的模式同步
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

mkdir -p /nfs/data

systemctl enable rpcbind
systemctl enable nfs-server
systemctl start rpcbind
systemctl start nfs-server

#配置生效
exportfs -r

检查/nfs/data这个目录暴露在外面

exportfs

在这里插入图片描述
到这里,nfs的服务端已经启动好了

3、从节点

#使用该命令查看master节点有哪些目录可以挂载
#这里应该是你自己的IP
showmount -e 192.168.10.100

在这里插入图片描述

#给所有的从节点创建一个跟master节点相同的目录
mkdir -p /nfs/data

#执行以下命令挂载nfs远程服务器上的共享目录到本机路径 /nfs/data
mount -t nfs 192.168.10.100:/nfs/data /nfs/data

4、测试NFS的主从同步

master节点新建文件

#验证从节点是否已经挂载了远程服务器的目录,可以在mster写入一个测试文件,
#然后去从节点的相同目录/nfs/data/下查看,是否有这个新建的文件
echo "hello nfs server" > /nfs/data/test.txt

在这里插入图片描述
从节点查看是否有这个文件,并且输出文件内容
在这里插入图片描述

方式一:学习以及简单使用什么是NFS(master节点执行)

1)、为什么要使用NFS?

使用原生方式数据挂载,将某个容器的目录挂载到NFS文件系统上,比如下面这个将nginx的数据目录挂载到NFS

vi deploy.yaml

#下面的ip需要改成你的master节点ip
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-pv-demo
  name: nginx-pv-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-pv-demo
  template:
    metadata:
      labels:
        app: nginx-pv-demo
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html # 挂载目录
      volumes:
        # 和 volumeMounts.name 一样
        - name: html
          nfs:
            # master IP
            server: 192.168.10.100  #master节点ip
            path: /nfs/data/nginx-pv # 要提前创建好文件夹,否则挂载失败
cd /nfs/data

mkdir -p nginx-pv

ls

kubectl apply -f deploy.yaml
cd /nfs/data/
ls
cd nginx-pv/
echo "cgxin" > index.html
# 进入 pod 里面查看

问题:占用空间,删掉之后,文件还在,内容也在,而且还是没法管理大小的
在这里插入图片描述

2)、PV和PVC
1)、PV和PVC的概念

PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置。
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格。
通俗讲:持久卷就是数据需要存储到的位置,持久卷申明就是pod需要写一份申请书这个申请书就是PVC,去申请多大的空间,申请一兆,那么就开一份一兆的实体化存储的PV空间。所以当这个pod被删除后,这个PVC申请书也会带着一起被删除,PVC删除后,申请的实体化PV存储空间也会被回收。
挂载目录。ConfigMap 挂载配置文件。 这里是 是 静态的, 就是自己创建好了 容量,然后 PVC 去挑。 还有 动态供应的,不用手动去创建 PV池子
在这里插入图片描述

3)、创建PV
1、创建 PV 池

静态供应

# 在 nfs主节点(master服务器) 执行
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03

使用pv.yaml 创建 3个 PV

vi pv.yaml

#下面有三个ip,需要改成你的master节点ip
apiVersion: v1
kind: PersistentVolume
metadata:
# 这个name 要小写,如 Gi 大写就不行
  name: pv01-10m
spec:
  # 限制容量必须是大写
  capacity:
    storage: 10M
  # 读写模式:可读可写
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    # 挂载 上面创建过的文件夹
    path: /nfs/data/01
    # nfs 主节点服务器的 IP
    server: 192.168.10.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
  # 这个name 要小写,如 Gi 大写就不行
  name: pv02-1gi
spec:
  capacity:
    # 限制容量必须是大写
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/02
    # nfs 主节点服务器的 IP
    server: 192.168.10.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
# 这个name 要小写,如 Gi 大写就不行
  name: pv03-3gi
spec:
  capacity:
    # 限制容量必须是大写
    storage: 3Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/03
    # nfs 主节点服务器的 IP
    server: 192.168.10.100
kubectl apply -f pv.yaml
#获取资源,看看系统有多少种资源
kubectl get persistentvolume
#或者使用
kubectl get pv

可以看到10M、1G、3G的资源池
在这里插入图片描述

4)、PVC创建与绑定

相当于创建设用pv的申请书

vi pvc.yaml

#直接拷贝使用
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      # 需要 200M的 PV
      storage: 200Mi
  # 上面 pv.yaml中storageClassName写的什么 这里就写什么
  #这个storageClassName相当于是一个分组,上面nfs下有三个不同大小存储空间,下面使用
  #nfs,就会去pv找nfs的分组,在nfs分组下找一个合适它的存储空间,这里申请的是200兆,所以就会申请1G的空间
  storageClassName: nfs

使用命令

kubectl get pv

这个STATUS状态为Available的。表示这个pv没有人使用,可以使用
在这里插入图片描述

kubectl apply -f pvc.yaml

再次使用命令,查看pv

kubectl get pv

可以看到,这个1G的空间,状态已经变为Bound,这个空间被default/nginx-pvc使用了(默认名称空间下的nginx-pvc);10M 不够,3G太大,就选择了 1G;;如果删除这个pvc再重新应用,1G的还处在释放中,这个时候会去绑定3G的空间
在这里插入图片描述

5)、创建 Pod 绑定 PVC
vi pod-banding-pvc.yaml

#直接拷贝使用
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-pvc
  name: nginx-deploy-pvc
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy-pvc
  template:
    metadata:
      labels:
        app: nginx-deploy-pvc
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          # 之前是 nfs,这里用 pvc,就是前面申请的pvc空间名称
          persistentVolumeClaim:
            claimName: nginx-pvc
kubectl get pod

两个nginx的pod创建好了
在这里插入图片描述
查看pvc的绑定关系

kubectl get pvc

在这里插入图片描述
查看pvc和pv

kubectl get pvc,pv

在这里插入图片描述
到这里就看到,目录挂载成功了,后面如果要修改pod被挂载的目录内容,就可以直接在外面的/nfs/data/02目录修改就可以了

6)、使用ConfigMap配置集部署redis测试pvc挂载
1、准备ConfigMap ★

ConfigMap:抽取应用配置,并且可以自动更新。挂载配置文件, PV 和 PVC 是挂载目录的。
在这里插入图片描述

vi redis.conf
# 写
appendonly yes

# 创建配置,redis保存到k8s的etcd;
#使用kubectl create命令创建一个ConfigMap(配置集),以后专门管理所有的配置
#生成的这个k8s配置集,是在etcd存的
kubectl create cm redis-conf --from-file=redis.conf

# 查看配置集
kubectl get cm

#前面生成的redis.conf可以删除了,因为使用kubectl create命令已经生成了一个k8s可以直接使用的配置集
rm -rf redis.conf

查看生成的这个redis-conf配置集内容

kubectl get cm redis-conf -oyaml

#修改cm配置集
kubectl edit cm redis-conf
apiVersion: v1
# data是所有真正的数据,key:默认是文件名   value:配置文件的内容(appendonly yes 这个值是前面删除的redis.conf文件内容,该文件内容随便写的)
data:
  redis.conf: |
    appendonly yes
kind: ConfigMap
metadata:
  creationTimestamp: "2025-06-12T11:38:25Z"
  name: redis-conf
  namespace: default
  resourceVersion: "392472"
  uid: 4aa3aed8-0600-43c8-a5d6-ad97d62aa632

在这里插入图片描述

2、创建redis的Pod

准备yaml文件

vi redis.yaml

#直接拷贝使用
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    command:
      # 启动命令
      - redis-server
      # 指的是redis容器内部的位置
      - "/redis-master/redis.conf"  
    ports:
    - containerPort: 6379
    volumeMounts:
    - mountPath: /data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        #这个redis-conf就是前面cm生成的配置文件
        name: redis-conf
        items:
        - key: redis.conf
          path: redis.conf
kubectl apply -f redis.yaml

kubectl get pod

在这里插入图片描述

3、在bashboard页面中进入redis容器内部

在这里插入图片描述

4、查看 redis.conf 配置文件 内容,可以i看到,就是最开始创建redis.conf文件时添加的内容

在这里插入图片描述

5、修改cm的Pod内容
kubectl get cm

# 修改配置 里 redis.conf 的内容,在里面随意修改成其它东西
kubectl edit cm redis-conf

在这里插入图片描述
在这里插入图片描述
修改 redis-conf 的 redis.conf 内容,过了一会, 就同步了
在这里插入图片描述

6、测试进入redis容器内部
kubectl exec -it redis -- redis-cli

在这里插入图片描述

方式二:配置动态供应的默认存储类(生产环境使用,master节点执行)

注意:如果你前面使用方式一安装过NFS,需要把NFS清理干净,如果担心有残留,直接重置系统

1、配置动态供应的默认存储类(注意下面两处的ip修改为自己master节点的ip)
vi sc.yaml
## 创建了一个存储类,下面有两个地方的ip需要改成你的master节点IP
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  archiveOnDelete: "true"  ## 删除pv的时候,pv的内容是否要备份

---
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.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nfs-subdir-external-provisioner:v4.0.2
          # resources:
          #    limits:
          #      cpu: 10m
          #    requests:
          #      cpu: 10m
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 139.198.171.181 ## 指定自己nfs服务器地址
            - name: NFS_PATH  
              value: /nfs/data  ## nfs服务器共享的目录
      volumes:
        - name: nfs-client-root
          nfs:
            server: 139.198.171.181
            path: /nfs/data
---
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
2、应用sc.yaml
kubectl apply -f sc.yaml
3、使用命令查看默认存储类
kubectl get storageclass

就可以看到有一个默认的nfs-storage存储类,这个存储类的作用就是使用nfs进行存储,以后写的申请书可以动态的创建空间(也叫动态供应),方式一是需要自己先创建好空间比如方式一中01,02,03三个空间,这叫静态空间
在这里插入图片描述

4、测试动态供应空间
kubectl get pod -A

需要这个default名称空间的状态是Running
在这里插入图片描述

vi pvc.yaml

#直接拷贝使用
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      # 需要 200M的 PV
      storage: 200Mi
  #方式一中是有这段配置的,那是因为我这边是先安装的kubesphere,
  #它默认存储类不是nfs,所以需要这段配置来指定存储类,这个配置也可以加上,
  #只是value值就应该上面sc.yaml中指定的name名字nfs-storage(metadata:name: nfs-storage)
  storageClassName: nfs-storage
kubectl apply -f pvc.yaml

kubectl get pvc

kubectl get pv

可以看到,这里直接就创建了一个200M的空间,并且是绑定状态,绑定到nginx-pvc中。到这里nfs就创建好了
在这里插入图片描述

五、安装metrics-server

metrics-server概念:是集群指标监控组件,比如CPU、内存占用率

1、准备metrics-server的yaml文件

vi metrics-server.yaml

#直接拷贝,不需要改任何东西
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-view: "true"
  name: system:aggregated-metrics-reader
rules:
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - nodes
  - nodes/stats
  - namespaces
  - configmaps
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server-auth-reader
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server:system:auth-delegator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:metrics-server
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --kubelet-insecure-tls
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/metrics-server:v0.4.3
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /livez
            port: https
            scheme: HTTPS
          periodSeconds: 10
        name: metrics-server
        ports:
        - containerPort: 4443
          name: https
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /readyz
            port: https
            scheme: HTTPS
          periodSeconds: 10
        securityContext:
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
      nodeSelector:
        kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      serviceAccountName: metrics-server
      volumes:
      - emptyDir: {}
        name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  labels:
    k8s-app: metrics-server
  name: v1beta1.metrics.k8s.io
spec:
  group: metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:
    name: metrics-server
    namespace: kube-system
  version: v1beta1
  versionPriority: 100
kubectl apply -f metrics-server.yaml

kubectl get pod -A

等待这个metrics-server的Pod启动成功
在这里插入图片描述

2、查看所有节点CPU、内容占用率

kubectl top nodes

可以看到master节点cpu已经占用到了86了,这里m的换算率是,1000M差不多是一核
在这里插入图片描述

3、查看某个节点所有的Pod的CPU、内存占用率

kubectl top pods -A

可以看到master节点cpu占用率最高的pod是calico网络插件
在这里插入图片描述

六、使用阿里云私有镜像仓库,docker hub无法访问

1)、创建阿里云镜像仓库地址

控制台选择容器镜像服务
在这里插入图片描述

2)、创建个人版本实例

步骤:【实例列表】 ===》【创建个人实例】 ===》【设置Registry登录密码】
这个Registry登录密码就是后面在服务器使用docker login登录时所需要的密码

3)、创建名称空间

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4)、测试向阿里云镜像仓库推送镜像

创建完镜像仓库以后有仓库列表,点击刚刚创建的仓库,进入后在基本信息可以看到相关docker命令
在这里插入图片描述
在这里插入图片描述

5)、查找私有镜像仓库的凭证,用于在k8s中生成密钥

在这里插入图片描述

6)、在私有仓库拉取镜像

1、使用kubectl命令创建私有仓库的密钥

前面有介绍怎么找阿里云镜像仓库用户名以及地址

kubectl create secret docker-registry regcred \
  --docker-server=<你的镜像仓库服务器> \
  --docker-username=<你的用户名> \
  --docker-password=<你的密码> \
  --docker-email=<你的邮箱地址>

<secret-name>:自己定义的secret名字,也就是前面创建的镜像仓库名称

<your-registry>:阿里云镜像仓库地址

<your-username>:阿里云镜像仓库用户名

<your-password>:阿里云镜像仓库密码

<your-email>:邮箱
在这里插入图片描述

2、测试拉取阿里云仓库镜像

docker pull <阿里云镜像仓库地址>

在这里插入图片描述

七、安装语言环境Helm

1)、去除主节点的污点 kubectl describe node <你的hostname名字>;污点:【污点,就是不让master可以部署。去掉后就可以部署了】

kubectl describe node k8s-node1 | grep Taint

#去掉 master 节点的 Taint
kubectl taint nodes k8s-node1 node-role.kubernetes.io/master:NoSchedule-

2)、Helm安装

mkdir /root/k8s/helmv3.8.2/
cd /root/k8s/helmv3.8.2/

#下载Helm的压缩包文件
wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz

# 解压
tar -zxvf helm-v3.8.2-linux-amd64.tar.gz

# 将 helm 二进制文件移动到 PATH 目录
mv linux-amd64/helm /usr/local/bin/

# 验证版本
helm version --short
# 输出应为: v3.8.2+g5ab6a61

yum install -y socat 

3)、添加国内镜像源仓库

helm repo add kubesphere https://charts.kubesphere.io/main
#等待一会输出  "kubesphere" has been added to your repositories

在这里插入图片描述
更新仓库

helm repo update

#验证仓库中有哪些ks-core的版本
helm search repo kubesphere/ks-core --versions

#查看helm中所有kubesphere的版本
helm search repo kubesphere --versions | grep -E "kubesphere|ks-core"

在这里插入图片描述

4)、我看很多文档上Helm服务是3.X版本的,还在安装Tiller,Helm3.X已经不需要安装Tiller了。Helm 3 与 Helm 2 相比有较大的架构变化,Helm 3 将 Tiller 移除了。在 Helm 2 中,Tiller 是服务端组件,负责在 Kubernetes 集群中安装、升级、删除等操作,但由于 Tiller 存在一些安全风险和架构上的限制,Helm 3 采用了更简单的架构,将相关功能集成到了 Helm 客户端中,直接与 Kubernetes API 服务器进行交互,从而不再需要 Tiller 组件。所以在你基于当前环境安装 Helm 3 并准备安装 KubeSphere 时,无需考虑 Tiller 的安装及版本问题

5)、看到还有很多文档上还使用Tiller去分配权限,上面已经说了,3.X版本及以上不再使用Tiller,kubelet的上下文中已经有了用户,~/.kube/config 文件的具体位置是用户主目录下的 .kube 目录中的 config 文件。

其中 ~ 代表用户主目录,对于大多数 Linux 系统,如果以 root 用户登录,其主目录是 /root,那么 ~/.kube/config 实际路径就是 /root/.kube/config;如果是普通用户(例如 user1),其主目录是 /home/user1,则 ~/.kube/config 实际路径为 /home/user1/.kube/config 。
在这里插入图片描述
如果你想给kubernetes-admin分配具体权限。使用现有管理员用户(如 kubernetes-admin),如果你已经有一个具有 cluster-admin 权限的用户(如 kubernetes-admin),可以直接使用它,无需额外配置

#检查当前上下文,确保输出为 kubernetes-admin@kubernetes 或类似的管理员上下文
kubectl config current-context

#直接使用 Helm 3,需要先创建my-chart目录
helm install my-release my-chart/

命令解释:在 Helm 命令中,install my-release my-chart/ 是执行安装 Helm Chart 的核心操作,具体含义如下:
参数解析
install
Helm 的子命令,用于将一个 Chart 部署到 Kubernetes 集群中。
my-release
Release 名称:Helm 为每个部署的 Chart 实例分配的唯一标识符。
用途:
区分同一 Chart 的不同部署(例如,开发环境和生产环境可能使用相同的 Chart,但需要不同的 Release 名称)。
通过 helm upgrade 或 helm uninstall 操作
示例

helm install dev-mysql stable/mysql  # 开发环境的 MySQL 实例
helm install prod-mysql stable/mysql  # 生产环境的 MySQL 实例

my-chart/
Chart 路径:指向本地文件系统中的 Chart 目录。
要求:
目录必须包含有效的 Chart 结构(如 Chart.yaml、values.yaml、templates/ 目录等)。
可以是相对路径或绝对路径。

八、通过kubectl命令安装OpenEBS存储类

1)、创建新的名称空间

#在kubelet中创建新的名称空间
kubectl create ns openebs
#查看所有的名称空间
kubectl get ns
mkdir /root/k8s/openebs/

cd /root/k8s/openebs/

#下载yaml配置文件
wget  https://openebs.github.io/charts/openebs-operator.yaml

kubectl apply -f openebs-operator.yaml

在这里插入图片描述

2)、检查 OpenEBS 组件状态、验证存储类

#检查 OpenEBS 组件状态
kubectl get pods -n openebs

在这里插入图片描述
需要等待一会,等它容器创建好

#验证存储类
kubectl get sc

在这里插入图片描述
openebs-hostpath:使用节点本地目录作为存储(适合测试环境)
openebs-device:使用裸磁盘作为存储(性能更高)

3)、设置默认的StorageClass

#将openebs-hostpath设置为默认的StorageClass
kubectl patch storageclass openebs-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

#输出应为  storageclass.storage.k8s.io/openebs-hostpath patched

在这里插入图片描述

#再次使用命令查看,openebs-hostpath变成默认存储
kubectl get sc

在这里插入图片描述

4)、到这里,差不多已经完成了,前面我们把master节点污点去掉了,现在要把master污点加上,避免其他节点资源跟它抢占

kubectl taint nodes k8s-node1 node-role.kubernetes.io=master:NoSchedule

#应为输出 node/k8s-node1 tainted

前置环境已经安装好了

九、NFS和OpenEBS存储类对比,以及这两个存储类的应用场景

在这里插入图片描述

1)、NFS

1、NFS特点

跨节点共享文件,通俗讲:可以把NFS比作共享网盘,所有节点访问同一个存储空间

2、类型

网络文件系统(共享存储)

3、部署位置

独立服务器(物理机/虚拟机)

4、数据访问协议

文件级(POSIX 接口)

2)、OpenEBS

1、OpenEBS特点

为容器提供持久化、可移植的存储;通俗讲:OpenEBS更像给每个Pod分配专属移动硬盘

2、类型

Kubernetes 原生的容器附加存储 (CAS)

3、部署位置

直接运行在 Kubernetes 集群节点上

4、数据访问协议

块级(iSCSI)或文件级(ZFS/NFS Provisioner)

3)、架构对比

在这里插入图片描述
在这里插入图片描述

4)、关键特性对比

在这里插入图片描述

5)、典型使用场景

1、NFS使用场景

  • 共享配置文件、静态资源(如图片/视频)

  • 开发测试环境

  • 需要跨节点共享读写的应用(如 CI/CD 工件仓库)

2、OpenEBS使用场景

  • 数据库类应用(MySQL, PostgreSQL, Redis)

    • 因块存储提供更低延迟和更高 IOPS
  • 有状态服务的多副本部署

    • 如 Kafka、Elasticsearch(利用 cStor 跨节点复制)
  • 对存储性能敏感的云原生应用

  • 避免云厂商锁定的场景(跨公有云/混合云部署)

在这里插入图片描述

6)、性能对比(示例)

在这里插入图片描述

7)、运维对比

在这里插入图片描述

8)、如何选择?

选择 NFS 当:

  • 已有 NFS 基础设施

  • 需要低成本共享存储

  • 应用只需文件级存储(如 Web 静态资源)

选择 OpenEBS 当:

  • 运行数据库或有状态服务

  • 追求 Kubernetes 原生存储体验

  • 需要低延迟本地磁盘性能(LocalPV)

  • 避免云厂商托管存储(如 EBS/Azure Disk)的锁定

9)、 互补使用方案

在这里插入图片描述

总结

在这里插入图片描述

九、安装kubesphere图形化工具(master节点执行)

更多详细操作可以参考下面的官方链接:
https://kubesphere.io/zh/docs/v4.1/03-installation-and-upgrade/02-install-kubesphere/05-appendix/

安装kubesphere方式一

0)、安装kubesphere前置条件

参考目录一、二、三、四目录操作一次,操作完,前置环境就准备好了

1)、最小化安装kubesphere,也就是仅安装ks-core

vi heml-install-kubesphere.yaml

# ============== 1. CRD 自动安装配置 ==============
crds:
  enabled: true  # Helm 自动安装 CRD

# ============== 2. 国内镜像源替换 ==============
images:
  # KubeSphere 核心组件镜像(阿里云镜像源)
  ks_installer:
    repository: registry.cn-beijing.aliyuncs.com/kubesphere/ks-installer
    tag: v3.3.0
    pullPolicy: IfNotPresent

  # 其他依赖组件镜像(按需替换)
  kubesphere:
    repository: registry.cn-beijing.aliyuncs.com/kubesphere
    tag: v3.3.0
  etcd:
    repository: registry.cn-hangzhou.aliyuncs.com/google_containers/etcd
    tag: v3.4.13
  mysql:
    repository: registry.cn-hangzhou.aliyuncs.com/kubesphere/mysql
    tag: 5.7

# ============== 3. KubeSphere 核心配置 ==============
configuration:
  # 持久化存储配置
  persistence:
    storageClass: ""  # 填写你的 StorageClass 名称(如 "nfs-storage")

  # ETCD 配置
  etcd:
    monitoring: false
    endpointIps: "192.168.10.100,192.168.10.101,192.168.10.102"  # 替换为你的 ETCD 节点 IP
    port: 2379
    tlsEnable: true

  # 基础组件资源配置
  common:
    mysqlVolumeSize: 20Gi
    minioVolumeSize: 20Gi
    etcdVolumeSize: 20Gi
    redisVolumSize: 2Gi

  # 监控组件配置
  monitoring:
    prometheusReplicas: 1
    prometheusMemoryRequest: 400Mi
    prometheusVolumeSize: 20Gi
    grafana:
      enabled: true  # 禁用 Grafana(国内镜像可自行开启)

  # 日志组件配置
  logging:
    enabled: false  # 禁用 ELK(国内镜像可自行开启)
    elasticsearchMasterReplicas: 1
    elasticsearchDataReplicas: 1
    logsidecarReplicas: 2
    elasticsearchMasterVolumeSize: 4Gi
    elasticsearchDataVolumeSize: 20Gi

  # DevOps 配置
  devops:
    enabled: true #这个必须要开启,因为devops已经内嵌了jekins以及整合了jekins的CI/CD流水线发布功能
    jenkinsMemoryLim: 2Gi
    jenkinsMemoryReq: 1000Mi
    jenkinsJavaOpts_Xms: 512m
    jenkinsJavaOpts_Xmx: 512m
    jenkinsJavaOpts_MaxRAM: 2g
    jenkinsVolumeSize: 8Gi
    sonarqube:
      enabled: true
      postgresqlVolumeSize: 8Gi


  # 其他功能开关
  servicemesh:
    enabled: false
  notification:
    enabled: true
  alerting:
    enabled: true

# ============== 4. 网络配置(按需修改) ==============
network:
  kubePodsCIDR: "10.233.64.0/18"
  kubeServiceCIDR: "10.233.0.0/18"

2)、如果你电脑之前安装过kubesphere,但是安装失败了,换成Helm安装kubesphere,要先删除kubelet-system命名空间

kubectl delete ns kubesphere-system
#多删除几次,直到输出No resources found

3)、创建命名空间,开始安装kubesphere

#再创建命名空间
kubectl create ns kubesphere-system

#开始下载CRD以及安装kubesphere
helm install kubesphere kubesphere/ks-core   --namespace kubesphere-system   --create-namespace   --values heml-install-kubesphere.yaml   --replace

出现下面这地址,就表示安装成功了

Please be patient and wait for several seconds for the KubeSphere deployment to complete.

1. Wait for Deployment Completion

    Confirm that all KubeSphere components are running by executing the following command:

    kubectl get pods -n kubesphere-system
2. Access the KubeSphere Console

    Once the deployment is complete, you can access the KubeSphere console using the following URL:  

    http://192.168.10.100:30880

3. Login to KubeSphere Console

    Use the following credentials to log in:

    Account: admin
    Password: P@88w0rd

在这里插入图片描述

如果出现上面地址,在浏览器访问失败,不要慌,看看组件运行状态,可能是组件还没完全运行起来

#查看组件运行状态
kubectl get pods -n kubesphere-system -w

在这里插入图片描述
或者使用命令查看kubesphere的安装日志

kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f

我这边全都运行起来了,再去访问一下浏览器,输入控制台答应的账号密码后
账号:admin
密码:P@88w0rd
在这里插入图片描述

要查看集群节点,需要点host才会进入所有节点页面,以及其它配置项

新版kubesphere和旧版本2.Xkubesphere控制台页面差别还是挺大的,下面展示一下旧版的控制台页面,旧版本中,如果需要重新选装一些组件,需要在ks-installer中去选择开启的组件。而新版中,有两种方式,一种使用命令行,下面有介绍;另外一种则是通过控制台页面,左上角的扩展市场去选择安装什么组件
在这里插入图片描述

4)、如果想查看Jenkins账号密码(kubesphere将Jenkins内嵌了)

4-1)、获取jekins的账号密码
kubectl -n kubesphere-devops-system get secret devops-jenkins -o yaml

#输出中,可以看到账号和密码都用base64加密了
#data:
#  jenkins-admin-password: d0lUQ0JUMlNaQ1JObVNRSFFLMm9iOQ==
#  jenkins-admin-token: MTE3OTczMzk2MzMxODkzNzk2MTUzMDg2MjI4MjU2NjIzNQ==
#  jenkins-admin-user: YWRtaW4=
#kind: Secret
#metadata:
#  annotations:
#    meta.helm.sh/release-name: devops
#    meta.helm.sh/release-namespace: kubesphere-devops-system
#  creationTimestamp: "2025-05-26T12:45:06Z"
#  labels:
#    app.kubernetes.io/instance: devops
#    app.kubernetes.io/managed-by: Helm
#    app.kubernetes.io/name: devops-extension
#    app.kubernetes.io/version: v4.1.3
#    devops.kubesphere.io/component: Jenkins
#    helm.sh/chart: extension-1.1.3
#    heritage: Helm
#    kubesphere.io/extension-ref: devops
#  name: devops-jenkins
#  namespace: kubesphere-devops-system
#  resourceVersion: "220082"
#  uid: 4f9fa29a-d6f9-421e-9b9c-462b2bf34dbc
#type: Opaque

在这里插入图片描述

4-2)、将使用base64加密后的账号密码解密
JENKINS_ADMIN_USER=$(kubectl get secret devops-jenkins -n kubesphere-devops-system -o jsonpath="{.data.jenkins-admin-user}" | base64 -d)
JENKINS_ADMIN_PASSWORD=$(kubectl get secret devops-jenkins -n kubesphere-devops-system -o jsonpath="{.data.jenkins-admin-password}" | base64 -d)
echo "用户名: $JENKINS_ADMIN_USER,密码: $JENKINS_ADMIN_PASSWORD"

#输出   用户名: admin,密码: wITCBT2SZCRNmSQHQK2ob9

在这里插入图片描述

安装kubesphere方式二(这个安装方式是完整版的kubesphere,开启所有的功能组件)

硬件要求:
在这里插入图片描述

0)、安装kubesphere前置条件

参考目录一、二、三、四目录操作一次,操作完,前置环境就准备好了

1)、下载kubesphere-installer和cluster-configuration

wget https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/kubesphere-installer.yaml

wget https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/cluster-configuration.yaml

在这里插入图片描述
如果下载不下来,可以从我的网盘中下载,里面的cluster-configuration.yaml是已经修改好了的,你们使用只需要修改etcd监控指标这一项中有个IP,修改成你们master节点IP就可以了,然后直接使用命令安装kubesphere
kubectl apply -f kubesphere-installer-v3.1.1.yaml
kubectl apply -f cluster-configuration-v3.1.1.yaml将这两个yaml文件进行安装部署,第二步就可以跳过了
通过网盘分享的文件:3.X版本kubesphere安装所需的yaml文件
链接: https://pan.baidu.com/s/1EoDTSNSEpuZfVwGkK0Fgog?pwd=bgt3
提取码: bgt3

2)、修改集群配置文件的cluster-configuration.yaml

在 cluster-configuration.yaml中指定我们需要开启的功能,参照官网“启用可插拔组件”
https://kubesphere.io/zh/docs/v3.4/pluggable-components/

vim cluster-configuration.yaml
#开启etcd监控指标、redis等功能;需要开启的功能都用红框标注,开启etcd的监控指标,下面还有个IP配置,这个要配置你的master节点IP

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后退出并保存

3)、开始安装kubesphere-installer.yaml和cluster-configuration

#先安装kubesphere-installer.yaml
kubectl apply -f kubesphere-installer.yaml
#安装集群配置
kubectl apply -f cluster-configuration.yaml

4)、检查安装日志

kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f

在这里插入图片描述
打印出这个表示已经安装好了,直接浏览器输入打印的ip地址,然后输入账号密码就可以访问kubesphere控制台页面了。30880端口不需要再配置防火墙了,因为前面在云服务配置中已经配置了一个端口区间,使用任意机器的ip:30880就可以访问kubesphere控制台页面。
账号:admin
密码:P@88w0rd

如果发现过去很久,还有很多Pod状态不是Running的,需要查看一下,是不是出问题了

kubectl describe pod -n <名称空间> <Podname>
kubectl describe pod -n kubesphere-monitoring-system alertmanager-main-1

只要是pulling images就表示没问题,正在下载镜像

5)、解决etcd监控证书找不到问题

前面在集群配置的yaml文件中开启了etcd指标监控,这是需要etcd的证书,报错信息如下

kubectl describe pod -n kubesphere-monitoring-system prometheus-k8s-0

报错信息如下:

kube-etcd-client-certs not found

在这里插入图片描述
解决方案执行以下命令:

kubectl -n kubesphere-monitoring-system create secret generic kube-etcd-client-certs  --from-file=etcd-client-ca.crt=/etc/kubernetes/pki/etcd/ca.crt  --from-file=etcd-client.crt=/etc/kubernetes/pki/apiserver-etcd-client.crt  --from-file=etcd-client.key=/etc/kubernetes/pki/apiserver-etcd-client.key

在这里插入图片描述
然后继续等待,大概5分钟左右,所有的pod全部都是Running状态了

单节点使用kubekey一站式安装k8s、kubesphere,方式三

注意,这个是没有安装前置条件,这个方式三是在一台机器上部署所有东西docker、kubernetes、kubesphere

0)、这种安装方式除了修改hostname外(当然你要是不想改也行),就没有前置条件前置条件,kk会自动安装一系列所有的东西,包括docker、k8s、kubesphere

1)、硬件要求

Centos7:2核CPU,4GB内存,40GB磁盘空间
在这里插入图片描述

2)、准备kubekey

export KKZONE=cn

curl -sfL https://get-kk.kubesphere.io | VERSION=v1.1.1 sh -

在这里插入图片描述
这个绿色的kk就是可执行文件

#修改kk的权限,如果kk是绿色的,可以不用执行这个命令
chmod +x kk

3)、使用kubekey引导安装docker、k8s、kubesphere

系统非常纯净,连docker都没有安装的情况下,kubekey会将docker、k8s、kubesphere一起安装。安装顺序是先安装docker-->k8s----->kubesphere

yum install -y conntrack
./kk create cluster --with-kubernetes v1.20.4 --with-kubesphere v3.1.1

在这里插入图片描述
正在安装中,可以在开一个窗口,看看安装情况

kubectl get pod -A

可以看到pod正在创建中
在这里插入图片描述
大概十几分钟后,控制台就打印出这个,已经安装好了
在这里插入图片描述
确认所有的pod都是运行中状态,就可以通过浏览器访问kubesphere控制台。通过这种kk方式部署的,发现会很少东西,kk安装方式默认就是最小化安装的
账号:admin
密码:P@88w0rd

4)、安装后开启某些功能

在这里插入图片描述
1.在kubesphere控制台页面,找到自定义资源,搜索clusterconfiguration
在这里插入图片描述
点击这个clusterconfiguration
2.编辑这个clusterconfiguration文件
在这里插入图片描述
3.想要开启什么功能,可以将这个false改成true
在这里插入图片描述

集群部署使用kubekey一站式安装k8s、kubesphere,方式四

注意:这种方式也是没有前置条件的,方式四安装是多节点的,针对k8s集群的简单安装方式

1)、准备kubekey

export KKZONE=cn

curl -sfL https://get-kk.kubesphere.io | VERSION=v1.1.1 sh -

在这里插入图片描述
这个绿色的kk就是可执行文件

#修改kk的权限,如果kk是绿色的,可以不用执行这个命令
chmod +x kk

2)、创建集群

./kk create config --with-kubernetes v1.20.4 --with-kubesphere v3.1.1

在这里插入图片描述

3)、编辑下载的config-sample.yaml文件

vim config-sample.yaml

注意,需要修改的就只有这两个框的内容,第一个框:你有多少个节点,填多少个,有四个或者更多,就继续复制- {name}然后修改ip。第二个地方就是哪个节点是etcd、master,如果想做多主多从,master:这个配置继续复制粘贴就好了,哪几个节点当woker从节点,就配置对应的hostname,继续往下看会有ClusterConfiguration,这个是集群配置,想开启什么功能,就将false改为true,机器配置不高,可以不用开启其它配置了。然后退出并且保存
在这里插入图片描述
下面给出yaml文件的全部内容

vim config-sample.yaml


apiVersion: kubekey.kubesphere.io/v1alpha1
kind: Cluster
metadata:
  name: sample
spec:
  hosts:
  - {name: k8s-node1, address: 192.168.10.100, internalAddress: 192.168.10.100, user: root, password: root}
  - {name: k8s-node2, address: 192.168.10.101, internalAddress: 192.168.10.101, user: root, password: root}
  - {name: k8s-node3, address: 192.168.10.102, internalAddress: 192.168.10.102, user: root, password: root}
  roleGroups:
    etcd:
    - k8s-node1
    master: 
    - k8s-node1
    worker:
    - k8s-node2
    - k8s-node3
  controlPlaneEndpoint:
    domain: lb.kubesphere.local
    address: ""
    port: 6443
  kubernetes:
    version: v1.20.4
    imageRepo: kubesphere
    clusterName: cluster.local
  network:
    plugin: calico
    kubePodsCIDR: 10.233.64.0/18
    kubeServiceCIDR: 10.233.0.0/18
  registry:
    registryMirrors: []
    insecureRegistries: []
  addons: []


---
apiVersion: installer.kubesphere.io/v1alpha1
kind: ClusterConfiguration
metadata:
  name: ks-installer
  namespace: kubesphere-system
  labels:
    version: v3.1.1
spec:
  persistence:
    storageClass: ""       
  authentication:
    jwtSecret: ""
  zone: ""
  local_registry: ""        
  etcd:
    monitoring: false      
    endpointIps: localhost  
    port: 2379             
    tlsEnable: true
  common:
    redis:
      enabled: false
    redisVolumSize: 2Gi 
    openldap:
      enabled: false
    openldapVolumeSize: 2Gi  
    minioVolumeSize: 20Gi
    monitoring:
      endpoint: http://prometheus-operated.kubesphere-monitoring-system.svc:9090
    es:  
      elasticsearchMasterVolumeSize: 4Gi   
      elasticsearchDataVolumeSize: 20Gi   
      logMaxAge: 7          
      elkPrefix: logstash
      basicAuth:
        enabled: false
        username: ""
        password: ""
      externalElasticsearchUrl: ""
      externalElasticsearchPort: ""  
  console:
    enableMultiLogin: true 
    port: 30880
  alerting:       
    enabled: false
    # thanosruler:
    #   replicas: 1
    #   resources: {}
  auditing:    
    enabled: false
  devops:           
    enabled: false
    jenkinsMemoryLim: 2Gi     
    jenkinsMemoryReq: 1500Mi 
    jenkinsVolumeSize: 8Gi   
    jenkinsJavaOpts_Xms: 512m  
    jenkinsJavaOpts_Xmx: 512m
    jenkinsJavaOpts_MaxRAM: 2g
  events:          
    enabled: false
    ruler:
      enabled: true
      replicas: 2
  logging:         
    enabled: false
    logsidecar:
      enabled: true
      replicas: 2
  metrics_server:             
    enabled: false
  monitoring:
    storageClass: ""
    prometheusMemoryRequest: 400Mi  
    prometheusVolumeSize: 20Gi  
  multicluster:
    clusterRole: none 
  network:
    networkpolicy:
      enabled: false
    ippool:
      type: none
    topology:
      type: none
  openpitrix:
    store:
      enabled: false
  servicemesh:    
    enabled: false  
  kubeedge:
    enabled: false
    cloudCore:
      nodeSelector: {"node-role.kubernetes.io/worker": ""}
      tolerations: []
      cloudhubPort: "10000"
      cloudhubQuicPort: "10001"
      cloudhubHttpsPort: "10002"
      cloudstreamPort: "10003"
      tunnelPort: "10004"
      cloudHub:
        advertiseAddress: 
          - ""           
        nodeLimit: "100"
      service:
        cloudhubNodePort: "30000"
        cloudhubQuicNodePort: "30001"
        cloudhubHttpsNodePort: "30002"
        cloudstreamNodePort: "30003"
        tunnelNodePort: "30004"
    edgeWatcher:
      nodeSelector: {"node-role.kubernetes.io/worker": ""}
      tolerations: []
      edgeWatcherAgent:
        nodeSelector: {"node-role.kubernetes.io/worker": ""}
        tolerations: []

4)、使用kubekey引导安装集群

系统非常纯净,连docker都没有安装的情况下,kubekey会将docker、k8s、kubesphere一起安装。安装顺序是先安装docker-->k8s----->kubesphere

#所有节点都要执行
yum install -y conntrack
#kk使用配置文件安装docker、k8s、kubesphere
./kk create cluster -f config-sample.yaml

出现这个表示安装完成
在这里插入图片描述
注意:要等待所有的pod都是运行中状态

kubectl get pod -A

5)、验证安装

1、云服务的组内互相通信要打开

在这里插入图片描述

2、将k8s的区间端口暴露

在这里插入图片描述
在这里插入图片描述

3、访问任意节点IP:30880,进入kubesphere控制台页面

在这里插入图片描述
账号:admin
密码:P@88w0rd

十、kubesphere多租户

1)、多租户角色关系介绍图

在这里插入图片描述

2)、创建用户管理员账号

1、进入访问控制

在这里插入图片描述

十一、Ingress安装

1)、Ingress的概念

Ingress概念(统一网关入口):Service的统一网关入口;而service是统一管理所有的pod,例如,将三台机器上的nginx交由service统一管理,当nginx扩容或者缩容IP地址发生变化这样就不需要去修改前端地址,因为service是统一管理所有的80端口。ingress底层其实就是一个nginx

在这里插入图片描述

2)、下载Ingress的yaml文件

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
# 修改镜像地址
vi deploy.yaml

#将images-的值改为如下值:
registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0

#检查安装的结果
kubectl get pod,svc -n ingress-nginx
#最后别忘记把svc暴露的端口要放行

如果通过wget下载不到yaml文件,也可以直接使用下面的yaml文件无需修改直接拷贝使用

vi ingress-deploy.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx

---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx
  namespace: ingress-nginx
automountServiceAccountToken: true
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
  name: ingress-nginx
rules:
  - apiGroups:
      - ''
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ''
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io   # k8s 1.14+
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - extensions
      - networking.k8s.io   # k8s 1.14+
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - networking.k8s.io   # k8s 1.14+
    resources:
      - ingressclasses
    verbs:
      - get
      - list
      - watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
  name: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx
subjects:
  - kind: ServiceAccount
    name: ingress-nginx
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx
  namespace: ingress-nginx
rules:
  - apiGroups:
      - ''
    resources:
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ''
    resources:
      - configmaps
      - pods
      - secrets
      - endpoints
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io   # k8s 1.14+
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io   # k8s 1.14+
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - networking.k8s.io   # k8s 1.14+
    resources:
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - configmaps
    resourceNames:
      - ingress-controller-leader-nginx
    verbs:
      - get
      - update
  - apiGroups:
      - ''
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ''
    resources:
      - events
    verbs:
      - create
      - patch
---
# Source: ingress-nginx/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx
subjects:
  - kind: ServiceAccount
    name: ingress-nginx
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller-admission
  namespace: ingress-nginx
spec:
  type: ClusterIP
  ports:
    - name: https-webhook
      port: 443
      targetPort: webhook
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/component: controller
  revisionHistoryLimit: 10
  minReadySeconds: 0
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/component: controller
    spec:
      dnsPolicy: ClusterFirst
      containers:
        - name: controller
          image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0
          imagePullPolicy: IfNotPresent
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown
          args:
            - /nginx-ingress-controller
            - --election-id=ingress-controller-leader
            - --ingress-class=nginx
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
            - --validating-webhook=:8443
            - --validating-webhook-certificate=/usr/local/certificates/cert
            - --validating-webhook-key=/usr/local/certificates/key
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            runAsUser: 101
            allowPrivilegeEscalation: true
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: LD_PRELOAD
              value: /usr/local/lib/libmimalloc.so
          livenessProbe:
            failureThreshold: 5
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
            - name: webhook
              containerPort: 8443
              protocol: TCP
          volumeMounts:
            - name: webhook-cert
              mountPath: /usr/local/certificates/
              readOnly: true
          resources:
            requests:
              cpu: 100m
              memory: 90Mi
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
        - name: webhook-cert
          secret:
            secretName: ingress-nginx-admission
---
# Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
# before changing this value, check the required kubernetes version
# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  name: ingress-nginx-admission
webhooks:
  - name: validate.nginx.ingress.kubernetes.io
    matchPolicy: Equivalent
    rules:
      - apiGroups:
          - networking.k8s.io
        apiVersions:
          - v1beta1
        operations:
          - CREATE
          - UPDATE
        resources:
          - ingresses
    failurePolicy: Fail
    sideEffects: None
    admissionReviewVersions:
      - v1
      - v1beta1
    clientConfig:
      service:
        namespace: ingress-nginx
        name: ingress-nginx-controller-admission
        path: /networking/v1beta1/ingresses
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress-nginx-admission
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-nginx-admission
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
rules:
  - apiGroups:
      - admissionregistration.k8s.io
    resources:
      - validatingwebhookconfigurations
    verbs:
      - get
      - update
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ingress-nginx-admission
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx-admission
subjects:
  - kind: ServiceAccount
    name: ingress-nginx-admission
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ingress-nginx-admission
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  namespace: ingress-nginx
rules:
  - apiGroups:
      - ''
    resources:
      - secrets
    verbs:
      - get
      - create
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ingress-nginx-admission
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx-admission
subjects:
  - kind: ServiceAccount
    name: ingress-nginx-admission
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: ingress-nginx-admission-create
  annotations:
    helm.sh/hook: pre-install,pre-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  namespace: ingress-nginx
spec:
  template:
    metadata:
      name: ingress-nginx-admission-create
      labels:
        helm.sh/chart: ingress-nginx-3.33.0
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/version: 0.47.0
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/component: admission-webhook
    spec:
      containers:
        - name: create
          image: docker.io/jettech/kube-webhook-certgen:v1.5.1
          imagePullPolicy: IfNotPresent
          args:
            - create
            - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
            - --namespace=$(POD_NAMESPACE)
            - --secret-name=ingress-nginx-admission
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
      restartPolicy: OnFailure
      serviceAccountName: ingress-nginx-admission
      securityContext:
        runAsNonRoot: true
        runAsUser: 2000
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: ingress-nginx-admission-patch
  annotations:
    helm.sh/hook: post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-3.33.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.47.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  namespace: ingress-nginx
spec:
  template:
    metadata:
      name: ingress-nginx-admission-patch
      labels:
        helm.sh/chart: ingress-nginx-3.33.0
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/version: 0.47.0
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/component: admission-webhook
    spec:
      containers:
        - name: patch
          image: docker.io/jettech/kube-webhook-certgen:v1.5.1
          imagePullPolicy: IfNotPresent
          args:
            - patch
            - --webhook-name=ingress-nginx-admission
            - --namespace=$(POD_NAMESPACE)
            - --patch-mutating=false
            - --secret-name=ingress-nginx-admission
            - --patch-failure-policy=Fail
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
      restartPolicy: OnFailure
      serviceAccountName: ingress-nginx-admission
      securityContext:
        runAsNonRoot: true
        runAsUser: 2000

3)、使用kubectl apply 安装ingress

kubectl apply -f ingress-deploy.yaml

在这里插入图片描述

kubectl get svc -A

可以看到,type是NodePort,ingress-nginx暴漏了两个端口,一个30925,一个32299。30925是http请求暴露的端口,32299是https暴露的端口,NodePort会在所有的节点都暴露这两个端口
在这里插入图片描述

4)、准备一个测试文件,测试ingress的转发

在这里插入图片描述

vi test.yaml

#直接拷贝使用
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-server
  template:
    metadata:
      labels:
        app: hello-server
    spec:
      containers:
      - name: hello-server
        image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/hello-server
        ports:
        - containerPort: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - image: nginx
        name: nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
spec:
  selector:
    app: nginx-demo
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: hello-server
  name: hello-server
spec:
  selector:
    app: hello-server
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 9000
kubectl apply -f test.yaml

在这里插入图片描述

kubectl get pods -A

可以看到,创建了两个副本为nginx-demo、hello-server的pod

在这里插入图片描述
直接使用curl测试nginx-demo的service

kubectl get svc -A

输出nginx-demo和hello-server的service
在这里插入图片描述

curl 10.96.157.177:8000

可以看到返回了nginx的首页
在这里插入图片描述

1)、添加路由规则。使用域名请求,通过不同的域名请求由ingress转发到相对应的service,比如hello-server或者nginx-demo

准备一个ingress转发规则的yaml文件

vi ingress-rule.yaml

#直接拷贝使用
apiVersion: networking.k8s.io/v1
kind: Ingress  
metadata:
  #这个name名字随便取,只要跟别的名字不重复就行了
  name: ingress-host-bar
spec:
  ingressClassName: nginx
  rules:
  #- host:表示域名匹配规则,如果是hello.atguigu转发到hello-server
  - host: "hello.atguigu.com"
    http:
      paths:
      #pathType: Prefix  表示前缀模式
      - pathType: Prefix
        #path:以/开始的请求
        path: "/"
        #backend:后台服务
        backend:
          service:
            name: hello-server
            port:
              # hello-server的端口8000
              number: 8000
  - host: "demo.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        # 如果请求的域名是demo.atguigu.com并且是/nginx,
        #则就会把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404,
        #可以在静态资源文件创建一个名为nginx文件,然后在浏览器使用demo.atguigu.com/nginx就会下载下载这个资源文件
        path: "/nginx"  
        backend:
          service:
            name: nginx-demo  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000

应用ingress路由规则

kubectl apply -f ingress-rule.yaml

#如果已经应用了这个yaml文件,后面想要修改yaml文件的内容,可以使用下面命令,如果是文件不在默认名称空间,命令后面要加-n <名称空间>
kubectl edit ing ingress-rule.yaml

在这里插入图片描述

1)、查看ingress有多少路由规则
kubectl get ingress

在这里插入图片描述

2)、在windows的hots文件添加域名映射关系

注意:这里的IP应该是k8s给ingress分配的IP

在这里插入图片描述

3)、在浏览器使用域名访问hello-server

流程:浏览器向k8s的ingress发送http请求,根据ingress路由规则匹配转发到哪个service上
在这里插入图片描述

2)、ingress其它规则:路径重写规则

apiVersion: networking.k8s.io/v1
kind: Ingress  
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: ingress-host-bar
spec:
  ingressClassName: nginx
  rules:
  - host: "hello.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-server
            port:
              number: 8000
  - host: "demo.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        path: "/nginx(/|$)(.*)"  # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
        backend:
          service:
            name: nginx-demo  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000

3)、ingress其它规则:流量限制

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-limit-rate
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "1"
spec:
  ingressClassName: nginx
  rules:
  - host: "haha.atguigu.com"
    http:
      paths:
      - pathType: Exact
        path: "/"
        backend:
          service:
            name: nginx-demo
            port:
              number: 8000

十二、kubesphere部署mysql应用

1、kubesphere添加阿里云私有镜像仓库密钥

私有仓库可以使用阿里云的,也可以使用harbor自己搭建一个私有仓库,因为dockerhub被强了,在kubesphere中直接搜索mysql等镜像,是搜不到的
在这里插入图片描述
在这里插入图片描述
注意:这里添加的阿里云镜像仓库地址,HTTPS://<阿里云镜像仓库地址>/
这个<阿里云镜像仓库地址>是带有名称空间的,要从阿里云的仓库基本信息中有个docker命令----Registry中拉取镜像
取马赛克那部分
在这里插入图片描述

在这里插入图片描述

2、给mysql在配置中心创建配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
key:my.cnf
mysql配置示例

[client]
default-character-set=utf8mb4
 
[mysql]
default-character-set=utf8mb4
 
[mysqld]
init_connect='SET collation_connection = utf8mb4_unicode_ci'
init_connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

在这里插入图片描述

3、给mysql创建pvc挂载

给mysql创建pvc挂载作用是用于存储mysql的数据
在这里插入图片描述
选择单节点读写,一般有状态服务都是选择单节点读写,无状态应用是使用多节点读写;测试使用,内存就给5G
在这里插入图片描述

在这里插入图片描述

4、进入工作负载,开始创建mysql应用

部署应用,要先进入企业空间的某个项目里面
在这里插入图片描述

部署的三个状态解释:

  • 部署:
    • 开发的微服务程序,可以使用这个部署状态,微服务是无状态应用。
  • 有状态副本集:
    • 部署中间件,比如mysql、redis、mq,这种中间件需要有状态应用,它的数据存在别的地方,如果某个中间件器挂了,在别的机器重新拉起了中间件,它的数据应该还是存在的。
  • 守护进程集:
    • 假设集群里面有五台机器,想要做一个日志收集工作,收集每一台机器上的日志,所以需要在每一个机器运行日志收集器。

不管是部署、还是有状态副本集、守护进程集最终都是部署成一个个的pod,运行在容器组中,也就是工作负载下面有个容器组

在这里插入图片描述

在这里插入图片描述
注意:我这里使用的私有镜像仓库,因为dockerhub被墙了,使用dockerbub无法搜索镜像了,前面章节有介绍怎么创建阿里云的私有镜像仓库
在这里插入图片描述
注意:不要配置预留,这个pod预留,那个pod配置预留,最后会导致服务器空间就不够了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
mysql的所有数据都是在这个目录下的/var/lib/mysql,所以要将这个目录的数据挂载出去,挂载到前面创建的pvc中
在这里插入图片描述
在这里插入图片描述
这里配置的my.cnf就是前面创建的mysql配置文件,将mysql内部目录/etc/mysql/conf.d下需要一个cnf的配置文件,将所需要的配置文件使用挂载方式使用外部的my.cnf
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、进入mysql容器内部

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十三、如果后期想要启用某些配置,比如启用monitoring,我第一次安装的时候,那个yaml配置的monitoring是没有开启的,现在要开启它

1)、修改配置后的更新流程,更新 values.yaml 文件

(1)更新 values.yaml 文件
编辑您的 values.yaml,启用需要的功能(例如开启 monitoring或 logging),将false改为true

monitoring:
  enabled: true  # 从 false 改为 true
logging:
  enabled: true  # 从 false 改为 true

2)、执行 Helm 升级命令

helm upgrade kubesphere kubesphere/ks-core \
  --namespace kubesphere-system \
  --values values.yaml \
  --reuse-values  # 保留未修改的原有配置

关键参数说明:
–reuse-values:保留之前安装时设置的未在本次 values.yaml 中覆盖的值。

如果某些配置需要强制重置,可以去掉 --reuse-values。

3)、验证更新状态

# 查看 ks-installer Pod 的日志
kubectl logs -n kubesphere-system \
  $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') \
  -f

# 检查新组件的 Pod 状态(例如 servicemesh)
kubectl get pod -n kubesphere-service-mesh-system

十四、生产环境做更新升级(都必须重新搞一个跟生产环境一模一样的环境来做下测试),需要注意几个方面:

1)、生产环境低风险推荐升级流程

步骤 1:预升级检查

# 检查当前 Helm 发布状态
helm get values kubesphere -n kubesphere-system --all > current-values.yaml

# 检查集群健康状态
kubectl get nodes
kubectl get pod -A | grep -v Running

步骤 2:执行差异化升级(推荐)

# 仅应用本次修改的配置(避免意外覆盖其他值)
helm upgrade kubesphere kubesphere/ks-core \
  --namespace kubesphere-system \
  --values values.yaml \
  --reset-values  # 明确要求 Helm 仅使用 values.yaml 中的值(忽略历史配置)

为什么用 --reset-values 而不是 --reuse-values?
生产环境中避免配置漂移(例如有人曾经通过 --set 临时修改过参数),确保升级后的状态完全由版本控制的 values.yaml 定义。

步骤 3:灰度观察

# 观察 ks-installer 日志(关键!)
kubectl logs -n kubesphere-system \
  $(kubectl get pod -n kubesphere-system -l app=ks-install -o name) \
  --tail=100 -f

# 按组件验证
watch kubectl get pod -n kubesphere-monitoring-system  # 如果启用了监控
watch kubectl get pod -n kubesphere-devops-system     # 如果启用了 DevOps

步骤 4:回滚准备(必须!)

# 查看历史版本
helm history kubesphere -n kubesphere-system

# 回滚命令(如果需要)
helm rollback kubesphere <REVISION> -n kubesphere-system

2)、生产环境高风险变更的特殊处理

案例 1:修改存储类

persistence:
  storageClass: "new-nfs-storage"  # 旧值为 "old-nfs-storage"

操作建议:

手动迁移原有 PVC/PV 到新存储类

分两步升级:

# 第一步:先禁用依赖存储的组件
helm upgrade kubesphere --set monitoring.enabled=false,logging.enabled=false

# 第二步:修改存储类后重新启用
helm upgrade kubesphere --values values.yaml

案例 2:启用 ServiceMesh

servicemesh:
  enabled: true

操作建议:
先在非生产环境测试 Istio 与现有服务的兼容性
使用 istioctl analyze 预检查:

istioctl analyze -n kubesphere-service-mesh-system

十五、k8s相关重点命令

pod和容器的概念:容器是docker的,一个应用就是一个容器;而一个pod里面可以有多个容器,比如在一个pod里面部署nginx容器以及tomcat容器

0、容器正在创建状态,查看容器详细描述

kubectl describe pod <podname>
#输出内容在最后面有个EVENT事件,这里会详细描诉失败原因

1、对于已经部署了的应用查看部署使用的yaml文件

无论是使用yaml方式部署还是在kubesphere界面部署,都可以使用这个命令

kubectl get pod his-redis-0 -n his -o yaml

2、使用yaml文件部署应用或者删除应用

#根据某个yaml部署
kubectl apply -f xxx.yaml

#删除这个yaml的部署
kubectl delete -f xxx.yaml

3、查看所有pods详细

#输出pod名称,pod中有多少个容器,运行状态,k8s分配的ip,pod所在的节点
kubectl get pods -owide

4、linux系统每秒输出一次容器安装状态

watch -n 1 kubectl get pod

5、查看某个pod的运行日志

kubectl logs <podname>

6、Deployment部署pod的扩容和缩容

# 比如原nginx的副本数是3份,这个命令会扩容到5
# kubectl scale deploy/<podname,不要pod名后面的随机数,比如nginx-5b889fhjhj,podname只取nginx就行> --replicas=5

kubectl scale deploy/nginx --replicas=5
#或者给别的名称空间扩缩容(default名称空间)
kubectl scale -n default deploy/nginx --replicas=5

#缩容,将5份副本缩容到3份
kubectl scale deploy/nginx --replicas=3

7、Deployment部署,自愈&故障转移

如果只是pod中某个容器挂掉了,比如nginx停了,k8s会自动重新启动nginx,使用kubectl get pods 就可以看到后面有个重启次数;如果是机器宕机了,大概5分钟的阈值,k8s就会在其它节点部署容器以达到要求的副本数,比如nginx有三个副本,在三台机器上,其中一起机器宕机了,那么k8s会在其它节点再重新部署一个nginx的pod

1、演示Deployment部署的自愈能力

# 清除所有Pod,比较下面两个命令有何不同效果?
kubectl run mynginx --image=nginx

发现这个mynginx被完全删除了
在这里插入图片描述

#演示使用deployment方式部署的,被删除后的效果
kubectl create deployment mytomcat --image=tomcat:8.5.68

可以看到,被删除后立马又重新拉起了一份tomcat
在这里插入图片描述
那么要如何完全的删除这个tomcat呢?

#必须使用删除deploy才能完全删除这个pod
#查看deploy
kubectl get deploy

#删除deploy
kubectl delete deploy mytomcat

在这里插入图片描述

2、演示Deployment部署,故障转移能力

#查看pod都运行在哪些机器上
kubectl get pod -owide

#在master节点,一直监控my-dep这些pod的状态
#watch -n 1 这个命令是linux自带的,后面跟着命令,表示一秒钟输出一次后面指令的内容,
#也就是一秒钟输出一次kubectl get pod 
#也可以让linux一秒钟输出一次docker的运行容器,比如:watch -n 1 docker ps
watch -n 1 kubectl get pod

发现my-dep这三个pod都运行在k8s-node2机器上,现在直接把k8s-node2机器关机,然后等待五分钟看结果。

在这里插入图片描述
可以看到,k8s-node2机器关机后,五分钟后,k8s集群在k8s-node3机器上拉起了k8s-node2机器上的所有的pod
在这里插入图片描述

8、滚动更新(不停机更新):Deployment

描述:如果有一个应用需要升级,比如原先是v1版本,需要升级到v2版本,黑色箭头代表是目前有流量进来,将一个pod杀死,然后启动新版本,新版本启动成功后再继续杀死一个老版本的pod,启动新版本
在这里插入图片描述

# kubectl set deploy/<podname> image <容器名>=<镜像名>:<镜像版本> --record

# --record表示记录这一次版本的更新
kubectl set deploy/my-dep image nginx=nginx:1.61.1 --record

输出:
在这里插入图片描述

#使用kubectl自带的监控pod状态命令
kubectl get pod -w 

可以看到,原来旧版本的容器还是依然存在,新版本的容器正在创建中
在这里插入图片描述
可以看到,起一个新的,就杀死一个旧的(status状态中的Terminating)
在这里插入图片描述

9、版本回退

查看某个pod部署过的所有版本记录

# kubectl rollout history deployment/<podname>

kubectl rollout history deployment/my-dep

在这里插入图片描述
回滚某个pod

#通过上面图片可以看到,回滚到1版本,1版本的nginx当时部署的时候是拉取的最新版本,而且这个回滚命令的也是滚动更新的
kubectl rollout undo deploy/my-dep --to-revision=1

在这里插入图片描述

10、暴漏端口,让service统一管理所有节点上的nginx,前端vue项目不会直接去请求节点上的nginx,因为nginx扩容或者缩容了,前端项目就得更换地址,所以由前端去请求service的地址,由service统一管理nginx

service的概念:管理一组pod的就表示service(也叫服务)

#给前端配置一个公共的地址,也就是service
# kubectl expose deploy <podname> --port=8000 target-port=80
kubectl expose deploy my-dep --port=8000 target-port=80
#命令解释
#expose:暴漏
#--port:表示暴漏的服务端口
#target-port:表示要暴漏服务它的目标端口
#所以后续即便nginx扩容或者缩容,都不需要修改什么地方了,因为这个暴漏的service已经管理了所有nginx,因为nginx的端口就是80

使用命令查看k8s给service分配的ip

kubectl get service

通过请求service地址,访问nginx的index页面

curl 10.96.8.0:8000

可以看到,这个service负载均衡给所有nginx
在这里插入图片描述
或者在容器内部使用service域名,也可以访问
部署tomcat测试使用域名访问nginx

#创建一次部署,部署tomcat,podname叫my-tomcat
kubectl create deploy my-tomcat --image=tomcat
curl my-dep.default.svc:8000

在这里插入图片描述
我这里是使用的tomcat,在tomcat容器里面使用域名访问nginx,发现也是负债均衡的。注意:使用域名的方式,只能在容器内部,不可以直接在节点上访问,而使用IP的方式,可以直接在节点上使用;浏览器是无法通过ip的方式访问容器的nginx的,需要在kubesphere控制台页面配置应用路由,暴露这个端口后才可以访问

11、在k8s中进入容器内部,比如redis容器

kubectl exec -it redis -- redis-cli

在这里插入图片描述

12、K8s 集群中 503 错误排查指南。如果服务正常运行且没有任何错误日志,但是前端无法访问服务

1、问题分析

503 错误通常表示服务不可用,但您的 User 服务定时任务正常且无错误日志,这表明服务本身可能在运行,但无法响应外部请求。可能的原因包括:

  1. Ingress 配置错误
  2. Nginx Service 配置错误
  3. Pod 网络问题
  4. 健康检查失败
  5. 请求路由异常

2、排查步骤

1. 验证 Ingress 配置
# 检查Ingress资源定义
kubectl get ingress -n <namespace>
kubectl describe ingress <ingress-name>

# 检查规则是否正确指向服务,比如User Service

关键检查点:

  • host 规则是否匹配请求域名
  • path 规则是否正确(如/user对应 User 服务)
  • backend 是否指向正确的 Service 和 Port
2. 检查 Nginx Service 配置
# 查看Service配置
kubectl get service -n <namespace>
kubectl describe service <nginx-service-name>
# 检查端口映射和选择器

关键检查点:

  • port 和 targetPort 是否正确
  • selector 是否匹配 Nginx Pod 的 labels
  • type 是否为 LoadBalancer 或 NodePort(外部访问需要)
3. 验证 Nginx 内部配置
# 进入Nginx Pod查看配置
kubectl exec -it <nginx-pod-name> -n <namespace> -- bash

# 查看Nginx配置文件
cat /etc/nginx/nginx.conf
cat /etc/nginx/conf.d/*.conf

# 检查User服务的upstream配置

关键检查点:

  • upstream 块是否正确指向 User Service 域名(如user-service..svc.cluster.local)
  • proxy_pass 配置是否正确
4. 检查 User Service 健康状态
# 查看Service和Endpoint
kubectl get service <user-service-name> -n <namespace>
kubectl get endpoints <user-service-name> -n <namespace>

# 确认Endpoint是否有IP地址(表示Pod已就绪)

关键检查点:

  • Endpoints 是否包含 User Pod 的 IP 和 Port
  • 如果 Endpoint 为空,检查 Pod 的 Readiness/Liveness Probe 配置
5. 网络连通性测试
# 从Nginx Pod测试到User Service的连通性
kubectl exec -it <nginx-pod-name> -n <namespace> -- bash
curl http://user-service.<namespace>.svc.cluster.local:<port>/health

# 从Ingress Controller测试到Nginx的连通性
kubectl exec -it <ingress-pod-name> -n ingress-nginx -- curl http://<nginx-service-ip>:<port>
6. 检查 Ingress Controller 日志
# 获取Ingress Controller日志
kubectl logs -n ingress-nginx <ingress-controller-pod-name> | grep <user-service-name>

关键检查点:

  • 是否有连接超时、拒绝等错误
  • 是否正确路由到 Nginx Service
7. 检查 User Pod 网络策略
# 查看是否有NetworkPolicy限制流量
kubectl get networkpolicy -n <namespace>

关键检查点:

  • 是否有策略阻止 Ingress→Nginx→User 的流量路径

3、常见问题解决方案

1. Ingress 规则错误
# 示例:正确的Ingress规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /user
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
2. Nginx 配置错误
# 示例:正确的Nginx upstream配置
upstream user_backend {
    server user-service.<namespace>.svc.cluster.local:8080;
}

server {
    listen 80;
    location /user {
        proxy_pass http://user_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
3. 健康检查问题
# 示例:添加Readiness Probe
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: user-container
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5

4、验证修复效果

# 重新部署修改后的资源
kubectl apply -f ingress.yaml
kubectl apply -f nginx-config.yaml

# 检查Pod状态
kubectl get pods -n <namespace>

# 重试前端请求,检查是否恢复正常

13、快速生成一个yaml格式的文件

快速生成一个nginx的yaml

mkdir pratice/
cd pratice/


#命令解释
#kubectl create deployment nginx:创建一个nginx的deployment
#--image:镜像来源
#--replicas=3:表示副本数
#-oyaml:表示生成yaml格式
#--dry-run=client:表示执行的这个kubectl命令不落地,发给apiserver不持久化,也就不生成deployment
#> nginx-deployment.yaml:表示将生成的yaml输出到本地文件中
kubectl create deployment nginx --image=registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine --replicas=3 -oyaml --dry-run=client > nginx-deployment.yaml

在这里插入图片描述

十五、如果想安装旧版本的kubernetes、kubesphere,请点下方链接

旧版kubernetes、kubesphere详细安装步骤
https://blog.csdn.net/weixin_49186526/article/details/148349671?spm=1011.2415.3001.5331

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐