Kubeadm 快速搭建 k8s v1.24.1 集群(openEuler 22.03 LTS)

bf8deaccd49fb6989dad0bfb7142cba4.png

kubeadm 简介

kubeadm 是 Kubernetes(以下简称 k8s)官方提供的用于快速安装部署 k8s 集群的工具,伴随 k8s 每个版本的发布都会同步更新,kubeadm 会对集群配置方面的一些实践做调整,通过实验 kubeadm 可以学习到 k8s 官方在集群配置上一些新的最佳实践。

这个工具能通过两条指令完成一个 k8s 集群的部署:

# 创建一个 Master 节点
$ kubeadm init# 将一个 Node 节点加入到当前集群中
$ kubeadm join <Master节点的IP和端口 >

使用 kubeadm 工具大大简化了 k8s 的部署操作。

k8s 的部署方式

通常使用 kubeadm 部署和二进制方式部署,他们之间的区别:

  • kubeadm 方式部署,组件容器化部署,只有 kubelet 没有被容器化

  • 二进制方式部署,传统的守护进程(systemd)管理服务 systemctl

实现目标

基于 华为 openEuler 22.03 LTS 系统,使用 kubeadm v1.24.1 搭建一套由单 Master node 和两个 Worker node 组成的 k8s v1.24.1 版本的集群环境。

系统环境准备

部署要求

在开始部署之前,部署 k8s 集群的宿主机(vm 或 物理机)需要满足以下几个条件:

  • 宿主机 3 台,操作系统 CentOS7.x/8.x-86_x64 系列(此处使用 openEuler 22.03 LTS)

  • 硬件配置:RAM 4GB或更多,CPU 核数 2c 或更多,硬盘 60GB 或更多

  • 集群中所有机器之间网络互通

  • 可以访问外网,需要拉取镜像

  • 关闭防火墙,禁止 swap 分区

  • 所有集群节点同步系统时间(使用 ntpdate 工具)

注意:以上部署规格的配置要求为最小化集群规模要求,生产环境的集群部署要求按实际情况扩展配置,为了保障集群环境的高可用性,搭建集群环境的宿主机通常以奇数( ≥ 3、5、7...)节点最佳。

部署规划

此处以单 master node 和两 worker node 集群模式为例,使用 kubeadm 部署  Kubernetes v1.24.1 版本集群环境。

1. 单 master 集群模式

62b29ed709c814b668c66c5f2ca4ed45.png
单 master 和 3 worker node 集群模式

2. vm 资源编排

此处使用 VMware Workstation Pro v16.2.2 虚拟机搭建 vm 环境,规划如下:

k8s 集群角色ip 地址hostname 主机名称资源规格操作系统安装组件
master192.168.18.130k8s-master-012c4g/60gopenEuler 22.03 LTSkube-apiserver、kube-controller-manager、kube-scheduler、etcd、containerd、kubelet、kube-proxy、keepalived、nginx、calico、metrics-server、dashboard
worker node192.168.18.131k8s-node-012c4g/60gopenEuler 22.03 LTScontainerd、kubelet、kube-proxy、ingress-controller、calico,coredns
worker node192.168.18.132k8s-node-022c4g/60gopenEuler 22.03 LTScontainerd、kubelet、kube-proxy、ingress-controller、calico,coredns

关于 VMware Workstation Pro v16.2.2 虚拟机自行下载,并安装配置好,vm 系统使用华为 openEuler 22.03 LTS ISO 镜像。

注意:VMware 中网络配置选择【NAT 模式】,确保 vm 内部网络环境可以访问到外部网络环境。

3. k8s 组件版本

关于 k8s 的常用资源组件版本信息规划如下:

名称版本下载地址
kubernetesv1.24.1https://github.com/kubernetes/kubernetes/releases/tag/v1.24.1
kubelet、kubeadm、kubectlv1.24.1yum install -y kubelet-1.24.1 kubeadm-1.24.1 kubectl-1.24.1
containerdv1.6.4,cni v0.3.1https://github.com/containerd/containerd/releases/tag/v1.6.4
flannelv0.18.0https://github.com/flannel-io/flannel/releases/tag/v0.18.0
calicov3.23.1https://github.com/projectcalico/calico/releases/tag/v3.23.1
kube-state-metricsv2.4.2https://github.com/kubernetes/kube-state-metrics/releases/tag/v2.4.2
metrics-server-helm-chartv3.8.2https://github.com/kubernetes-sigs/metrics-server/releases/tag/metrics-server-helm-chart-3.8.2
Kong Ingress Controller for Kubernetes (KIC)v2.3.1https://github.com/Kong/kubernetes-ingress-controller/releases/tag/v2.3.1
dashboardv2.5.1https://github.com/kubernetes/dashboard/releases/tag/v2.5.1

4. 关于 openEuler

基于华为 openEuler 系统环境部署,推荐使用 openEuler 22.03 LTS 和 openEuler 20.03 LTS SP3,以 root 身份执行下面命令。

da00506d51d9ea2eec0ff3280c73b782.png

openEuler LTS

为了方便操作,vm 中的 openEuler 系统网络 ip 可以按照上面的编排规划,设置静态 ip 地址。

关于 openEuler 系统的安装,请自行参考官方文档,此处不是重点,接下来介绍 openEuler 系统安装后,我们需要设置的相关事项。

openEuler 资源地址:

  • ISO下载,https://www.openeuler.org/zh/download/

  • 安装指南,https://docs.openeuler.org/zh/docs/22.03_LTS/docs/Installation/installation.html

5. shell 终端

以下是一些比较常用的 shell 终端,选择自己喜欢的一个安装配置即可。

  • Xshell 5/6/7

  • Windows PowerShell / PowerShell

  • Windows Terminal

  • PuTTY

  • Visual Studio Code

VM 系统部署操作事项(所有节点)

注意:下面命令在 k8s 所有节点(master + worker)执行。

1. 关闭防火墙 Firewalld

