1、前言
因为工作的原因会接触到,借此机会写个 kubernetes 集群的搭建教程,看了官方文档以及太多的博客,决定整合一下。(主要是自己想搭一个类似生产环境的k8s来玩)
当然也有简单一键启动 k8s 的方法,docker desktop 自带了一个单点 k8s 。不想折腾的装个 docker 桌面版即可。
官方说明文档里生产环境有 3 种部署方式,kubeadm、Kops、Kubespray。本文基于 debian 10 使用 kubeadm 来搭建生产(娱乐)环境集群。k8s 版本为当时最新的 v1.12.1
2、 前期准备
准备 7 台 Debian 10.4 系统 2c2g 的机器(2c2g已经是最低要求了),Node 节点需要有 2 块硬盘。因为使用了 GlusterFS 作为持久化存储。
你想要多大的集群都可以扩。如实力不允许,其实可以不用搭建这么大的规模,尽量保持一主一备。
节点类型 | 主机名 | IP地址 | 备注 |
---|---|---|---|
Proxy | Master-HAProxy | 10.1.0.10 | 负载均衡 |
Control-Plane | Master-Control-0 | 10.1.0.20 | 控制器1 |
Control-Plane | Master-Control-1 | 10.1.0.21 | 控制器2 |
Control-Plane | Master-Control-2 | 10.1.0.22 | 控制器3 |
Node / GlusterFS | Master-worker-0 | 10.1.0.30 | 节点1 |
Node / GlusterFS | Master-worker-1 | 10.1.0.31 | 节点2 |
Node / GlusterFS | Master-worker-2 | 10.1.0.32 | 节点3 |
2.1、 环境准备
在 Proxy 节点上安装 ansible 和 ha-proxy,并配置所有主机的 ssh 单信( 由于前期很多安装都是一模一样的,这里就借助 ansible 来批量安装 k8s 的基础件 )
# 习惯性先更新一波再装
apt update && apt upgrade -y && apt autoremove -y
apt install -y ansible haproxy ufw
# 关闭防火墙
ufw disable
给 hosts / ansible 添加主机信息(统一使用主机名)
cat >> /etc/hosts <<-EOF
10.1.0.20 master-control-0
10.1.0.21 master-control-1
10.1.0.22 master-control-2
10.1.0.30 master-worker-0
10.1.0.31 master-worker-1
10.1.0.32 master-worker-2
EOF
cat >> /etc/ansible/hosts <<-EOF
# Master-Control-Cluster
[mcc]
master-control-1
master-control-2
# All-Control-Cluster
[acc]
master-control-0
master-control-1
master-control-2
# Master-Worker-Cluster
[mwc]
master-worker-1
master-worker-2
# All-Worker-Cluster
[awc]
master-worker-0
master-worker-1
master-worker-2
EOF
配置 SSH 单信(需要确保免密登录的用户有 sudo 权限,且可以无密使用 sudo),使用 root 的请确保 /etc/ssh/sshd_config 里的 PermitRootLogin 为 yes
ssh-keygen -t ed25519 #无脑回车即可
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@master-control-0
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@master-control-1
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@master-control-2
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@master-worker-0
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@master-worker-1
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@master-worker-2
关闭所有节点的 swap 分区
# 查看 swap 分区
swapon -s
# 临时删除 swap 分区
swapoff /dev/sda5
# 删除 /etc/fstab 里的 swap 挂载,避免重启后 swap 分区又挂了回来
关闭所有节点的防火墙
# apt 安装 ufw
ansible all -m apt -a "name=ufw"
# 禁用防火墙
ansible all -m shell -a "ufw disable"
2.2、 安装/配置 Containerd
使用 ansible-playbook 在所有的集群节点上安装 containerd vi containerd_install.yml
---
- hosts: all
remote_user: root
tasks:
- name: 添加开机启动模块
shell:
cmd: |
cat <<EOF | tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
- name: 添加开机启动模块
shell:
cmd: |
cat <<EOF | tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
- name: 加载 overlay 模块
shell: modprobe overlay
- name: 加载 br_netfilter 模块
shell: modprobe br_netfilter
- name: 设置 sysctl
shell:
cmd: |
cat <<EOF | tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
notify:
- load sysctl
- name: 更新源
apt: update_cache=yes
- name: 安装必要软件包
apt:
pkg:
- curl
- apt-transport-https
- ca-certificates
- gnupg
- lsb-release
- git
- wget
- tmux
- lvm2
- name: 添加 docker gpg key
apt_key:
url: https://download.docker.com/linux/debian/gpg
state: present
- name: 添加 Docker 源
apt_repository:
repo: deb https://download.docker.com/linux/debian buster stable
state: present
- name: 安装 containerd
apt: update_cache=yes name=containerd.io state=latest
handlers:
- name: 重载 sysctl
shell: sysctl --system
使用 playbook 一键安装
ansible-playbook containerd_install.yml
生成默认配置,并修改 /etc/containerd/config.toml 让 containerd 使用 systemd cgroup。
ansible master-control-0 -m shell -a "containerd config default | tee /etc/containerd/config.toml"
使用上面的命令生成并获取完整的配置文件,复制到 vi containerd_config.yml
中。
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true # 在默认配置文件中添加这一行,并复制到下面的 yaml 中
---
- hosts: all
remote_user: root
tasks:
- name: 配置 containerd
shell:
cmd: |
cat <<EOF | tee /etc/containerd/config.toml
复制到这里,注意缩进
EOF
notify:
- restart containerd
handlers:
- name: restart containerd
service:
name: containerd
state: restarted
一键配置 containerd
ansbile-playbook containerd_config.yml
2.3、 安装 kubeadm kubectl kubelet
使用虚拟机的朋友需要确保每个节点上的 MAC 地址和 product_uuid 是唯一的。
ansible all -m shell -a "ip link"
ansible all -m shell -a "cat /sys/class/dmi/id/product_uuid"
playbook 安装 kubeadm vi kube_install.yml
---
- hosts: all
remote_user: root
tasks:
- name: 更新源
apt: update_cache=yes
- name: 添加 kubeadm gpg 密钥
apt_key:
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
state: present
- name: 添加 kubeadm 仓库
apt_repository:
repo: deb https://apt.kubernetes.io/ kubernetes-xenial main
state: present
- name: 更新源
apt: update_cache=yes
- name: 安装 kubeadm kubectl kubelet
apt:
pkg:
- kubelet
- kubeadm
- kubectl
- name: 锁定 kubeadm kubectl kubelet 版本
shell: apt-mark hold kubelet kubeadm kubectl
- name: 添加所有节点信息到 hosts
shell:
cmd: |
cat >> /etc/hosts <<-EOF
10.1.0.20 master-control-0
10.1.0.21 master-control-1
10.1.0.22 master-control-2
10.1.0.30 master-worker-0
10.1.0.31 master-worker-1
10.1.0.32 master-worker-2
# 负载均衡地址,需要与后面的 control-plane-endpoint 一致
10.1.0.10 kube.api
EOF
一键安装 kube 三件套
ansible-playbook kube_install.yml
到这里,就已经完成了所有机器的 k8s 安装。
3、 配置 k8s 集群
3.1、配置 ha-proxy 负载均衡
在开始初始化集群前需要先配置好 ha-proxy 的负载均衡,避免后面的控制节点、工作节点无法加入到集群里
cat >> /etc/haproxy/haproxy.cfg <<-EOF
#监控界面
listen admin_stats
#监控界面的访问的IP和端口
bind 0.0.0.0:8888
#访问协议
mode http
#URI相对地址
stats uri /status
#统计报告格式
stats realm Global\ statistics
#登陆帐户信息
#stats auth admin:123456
#负载均衡
listen kubernetes-api
#访问的IP和端口
bind 0.0.0.0:6443
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source
balance source
#日志格式
option tcplog
server master-control-0 10.1.0.20:6443 weight 1 maxconn 2000
server master-control-1 10.1.0.21:6443 weight 1 maxconn 2000
server master-control-2 10.1.0.22:6443 weight 1 maxconn 2000
listen etcd-api-0
#访问的IP和端口
bind 0.0.0.0:2379
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source
balance source
#日志格式
option tcplog
server master-control-0 10.1.0.20:2379 weight 1 maxconn 2000
server master-control-1 10.1.0.21:2379 weight 1 maxconn 2000
server master-control-2 10.1.0.22:2379 weight 1 maxconn 2000
listen etcd-api-1
#访问的IP和端口
bind 0.0.0.0:2380
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source
balance source
#日志格式
option tcplog
server master-control-0 10.1.0.20:2380 weight 1 maxconn 2000
server master-control-1 10.1.0.21:2380 weight 1 maxconn 2000
server master-control-2 10.1.0.22:2380 weight 1 maxconn 2000
listen kubelet-api
#访问的IP和端口
bind 0.0.0.0:10250
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source
balance source
#日志格式
option tcplog
server master-control-0 10.1.0.20:10250 weight 1 maxconn 2000
server master-control-1 10.1.0.21:10250 weight 1 maxconn 2000
server master-control-2 10.1.0.22:10250 weight 1 maxconn 2000
listen kube-scheduler
#访问的IP和端口
bind 0.0.0.0:10251
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source
balance source
#日志格式
option tcplog
server master-control-0 10.1.0.20:10251 weight 1 maxconn 2000
server master-control-1 10.1.0.21:10251 weight 1 maxconn 2000
server master-control-2 10.1.0.22:10251 weight 1 maxconn 2000
listen kube-controller-manager
#访问的IP和端口
bind 0.0.0.0:10252
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source
balance source
#日志格式
option tcplog
server master-control-0 10.1.0.20:10252 weight 1 maxconn 2000
server master-control-1 10.1.0.21:10252 weight 1 maxconn 2000
server master-control-2 10.1.0.22:10252 weight 1 maxconn 2000
EOF
service haproxy restart
3.2、初始化集群
在 master-control-0 上执行,输出信息的最后10几行包含了 控制节点/工作节点 的加入命令。
此处的 control-plane-endpoint 需要与 2.3 playbook 里的节点信息一致
# 如果不想单独连接到 master-control-0 上时可以使用 ansible 执行
ansible master-control-0 -m shell -a "kubeadm init --apiserver-advertise-address 0.0.0.0 --apiserver-bind-port 6443 --cert-dir /etc/kubernetes/pki --control-plane-endpoint kube.api --kubernetes-version 1.21.1 --pod-network-cidr 10.10.0.0/16 --service-cidr 10.20.0.0/16 --service-dns-domain cluster.local --upload-certs"
# 与上面的命令功能相同,区别是要登录 master-control-0 上执行
kubeadm init \
--apiserver-advertise-address 0.0.0.0 \
--apiserver-bind-port 6443 \
--cert-dir /etc/kubernetes/pki \
--control-plane-endpoint kube.api \
--kubernetes-version 1.21.1 \
--pod-network-cidr 10.10.0.0/16 \
--service-cidr 10.20.0.0/16 \
--service-dns-domain cluster.local \
--upload-certs
命令详解:
kubeadm init \
--apiserver-advertise-address 0.0.0.0 \
# API 服务器将通告它正在侦听的 IP 地址。如果未设置,将使用默认网络接口。
# 如果有多网卡,可以使用此选项指定某个网卡
--apiserver-bind-port 6443 \
# API 服务器绑定的端口。(默认 6443)
--cert-dir /etc/kubernetes/pki \
# 保存证书的路径,默认值:"/etc/kubernetes/pki"
--control-plane-endpoint kube.api \
# 为控制平面指定一个稳定的 IP 地址或 DNS 名称
--image-repository registry.aliyuncs.com/google_containers \
# 选择用于拉取 control-plane 镜像的容器仓库,默认值:"k8s.gcr.io"
# 人在海外,不需要考虑这个,需要的可以自行添加
--kubernetes-version 1.21.1 \
# 为 control-plane 选择一个特定的 Kubernetes 版本, 默认值:"stable-1"
--node-name master-control-0 \
# 指定节点的名称,不指定的话为主机hostname,默认可以不指定
--pod-network-cidr 10.10.0.0/16 \
# 指定pod的IP地址范围,如果设置,control-plane 将自动为每个节点分配 CIDR。
--service-cidr 10.20.0.0/16 \
# 指定 Service 的 VIP 地址范围
--service-dns-domain cluster.local \
# 为 Service 另外指定域名,默认"cluster.local"
--upload-certs
# 将 Control-plane 证书上传到 kubeadm-certs Secret
运行后会看到,类似这样的信息。
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join kube.api:6443 --token 7z76y1.za0ug2gwved0mgbn \
--discovery-token-ca-cert-hash sha256:eaf49cbe3e86dd03e1902ab52cf493984a9214d58fdf5e9f36884792848a8911 \
--control-plane --certificate-key fafb26b4387d87331a6d541b1b82e18de608f159608d04cf9ad14f8f9be660f9
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join kube.api:6443 --token 7z76y1.za0ug2gwved0mgbn \
--discovery-token-ca-cert-hash sha256:eaf49cbe3e86dd03e1902ab52cf493984a9214d58fdf5e9f36884792848a8911
需要注意的几条信息:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# root 用户 执行这个就好了
export KUBECONFIG=/etc/kubernetes/admin.conf
# 下面这两个指令的证书有效期为24小时
# Control-Plane 的加入指令
kubeadm join kube.api:6443 --token 7z76y1.za0ug2gwved0mgbn \
--discovery-token-ca-cert-hash sha256:eaf49cbe3e86dd03e1902ab52cf493984a9214d58fdf5e9f36884792848a8911 \
--control-plane --certificate-key fafb26b4387d87331a6d541b1b82e18de608f159608d04cf9ad14f8f9be660f9
# Node 的加入指令
kubeadm join kube.api:6443 --token 7z76y1.za0ug2gwved0mgbn \
--discovery-token-ca-cert-hash sha256:eaf49cbe3e86dd03e1902ab52cf493984a9214d58fdf5e9f36884792848a8911
一键加入 Control-Plane(别傻乎乎的把我的命令复制去执行喔,根据 kubeadm 执行后给出信息进行相对应的更改)
ansible mcc -m shell -a "kubeadm join kube.api:6443 --token 7z76y1.za0ug2gwved0mgbn --discovery-token-ca-cert-hash sha256:eaf49cbe3e86dd03e1902ab52cf493984a9214d58fdf5e9f36884792848a8911 --control-plane --certificate-key fafb26b4387d87331a6d541b1b82e18de608f159608d04cf9ad14f8f9be660f9"
一键加入 Node
ansible awc -m shell -a "kubeadm join kube.api:6443 --token 7z76y1.za0ug2gwved0mgbn --discovery-token-ca-cert-hash sha256:eaf49cbe3e86dd03e1902ab52cf493984a9214d58fdf5e9f36884792848a8911"
检查集群状态
# 执行这个的时候会发现 scheduler controller-manager 状态是不健康的
ansible master-control-0 -m shell -a "kubectl get cs"
# 修改配置文件,把 port=0 那行注释掉,再执行上面的命令就会发现全部的状态都是健康
vi /etc/kubernetes/manifests/kube-scheduler.yaml
vi /etc/kubernetes/manifests/kube-controller-manager.yaml
查看 Node 状态,这时运行下面的命令会发现所有的节点状态都处于 未准备 这是正常现象。由于没有安装网络附加组件,CoreDNS 并不会启动,导致了所有节点都处于 未准备 的状态。
# 查看 node 状态
ansible master-control-0 -m shell -a "kubectl get nodes"
# 查看 coredns pod 状态
ansible master-control-0 -m shell -a "kubectl get pods --all-namespaces|grep coredns"
设置所有节点 kubelet 在启动时运行
ansible all -m shell -a "systemctl enable kubelet"
3.3、安装 POD 网络附加组件
集群必装 Pod 网络插件,使 Pod 可以相互通信,只需要在 master-control-0 节点上操作,其他的节点都会自动创建相关 Pod
kubeadm 支持多种网络插件,这里选用的是 Calico 网络插件
当前小节的所有操作都是在 master-control-0 的机器上执行,必须在任何应用程序之前部署网络组件。
mkdir calico && cd calico
wget https://docs.projectcalico.org/manifests/calico.yaml # 此时的版本为 3.19.1
# 去掉 calico.yaml 中的 3683/3684行的注释并修改 value 为 10.10.0.0/16 这里的 value 要与集群初始化时的 pod-network-cidr 一致
# 修改 calico.yaml 中的 3867 行的 policy/v1beta1 为 policy/v1 避免应用时出现 Warning
vi calico.yaml
# 部署 Pod 网络组件
kubectl apply -f calico.yaml
等待片刻后,执行下面的命令可以看到 Node 状态已经全部变为 已准备 的状态
kubectl get nodes
至此 k8s 就已经算装完了。
4、配置持久存储
持久化存储需要至少 3 个 Node 节点用来部署 glusterfs 集群,并且这 3 个 Node 节点每个节点需要至少一个空余的磁盘。
本节所有操作都在 master-control-0 节点上执行
# 最新的文件
git clone https://github.com/heketi/heketi.git
cd heketi/extras/kubernetes
部署 Glusterfs DaemonSet
# 给 Node 打上 storagenode 标签
kubectl label nodes master-worker-0 storagenode=glusterfs
kubectl label nodes master-worker-1 storagenode=glusterfs
kubectl label nodes master-worker-2 storagenode=glusterfs
# 部署 Glusterfs DaemonSet
kubectl create -f glusterfs-daemonset.json
# 查看 Pod 状态
kubectl get pods
创建一个 Heketi 的服务帐户( service-account )
kubectl create -f heketi-service-account.json
# 绑定权限
kubectl create clusterrolebinding heketi-gluster-admin --clusterrole=edit --serviceaccount=default:heketi-service-account
创建一个 Kubernetes secret 来保存我们 Heketi 实例的配置。必须将配置文件的执行程序设置为 kubernetes才能让Heketi server控制gluster pod(配置文件的默认配置)
# 可修改 heketi.json 来开启验证,设置 admin / user 密码
vi heketi.json
# 创建 Kubernetes secret
kubectl create secret generic heketi-config-secret --from-file=./heketi.json
# 部署初始 Pod 和 服务
kubectl create -f heketi-bootstrap.json
# 查看初始 Pod 状态
kubectl get pods
连接 Pod 配置 Heketi
tmux new -s heketi
# 查看 Pod 名称
kubectl get pods
# 进入容器 需要等待 Pod 的状态为 Running
kubectl exec -it deploy-heketi-974d59f8c-xmwmv /bin/bash
# 检查 heketi 状态
curl http://localhost:8080/hello
export HEKETI_CLI_SERVER=http://localhost:8080
Ctrl+bd 切出 tmux,修改拓扑文件
cp topology-sample.json topology.json
vi topology.json
确保 hostnames / manage 指向确切的 Node 名称( kubectl get nodes
可以看到主机名),并且 hostnames / storage 是存储网络的IP地址。
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"master-worker-0"
],
"storage": [
"10.1.0.30"
]
},
"zone": 1
},
"devices": [
{
"name": "/dev/sdb",
"destroydata": false
}
]
},
{
"node": {
"hostnames": {
"manage": [
"master-worker-1"
],
"storage": [
"10.1.0.31"
]
},
"zone": 1
},
"devices": [
{
"name": "/dev/sdb",
"destroydata": false
}
]
},
{
"node": {
"hostnames": {
"manage": [
"master-worker-2"
],
"storage": [
"10.1.0.32"
]
},
"zone": 1
},
"devices": [
{
"name": "/dev/sdb",
"destroydata": false
}
}
]
}
]
}
]
}
拷贝 topology.json
到容器中进行部署,并使用 heketi 为其存储其数据库提供一个卷
# 拷贝文件到容器中
kubectl cp topology.json deploy-heketi-974d59f8c-xmwmv:/topology.json
# 进入容器
tmux att -t heketi
# 部署拓扑
heketi-cli topology load --json=topology.json --user admin --secret adminpasswd
heketi-cli setup-openshift-heketi-storage --user admin --secret adminpasswd
# 在上面的过程中出现错误,使用下面的命令停止容器并重来(需要修改 topology.json 中的 devices/destroydata 为 true)
kubectl scale deployment deploy-heketi --replicas=0
kubectl scale deployment deploy-heketi --replicas=1
# 退出容器
exit
# 把生成的配置文件复制到主机上
kubectl cp deploy-heketi-974d59f8c-4pqf4:heketi-storage.json $PWD/heketi-storage.json
# 部署 heketi 存储
kubectl create -f heketi-storage.json
# 检查部署状态(完成后的状态为 Completed )
kubectl get pods
# 删除bootstrap Heketi实例相关的组件
kubectl delete all,service,jobs,deployment,secret --selector="deploy-heketi"
创建长期使用的 Heketi 实例:
kubectl create -f heketi-deployment.json
# 获取 Pod 名称
kubectl get pods
# 进入容器,查看集群信息和 IP
kubectl exec -it heketi-5dccbd5d49-v6xrl /bin/bash
# 查看 集群信息
heketi-cli cluster list --user admin --secret adminpasswd
heketi-cli volume list --user admin --secret adminpasswd
# 查看 IP
cat /etc/hosts
添加到 Storage Class 中 vi storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: glusterfs-cluster
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://10.10.233.135:8080"
restuser: "admin"
secretNamespace: "default"
secretName: "heketi-config-secret"
volumetype: "replicate:3"
# 添加到 sc 中
kubectl create -f storage-class.yaml
# 查看 Storage Class
kubectl get sc
# 设置为默认存储
kubectl patch storageclass glusterfs-cluster -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
# 再次查看名字后面会多出一个 (default)
kubectl get sc
至此,你已经完成了 k8s 的安装,集群/持久化存储的配置。享受自己搭建的成果