一、简介
二、核心内容
架构:
etcd 保存了整个集群的状态;
apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
kubelet 负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡
概念
yaml
yaml
定以
Pod
Pod 是 Kubernetes 中最小的调度和管理单元,它代表着集群中运行的一个或多个容器实例。在一个 Pod 中,所有容器共享相同的网络命名空间、进程命名空间和存储卷,因此它们可以互相通信和共享数据。Pod 可以通过控制器进行创建、扩缩容和更新等操作。
容器
Pod 中的容器是指实际运行业务逻辑的进程,可以使用 Docker、CRI-O、containerd 等各种容器运行时来运行。每个 Pod 中可以包含一个或多个容器,这些容器可以通过共享网络和存储资源,实现相互通信和协作。
生命周期
Pod 的生命周期包括 Pending、Running、Succeeded、Failed 和 Unknown 等几个阶段。在创建一个 Pod 后,它会首先进入 Pending 阶段,等待被调度到某个节点上。如果调度成功,Pod 就会进入 Running 阶段,开始正常运行。如果 Pod 运行失败或者所有容器都退出了,Pod 就会进入 Failed 或 Succeeded 阶段。如果调度和运行过程中出现了异常,Pod 就会进入 Unknown 阶段。
Pod 网络
Pod 网络是指 Kubernetes 中用于实现容器之间通信的网络环境。Pod 中的每个容器都有一个独立的 IP 地址,但它们共享相同的网络命名空间和端口空间,因此可以互相访问和通信。Kubernetes 支持多种网络插件和方案,如 Flannel、Calico、Cilium 等,用户可以根据实际情况进行选择和配置。
Service
Service 是 Kubernetes 中用于提供内部负载均衡和服务发现的组件,它可以将同一个应用程序的不同副本暴露在集群内部,并为这些副本提供唯一的虚拟 IP 地址和 DNS 域名。Service 可以通过控制器进行创建、更新和删除操作。
ClusterIP
ClusterIP 是 Service 的默认类型,它会分配一个集群内部的虚拟 IP 地址,并将该地址绑定到 Service 上。当其他 Pod 或容器需要访问 Service 时,只需要使用该虚拟 IP 地址即可。
NodePort
NodePort 是一种扩展 ClusterIP 的功能,它会在每个节点上分配一个唯一的端口号,并将该端口号映射到 Service 上。当其他节点或外部网络需要访问 Service 时,只需要使用该节点 IP 地址和映射的端口号即可。
LoadBalancer
LoadBalancer 是一种针对外部流量的负载均衡方案,它可以通过云服务商提供的负载均衡器或自定义的负载均衡器,将流量从外部网络转发到集群内部的 Service 上。
Namespace
Namespace 是 Kubernetes 中用于隔离和管理资源对象的逻辑分区,它可以帮助用户将不同的资源对象归类、管理和隔离。Kubernetes 中默认存在一些 Namespace,如 default、kube-system 等,用户也可以根据需要创建自定义的 Namespace。
Deployment
Deployment 是 Kubernetes 中用于管理 Pod 副本集的控制器,它可以控制一组 Pod 的创建、扩缩容和更新等操作。Deployment 支持滚动更新和回滚等功能,可以实现无缝的应用程序版本升级。
StatefulSet
StatefulSet 是 Kubernetes 中用于管理有状态应用程序副本集的控制器,它可以为每个 Pod 分配唯一的标识符和稳定的网络名称,保证每个 Pod 的唯一性和可访问性。StatefulSet 还支持有序部署和扩缩容等功能,可以实现高可靠性的有状态应用程序部署和管理。
DaemonSet
DaemonSet 是 Kubernetes 中用于在每个节点上运行一组 Pod 的控制器,它通常用于运行系统级别的服务或代理程序等,在每个节点上保证资源对象的一致性和状态。
Job
Job 是 Kubernetes 中用于管理一次性任务的控制器,它会创建一个或多个 Pod 来执行某个任务,并在任务完成后自动删除这些 Pod。Job 还支持任务成功和失败的检测和处理等功能。
CronJob
CronJob 是 Kubernetes 中用于周期性执行任务的控制器,它可以根据用户定义的时间表,自动创建和删除相应的 Job 对象。CronJob 还支持任务成功和失败的检测和处理等功能。
三、编译安装
调用链说明
k8s v1.24之前
k8s v1.24之后dockers运行时
containerd 运行时流程
组件版本
组件 | 描述 | 版本 | 安装包 |
docker | v20.10.5 | ||
docker-compose | Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务 | v2.6.1 | |
cri-dockerd | |||
v1.26.3 | https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.26.md | ||
kubeadm | 官方社区推出的一个用于快速部署kubernetes集群的工具 | https://dl.k8s.io/release/v1.26.3/bin/linux/amd64/{kubeadm,kubelet} | |
kubelet | Kubernetes中的节点代理,它负责在每个计算节点上运行和管理容器。它是每个节点上Kubernetes核心组件之一,负责与Docker或其他容器运行时交互,以启动和管理由Kubernetes调度到该节点的容器 | https://dl.k8s.io/release/v1.26.3/bin/linux/amd64/{kubeadm,kubelet} | |
kubectl | Kubernetes 命令行工具 | v1.26 | |
Kustomize | Kustomize 引入了一种无需模板的方式来自定义应用程序配置,从而简化了现成应用程序的使用。现在,内置到kubectlas中apply | Release kustomize/v5.0.3 · kubernetes-sigs/kustomize · GitHub |
服务器
角色 | 配置 | 描述 | |
ml01(master) | 192.168.6.50 | 16U32G、系统盘200G | |
ml02 | 192.168.6.51 | 16U32G、系统盘200G | |
ml03 | 192.168.6.52 | 16U32G、系统盘200G | |
mltest | 192.168.5.200 | nfs/harbor |
# 1、修改hostname和hosts
vim /etc/hostname
vim /etc/hosts
192.168.6.50 ml01
192.168.6.51 ml02
192.168.6.52 ml0
# 2、永久关闭selinux
sed -i 's/enforcing/disabled/g' /etc/selinux/config
#临时关闭selinux
setenforce 0
# 3、永久并立即关闭防火墙
systemctl disable firewalld --now
#4、临时关闭swap
swapoff -a
# 永久关闭swap 进去注释掉swap那一行
vim /etc/fstab
#5、置时间同步
yum install ntpdate -y
ntpdate ntp.aliyun.com #内网地址需要修改
#6、加载br_netfilter
modprobe br_netfilter
#7、安装配置ipset、ipvsadm
yum -y install ipset ipvsadm
vim /etc/sysconfig/modules/ipvs.modules
输入如下内容
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
#授权
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack
# 8、关闭swap分区(以下你也可以新建另外的配置文件,我这里图省事就直接追加了)
echo "vm.swappiness=0" >> /etc/sysctl.d/99-sysctl.conf
# 把max_map_count调大
echo "vm.max_map_count = 262144" >> /etc/sysctl.d/99-sysctl.conf
# 设置ip转发
cat >> /etc/sysctl.d/99-sysctl.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
EOF
# 使配置文件生效
sysctl -p
# 9、安装基础软件
yum install wget tar socat conntrack ipset ipvsadm -y
docker
解压拷贝
#上传按转包并解压
tar -zxvf docker-20.10.5.tgz
#将解压出来的docker文件内容移动到 /usr/bin/ 目录下
cp docker/* /usr/bin/
#查看docker版本
docker version
#查看docker信息
docker info
开机启动配置
#添加docker.service文件
vi /etc/systemd/system/docker.service
#按i插入模式,复制如下内容:
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
执行权限、开机启动
#添加文件可执行权限
chmod +x /etc/systemd/system/docker.service
#重新加载配置文件
systemctl daemon-reload
#启动Docker
systemctl start docker
#查看docker启动状态
systemctl status docker
#查看启动容器
docker ps
#设置开机自启动
systemctl enable docker.service
#查看docker开机启动状态 enabled:开启, disabled:关闭
systemctl is-enabled docker.service
docker-compose
#上传docker-compose文件并移动到/usr/local/bin/下
mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
2、赋予可执行权限
sudo chmod +x /usr/local/bin/docker-compose
3、查看版本验证是否成功
docker-compose -v
cri-dockerd
k8s 1.24后需要使用cri-dockerd和docker通信
rpm -ivh cri-dockerd-0.3.0-3.el8.x86_64.rpm --nodeps --force
# 修改配置 配置镜像地址,我这里使用的是harbor
vim /usr/lib/systemd/system/cri-docker.service
替换如下内容 : 注意后面pause镜像的版本,和kubadm,依赖的保持一致,查看第10步
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=192.168.5.200:5000/ml/registry.k8s.io/pause:3.9
#启动:
systemctl daemon-reload && systemctl restart cri-docker.socket
systemctl start cri-docker.socket cri-docker
#查看状态
systemctl status cri-docker.socket cri-docker
异常:Failed to listen on CRI Docker Socket for the API.
权限问题我们需要修改对应权限配置
vim /usr/lib/systemd/system/cri-docker.socket
修改 SocketGroup=docker 为 SocketGroup=root
安装CNI
# 下载
https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
# 主节点 解压cni-plugins
mkdir -p /opt/cni/bin/
tar xvf cni-plugins-linux-amd64-v1.1.1.tgz -C /opt/cni/bin/
#从节点
scp -r /opt/cni ml02:/opt
scp -r /opt/cni ml03:/opt
安装crictl
# 上传上一步下载的文件到主节点机器
# 解压crictl的压缩包
tar xvf crictl-v1.26.1-linux-amd64.tar.gz -C /usr/local/bin/
# 创建crictl配置文件
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: false
pull-image-on-create: true
EOF
#如果使用cri-docker 配置 crictl
vi /etc/crictl.yaml
修改成如下
runtime-endpoint: unix:///var/run/cri-dockerd.sock
image-endpoint: unix:///var/run/cri-dockerd.sock
# 把crictl程序拷贝过来
scp /usr/local/bin/crictl ml02:/usr/local/bin/
scp /usr/local/bin/crictl ml03:/usr/local/bin/
# 把crictl配置文件拷贝过来
scp /etc/crictl.yaml ml02:/etc/
scp /etc/crictl.yaml ml03:/etc/
安装kubeadm、kubelet、kubectl、Kustomize
kubeadm、kubelet、kubectl安装
下载安装包:
#下载kubeadm、kubelet
curl -L --remote-name-all https://dl.k8s.io/release/v1.26.3/bin/linux/amd64/{kubeadm,kubelet}
#下载kubectl
wget https://dl.k8s.io/release/v1.26.3/bin/linux/amd64/kubectl
# 下载对应的kubelet.service
RELEASE_VERSION="v0.4.0"
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/{RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:/usr/local/bin:g" | tee kubelet.service
mkdir kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/{RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:/usr/local/bin:g" | tee kubelet.service.d/10-kubeadm.conf
- 主节点机器
#上传文件到服务器,并执行如下命令
# 添加执行权限
chmod +x kubelet kubectl kubeadm
# 移动到path目录
mv kubelet \
kubectl \
kubeadm /usr/local/bin
# systemd配置文件移动到/etc/systemd/system/目录
mv kubelet.service /etc/systemd/system/
mv kubelet.service.d /etc/systemd/system/
# 重载systemd配置
systemctl daemon-reload
# 设置自启动
systemctl enable --now kubelet
# 启动containerd
systemctl start kubelet
kubelet.service ,添加如下内容:
- 从节点机器
# 拷贝主节点机器程序和systemd到从节点
scp ml01:/usr/local/bin/kube* /usr/local/bin
scp -r ml01:/etc/systemd/system/kubelet.service* /etc/systemd/system/
# 重载systemd配置
systemctl daemon-reload
# 设置自启动
systemctl enable --now kubelet
# 启动containerd
systemctl start kubelet
# 查看启动日志
journalctl -xefu kubelet
Kustomize
kubeflow1.8 需要5.0.3版本的Kustomize
tar -zxvf kustomize_v5.0.3_linux_amd64.tar.gz
chmod +x ./kustomize
sudo mv kustomize /usr/local/bin
harbor 镜像库
# 上传到/opt目录解压
tar -xzf harbor-offline-installer-v2.9.2.tgz
# 修改配置文件
cd /opt/apps/harbor
cp harbor.yml.tmpl harbor.yml
vim harbor.yml
修改hostname为私网IP;修改
port:80为5000;
注销 https 所有内容
启动harbor
# cd /opt/apps/harbor
./prepare # 如果有二次修改harbor.yml文件,请执行使配置文件生效
./install.sh --help #查看启动参数
./install.sh --with-chartmuseum # 加载chart
# 重启
cd /opt/apps/harbor
docker-compose restart
配置daemon.json
vim /etc/docker/daemon.json
{"insecure-registries":["192.168.5.200:5000"]# 为harbor公网IP}
#重载systemd配置
systemctl daemon-reload
systemctl restart docker
镜像文件
查看需要镜像:
kubeadm config images list
拉取、tag、推送脚本,外网机器获取镜像,推送到内网harbor上
对于gcr.io/knative-releases/knative.dev/serving/cmd/webhook@sha256:4305209ce498caf783f39c8f3e85dfa635ece6947033bf50b0b627983fd65953
这种格式的镜像,需要pull下来后,添加版本tag,这里使用sha256作为版本号,见下面代码
#!/bin/bash
#代理仓库
DAO=m.daocloud.io/
#DAO=
# Harbor 仓库地址
HARBOR_REGISTRY=192.168.4.26/ml
# 登录 Harbor
docker login "${HARBOR_REGISTRY}" -u 用户名 -p 密码
# 读取镜像列表文件
while IFS= read -r IMAGE; do
imageName="${IMAGE}"
# 如果是digest reference 需要自己tag 版本
if [[ ${imageName} == *'@'* ]]; then
echo "镜像使用了digest reference,需要打版本tag,默认:sha256"
#获取镜像名称
image_without_digest=$(echo ${imageName} | cut -d'@' -f1)
# Tag the image without digest as "sha256" version
new_tag="${image_without_digest}:sha256"
imageName="${new_tag}"
echo "带版本镜像名称: $new_tag"
else
echo " "
fi
# 拉取镜像
docker pull "${DAO}${IMAGE}"
#给镜像打Tag
docker tag "${DAO}${IMAGE}" "${HARBOR_REGISTRY}/${imageName}"
#推送标签
docker push "${HARBOR_REGISTRY}/${imageName}"
done < image_list.txt
# 注销 Harbor
docker logout "${HARBOR_REGISTRY}"
kubeadm初始化
# 输出默认初始化配置文件
kubeadm config print init-defaults > kubeadm.yaml
# 修改配置文件
sed -i "s/kubernetesVersion:/#kubernetesVersion:/" kubeadm.yaml && \
sed -i "s/advertiseAddress: 1.2.3.4/advertiseAddress: (ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", 2)}' | awk 'NR<2{print 1}')/" kubeadm.yaml && \
sed -i "s/name: node/name: ml01/" kubeadm.yaml
echo "kubernetesVersion: (kubeadm version -o short)" >> kubeadm.yaml
# 如果你是用阿里云拉取的镜像,那就需要对应的修改imageRepository,不然会找不到镜像
# 如果你是内网harbor
# sed -i "s#imageRepository: registry.k8s.io#imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers#" kubeadm.yaml
#如果是docker 修改criSocket
nodeRegistration:
criSocket: unix:///var/run/cri-dockerd.sock
# 执行初始化
kubeadm init --config kubeadm.yaml
# 等待初始化完成会输出类似如下内容:
# 如果失败,解决后,先重置
kubeadm reset
# 查看集群状态
kubectl get nodes
主节点设计环境变量
# 设置一个环境变量 echo"export KUBECONFIG=/etc/kubernetes/admin.conf" > /etc/profile.d/kube.sh
source /etc/profile.d/kube.sh
安装Pod 网络附加组件calico
上面的操作做完coredns还是起不来,必须部署一个基于 Pod 网络插件的 容器网络接口 (CNI),以便 Pod 可以相互通信,在安装网络之前,集群 DNS (CoreDNS) 不会启动
# 1、下载calico配置文件
wget https://raw.githubusercontent.com/projectcalico/calico/release-v3.25/manifests/calico.yaml
# 2、获取镜像列表
cat calico.yaml | grep "image:" | awk "{print 1}" | awk '{print substr(0 ,18)}' | sort | uniq > calico_image.list
# 根据镜像列表拉取镜像,并推送到内网harbor上
# 3、上传calico配置文件calico.yaml到主节点
# 注意:如果你使用harbor 作为镜像库,修改calico.yaml文件中的image镜像名词,在镜像前加上harbor库地址
# 样例:image: 192.168.5.200:5000/ml/docker.io/calico/kube-controllers:v3.25.2
# kubectl启动calico
kubectl apply -f calico.yaml
# 4、看看对应的pod都起来没有
kubectl -n kube-system get pods
#查看pod日志
kubectl -n kube-system describe pods/calico-node-5sdtv
从节点加入集群
# 这是kube init的时候系统打印的
# 忘记了就去主节点用这个打印出来
# kubeadm token create --print-join-command
kubeadm join <这是个apiserver ip>:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:cbe9bd17dbdbeaf4acbf69b485c949f5db9b9ceee00895a2eab5cc9ab54cb4d0
pv、pvc、存储pv NFS
安装NFS
在192.168.5.200 上执行
# 开始安装nfs,如果是离线环境,可以在有网的环境下将rpm包先下载下来
yum install -y nfs-utils
# 设置允许访问网段 我们集群网段
vim /etc/exports
/nfsdata 192.168.6.0/24(rw,no_root_squash,sync)
#创建共享目录,并修改权限
mkdir /nfsdata
chmod -R 777 /nfsdata/
#设置开机启动
systemctl enable rpcbind.service
systemctl enable nfs-server.service
systemctl start rpcbind.service
systemctl start nfs-server.service
#加载配置
exportfs -r
#查看配置
exportfs
#在所有节点安装
yum install -y nfs-utils
nfs-provisioner 准备镜像
镜像:registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
#如果下载不下来可以使用m.daocloud.io 下载
docker pull m.daocloud.io/registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
#harbor参考harbor配置
nfs-provisioner 部署
调用链条 pvc->StorageClass->nfs-provisioner->rbac->nfs
rbac.yaml
创建ServiceAccount、ClusterRole、ClusterRoleBinding等,为nfs-client-provisioner授权
# 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: ["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
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
nfs-provisioner.yaml
nfs-client-provisioner 是一个 Kubernetes 的简易 NFS 的外部 provisioner,本身不提供 NFS,需要现有的 NFS 服务器提供存储。
注意:image部分的 配置,我这里使用的是自建harbor的库地址
# nfs-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default #与RBAC文件中的namespace保持一致
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: 192.168.5.200:5000/ml/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.5.200 #NFS Server IP地址
- name: NFS_PATH
value: /nfsdata #NFS 挂载卷
volumes:
- name: nfs-client-root
nfs:
server: 192.168.5.200 #NFS Server IP地址
path: /nfsdata #NFS 挂载卷
nfs-storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
pathPattern: "${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}" # waits for nfs.io/storage-path annotation, if not specified will accept as empty string.
onDelete: delete
nfs-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
annotations:
nfs.io/storage-path: "test-path" # not required, depending on whether this annotation was shown in the storage class description
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50Mi
执行部署
kubectl apply -f rbac.yaml
kubectl apply -f nfs-provisioner.yaml
kubectl apply -f nfs-storage-class.yaml
kubectl apply -f nfs-pvc.yaml
#验证 PVC 和 PV 的绑定情况:验证 PVC 是否与自动创建的 PV 绑定成功。可以使用以下命令来查看
kubectl get pvc
kubectl get pv
#设置为默认的存储
kubectl patch storageclass alicloud-nas -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
#查看设置是否成功:名称中包含 (default) 则设置成功
kubectl get sc
#如果以上步骤都执行成功,则说明 nfs-client-provisioner 工具已经搭建完成,
#可以通过它来动态地创建和删除 PV,并将其绑定到对应的 PVC 上。
dashboard安装
安装
# 1、下载calico配置文件
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
# 2、获取镜像列表
cat recommended.yaml | grep "image:" | awk "{print 1}" | awk '{print substr(0 ,18)}' | sort | uniq > dash_image.list
# 根据镜像列表拉取镜像,并推送到内网harbor上
3、上传dashboard配置文件recommended.yaml到主节点
注意:如果你使用harbor 作为镜像库,修改recommended.yaml文件中的image镜像名词,在镜像前加上harbor库地址
# 样例:image: 192.168.5.200:5000/ml/docker.io/calico/kube-controllers:v3.25.2
# 启动dashboard
kubectl apply -f recommended.yaml
#查看状态
kubectl -n kubernetes-dashboard get pods
配置dashboard访问
- 开放访问端口
# 其实还有其他的方式,我这里写一种,配置NodePort方式访问
kubectl -n kubernetes-dashboard edit service kubernetes-dashboard
apiVersion: v1
kind: Service
...
...
ports:
- nodePort: <端口>
port: 443 protocol: TCP
targetPort: 8443 selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
type: NodePort #修改这一行即可,原为type: ClusterIP
loadBalancer: {}
- 配置登录密钥
# 通过yaml文件创建服务用户Service Account和集群角色权限ClusterRoleBinding
cat > dash_accout.yaml <<EOF
# Creating a Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
# Creating a ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
---
# Creating a token
apiVersion: v1
kind: Secret
metadata:
name: admin-user
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: "admin-user"
type: kubernetes.io/service-account-token
EOF
- 创建角色
kubectl apply -f dash_accout.yaml
- 获取访问密钥
kubectl describe secret admin-user -n kubernetes-dashboard
#不记名密钥,创建命令
kubectl -n kubernetes-dashboard create token admin-user
- 网页登录
#网页登录
# <master-ip> => 主节点ip# <apiserver-port> => 上面的nodePort: <端口>,这个端口
# 访问https://<master-ip>:<apiserver-port>/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/# 填入上一步获取的token
kubernetes-dashboard