防火墙 firewalld 先 stop 再 disable ,操作如下:

systemctl stop firewalld #停止 $
systemctl disable firewalld #开机禁用 $

查看防火墙状态

systemctl status firewalld #查看状态

输出如下信息,说明已经关闭

[root@k8s-master-01 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemonLoaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)Active: inactive (dead)Docs: man:firewalld(1)

[Linux防火墙操作命令,开放或关闭端口] =》 https://zhuanlan.zhihu.com/p/161196711

2. 关闭 SELinux

安全增强型 Linux(SELinux)是一个 Linux 内核的功能,它提供支持访问控制的安全政策保护机制。

# 临时关闭 SELinux。
setenforce 0 # 永久关闭 SELinux。
vi /etc/selinux/config
SELINUX=disabled

验证 selinux 状态

getenforce

输出如下信息,说明已经关闭

[root@k8s-node-01 ~]# getenforce
Disabled

SELinux 状态说明

  • SELinux 状态为 disabled,表明 SELinux 已关闭

  • SELinux 状态为 enforcing 或者 permissive,表明 SELinux  在运行

3. 关闭 Swap

swap 的用途 ?

swap 分区就是交换分区,(windows 平台叫虚拟内存) 在物理内存不够用时,操作系统会从物理内存中把部分暂时不被使用的数据转移到交换分区,从而为当前运行的程序留出足够的物理内存空间。

为什么要关闭 swap ?

swap 启用后,在使用磁盘空间和内存交换数据时,性能表现会较差,会减慢程序执行的速度。

有的软件的设计师不想使用交换分区,例如:kubelet 在 v1.8 版本以后强制要求 swap 必须关闭,否则会报错:

Running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false

或者 kubeadm init 时会报错:

[ERROR Swap]: running with swap on is not supported. Please disable swap

关闭 swap

swapoff -a # 临时关闭
vi /etc/fstab # 永久关闭,注释掉 swap 这行

查看 swap 是否关闭

[root@k8s-master-01 ~]# free -mtotal        used        free      shared  buff/cache   available
Mem:           1454         881         147          73         425         179
Swap:             0           0           0

显示 total/used/free 为 0,说明已经关闭。

4. 设置宿主机名称

依据宿主机(vm 或物理机)资源编排情况,使用 systemd 里面的 hostnamectl 设置主机名。

# 临时
hostnamectl set-hostname k8s-master-01
hostnamectl set-hostname k8s-node-01
hostnamectl set-hostname k8s-node-02# 永久,编写对应的 hostname
vi /etc/hostname

设置完成后,重新进入下 shell 终端,使配置生效。

bash

5. 在 Master node 和 Worker node 添加 hosts

修改 hosts 文件,配置主机名称和 ip 之间的映射。

$ cat > /etc/hosts << EOF
192.168.18.130 k8s-master-01
192.168.18.131 k8s-node-01
192.168.18.132 k8s-node-02
EOF

进入 bash 访问测试 node 节点网络是否连通

bash
...
ping k8s-master-01
ping k8s-node-01
ping k8s-node-02

6. 创建 containerd.conf 配置文件

在路径 "/etc/modules-load.d/containerd.conf" 创建配置文件。

cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

执行以下命令使配置生效

modprobe overlay
modprobe br_netfilter

7. 将桥接的 IPv4 流量传递到 IPTABLES 链

IPTABLES 规则实现 Docker 或 K8s 的网络通信,非常关键。查看 "/etc/sysctl.d/99-xxx.conf" 配置文件。

[root@k8s-master-01 /]# ls /etc/sysctl.d/
99-kubernetes-cri.conf  99-sysctl.conf
[root@k8s-master-01 /]# cat /etc/sysctl.d/99-sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
kernel.sysrq=0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
user.max_user_namespaces=28633
net.ipv4.ip_forward=1
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.tcp_syncookies=1
kernel.dmesg_restrict=1
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0

修改内核参数(上面的 99-sysctl.conf 配置文件已经修)

# 1、加载br_netfilter模块
modprobe br_netfilter# 2、验证模块是否加载成功
lsmod | grep br_netfilter# 3、修改内核参数
cat > /etc/sysctl.d/99-sysctl.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
user.max_user_namespaces=28633
net.ipv4.ip_forward = 1
EOF# 4、使刚才修改的内核参数生效,此处使用的是 99-sysctl.conf 配置文件。
sysctl -p /etc/sysctl.d/99-sysctl.conf

sysctl 命令用于运行时配置内核参数,这些参数位于 "/proc/sys" 目录下。sysctl 配置与显示在 "/proc/sys" 目录中的内核参数。可以用 sysctl 来设置或重新设置联网功能,如 IP 转发、IP 碎片去除以及源路由检查等。用户只需要编辑 "/etc/sysctl.conf" 文件,即可手工或自动执行由 sysctl 控制的功能。

8. 配置服务器支持开启 IPVS 的前提条件(K8s 推荐配置)

IPVS 称之为 IP虚拟服务器(IP Virtual Server,简写为 IPVS)。是运行在 LVS 下的提供负载平衡功能的一种技术。

IPVS 基本上是一种高效的 Layer-4 交换机,它提供负载平衡的功能。

由于 IPVS 已经加入到了 Linux 内核的主干,所以为 kube-proxy(Kubernetes Service) 开启 IPVS 的前提需要加载以下的 Linux 内核模块:

ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4 # 或 nf_conntrack

在所有服务器集群节点上执行以下脚本

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4 # 若提示在内核中找不到 nf_conntrack_ipv4, 可以尝试切换 nf_conntrack
EOF# 或者 grep -e ip_vs -e nf_conntrack
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

上面脚本创建了的 "/etc/sysconfig/modules/ipvs.modules" 文件,保证在节点重启后能自动加载所需模块。可执行命令 【lsmod | grep -e ip_vs -e nf_conntrack_ipv4】查看所需内核模块是否正确加载。

接下来还需要确保各个节点上已经安装了 ipset 软件包,为了便于查看 ipvs 的代理规则,最好安装一下管理工具 ipvsadm。

yum install -y ipset ipvsadm

如果不满足以上前提条件,则即使 kube-proxy 的配置开启了 ipvs 模式,也会退回到 iptables 模式。

9. 同步系统时间

ntpdate 指令通过轮询指定为服务器参数的 网络时间协议(NTP)  服务器来设置本地日期和时间,从而确定正确的时间。

此命令的适用范围:RedHat、RHEL、Ubuntu、CentOS、Fedora。

# 安装 ntpdate 
yum install ntpdate -y# 执行同步命令
ntpdate time.windows.com
# 跟网络源做同步
ntpdate cn.pool.ntp.org# 把时间同步做成计划任务
crontab -e
* */1 * * * /usr/sbin/ntpdate   cn.pool.ntp.org# 重启crond服务
service crond restart# 查看当前时区
date -R

同步系统时间输出如下信息

[root@k8s-master-01 /]# ntpdate time.windows.com
29 May 16:19:17 ntpdate[7873]: adjust time server 20.189.79.72 offset +0.001081 sec

IPVS 和 IPTABLES 对比分析

IPVS 是什么?

IPVS (IP Virtual Server) 实现了传输层负载均衡,也就是我们常说的 4 层局域网交换机(LAN Switches),作为 Linux 内核的一部分。IPVS 运行在主机上,在真实服务器集群前充当负载均衡器。IPVS 可以将基于 TCP 和 UDP 的服务请求转发到真实服务器上,并使真实服务器的服务在单个 IP 地址上显示为虚拟服务。

IPVS 和 IPTABLES 对比分析

kube-proxy 支持 iptables 和 ipvs 两种模式, 在 kubernetes v1.8 中引入了 ipvs 模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中就添加支持了,从 v1.2 版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和 iptables 都是基于 netfilter 的,但是 ipvs 采用的是 hash 表,因此当 service 数量达到一定规模时,hash 查表的速度优势就会显现出来,从而提高 service 的服务性能。

那么 ipvs 模式和 iptables 模式之间有哪些差异呢?

  1. ipvs 为大型集群提供了更好的可扩展性和性能

  2. ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等等)

  3. ipvs 支持服务器健康检查和连接重试等功能

在 k8s 的集群环境中,推荐配置  ipvs ,为一定数量规模的 service 提高服务性能。

安装 containerd/kubeadm/kubelet(所有节点)

Containerd 简介

Containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性,具备如下功能:

  • 管理容器的生命周期(从创建容器到销毁容器)

  • 拉取/推送容器镜像

  • 存储管理(管理镜像及容器数据的存储)

  • 调用 runc 运行容器(与 runc 等容器运行时交互)

  • 管理容器网络接口及网络

