文章目录
- 环境准备
- 主机间做信任
- 使用ssh-copy-id命令实现免密登录的安装与配置
- 1. 安装Git Bash软件
- 2. 生成公钥
- 3. SSH登录Linux服务器
- 4. 公钥复制到Linux服务器
- 5. SSH免密登录测试
- 安装ansible工具
- 升级内核版本
- 使用elrepo源升级内核
- 查看最新版内核
- 安装最新的内核版本
- 设置系统默认内核
- 设置默认内核为我们刚才升级的内核版本
- 初始化
- 关闭防火墙
- 关闭selinux
- 关闭swap
- 修改主机名
- 修改hosts文件
- 将桥接的IPv4流量传递到iptables的链
- 配置时间同步
- 安装containerd
- 测试containerd是否能创建和启动成功
- 安装kubernetes
- 添加kubernetes源
- 安装
- 初始化
- node节点配置
- 网络配置
- CNI插件问题
- 验证
- nodes/集群内部 无法访问ClusterIP
- 扩展
环境准备
本地用的操作系统是Windows 10 专业版,版本号22H2,操作系统内部版本19045.3324,内存64.0 GB,处理器12th Gen Intel® Core™ i9-12900K 3.19 GHz,三台机都是通过VMware Workstation Pro安装Centos7的操作系统。
规划Kubernetes集群配置
角色 | IP | kubernetes版本 |
---|---|---|
k8s-master | 192.168.122.130 | |
k8s-node1 | 192.168.122.131 | |
k8s-node2 | 192.168.122.132 |
主机间做信任
在本地Windows操作系统生成秘钥文件,并把它上传到Linux操作系统CentOS7的3台机上面,做好免密登录,方便后续的操作。
执行ssh-copy-id root@目标IP地址
命令实现免密登录,其他两台做同样的操作。
在Windows系统中执行ssh-copy-id root@192.168.248.129命令时,需要使用第三方软件来实现SSH客户端的功能,如PuTTY、Git Bash等。
使用ssh-copy-id命令实现免密登录的安装与配置
下面以Git Bash为例,介绍在Windows系统中使用ssh-copy-id命令实现Linux的CentOS 7免密登录的安装与配置过程。
1. 安装Git Bash软件
可以从Git官网下载安装程序,安装时选择默认选项即可。
2. 生成公钥
在Git Bash中执行以下命令,生成公钥文件:
ssh-keygen -t rsa
执行后,会提示输入文件名和密码等信息,可以直接按回车选择默认选项。生成的公钥文件默认保存在用户目录的.ssh目录下,文件名为id_rsa.pub。
然后将这二个文件上传到k8s-master、k8s-node1、k8s-node2
3. SSH登录Linux服务器
使用Git Bash登录到Linux服务器,执行以下命令:
ssh root@192.168.122.130
第一次登录时,会提示是否添加主机到已知主机列表。输入yes,然后输入Linux服务器的密码即可登录成功。
4. 公钥复制到Linux服务器
使用以下命令将公钥复制到Linux服务器上:
ssh-copy-id root@192.168.122.130
执行后,会提示输入Linux服务器的密码,输入即可。
5. SSH免密登录测试
使用以下命令测试是否已实现SSH免密登录:
ssh root@192.168.122.130
若能直接登录而无需输入密码,则表示SSH免密登录已成功实现。
提示“/root/.ssh/id_rsa”的权限0777太开放,此私钥将被忽略,修改一下权限,代码如下:
chmod 600 /root/.ssh/id_rsa
执行过程中如果出现提示无法打开 ‘/root/.pub’ 这个文件,因为该文件或目录不存在。在尝试将SSH公钥复制到远程服务器时,可能指定了错误的公钥文件路径。可以尝试以下步骤来解决此问题:首先,确保具有SSH密钥对。运行以下命令来检查:
ls -al ~/.ssh
。如果结果中没有 id_rsa 和 id_rsa.pub 文件,说明您还没有SSH密钥对。您可以使用以下命令生成它们:ssh-keygen -t rsa
。按提示操作即可,不必理会默认设置。
其他二台机器也是如此操作,这样就可以在本地(Windows操作系统)、CentOS(3台机器)都可以使用,效果如下图所示:
安装ansible工具
是的,Ansible是一种自动化工具,可用于配置和管理多个服务器。它使用SSH连接来远程管理服务器,可以在多个服务器上同时执行命令,从而提高效率。安装Ansible也非常简单,只需从官方的yum源安装即可。在CentOS上,可以使用以下命令安装Ansible,只需要在master上安装,然后在配置/etc/ansible/hosts文件中,将要操作的主机加入一个组中即可。安装命令代码如下:
yum install epel-release -y
yum -y install ansible
在安装完成后,就可以开始使用Ansible进行自动化配置和管理服务器了。
配置/etc/ansible/hosts,该文件是存放要操作的主机,如下:
vim /etc/ansible/hosts
把上述三台机器加入一个组名字为k8s,如下:
[k8s]
192.168.122.130
192.168.122.131
192.168.122.132
执行ansible命令测试连通性,命令如下:
ansible k8s -m ping
该命令会对名为k8s的主机组中的所有主机执行ping模块,测试它们是否能正常连接。如果输出pong,就说明测试成功。如果输出失败信息,则需要检查主机的网络设置和防火墙等因素是否正确。
-m:指定使用的Ansible模块。 ping:是Ansible中一个模块,用于测试主机的连通性。 k8s:是Ansible中定义的主机组名,即要执行ping命令的目标主机所属的主机组。
k8s:刚定义的组名
升级内核版本
查看Linux内核版本号,可以使用以下命令:
uname -sr
这将返回当前正在运行的Linux内核版本号。
Linux 3.10.0-1160.95.1.el7.x86_64
当前内核版本是3.10,Kubernetes需要使用一些Linux内核的功能,例如Namespaces、Cgroups、OverlayFS等,这些功能是在比较新的Linux内核版本中才能够完整支持。因此,为了保证Kubernetes的正常运行,建议升级到最新的Linux内核版本。对于Kubernetes1.22版本来说,官方推荐的最低Linux内核版本为4.4。如果使用的是更老的Linux内核版本,可能会在Kubernetes的安装、部署和使用中遇到一些问题或者限制。因此,为了获得更好的Kubernetes使用体验,建议升级到官方推荐的Linux内核版本或者更高的版本。
使用elrepo源升级内核
在每台机器上都执行相同的命令来安装elrepo源,配置elrepo源,执行如下命令:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
查看最新版内核
执行如下命令查看最新的内核版本
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
kernel-ml #主线版本,比较新
kernel-lt #长期支持版本,比较旧
安装最新的内核版本
执行如下命令安装主线版本:
yum --enablerepo=elrepo-kernel install kernel-ml -y
设置系统默认内核
查看系统上的所有内核版本:
awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
设置默认内核为我们刚才升级的内核版本
备份
cp /etc/default/grub /etc/default/grub-bak
设置默认内核版本
grub2-set-default 0
编辑/etc/default/grub
vi /etc/default/grub
将GRUB_DEFAULT=saved修改为GRUB_DEFAULT=0
重新创建内核配置
grub2-mkconfig -o /boot/grub2/grub.cfg
查看默认内核
grubby --default-kernel
grub2-editenv list
效果如下:
更新软件包并重启
yum makecache
reboot
效果如下:
初始化
安装K8S之前需要对系统进行一些设置,比如 关闭防火墙,selinux,swap,设置主机名,ip解析,时间同步 。
关闭防火墙
通过ansible把三台机器的防火墙关闭,并设置开机不启动。执行如命令:
ansible k8s -m shell -a "systemctl stop firewalld"
ansible k8s -m shell -a "systemctl disable firewalld"
关闭selinux
通过ansible把三台机器的selinux永久关闭,执行如命令:
ansible k8s -m shell -a "sed -i 's/enforcing/disabled/' /etc/selinux/config"
关闭swap
执行swapoff -a 临时关闭,通过修改/etc/fstab文件实现永久关闭。执行如下命令
ansible k8s -m shell -a "sed -ri 's/.*swap.*/#&/' /etc/fstab"
修改主机名
分别对三台主机进行主机名的修改,通过图形页面直接修改更快,效果如下:
也可以执行如下的命令进行修改:
根据规划设置主机名【k8s-master节点上操作】
hostnamectl set-hostname k8s-master
根据规划设置主机名【k8s-node1节点操作】
hostnamectl set-hostname k8s-node1
根据规划设置主机名【k8s-node2节点操作】
hostnamectl set-hostname k8s-node2
修改hosts文件
在master节点上修改hosts文件,根据规划进行修改,命令如下:
sudo nano /etc/hosts
然后添加以下内容,如下:
192.168.122.130 k8s-master1
192.168.122.131 k8s-node1
192.168.122.132 k8s-node2
保存并退出nano编辑器,命令为Ctrl+X,输入Y确认保存,按Enter键,然后可以通过ping或者ssh命令测试hostname是否生效,例如:
ping k8s-master1
ssh k8s-node1
将桥接的IPv4流量传递到iptables的链
在/etc/sysctl.d/目录上新增k8s.conf,内容如下:
# 允许桥接设备对 IPv6 进行 iptables 调用
net.bridge.bridge-nf-call-ip6tables = 1
# 允许桥接设备对 IPv4 进行 iptables 调用
net.bridge.bridge-nf-call-iptables = 1
# 开启 IPv4 转发功能
net.ipv4.ip_forward = 1
把该文件拷贝到其他两台机器上,如下:
ansible k8s -m copy -a "src=/etc/sysctl.d/k8s.conf dest=/etc/sysctl.d/k8s.conf"
执行 sysctl --system命令使配置生效,代码如下:
ansible k8s -m shell -a "sysctl --system"
配置时间同步
使用yum命令安装ntpdate,如下:
ansible k8s -m shell -a "yum install ntpdate -y"
配置NTP网络时间同步服务器地址为 ntp.aliyun.com,执行如下命令:
ansible k8s -m shell -a "ntpdate ntp.aliyun.com"
安装containerd
执行如下命令下载最新containerd,如下:
wget https://download.fastgit.org/containerd/containerd/releases/download/v1.6.6/cri-containerd-cni-1.6.6-linux-amd64.tar.gz --no-check-certificate
需要注意大小是否正常,不正常后面解压不了
如果实在下载不了,这里提供地址:https://download.csdn.net/download/java_wxid/88206551
解压containerd安装包
tar -C / -zxf cri-containerd-cni-1.6.6-linux-amd64.tar.gz
配置环境变量,编辑用户目录下的bashrc文件添加如下内容:
export PATH=$PATH:/usr/local/bin:/usr/local/sbin
并执行如下命令使环境变量立即生效:
source ~/.bashrc
执行如下命令启动containerd
systemctl start containerd
执行如下命令查看版本号,出现如下信息表明安装成功。
ctr version
创建默认配置文件
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
vi /etc/containerd/config.toml
在配置文件中,将以下行的注释去掉:[plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc]
测试containerd是否能创建和启动成功
执行如下命令拉取镜像并创建容器:
拉取容器
ctr i pull docker.io/library/nginx:alpine
创建容器
ctr c create --net-host docker.io/library/nginx:alpine nginx
ctr task start -d nginx
查看Containerd服务启动信息:
systemctl status containerd -l
查看containerd组件加载情况,发现overlayfs异常
ctr plugin ls
通过以下命令查看containerd运行日志:
sudo journalctl -fu containerd
通过查看容器内的文件系统,确认为xfs文件系统:
df -Th
查阅官方资料:
其中有二条比较有用的:
OverlayFS是推荐的存储驱动程序,如果满足以下先决条件,则支持它:
4.0版或更高版本的Linux内核,或RHEL或使用3.10.0-514版或更高级内核的CentOS。(内核版本已经升级过了,符合条件)
overlay2驱动程序在xfs备份文件系统上受支持,但仅在启用d_type=true的情况下才受支持。(这个才是重点)
前面设置的系统内核版本是Linux 6.4.9-1.el7.elrepo.x86_64,这个版本默认的存储驱动是fuse-overlayfs,而不是overlay2。因此,在使用docker时,默认会使用fuse-overlayfs作为存储驱动,想要使用overlay2作为存储驱动,还需要手动配置docker,将存储驱动设置为overlay2, 在/etc/docker/daemon.json中添加以下内容:{ “storage-driver”: “overlay2” },然后使用命令systemctl restart docker.service进行重启。接着让文件系统需要支持d_type=true,使用命令mount | grep overlay进行检查是否支持,最后使用docker info命令检查是否成功修改存储驱动为overlay2。
如果启动容器出现如下报错,是由于缺少runc并升级libseccomp,libseccomp需要高于2.4版本。
ctr: failed to create shim task: OCI runtime create failed: unable to retrieve OCI runtime error
(open /run/containerd/io.containerd.runtime.v2.task/default/nginx/log.json: no such file or directory):
fork/exec /
containerd在v1.6.4版本以后使用v1.1.2的runc和v1.1.1的cni。
下载链接:https://github.com/opencontainers/runc/releases/download/v1.1.2/runc.amd64?spm=a2c6h.12873639.article-detail.8.31cb4c6a6D2Htj&file=runc.amd64
下载之后,执行如下命令安装并查看版本号:
install -m 755 runc.amd64 /usr/local/sbin/runc
runc -v
执行如下命令升级libseccomp:
查询原来的版本
rpm -qa | grep libseccomp
卸载原来的版本
rpm -e libseccomp-2.3.1-4.el7.x86_64 --nodeps
下载高版本的
wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
安装
rpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm
安装kubernetes
添加kubernetes源
在master节点上添加k8s软件源,并分发到其他两台机器上。在/etc/yum.repos.d/目录下新增kubernetes.repo。内容如下:
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
把kubernetes.repo文件分发到其他两台机器上,执行如下命令:
ansible k8s -m copy -a "src=/etc/yum.repos.d/kubernetes.repo dest=/etc/yum.repos.d/kubernetes.repo"
安装
在master节点下执行如下命令安装相应的软件:
yum install -y kubelet-1.24.3 kubeadm-1.24.3 kubectl-1.24.3
生成默认配置并修改相应的参数,通过如下命名生成一个默认的配置文件:
kubeadm config print init-defaults > kubeadm-init.yaml
根据自己的环境修改对应的参数:
# api版本是kubeadm.k8s.io/v1beta3
apiVersion: kubeadm.k8s.io/v1beta3
# 引导令牌
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef # 令牌
ttl: 24h0m0s # 过期时间为 24 小时
usages:
- signing # 用于签名
- authentication # 用于认证
# 初始化配置
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.122.130 #master节点IP
bindPort: 6443 # 绑定端口
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock # containerd 的 socket 文件地址
imagePullPolicy: IfNotPresent # 镜像拉取策略为 IfNotPresent
name: k8s-master # 节点名称
taints: null # 污点为空
# 集群配置
apiServer:
timeoutForControlPlane: 4m0s # 控制平面的超时时间为 4 分钟
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki # 证书目录
clusterName: kubernetes # 集群名称
controllerManager: {} # 控制器管理器
dns: {} # dns
etcd:
local:
dataDir: /var/lib/etcd # etcd 数据目录
imageRepository: registry.aliyuncs.com/google_containers #阿里云容器源地址
kind: ClusterConfiguration
kubernetesVersion: 1.24.0 # kubernetes 版本
networking:
dnsDomain: cluster.local # dns 域名
podSubnet: 10.244.0.0/16 #pod的IP网段
serviceSubnet: 10.96.0.0/12 # 服务子网
scheduler: {} # 调度器
初始化
执行如下命令进行初始化:
kubeadm init --config=kubeadm-init.yaml --v=6
–config:指定根据那个配置文件进行初始
–v:指定日志级别,越高越详细
按照初始化成功提示信息,做如下操作:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
接下来执行kubectl就可以看到node了
kubectl get node
查看k8s各部件启动情况,执行如下命令:
kubectl get pod --all-namespaces -o wide
node节点配置
node节点安装kubeadm
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
安装相关组件
yum install -y kubeadm-1.24.3 --disableexcludes=kubernetes
添加join命令
kubeadm join 192.168.248.130:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:e9e29c804f92193928f37ca157b73a7ad77e7929314db98855b3ba6e2ce2273d
如果我们后续需要添加node节点时,可以到master节点执行下面的命令获取token相关信息
kubeadm token create --print-join-command
如果添加某台节点异常了,修改后可以执行 kubeadm reset的命令,然后在重新join加入
网络配置
coredns还没启动,因为还没有安装网络插件,接下来安装网络插件,可以在该文档中选择我们自己的网络插件,这里安装flannel
wget http://down.i4t.com/k8s1.24/kube-flannel.yml
根据需求修改网卡配置,我这里ens33为主的:
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.12.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=ens33 # 如果是多网卡的话,指定内网网卡的名称
在kubeadm.yaml文件中设置了podSubnet网段,同时在flannel中网段也要设置相同的。 (我这里默认就是相同的配置)
执行部署
kubectl apply -f kube-flannel.yml
CNI插件问题
默认情况下containerd也会有一个cni插件,但是我们已经安装Flannel了,我们需要使用Flannel的cni插件,需要将containerd里面的cni配置文件进行注释,否则2个配置会产生冲突 。因为如果这个目录中有多个 cni 配置文件,kubelet 将会使用按文件名的字典顺序排列的第一个作为配置文件,所以前面默认选择使用的是 containerd-net 这个插件。
mv /etc/cni/net.d/10-containerd-net.conflist /etc/cni/net.d/10-containerd-net.conflist.bak
systemctl restart containerd kubelet
验证
验证dns是否正常能解析和pod之间。这里新建一个测试的yaml文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:alpine
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30001
---
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: abcdocker9/centos:v1
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
restartPolicy: Always
执行下面命令,创建pod
kubectl apply -f test.yaml
使用nslookup查看是否能返回地址
kubectl exec -it busybox -- nslookup kubernetes
测试nginx svc以及Pod内部网络通信是否正常 ,分别在三台机器上进行下面操作
ping 10.104.115.26 #nginx svc ip
ping 10.244.1.2 #podIP
如果成功ping同说明node跟pod的网络已经打通了。否则检查kube-proxy的模式是否正确。
nodes/集群内部 无法访问ClusterIP
默认情况下,我们部署的kube-proxy通过查看日志,能看到如下信息:Flag proxy-mode="" unknown,assuming iptables proxy
原因分析:
并没有正确使用ipvs模式
解决方法:
在master上修改kube-proxy的配置文件,添加mode为ipvs。
kubectl edit cm kube-proxy -n kube-system
kubectl edit cm kube-proxy -n kube-system
删除原来的POD,会自动重启kube-proxy 的pod
kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'
扩展
在使用过程中发现kubectl 命令不能补全,使用起来很不方便。为了提高使用kubectl命令工具的便捷性,介绍一下kubectl命令补全工具的安装。
1、安装bash-completion:
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
2、 应用kubectl的completion到系统环境:
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc