环境规划

Kubernetes 集群大致分为两类:一主多从和多主多从。
(1)一主多从(单 master ):一个 Master 节点,多台 Node 节点,搭建简单,但是有单机故障风险,适合用于测试环境。
(2)多主多从(高可用):多台 Master 节点和多台 Node 节点,搭建麻烦但安全性高,适合用于生产环境。

kubernetes有多种部署方式,目前主流的方式有kubeadmminikube二进制包三种。简介如下:
(1)minikube:一个用于快速搭建单节点的kubernetes工具。
(2)kubeadm:一个用于快速搭建kubernetes集群的工具。
(3)二进制包:从官网上下载每个组件的二进制包依次安装,此方式对于理解kubernetes组件更加有效。

  • 集群类型:一主多从

  • 安装方式:使用kubeadm工具快速搭建kubernetes集群

主机规划

角色 IP地址 实验环境
Master 192.168.40.101 Centos7.9
Node1 192.168.40.102 Centos7.9
Node2 192.168.40.103 Centos7.9

环境准备

搭建流程

  1. 准备3台机器,要求网络互通(云服务器私网互通,虚拟机网络互通),同时可联网,因为要拉取镜像
  2. 关闭``防火墙selinuxswap分区等,这些是可能会导致k8s集群出问题的地方,需要提前配置好
  3. 安装Docker容器化环境,同时安装三个核心组件:kubeadmkubeletkubectl
  4. 下载k8s所需镜像,创建一个Master节点,将Node节点加入到当前集群
  5. k8s集群安装相关服务进行验证,登录k8sweb的用户界面Dashboard

安装环境准备

其实简单来说通过两条指令就能部署一个kubernetes集群:
1.创建一个master节点:kubeadm init
2.将node节点加入当前集群:kubeadm join <Master 节点的IP和端口>
在执行kubeadm init 指令后,kubeadm首先会做一系列检查工作,确保机器能够安装kubernetes

linux系统内核的版本是否必须3.10以上?
linux cgroups模块是否可用?
机器的hostname是否标准?
安装的kubeadmkubelet是否匹配?
docker是否已经安装?

因此建议把环境配置好再部署。

升级系统内核

K8S集群服务器内核必须一致,建议在每个节点(三台机器)上都升级系统内核到最新版本。

检查操作系统版本
操作系统至少在7.5以上

#实验环境下机器的系统版本为7.9,内核版本为3.10.0
#查看系统版本
cat /etc/redhat-release
#查看当前系统的内核:
uname -sr
默认的 3.10.0版本较低,建议安装最新主线内核版本
#在 CentOS 7.x 上启用 ELRepo 仓库:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm

#查看可用的系统内核相关包:
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available

#安装最新主线内核版本:
yum -y --enablerepo=elrepo-kernel install kernel-ml
设置默认的内核版本
#修改GRUB_DEFAULT=0,设置为0表示默认启动第一个操作系统或内核,从0开始计数
vi /etc/default/grub

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=0 # 修改此处,原来是 saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
重新创建内核配置
grub2-mkconfig -o /boot/grub2/grub.cfg

#查看默认内核
grubby --default-kernel

#若不是最新的,使用以下命令设置,reboot重启生效。
grubby --set-default $(ls /boot/vmlinuz-* | grep elrepo)

设置主机名和hosts本地解析

这一步的作用是方便识别,如主节点所在的虚拟机命名为k8s-master,从节点所在的虚拟机命名为k8s-node1、k8s-node2(重启或者新开窗口可验证)。

Linux 的 /etc/hosts 文件是配置ip地址及其对应主机名的文件,这里可以记录本机的或其他主机的ip及其对应主机名,方便后面集群节点间的直接调用,因此在每个节点(三台机器)上都配置一下主机名解析。

#根据集群规划,各节点设置对应的主机名
hostnamectl set-hostname k8s-master #192.168.40.101
hostnamectl set-hostname k8s-node1 #192.168.40.102
hostnamectl set-hostname k8s-node2 #192.168.40.103

vi /etc/hosts
#所有节点编辑/etc/hosts文件,添加:
127.0.0.1 $(hostname)
192.168.40.101 k8s-master
192.168.40.102 k8s-node1
192.168.40.103 k8s-node2
[root@k8s-node2 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 k8s-node2
192.168.40.101 k8s-master
192.168.40.102 k8s-node1
192.168.40.103 k8s-node2
~

关闭防火墙和SELINUX

在每个节点(三台机器)上都关闭防火墙,并设置开机禁用。

在实际生产环境中,通常会采用防火墙和SELinux来增强系统的安全性,但在学习和测试环境中,这些安全措施可能会造成麻烦。因此,只用于学习环境建议关闭所有节点的防火墙和SELinux,以方便学习和测试。三台机器(所有节点)均需要在部署前配置好环境。

#关闭防火墙,关闭SELinux(设置为disabled)
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config

#确保防火墙和SElinux是关闭状态
systemctl status firewalld
getenforce

#查看selinux:cat /etc/selinux/config
#1.永久关闭 SELinux ,需要重启机器生效:sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
说明:修改SELinux配置文件,将SELINUX=enforcing改为SELINUX=disabled,禁用SELinux安全模块。其中,sed是一个文本编辑器,-i选项表示直接修改原文件,#是分隔符,g表示全局替换。

#2.临时关闭当前会话的 SELinux ,机器重启之后无效:setenforce 0
说明:将SELinux设置为Permissive模式,允许访问被拒绝的操作,但会记录到系统日志中。

安装NTP,时间同步设置

Kubernetes 要求集群中的节点时间必须精确一致,因此在每个节点(三台机器)上都添加时间同步

#从指定的NTP服务器获取时间信息,并将本地系统时间设置为该服务器时间
yum install ntpdate -y
ntpdate time.windows.com
#或者使用国内时间服务器:ntpdate ntp1.aliyun.com

关闭 swap 分区

当内存不足时,linux会自动使用swap,将部分内存数据存放到磁盘中。swap会导致docker的运行不正常,性能下降,还可能产生其他问题,因此部署k8s集群时一定要关闭swap分区。在每个节点(三台机器)上都进行以下操作

#所有节点关闭swap交换分区
sed -ri 's/.*swap.*/#&/' /etc/fstab
swapoff -a && sysctl -w vm.swappiness=0

#查看是否关闭(swap 0 0 0则成功关闭)
free -m

#临时关闭当前会话的 swap ,机器重启之后无效:
swapoff -a

将桥接的IPv4流量传递到iptables

netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能。
规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTPSMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)拒绝(reject)丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
在每个节点(三台机器)上都将桥接的IPv4流量传递到iptables的链

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
#加载br_netfilter模块
modprobe br_netfilter
#查看是否加载
lsmod | grep br_netfilter
#使生效
sysctl --system
#拓展:持久化修改(保留配置包本地文件,重启系统或服务进程仍然有效)
sysctl -p

开启 ipvs

ipvs (IP Virtual Server) 实现了传输层负载均衡,也就是4层LAN交换,作为Linux内核的一部分。ipvs运行在主机上,在真实服务器集群前充当负载均衡器
k8s 默认情况下有三种网络负载均衡模式:userspace 代理模式iptables代理模式ipvs代理模式。这三种代理模式的负载能力是依次递增
Kubernetesservice 有两种代理模型,一种是基于 iptables ,另一种是基于 ipvsipvs 的性能要高于 iptables 的,但是如果要使用它,需要手动载入 ipvs 模块

#在三台机器安装 ipset 和 ipvsadm :
yum -y install ipset ipvsadm

#在三台机器执行如下脚本:
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF

#授权、运行、检查是否加载:
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

重启机器

此时三台机器都基本上完成了安装前准备,因为有些配置是重启后生效

容器化环境和组件安装

Docker 安装

因为安装kubernetes需要docker容器化环境,因此先安装docker,但是注意kubernetes版本和docker的版本对应问题。按本博客的版本即可,如果是安装其他版本,需参考官方文档。
KubernetesDocker之间有版本的对应关系(如 Docker 版本v20.10对应 Kubernetes 的版本是 v1.21),版本对应不上可能会提示docker版本不兼容,可参考Kubernetes各版本对应支持的docker版本列表。
在每个节点(3台机器)上都安装docker

#卸载旧版本docker(如有)
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

# yum安装 gcc 相关软件,安装yum工具包

yum -y install gcc gcc-c++
yum -y install yum-utils

#设置阿里云的stable 镜像仓库
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#更新 yum 软件包索引
yum makecache fast

#安装指定版本的 Docker(v20.10.8):
yum -y install docker-ce-3:20.10.8-3.el7.x86_64 docker-ce-cli-1:20.10.8-3.el7.x86_64 containerd.io

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

#验证 Docker 是否安装成功:
systemctl status docker
docker -v

设置Docker镜像加速器

为了下载各组件时从国内镜像源下载,在每个节点(3台机器)上都需要配置镜像加速器。

mkdir -p /etc/docker

#配置阿里云镜像加速:
tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://du3ia00u.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://registry.docker-cn.com"
],
"live-restore": true,
"log-driver":"json-file",
"log-opts": {"max-size":"500m", "max-file":"3"},
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5,
"storage-driver": "overlay2"
}
EOF

#使之生效并重启docker
systemctl daemon-reload
systemctl restart docker

添加阿里云的YUM软件源

由于kubernetes的镜像源在国外,下载软件包较慢或者下载失败,这里在每个节点(3台机器)上都切换成国内的阿里云镜像源

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

安装kubeadmkubeletkubectl

在每个节点(3台机器)上都需要安装kubeadmkubeletkubectl,安装时指定版本为1.21.10

  • kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。
  • Kubelet:运行在cluster(集群)所有节点上,负责启动POD和容器。
  • kubectlKubernetes集群的命令行工具,通过kubectl可以部署和管理应用,查看各种资源,创建,删除和更新组件。
  • 安装三大组件
yum install -y kubelet-1.21.10 kubeadm-1.21.10 kubectl-1.21.10
  • 查看安装版本
kubelet --version
#为了实现Docker使用的cgroup drvier和kubelet使用的cgroup drver一致,修改"/etc/sysconfig/kubelet"文件为以下内容:
vi /etc/sysconfig/kubelet
# 修改为
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
  • 设置为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动
systemctl enable kubelet

kubernetes集群部署

下载k8s所需镜像

在每个节点(3台机器)上都安装好k8s集群所需的镜像。

  • 查看 Kubernetes 安装所需镜像
kubeadm config images list
  • 下载 Kubernetes 安装所需镜像
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.4.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0
  • 查看镜像下载情况
docker images

部署 KubernetesMaster 节点

192.168.40.101 机器上部署 KubernetesMaster 节点说明

  • apiserver-advertise-address =Master节点的 IP 地址
  • image-repository=容器镜像的仓库地址
  • kubernetes-version= 安装的kubernetes版本号
  • service-cidrapiserver-advertise-addresspod-network-cidr 不能在同一个网络范围内
  • 不要使用 172.17.0.1/16 网段范围,因为这是 Docker 默认使用的
kubeadm init \
--apiserver-advertise-address=192.168.40.101 \
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version=v1.21.10 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16
  • 结果如下
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/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.40.101:6443 --token yzpb7r.srd5ncljnngrr0t9 \
--discovery-token-ca-cert-hash sha256:c2404646a68904fa3faf89f1fb12d952aea8ae8ed464a09ea87d565fe9860e55
  • 拷贝kubectl使用的连接k8s认证文件到默认路径,根据日志提示,想要开始使用集群,需要在 master节点机器上(192.168.40.101 )执行如下命令
#创建目录存放 Kubernetes 的配置文件并配置 Kubernetes 客户端工具 kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
#将 $HOME/.kube/config 文件的权限修改为当前用户
chown $(id -u):$(id -g) $HOME/.kube/config
# 如果是 root 用户,可以执行如下命令,在使用 kubectl 命令时就不需要每次都指定配置文件的路径
export KUBECONFIG=/etc/kubernetes/admin.conf
  • 默认的 token 有效期为 2 小时,当过期之后,该 token 就不能用了,另外也可以生成一个永不过期的token,命令如下
#生成token,有效期2小时
kubeadm token create --print-join-command
# 生成一个永不过期的token
kubeadm token create --ttl 0 --print-join-command
#此时系统自动生成了一个kubeadm join命令,这个命令是用来将一个新的节点加入到 Kubernetes 集群中的。
#说明
kubeadm join 192.168.40.101:6443 ##集群的 API Server 地址
--token eu4sck.tkp2v9yr7ya8hzei ###用来认证新节点的凭证
--discovery-token-ca-cert-hash sha256:c2404646a68904fa3faf89f1fb12d952aea8ae8ed464a09ea87d565fe9860e55
#操作结果
[root@k8s-master ~]# kubeadm token create --ttl 0 --print-join-command
kubeadm join 192.168.40.101:6443 --token eu4sck.tkp2v9yr7ya8hzei --discovery-token-ca-cert-hash sha256:c2404646a68904fa3faf89f1fb12d952aea8ae8ed464a09ea87d565fe9860e55

部署 Kubernetes 的 Node节点

通过上面自动生成的kubeadm join命令,将两个node节点加入到kubernetes集群中

  • 192.168.40.102192.168.40.103两台机器上都执行生成的命令把这两个工作节点加入到当前集群
kubeadm join 192.168.40.101:6443 \
--token eu4sck.tkp2v9yr7ya8hzei \
--discovery-token-ca-cert-hash \
sha256:c2404646a68904fa3faf89f1fb12d952aea8ae8ed464a09ea87d565fe9860e55
  • 通过kubectl get node查看结果
[root@k8s-master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane,master 21m v1.21.10
k8s-node1 NotReady <none> 40s v1.21.10
k8s-node2 NotReady <none> 36s v1.21.10

部署网络插件

Kubernetes本身并没有自己实现容器网络,而是借助CNI标准,通过插件化的方式来集成各种网络插件,实现集群内部网络相互通信。

Kubernetes集群设计了Cluster IPNode IPPod IP三种类型的通信IP

  • Cluster IPService对象的IP地址,实现Pod服务的负载均衡,外部网络无法ping通,只在集群内部可以访问使用,是一个虚拟的IP
  • Node IP是集群节点NodeIP地址,可以是物理机的IP(也可能是虚拟机IP)。
  • Pod IP是容器组PodIP地址,是在容器组初始化过程由Pause容器申请的IP地址。其中Pod IP是容器网络接口CNI与具体的网络插件来实现IP的申请及数据包的转发。
  • Kubernetes 支持多种网络插件,比如 flannel、calico、canal 等,任选一种安装即可,这里选择 calico。在 master节点(192.168.40.101 )上执行
kubectl apply -f https://projectcalico.docs.tigera.io/v3.19/manifests/calico.yaml
  • 查看部署进度
kubectl get pods -n kube-system
#或者
watch kubectl get pods -n kube-system

[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-7cc8dd57d9-txx5m 0/1 Pending 0 10s
calico-node-gfrqm 0/1 Init:0/3 0 10s
calico-node-sm7z5 0/1 Init:0/3 0 10s
calico-node-wx4bw 0/1 Init:0/3 0 10s
coredns-6f6b8cc4f6-kfrdr 0/1 Pending 0 29m
coredns-6f6b8cc4f6-wqrvq 0/1 Pending 0 29m
etcd-k8s-master 1/1 Running 0 29m
kube-apiserver-k8s-master 1/1 Running 0 29m
kube-controller-manager-k8s-master 1/1 Running 0 29m
kube-proxy-5vg2s 1/1 Running 0 29m
kube-proxy-8v2q7 1/1 Running 0 9m7s
kube-proxy-cr6vl 1/1 Running 0 9m11s
kube-scheduler-k8s-master 1/1 Running 0 29m
  • master节点使用kubectl工具查看节点状态,此时节点状态应该都是Readypod全部running
kubectl get nodes

[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 54m v1.21.10
k8s-node1 Ready <none> 34m v1.21.10
k8s-node2 Ready <none> 34m v1.21.10

[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-7cc8dd57d9-txx5m 1/1 Running 0 24m
calico-node-gfrqm 1/1 Running 0 24m
calico-node-sm7z5 1/1 Running 0 24m
calico-node-wx4bw 1/1 Running 0 24m
coredns-6f6b8cc4f6-kfrdr 1/1 Running 0 53m
coredns-6f6b8cc4f6-wqrvq 1/1 Running 0 53m
etcd-k8s-master 1/1 Running 0 53m
kube-apiserver-k8s-master 1/1 Running 0 53m
kube-controller-manager-k8s-master 1/1 Running 0 53m
kube-proxy-5vg2s 1/1 Running 0 53m
kube-proxy-8v2q7 1/1 Running 0 33m
kube-proxy-cr6vl 1/1 Running 0 33m
kube-scheduler-k8s-master 1/1 Running 0 53m

至此一主两从的K8S集群就搭建好了

设置 kube-proxyipvs 模式

  • master节点(192.168.40.101)上设置 kube-proxyipvs 模式
kubectl edit cm kube-proxy -n kube-system
  • 找到ipvs模块,将 mode: " " 双引号里面加上ipvs44
38       syncPeriod: 0s
39 tcpFinTimeout: 0s
40 tcpTimeout: 0s
41 udpTimeout: 0s
42 kind: KubeProxyConfiguration
43 metricsBindAddress: ""
44 mode: "ipvs" #这里添加ipvs
45 nodePortAddresses: null
  • 删除 kube-proxy ,让 Kubernetes 集群自动创建新的 kube-proxy
kubectl delete pod -l k8s-app=kube-proxy -n kube-system
[root@k8s-master ~]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system
pod "kube-proxy-5vg2s" deleted
pod "kube-proxy-8v2q7" deleted
pod "kube-proxy-cr6vl" deleted
[root@k8s-master ~]#

配置Node节点也能使用 kubectl 命令

默认情况下,只有 master 节点才有 kubectl 命令,但是有些时候我们也希望在 Node 节点上执行 kubectl 命令

  • 在两个node节点(192.168.40.102192.168.40.103)上都创建config文件,执行命令
mkdir -pv ~/.kube
touch ~/.kube/config
  • node节点已经创建好了config文件,接下来将master节点的admin.conf文件远程拷贝复制到需要安装的机器(注意你配置的机器名是什么?如root@k8s-node1)。在master节点(192.168.40.101)上执行:
scp /etc/kubernetes/admin.conf root@k8s-node1:~/.kube/config
scp /etc/kubernetes/admin.conf root@k8s-node2:~/.kube/config
[root@k8s-master ~]# scp /etc/kubernetes/admin.conf root@k8s-node1:~/.kube/config
The authenticity of host 'k8s-node1 (192.168.40.102)' can't be established.
ECDSA key fingerprint is SHA256:+hj0bigTcIeKwE9jHOElGvftqP5bzysDzhN7vhf25Ow.
ECDSA key fingerprint is MD5:39:d2:bc:51:c0:7d:f6:85:c0:04:a3:6d:3d:28:45:27.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'k8s-node1,192.168.40.102' (ECDSA) to the list of known hosts.
root@k8s-node1's password:
admin.conf 100% 5598 6.4MB/s 00:00
[root@k8s-master ~]# scp /etc/kubernetes/admin.conf root@k8s-node2:~/.kube/config
The authenticity of host 'k8s-node2 (192.168.40.103)' can't be established.
ECDSA key fingerprint is SHA256:+hj0bigTcIeKwE9jHOElGvftqP5bzysDzhN7vhf25Ow.
ECDSA key fingerprint is MD5:39:d2:bc:51:c0:7d:f6:85:c0:04:a3:6d:3d:28:45:27.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'k8s-node2,192.168.40.103' (ECDSA) to the list of known hosts.
root@k8s-node2's password:
admin.conf
  • 此时在两个node节点验证,已经可以使用kubectl命令了
[root@k8s-node1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 69m v1.21.10
k8s-node1 Ready <none> 48m v1.21.10
k8s-node2 Ready <none> 48m v1.21.10

[root@k8s-node2 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 69m v1.21.10
k8s-node1 Ready <none> 48m v1.21.10
k8s-node2 Ready <none> 48m v1.21.10

服务部署

kubernetes集群已经部署完毕,接下来可以部署服务使用了

  • Kubernetes集群中部署nginx1.14,测试下集群是否正常工作
  • 部署Nginx
kubectl create deployment nginx --image=nginx:1.14-alpine
  • 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort
  • 查看服务状态
kubectl get pods,svc
[root@k8s-master ~]# kubectl create deployment nginx --image=nginx:1.14-alpine
deployment.apps/nginx created
[root@k8s-master ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
[root@k8s-master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-65c4bffcb6-z6p4q 0/1 ContainerCreating 0 13s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 71m
service/nginx NodePort 10.96.210.179 <none> 80:30532/TCP 4s
[root@k8s-master ~]#

自动补全

启动 kubectl 自动补全功能,参考kubernetes官网Linux 系统中的 Bash 自动补全功能

# 安装bash
yum -y install bash-completion
# 自动补全
echo 'source <(kubectl completion bash)' >>~/.bashrc
kubectl completion bash >/etc/bash_completion.d/kubectl
# 全局
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
source /usr/share/bash-completion/bash_completion

安装K8s-Dashboard

Dashboard 是基于网页的 Kubernetes 用户界面。可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。我们可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源 (如 DeploymentJobDaemonSet 等等)。常用的如对Deployment实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用,展示Kubernetes集群中的资源状态信息和所有报错信息等。
参考资料:安装Kubernetes Dashboard

  • 使用 wget 命令将Dashboard(这里版本为2.0.4)下载到master 节点上
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml
  • 构建 Pod
kubectl apply -f recommended.yaml
  • 查看 Pod 状态,等待一段时间,已经处于running状态
kubectl get pods --all-namespaces | grep dashboard
[root@k8s-master ~]# kubectl get pods --all-namespaces | grep dashboard
kubernetes-dashboard dashboard-metrics-scraper-5594697f48-8cbqx 1/1 Running 0 33s
kubernetes-dashboard kubernetes-dashboard-5b47f8964b-jfh6n 1/1 Running 0 33s
  • 删除现有的 dashboard 服务

dashboard 服务的 namespacekubernetes-dashboard,但是该服务的类型是ClusterIP,不便于我们通过浏览器访问,因此需要在后面配置 NodePort 类型的,使之在集群外部能否访问。

#查看所有命名空间namespace
kubectl get svc --all-namespaces

#删除现有dashboard服务
kubectl delete service kubernetes-dashboard --namespace=kubernetes-dashboard
[root@k8s-master ~]# kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 112m
default nginx NodePort 10.96.210.179 <none> 80:30532/TCP 40m
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 112m
kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.96.65.85 <none> 8000/TCP 2m5s
kubernetes-dashboard kubernetes-dashboard ClusterIP 10.96.155.148 <none> 443/TCP 2m6s
[root@k8s-master ~]# kubectl delete service kubernetes-dashboard --namespace=kubernetes-dashboard
service "kubernetes-dashboard" deleted

登录dashboard

  • 配置文件放在:/etc/Kubernetes
  • k8s所有证书的存放位置:/etc/kubernetes/pki
  • 环境变量(env)存放的位置:/var/lib/kubelet/kubeadm-flags.env
  • kubelet配置文件存放位置:/var/lib/kubelet/config.yaml
  • 创建一个nodePort类型的kubernetes-dashboard。进入/etc/kubernetes 目录下创建配置文件dashboard-svc.yaml
cd /etc/kubernetes
vi /etc/kubernetes/dashboard-svc.yaml
  • dashboard-svc.yaml文件内容如下:
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
  • 创建kubernetes-dashboardService服务
kubectl apply -f dashboard-svc.yaml
  • 此时再次查看namespace,已经有nodePort类型的kubernetes-dashboard,注意443:30221,即外部访问端口为32031
[root@k8s-master kubernetes]# kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 118m
default nginx NodePort 10.96.210.179 <none> 80:30532/TCP 46m
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 118m
kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.96.65.85 <none> 8000/TCP 7m54s
kubernetes-dashboard kubernetes-dashboard NodePort 10.96.150.63 <none> 443:30221/TCP 108s
[root@k8s-master kubernetes]#
  • 创建 kubernetes-dashboard 管理员角色,在/etc/kubernetes 目录下创建配置文件dashboard-svc-account.yaml,其内容如下
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: dashboard-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

  • 同样的执行创建,使该yaml文件生效
kubectl apply -f dashboard-svc-account.yaml
  • 获取 token,先查找token文件
kubectl get secret -n kube-system |grep admin|awk '{print $1}'
#系统返回dashboard-admin-token-bvhwm,查看token
kubectl describe secret dashboard-admin-token-bvhwm -n kube-system|grep '^token'|awk '{print $2}'
[root@k8s-master kubernetes]# kubectl get secret -n kube-system |grep admin|awk '{print $1}'
dashboard-admin-token-l269k
[root@k8s-master kubernetes]# kubectl describe secret dashboard-admin-token-l269k -n kube-system|grep '^token'|awk '{print $2}'
eyJhbGciOiJSUzI1NiIsImtpZCI6IkZPZS1HSTBKVEhzeFh4bjJCMXktdWJNMk93dnE0QzdoWm5qQzFFWEVVUncifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbDI2OWsiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNzNhMWVmNjctNGQzMC00OTIzLTk2ZWItNzE5MzEwMzgxMDEzIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.FdF5SoprlLGL8IDKMeOwWbnOx8Ry5WX2LkPIjGej4bOw603UvVBD2GXNrH7p97HXsL-6BuLe65oR24YN2oC_S-Ie8VhIg6JcG4itL4oeMqa5UOGVHyAZBP9OfuxFa36YDVc8LZ0S-_VzI3t1ZW2ybk1WOldyNn4XPsdNWpjMQaV0Cv2slXQWtFLiB3d5LQNiW1HykJcM5e1N-zXfYNErKzz1VfOA2K5bLIoLJACYLr1RefXtMyMet28Yu28WHwbaWegEykG2mng3DbqmazbPO062DZsKnXmU1AHrplcUlSSSzeMKmISbqsthiXbBDAePF2GoedN1EMBJ9JwFov96CQ
[root@k8s-master kubernetes]#
  • 此时我们得到了dashboardtoken,先复制保存一份
eyJhbGciOiJSUzI1NiIsImtpZCI6IkZPZS1HSTBKVEhzeFh4bjJCMXktdWJNMk93dnE0QzdoWm5qQzFFWEVVUncifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbDI2OWsiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNzNhMWVmNjctNGQzMC00OTIzLTk2ZWItNzE5MzEwMzgxMDEzIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.FdF5SoprlLGL8IDKMeOwWbnOx8Ry5WX2LkPIjGej4bOw603UvVBD2GXNrH7p97HXsL-6BuLe65oR24YN2oC_S-Ie8VhIg6JcG4itL4oeMqa5UOGVHyAZBP9OfuxFa36YDVc8LZ0S-_VzI3t1ZW2ybk1WOldyNn4XPsdNWpjMQaV0Cv2slXQWtFLiB3d5LQNiW1HykJcM5e1N-zXfYNErKzz1VfOA2K5bLIoLJACYLr1RefXtMyMet28Yu28WHwbaWegEykG2mng3DbqmazbPO062DZsKnXmU1AHrplcUlSSSzeMKmISbqsthiXbBDAePF2GoedN1EMBJ9JwFov96CQ
  • 查看外部访问端口,也就是之前我们创建的 Service
[root@k8s-master ~]# kubectl get svc --all-namespaces | grep dashboard
kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.96.65.85 <none> 8000/TCP 26m
kubernetes-dashboard kubernetes-dashboard NodePort 10.96.150.63 <none> 443:30221/TCP 20m

界面如图

如果出现 你的链接不是私密链接 请手动敲 thisisunsafe

登陆后界面