自 Kubernetes v1.24 起,Dockershim 已被删除,由于社区的关注,Docker 和 Mirantis 共同决定继续以 [cri-dockerd] 的形式支持 dockershim 代码(https://www.mirantis.com/blog/the-future-of-dockershim-is -cri-dockerd/), 允许你在需要时继续使用 Docker Engine 作为容器运行时。对于想要尝试其他运行时(如 containerd 或 cri-o) 的用户,已编写迁移文档(https://kubernetes.io/zh/docs/tasks/administer-cluster/migrating-from-dockershim/change-runtime-containerd/)。

查看删除 Dockershim 的原因

  • Dockershim:历史背景 =》 https://kubernetes.io/zh/blog/2022/05/03/dockershim-historical-context/

如果试图将链从最终用户(user)绘制到实际的容器进程(runc),它可能如下所示:059f9970ee96a425e973f3b8b38677a8.pngrunc 是一个命令行客户端,用于运行根据 OCI(开放容器计划,Open Container Initiative/OCI) 格式打包的应用程序,并且是 OCI 规范的兼容实现。

使用 Containerd 的理由

  • Kubernetes 在 v1.23 版本及以后版本不再默认采用 Docker/Dockershim ,而建议采用 Containerd;

  • Containerd 比 Docker/Dockershim 更加轻量级,在生产环境中使用更佳合适(稳定,性能);

Containerd 安装

下面我们进行 containerd 容器运行时的安装,操作如下:

1. 安装 wget (可选)

由于 openEuler 系统本身集成了 curl ,安装 wget 不是必须项。

# 安装 wget
sudo yum install wget -y# 此处安装的 wget 版本信息
...
Installed:wget-1.20.3-2.oe1.x86_64

2. 下载 containerd

分别使用 wget 和 curl 下载 containerd v1.6.4 版本。

# 使用 wget 下载 containerd v1.6.4
sudo wget https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz# 使用 curl 下载 containerd v1.6.4
curl -L https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz -O cri-containerd-cni-1.6.4-linux-amd64.tar.gz

3. 安装 tar

tar 命令简介

  • Linux tar(英文全拼:tape archive )命令用于备份文件。

  • tar 是用来建立,还原备份文件的工具程序,它可以加入,解开备份文件内的文件。

# 安装 tar
sudo yum install -y tar# 查看压缩包包含哪些文件
sudo tar -tf cri-containerd-cni-1.6.4-linux-amd64.tar.gz # 将压缩包解压至 cri-containerd-cni 文件夹(这里用命令创建 cri-containerd-cni文件夹,因为没有实现创建该文件夹),防止将文件都解压缩到当前文件夹(可以看到有etc、opt、usr三个子文件夹)。
sudo tar xzf cri-containerd-cni-1.6.4-linux-amd64.tar.gz -C cri-containerd-cni | mkdir cri-containerd-cni

cri-containerd-cni-1.6.4-linux-amd64.tar.gz 文件中包含三个文件夹,分别是【etc、opt、usr】,如下图所示:ad77f973594c5bf5f318862aaddbe948.png

4. 安装 containerd

# 解压 containerd 到根目录
tar zxvf cri-containerd-cni-1.6.0-linux-amd64.tar.gz -C /# 生成 containerd 默认配置
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

注意:确认 containerd 可执行文件所在目录在 PATH 环境变量中。

5. 配置 containerd 软件源

参考配置文件 "/etc/containerd/config.toml" 如下:

disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
version = 2[cgroup]path = ""[debug]address = ""format = ""gid = 0level = ""uid = 0[grpc]address = "/run/containerd/containerd.sock"gid = 0max_recv_message_size = 16777216max_send_message_size = 16777216tcp_address = ""tcp_tls_cert = ""tcp_tls_key = ""uid = 0[metrics]address = ""grpc_histogram = false[plugins][plugins."io.containerd.gc.v1.scheduler"]deletion_threshold = 0mutation_threshold = 100pause_threshold = 0.02schedule_delay = "0s"startup_delay = "100ms"[plugins."io.containerd.grpc.v1.cri"]disable_apparmor = falsedisable_cgroup = falsedisable_hugetlb_controller = truedisable_proc_mount = falsedisable_tcp_service = trueenable_selinux = falseenable_tls_streaming = falseignore_image_defined_volumes = falsemax_concurrent_downloads = 3max_container_log_line_size = 16384netns_mounts_under_state_dir = falserestrict_oom_score_adj = false#sandbox_image = "k8s.gcr.io/pause:3.6"
# 1. 修改基础镜像地址(此处以阿里云为例)#sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6"sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"selinux_category_range = 1024stats_collect_period = 10stream_idle_timeout = "4h0m0s"stream_server_address = "127.0.0.1"stream_server_port = "0"systemd_cgroup = falsetolerate_missing_hugetlb_controller = trueunset_seccomp_profile = ""[plugins."io.containerd.grpc.v1.cri".cni]bin_dir = "/opt/cni/bin"conf_dir = "/etc/cni/net.d"conf_template = ""max_conf_num = 1[plugins."io.containerd.grpc.v1.cri".containerd]default_runtime_name = "runc"disable_snapshot_annotations = truediscard_unpacked_layers = falseno_pivot = falsesnapshotter = "overlayfs"[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]base_runtime_spec = ""container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options][plugins."io.containerd.grpc.v1.cri".containerd.runtimes][plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]base_runtime_spec = ""container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_root = ""runtime_type = "io.containerd.runc.v2"[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]BinaryName = ""CriuImagePath = ""CriuPath = ""CriuWorkPath = ""IoGid = 0IoUid = 0NoNewKeyring = falseNoPivotRoot = falseRoot = ""ShimCgroup = ""SystemdCgroup = false[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]base_runtime_spec = ""container_annotations = []pod_annotations = []privileged_without_host_devices = falseruntime_engine = ""runtime_root = ""runtime_type = ""[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options][plugins."io.containerd.grpc.v1.cri".image_decryption]key_model = "node"[plugins."io.containerd.grpc.v1.cri".registry]config_path = ""[plugins."io.containerd.grpc.v1.cri".registry.auths][plugins."io.containerd.grpc.v1.cri".registry.configs][plugins."io.containerd.grpc.v1.cri".registry.headers][plugins."io.containerd.grpc.v1.cri".registry.mirrors]
# 2. 设置仓库地址(镜像源)[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://usydjf4t.mirror.aliyuncs.com","https://mirror.ccs.tencentyun.com","https://registry.docker-cn.com","http://hub-mirror.c.163.com"][plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]endpoint = ["https://registry.cn-hangzhou.aliyuncs.com/google_containers"]
#       [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.0.187:5000"]
#         endpoint = ["http://192.168.0.187:5000"]
#       [plugins."io.containerd.grpc.v1.cri".registry.configs]
#         [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.0.187:5000".tls]
#           insecure_skip_verify = true
#         [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.creditgogogo.com".auth]
#           username = "admin"
#           password = "Harbor12345"[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]tls_cert_file = ""tls_key_file = ""[plugins."io.containerd.internal.v1.opt"]path = "/opt/containerd"[plugins."io.containerd.internal.v1.restart"]interval = "10s"[plugins."io.containerd.metadata.v1.bolt"]content_sharing_policy = "shared"[plugins."io.containerd.monitor.v1.cgroups"]no_prometheus = false[plugins."io.containerd.runtime.v1.linux"]no_shim = falseruntime = "runc"runtime_root = ""shim = "containerd-shim"shim_debug = false[plugins."io.containerd.runtime.v2.task"]platforms = ["linux/amd64"][plugins."io.containerd.service.v1.diff-service"]default = ["walking"][plugins."io.containerd.snapshotter.v1.aufs"]root_path = ""[plugins."io.containerd.snapshotter.v1.btrfs"]root_path = ""[plugins."io.containerd.snapshotter.v1.devmapper"]async_remove = falsebase_image_size = ""pool_name = ""root_path = ""[plugins."io.containerd.snapshotter.v1.native"]root_path = ""[plugins."io.containerd.snapshotter.v1.overlayfs"]root_path = ""[plugins."io.containerd.snapshotter.v1.zfs"]root_path = ""[proxy_plugins][stream_processors][stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar"[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]path = "ctd-decoder"returns = "application/vnd.oci.image.layer.v1.tar+gzip"[timeouts]"io.containerd.timeout.shim.cleanup" = "5s""io.containerd.timeout.shim.load" = "5s""io.containerd.timeout.shim.shutdown" = "3s""io.containerd.timeout.task.state" = "2s"[ttrpc]address = ""gid = 0uid = 0

被修改的 "/etc/containerd/config.toml" 文件配置说明:

1、基础镜像设置

  • sandbox_image 设置国内基础镜像源地址。

2、镜像仓库设置

  • "docker.io" 配置 docker 公共镜像仓库源。

  • "k8s.gcr.io" 配置 k8s 仓库源。

  • 其中 “192.168.0.187:5000” 是私人仓库地址(没有可以配置)。

  • insecure_skip_verify = true 意为跳过 tls 证书认证。

  • "harbor.creditgogogo.com".auth 设置仓库用户名和密码。

6. 启动 containerd 并设置为开机启动

由于上面下载的 containerd 压缩包中包含一个 "etc/systemd/system/containerd.service" 的文件,这样我们就可以通过 systemd 来配置 containerd 作为守护进程运行。

[root@k8s-master-01 /]# ls etc/systemd/system/
bluetooth.target.wants  cron.service         dbus-org.bluez.service                      default.target      multi-user.target.wants      sockets.target.wants  timedatex.service
containerd.service      ctrl-alt-del.target  dbus-org.freedesktop.nm-dispatcher.service  getty.target.wants  network-online.target.wants  sysinit.target.wants  timers.target.wants

启动 containerd

# 启动 containerd,并设置为开机启动
systemctl daemon-reload && systemctl enable containerd && systemctl start containerd
# 查看 containerd 状态
systemctl status containerd
# 重启 containerd 
systemctl restart containerd

此处启动 containerd 可能会显示如下信息:

System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

因为 wsl 子系统不能使用 systemd(基于 systemctl 或 service 命令的服务无法运行)。了解更多信息,请查看【WSL2 中使用 systemctl 命令】。

  • WSL2 中使用 systemctl 命令 =》https://www.isolves.com/it/qt/2020-12-10/34360.html

查看 "etc/systemd/system/containerd.service" 文件

cat etc/systemd/system/containerd.service

输出配置信息如下:

# Copyright The containerd Authors.
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerdType=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999[Install]
WantedBy=multi-user.target

这里有两个重要的参数:

  • Delegate:这个选项允许 containerd 以及运行时自己管理自己创建容器的 cgroups。如果不设置这个选项,systemd 就会将进程移到自己的 cgroups 中,从而导致 containerd 无法正确获取容器的资源使用情况。

  • KillMode:这个选项用来处理 containerd 进程被杀死的方式。默认情况下,systemd 会在进程的 cgroup 中查找并杀死 containerd 的所有子进程。

KillMode 字段可以设置的值如下:

  • control-group:当前控制组里面的所有子进程,都会被杀掉

  • process:只杀主进程

  • mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号

  • none:没有进程会被杀掉,只是执行服务的 stop 命令

注意:需要将 KillMode 的值设置为 process,这样可以确保升级或重启 containerd 时不杀死现有的容器。

7. 查看 containerd 信息

crictl info
# 更多使用
crictl --help

K8s 配置阿里云 repo 文件(yum 软件源)

默认配置是国外的镜像源,由于国内网络原因无法访问,所以配置阿里云的 yum 软件源。

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

阿里云 Kubernetes 镜像:

  • 【容器】 https://developer.aliyun.com/mirror/?spm=a2c6h.13651102.0.0.3e221b11RAcHlc&serviceType=mirror&tag=%E5%AE%B9%E5%99%A8

  • 【Kubernetes 镜像源】 https://developer.aliyun.com/mirror/kubernetes

安装 kubeadm、kubelet 和 kubectl(所有节点)

由于版本更新频繁,因此这里指定版本号部署。

yum install -y kubelet-1.24.1 kubeadm-1.24.1 kubectl-1.24.1

启动 kubelet 并设置开机启动

systemctl enable kubelet && systemctl start kubelet

ps: 由于官网未开放同步方式,可能会有索引 gpg 检查失败的情况,这时请用【yum install -y --nogpgcheck kubelet kubeadm kubectl 】安装。

部署 K8s Master 节点

1. K8s 集群初始化(kubeadm init)

依据上面的 vm 资源规划,在 master 节点(192.168.18.130)执行如下命令:

kubeadm init \--apiserver-advertise-address=192.168.18.130 \--image-repository registry.aliyuncs.com/google_containers \--kubernetes-version v1.24.1 \--service-cidr=10.96.0.0/12 \--pod-network-cidr=10.244.0.0/16 \--ignore-preflight-errors=all

参数说明:

  • --apiserver-advertise-address 集群通告地址

  • --image-repository  由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址

  • --kubernetes-version K8s 版本,与上面安装的一致

  • --service-cidr 集群内部虚拟网络,Pod 统一访问入口

  • --pod-network-cidr Pod网络,与下面部署的 CNI 网络组件 yaml 中保持一致

  • --ignore-preflight-errors 忽略所有预检项的警告信息

或者使用配置文件引导:

$ vi kubeadm.conf
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.24.1
imageRepository: registry.aliyuncs.com/google_containers 
networking:podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12 $ kubeadm init --config kubeadm.conf --ignore-preflight-errors=all

kubeadm init 初始化成功,输出如下信息:

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/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou 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/Then you can join any number of worker nodes by running the following on each as root:kubeadm join 192.168.18.130:6443 --token pc5d3x.9ccv3m5y1llljk90 \--discovery-token-ca-cert-hash sha256:3f7b37c18a5ec21c3e225025e13a0ac53e7abdf717859808b24f9bc909b32b5b

此处注意保存下 kubeadm init 初始化产生的信息,方便下面环节的部署操作使用。

2. 拷贝文件到默认路径

拷贝 kubectl 使用的连接 k8s 认证文件到默认路径

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

3. 查看 k8s 集群节点信息

[root@k8s-master-01 ~]# kubectl get node
NAME            STATUS   ROLES           AGE     VERSION
k8s-master-01   Ready    control-plane   4h8m    v1.24.1
k8s-node-01     Ready    <none>          3h14m   v1.24.1
k8s-node-02     Ready    <none>          3h14m   v1.24.1

4. 查看 containerd 拉取的镜像

[root@k8s-master-01 /]# crictl image ls
IMAGE                                                             TAG                 IMAGE ID            SIZE
docker.io/calico/cni                                              v3.23.1             90d97aa939bbf       111MB
docker.io/calico/node                                             v3.23.1             fbfd04bbb7f47       76.6MB
registry.aliyuncs.com/google_containers/coredns                   v1.8.6              a4ca41631cc7a       13.6MB
registry.aliyuncs.com/google_containers/etcd                      3.5.3-0             aebe758cef4cd       102MB
registry.aliyuncs.com/google_containers/kube-apiserver            v1.24.1             e9f4b425f9192       33.8MB
registry.aliyuncs.com/google_containers/kube-controller-manager   v1.24.1             b4ea7e648530d       31MB
registry.aliyuncs.com/google_containers/kube-proxy                v1.24.1             beb86f5d8e6cd       39.5MB
registry.aliyuncs.com/google_containers/kube-scheduler            v1.24.1             18688a72645c5       15.5MB
registry.aliyuncs.com/google_containers/pause                     3.7                 221177c6082a8       311kB

注意:上面的镜像除了 calico 相关的(docker.io/calico/cni 和 docker.io/calico/node) 之外,其他都是 kubectl int 初始化拉取的镜像资源。

Worker 节点加入 K8s 集群

1. k8s 集群环境加入新的 worker node

向集群添加新 node 节点,执行在 kubeadm init 输出的 kubeadm join 命令,分别在 worker node 执行如下命令:

kubeadm join 192.168.18.130:6443 --token pc5d3x.9ccv3m5y1llljk90 \--discovery-token-ca-cert-hash sha256:3f7b37c18a5ec21c3e225025e13a0ac53e7abdf717859808b24f9bc909b32b5b

2. 生成加入 k8s 集群环境的 token

默认 token 有效期为 24 小时,当过期之后,该 token 就不可用了。这时就需要重新创建 token,操作如下:

$ kubeadm token create
$ kubeadm token list
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
63bca849e0e01691ae14eab449570284f0c3ddeea590f8da988c07fe2729e924$ kubeadm join 192.168.31.61:6443 --token nuja6n.o3jrhsffiqs9swnu --discovery-token-ca-cert-hash sha256:63bca849e0e01691ae14eab449570284f0c3ddeea590f8da988c07fe2729e924

或者直接命令快捷生成

kubeadm token create --print-join-command
  • 参考文档 =》https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/

部署容器网络/CNI(所有节点)

1. CNI 简介

CNI 全称是 Container Network Interface,即容器网络的 API 接口。

它是 K8s 中标准的一个调用网络实现的接口。Kubelet 通过这个标准的 API 来调用不同的网络插件以实现不同的网络配置方式。

CNI 插件就是实现了一系列的 CNI API 接口。常见的 CNI 插件包括 Calico、Flannel、Terway、Weave Net 以及 Contiv。

2. CNI 分类及选型参考

CNI 插件可以分为三种:Overlay、路由及 Underlay。

  • 【Overlay 模式】的典型特征是容器独立于主机的 IP 段,这个 IP 段进行跨主机网络通信时是通过在主机之间创建隧道的方式,将整个容器网段的包全都封装成底层的物理网络中主机之间的包。该方式的好处在于它不依赖于底层网络;

  • 【路由模式】中主机和容器也分属不同的网段,它与 Overlay 模式的主要区别在于它的跨主机通信是通过路由打通,无需在不同主机之间做一个隧道封包。但路由打通就需要部分依赖于底层网络,比如说要求底层网络有二层可达的一个能力;

  • 【Underlay 模式】中容器和宿主机位于同一层网络,两者拥有相同的地位。容器之间网络的打通主要依靠于底层网络。因此该模式是强依赖于底层能力的。

对于 CNI 插件的选择,有以下几个维度参考:

  • 环境限制,不同环境中所支持的底层能力是不同的。

  • 功能需求

  • 性能需求

了解更多可以参考 =》https://www.kubernetes.org.cn/6908.html

注意:CNI 插件只需要部署其中一个即可,这里推荐 Calico 或 Flannel。

3. Calico 简介

Calico 是一个纯三层的数据中心网络方案,Calico 支持广泛的平台,包括 Kubernetes、OpenStack 等。

Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播。

此外,Calico  项目还实现了 Kubernetes 网络策略,提供 ACL 功能。

4. 下载 Calico 插件

wget https://docs.projectcalico.org/manifests/calico.yaml

5. 修改里面定义的 Pod 网络

下载完后还需要修改里面定义 Pod 网络(CALICO_IPV4POOL_CIDR),与前面 kubeadm init 指定的一样【--pod-network-cidr=10.244.0.0/16】

# The default IPv4 pool to create on startup if none exists. Pod IPs will be
# chosen from this range. Changing this value after installation will have
# no effect. This should fall within `--cluster-cidr`.
# - name: CALICO_IPV4POOL_CIDR
#   value: "192.168.0.0/16"
- name: CALICO_IPV4POOL_CIDRvalue: "10.244.0.0/16"

查找 CALICO_IPV4POOL_CIDR

vi calico.yaml
...
/CALICO_IPV4POOL_CIDR

6. 应用 calico.yaml 配置

修改完后应用 calico.yaml 清单

kubectl apply -f calico.yaml

输出如下信息:

[root@k8s-master-01 /]# ls
bin  boot  calico.yaml  cri-containerd-cni-1.6.4-linux-amd64.tar.gz  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@k8s-master-01 /]# kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
poddisruptionbudget.policy/calico-kube-controllers created

7. 查看命名空间 kube-system 下的 pod

kubectl get pods -n kube-system

输出如下信息:

[root@k8s-master-01 /]# kubectl get pods -n kube-system
NAME                                       READY   STATUS             RESTARTS        AGE
calico-kube-controllers-56cdb7c587-mfl9d   1/1     Running            22 (21m ago)    126m
calico-node-2dtr8                          0/1     Running            35 (5s ago)     126m
calico-node-hmdkf                          0/1     CrashLoopBackOff   35 (2m6s ago)   126m
calico-node-l6448                          0/1     Error              38 (70s ago)    126m
coredns-74586cf9b6-b5r68                   1/1     Running            0               7h5m
coredns-74586cf9b6-jndhp                   1/1     Running            0               7h6m
etcd-k8s-master-01                         1/1     Running            0               7h9m
kube-apiserver-k8s-master-01               1/1     Running            6 (20m ago)     7h9m
kube-controller-manager-k8s-master-01      0/1     CrashLoopBackOff   23 (119s ago)   7h9m
kube-proxy-ctx7q                           1/1     Running            0               7h6m
kube-proxy-l72sj                           1/1     Running            0               6h15m
kube-proxy-s65x9                           1/1     Running            0               6h15m
kube-scheduler-k8s-master-01               0/1     CrashLoopBackOff   21 (119s ago)   7h9m

测试 K8s 集群

  • 验证 Pod 工作

  • 验证 Pod 网络通信

  • 验证 DNS 解析

在 K8s 集群中创建一个 Pod,验证是否正常运行:

kubectl create deployment nginx --image=nginx:latest -p 80:8080
kubectl expose deployment nginx --port=8080 --type=NodePort
kubectl get pod,svc

访问 nginx 的 svc 地址:

http://NodeIP:Port

关于 K8s nodePort、port、targetPort、hostPort 端口的介绍 =》https://www.jianshu.com/p/8275f2031c83

在 Master 节点部署 Dashboard

1. 下载 dashboard 的 recommended.yaml 配置文件

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml

2. recommended.yaml 文件重命名(可选)

把下载的 recommended.yaml 文件重命名为 dashboard-v2.5.1.yaml (可选,方便文件记录)

mv recommended.yaml dashboard-v2.5.1.yaml

3. 修改 Dashboard 配置文件暴露到外部访问

默认 Dashboard 只能集群内部访问,修改 Service 为 NodePort 类型,暴露到外部访问:

$ vi dashboard-v2.5.1.yaml
---
kind: Service
apiVersion: v1
metadata:labels:k8s-app: kubernetes-dashboardname: kubernetes-dashboardnamespace: kubernetes-dashboard
spec:ports:- port: 443targetPort: 8443nodePort: 30001selector:k8s-app: kubernetes-dashboardtype: NodePort
---

4. 执行 dashboard-v2.5.1.yaml  配置文件

kubectl apply -f dashboard-v2.5.1.yaml

输出如下信息:

[root@k8s-master-01 /]# kubectl apply -f /root/dashboard-v2.5.1.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created

5. 查看 kubernetes-dashboard

kubectl get pods -n kubernetes-dashboard

输出如下信息:

[root@k8s-master-01 /]# kubectl get pods -n kubernetes-dashboard
NAME                                         READY   STATUS              RESTARTS   AGE
dashboard-metrics-scraper-7bfdf779ff-q9tsk   0/1     ContainerCreating   0          74s
kubernetes-dashboard-6465b7f54c-frf2b        0/1     ContainerCreating   0          74s[root@k8s-master-01 /]# kubectl get pods -n kubernetes-dashboard
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-7bfdf779ff-q9tsk   1/1     Running   0          32m
kubernetes-dashboard-6465b7f54c-frf2b        1/1     Running   0          32m

6. 访问 kubernetes-dashboard

访问 kubernetes-dashboard 地址

https://NodeIP:30001

创建 ServiceAccount 并绑定默认 cluster-admin 管理员集群角色:

# 创建用户
$ kubectl create serviceaccount dashboard-admin -n kube-system# 用户授权
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin# 获取用户 Token
$ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

此处 master 节点的 ip 是 192.168.18.130, 浏览器访问地址 =》https://192.168.18.130:30001/#/login

25a068f93391cca4d90633b72ad6f337.png
dashboard-login

最后使用输出的 token 登录 Dashboard。

总结

搭建 k8s 集群环境时,事先要规划编排好相关的资源环境以及各个组件的版本信息,开始部署之前务必保障系统环境准备事项的相关设置操作,此处我们采用的容器运行时是 containerd,由于默认的 yum 镜像源是国外环境,在国内网络环境无法访问,可配置国内的 yum 源(比如:阿里云 yum 镜像源)保障网络资源的连通性和可访问性,方便后面环节的相关操作(比如:containerd/kubeadm/kubelet 的安装、k8s master 节点的部署、容器网络 CNI 安装及网络编排)。

每一个环节都很重要,中途遇到异常,多查看资料分析下原因,关键在于理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283474.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汇编试验五:编写、调试具有多个段的程序

ds 数据段放入数据正确&#xff1b; 两次push 操作后&#xff0c;ss栈段正确&#xff1b; 由于pop 操作顺序&#xff0c;ds数据段并没有发生改变&#xff1b; Source Code: assume cs:code, ds:data, ss:stackdata segmentdw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H …

SVN四部曲之SVN设置详解深入

想知道不同的设置是干什么用的&#xff0c;你只需将鼠标指针在编辑框/选项框上停留一秒钟...一个帮助提示气泡就会弹出来。 常规设置 图 4.68. 设置对话框&#xff0c;常规设置页面 这个对话框允许你指定自己喜欢的语言&#xff0c;同时也可做那些与Subversion相关的特殊设置。…

Vue3.2单文件组件setup的语法糖总结

目录 前言 setup语法糖 一、基本用法 二、data和methods 三、计算属性computed 四、监听器watch、watchEffect 五、自定义指令directive 六、import导入的内容可直接使用 七、声明props和emits 八、父组件获取子组件的数据 九、provide和inject传值 十、路由useRou…

使用dotnet-monitor分析在Kubernetes的应用程序:Sidecar模式

dotnet-monitor可以在Kubernetes中作为Sidecar运行&#xff0c;Sidecar是一个容器&#xff0c;它与应用程序在同一个Pod中运行&#xff0c;利用Sidecar模式使我们可以诊断及监控应用程序。如下图所示&#xff0c;这是我们最终要实现的目标&#xff0c;通过可视化界面查看应用程…

SFB 项目经验-07-Skype for Business 话机 Polycom CX700

本系列博文&#xff1a;Lync 项目经验-01-共存迁移-Lync2013-TO-SFB 2015-规划01http://dynamic.blog.51cto.com/711418/1858520 Lync 项目经验-02-共存迁移-Lync2013-TO-SFB 2015-规划02http://dynamic.blog.51cto.com/711418/1859143 Lync 项目经验-03-共存迁移-Lync2013-TO…

亿方云CEO程远:转型第一式:链接企业人与数据

传统企业一直在探讨如何做好互联网转型&#xff0c;那么互联网核心是什么&#xff1f;转型目标是什么&#xff1f;亿方云CEO程远在此次峰会上发表了自己看法&#xff0c;他认为快、人、连接是互联网核心基因&#xff0c;转型第一步就在于企业、人与数据的充分链接。中国企业的互…

使用.NET简单实现一个Redis的高性能克隆版(七-完结)

译者注该原文是Ayende Rahien大佬业余自己在使用C# 和 .NET构建一个简单、高性能兼容Redis协议的数据库的经历。首先这个"Redis"是非常简单的实现&#xff0c;但是他在优化这个简单"Redis"路程很有趣&#xff0c;也能给我们在从事性能优化工作时带来一些启…

解决 Vue 里 Script 标签首层不缩进 - VS Code

问题&#xff1a; 在 vscode 使用 vue 的时候&#xff0c;发现 script 标签首层不缩进&#xff1f;&#xff1f;&#xff1f; 下载扩展&#xff1a;prettier 解决方法一&#xff1a; 打开 setting.json文件 添加&#xff1a;"prettier.vueIndentScriptAndStyle": tru…

Android应用开发性能优化完全分析

1 背景 其实有点不想写这篇文章的&#xff0c;但是又想写&#xff0c;有些矛盾。不想写的原因是随便上网一搜一堆关于性能的建议&#xff0c;感觉大家你一总结、我一总结的都说到了很多优化注意事项&#xff0c;但是看过这些文章后大多数存在一个问题就是只给出啥啥啥不能用&am…

ZBLOG-ASP2.2如何给图片增加ALT标签说明文字?

2019独角兽企业重金招聘Python工程师标准>>> 一直以来&#xff0c;我们在建设网站的时候&#xff0c;都容易犯下一个大错误&#xff0c;那就是没有重视图片的文字说明&#xff0c;而大多数时候&#xff0c;技术方面并不能很好的识别图片的内容&#xff0c;这也是受限…

[asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?

在QQ群或者一些程序的交流平台&#xff0c;经常会有人问&#xff1a;我怎么传一个数组在Action中接收、我传的数组为什么Action的model中接收不到、或者我在ajax的data中设置了一些数组&#xff0c;为什么后台还是接收不了、还有一些怎么传送一个复杂的对象或者Action怎么接收一…

拒绝“高冷”词汇!初学C#中的委托

拒绝“高冷”词汇&#xff01;初学C#中的委托 有一天&#xff0c;你写了好多好多带“形参”的构造函数&#xff08;就是“方法”&#xff0c;同义&#xff09;&#xff0c;而且需要向这些构造函数里传递同样的“实参”&#xff0c;然后你就憨憨地一个一个函数的调用并赋予同样的…

JAVA企业级应用TOMCAT实战视频课程

1. Tomcat简介Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目&#xff0c;由Apache、Sun和其他一些公司及个人共同开发而成。Tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用服务器…

WPF 系列-01默认程序结构

WPF应用程序启动项创建一个WPF应用程序&#xff0c;系统为我们自动生成了App.xaml和一个普通的MainWindow.xaml窗体文件。App.xaml 和cs 文件文件如下&#xff1a;<Application x:Class"Example_01.App"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/…

纳税服务系统【角色与用户】

用户与角色之间的关系 我们在做用户模块的时候&#xff0c;漏掉了最后一个功能。在新增功能中是可以选择角色的。 用户与角色之间的关系也是多对多 一个用户对应多个角色一个角色可以被多个用户使用。现在呢&#xff0c;我们的用户表已经是写的了。我们最好就不要修改原有的用户…

flex-grow flex-shrink 解决最后一行个数不足无法对齐

正常情况下&#xff0c;每页大小15个&#xff0c;设置每行3列&#xff0c;刚好5行。 当外部容器宽度不足以放3列时&#xff0c;自动换行&#xff0c;但最后一行元素自动撑满 &#xff0c;会造成元素块大小不一致&#xff0c;不是想要的效果 原始代码示例&#xff1a; <ul …

C# 并行编程避坑指南之-Try Catch系列

自从.NET Framework 4.5(含4.5)提供了Task开启线程后&#xff0c;基本上Thread的使用频率就大幅度降低了&#xff0c;但是一些老项目&#xff0c;或者老程序还是习惯用Thread去做&#xff0c;如果一定要使用Thred&#xff0c;那我们就必须在代码中使用try、catch块去处理异常的…

spring boot 整合mybatis

1、添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.oracle</groupId><artifactId>ojdbc6</art…

k8s 读书笔记 - CRI(容器运行时接口)详解

k8s Node 节点&#xff08;kubelet&#xff09;的主要功能就是启动和停止容器的组件&#xff0c;这组件我们称之为 容器运行时&#xff08;Container Runtime&#xff09;&#xff0c;这其中最知名的就是 Docker 了。为了更具扩展性&#xff0c;k8s 从 v1.5 版本开始就加入了容…

Win11的这个功能,厉害了!

上周微软正式发布了Windows11的22H2版本&#xff0c;虽说是一周年更新版&#xff0c;但仍然有不少的问题。微软给Win10换了一套皮肤&#xff0c;并做了一些优化升级&#xff0c;摇身一变成了Win11&#xff0c;但是外观方面却做的并不是很协调&#xff0c;有一些界面仍然保留着以…