almalinux9.6系统:kubeadm部署kubernetes-1.33版本环境-三节点
一、简介:
本文是在almalinux9.6系统的环境下使用kubeadm来部署一个三节点的最新版(1.33)kubernetes环境。
kubernetes官方文档:官方安装文档【v1.33】
容器镜像压缩包:百度云
登录官方文档查看kubeadm部署kubernetes集群最新版本是1.33,那我这里部署的就是1.33了。
机器信息:
这里准备三台虚拟机,配置都是2C4G的,我笔记本是8C16G配置,创建这么三台虚机是我笔记本在不影响运行下能给到的最大了。
主机名 | IP地址 |
---|---|
almalinux-master-192e168e100e30 | 192.168.100.30 |
almalinux-node01-192e168e100e31 | 192.168.100.31 |
almalinux-node02-192e168e100e32 | 192.168.100.32 |
版本信息:
这里需要注意,我这里使用的是container不是docker-ce了。
描述 | 版本 |
---|---|
almalinux9.6 | 5.14.0-570.12.1.el9_6.x86_64 |
ansible | ansible-2.14.18 |
kubeadm | v1.33.4 |
kubectl | v1.33.4 |
kubelet | v1.33.4 |
flannel | v1.7.1 |
二、基础环境准备
0、准备个ansible
下面我们需要对这三台机器机型基础设置,一台台检查太麻烦,不检查又怕遗漏设置后续给自己挖坑,这里安装个ansible,方便批量检查。
ansible软件在这里没得要求直接安装就可以,创建一个工作目录,然后将ansible.cfg拷贝一份过来修改下,然后创建一个hosts文件,我的示例在下面:
yum install -y ansible
mkdir -p /home/secure/xylong/ansible-2.14.8-playbook ; cd /home/secure/xylong/ansible-2.14.8-playbook
cp /etc/ansible/ /home/secure/xylong/ansible-2.14.8-playbook/
这是我的hosts和ansible.cfg文件的示例
[root@localhost ansible-2.14.8-playbook]# pwd
/home/secure/xylong/ansible-2.14.8-playbook
[root@localhost ansible-2.14.8-playbook]#
[root@localhost ansible-2.14.8-playbook]# cat hosts
[all:vars] ### 所有节点的变量
ansible_ssh_user=secure ### 指定ansible通过ssh连接机器的用户,机器是创建了普通用户做了免密的
ansible_ssh_pass= ### 指定密码,机器优化过通过秘钥登录,空着
ansible_ssh_port=10000 ### 指定端口号,默认是22但是我优化修改了是10000
ansible_become=true ### 是否允许提权——》true允许
ansible_become_method=sudo ### 提权是通过sudo来操作
ansible_become_user=root ### 提权后是root用户身份
[test] ###所有节点都写入这个主机组
192.168.100.30
192.168.100.31
192.168.100.32
#192.168.100.33
[node] ### node节点的主机组
192.168.100.31
192.168.100.32
#192.168.100.33
[root@localhost ansible-2.14.8-playbook]# cat ansible.cfg | egrep -v '^#|^$|^;'
[defaults]
forks=5 ### 查看-并行执行数量,如果机器多可以往大放,我这里就三台默认就好
inventory=./hosts ### 修改-指定hosts文件位置,这里是避免每次执行ansible命令使用-i指定位置,省事
log_path=/var/log/ansible.log ### 默认-指定日志输出位置
host_key_checking=False ### 默认-这是将初次登录机器手动输入yes那个操作忽略
[privilege_escalation]
[persistent_connection]
[connection]
[colors]
[selinux]
[diff]
[galaxy]
[inventory]
[netconf_connection]
[paramiko_connection]
[jinja2]
[tags]
[root@localhost ansible-2.14.8-playbook]#
1、主机名和本地dns修改
hostnamectl set-hostname alma-master-com-192e168e100e30
hostnamectl set-hostname alma-node1-com-192e168e100e31
hostnamectl set-hostname alma-node2-com-192e168e100e32
echo "192.168.100.30 alma-master-com-192e168e100e30
192.168.100.31 alma-node1-com-192e168e100e31
192.168.100.32 alma-node2-com-192e168e100e32" | sudo tee -a /etc/hosts
2、时间同步
时间同步软件我这里选择用chrony软件,这里三台机器master和公网阿里云时钟源进行同步,剩下两台node节点和master进行时间同步,保证三台机器之间时间同步。
三台机器都需要安装哈!
yum install -y chrony
systemctl enable --now chronyd
这是master节点的配置文件
[root@localhost ansible-2.14.8-playbook]# cat /etc/chrony.conf
server ntp.aliyun.com iburst minpoll 2 maxpoll 4 ### 公网阿里云时钟源
allow 192.168.100.0/24 ### 允许网段机器进行时间同步
local stratum 8 ### 优先级,越小优先级越高,起码要比另外两台node节点数字要小
sourcedir /run/chrony-dhcp
driftfile /var/lib/chrony/drift
makestep 0.01 5
maxchange 1000 0 0
maxdistance 0.05
maxslewrate 500
maxupdateskew 100.0
rtcsync
clientloglimit 100000000
keyfile /etc/chrony.keys
ntsdumpdir /var/lib/chrony
leapsectz right/UTC
logdir /var/log/chrony
[root@localhost ansible-2.14.8-playbook]#
这是两台node节点的配置文件
[root@almalinux-node01-192e168e100e31 ~]# cat /etc/chrony.conf
server 192.168.100.30 iburst
sourcedir /run/chrony-dhcp
driftfile /var/lib/chrony/drift
makestep 0.01 5
maxchange 1000 0 0
maxdistance 0.05
maxslewrate 500
maxupdateskew 100.0
rtcsync
clientloglimit 100000000
keyfile /etc/chrony.keys
ntsdumpdir /var/lib/chrony
leapsectz right/UTC
logdir /var/log/chrony
[root@almalinux-node01-192e168e100e31 ~]#
3、防火墙和selinux
防火墙和selinux在我创建虚机时候有优化了,可以参考我之前的文档almalinux9.6系统-基础环境准备
4、k8s内核参数优化
三台机器都要执行哈
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
EOF
# 修改生效
sysctl -p /etc/sysctl.d/k8s.conf
5、关闭swap分区
swapoff -a
sed -i '/swap/ s/^/#/' /etc/fstab # 永久禁用
6、加载内核模块
modprobe overlay
modprobe br_netfilter
echo "overlay" | sudo tee -a /etc/modules-load.d/k8s.conf
echo "br_netfilter" | sudo tee -a /etc/modules-load.d/k8s.conf
7、安装container软件
container也是在docker-ce软件仓库中的,我们之前准备虚机时候就准备了阿里云的docker-ce软件源,这里直接安装就好了。
PS:这里还是不用添加镜像源加速,我还是已经将容器镜像都下载好了,直接导入使用就好了。
yum install -y containerd.io
systemctl enable --now containerd
containerd --version
# containerd服务初始化
containerd config default | sudo tee /etc/containerd/config.toml
# 将containerd服务的cgroup控制组设置为systemd——》如果不修改默认是false那么就是cgroup管理会导致master节点启动的频繁重启
sed -i '/SystemdCgroup/s/false/true/' /etc/containerd/config.toml
# 添加ctrctl命令的配置
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 5
debug: false
EOF
8、安装kubeadm、kubelet、kubectl
# 写入kubernetes-1.33版本的仓库源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
# 软件安装并将kubelet设置为开机自启
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
# 版本检查
kubeadm version
kubectl version
kubelet --version
9、好用命令行工具
kubens工具可以查看所有命名空间然后进行切换,kube-ps1可以显示你当前所在的命名空间是哪,还是非常实用的
# kubens
pwd——》/home/secure/kubeadmin-kubernetes-v1.33
unzip kubectx-master.zip
mv /home/secure/kubeadmin-kubernetes-v1.33/kubectx-master/kubens /usr/local/bin/
export PATH=$PATH:/usr/local/bin/
echo "export PATH=$PATH:/usr/local/bin/" >> /etc/profile
# kube-ps1
pwd——》/home/secure/kubeadmin-kubernetes-v1.33
unzip kube-ps1-master.zip
cd /home/secure/kubeadmin-kubernetes-v1.33/kube-ps1-master/ ; source kube-ps1.sh ;PS1='[\u@\h \W $(kube_ps1)]\$ '
sudo vim /etc/profile
SHORT_NAME=$(hostname -s | awk -F- '{print $2}')
source /home/secure/kubeadmin-kubernetes-v1.33/kube-ps1-master/kube-ps1.sh
export PS1='[\u@$SHORT_NAME \W $(kube_ps1)]\$ '
source /etc/profile
当我们k8s集群拉起来之后这里可以通过kubns来进行命名空间切换,然后通过kube-ps1他会将命令行修改了。
——》显示下【k8s集群登录身份+当前集群名称:当前登录的命名空间】
kubens kube-system
三、kubeadm部署kubernetes集群
1、容器镜像导入
上面准备工作完成我们就可以使用kubeadm将kubernetes集群拉起来了,但是基于我这个完全无法正常拉取容器镜像的环境,还是手动导入下容器镜像让我放心。
我会将容器部署镜像压缩包放到百度云,链接在介绍中,大家自取哈!我这里将压缩包放到了/home/secure目录下面了,
docker-images/kubernetes-master-1.33/ master节点上需要导入的容器镜像
docker-images/kubernetes-node-1.33/ node节点上需要导入的
docker-images/kubernetes-flannel-1.33/ 这是flannel网络插件的容器镜像,所有节点都是需要导入的
master节点导入所需的容器镜像
ls /home/secure/kubeadmin-kubernetes-v1.33/docker-images/kubernetes-master-1.33/* | awk '{print "ctr -n=k8s.io images import " $1}' | bash
ls /home/secure/kubeadmin-kubernetes-v1.33/docker-images/kubernetes-flannel-1.33/* | awk '{print "ctr -n=k8s.io images import " $1}' | bash
node节点导入所需容器镜像
ls /tmp/docker-images/kubernetes-node-1.33/* | awk '{print "ctr -n=k8s.io images import " $1}' | bash
ls /tmp/docker-images/kubernetes-flannel-1.33/* | awk '{print "ctr -n=k8s.io images import " $1}' | bash
这就是我们导入完成之后的镜像情况了
2、初始化拉起k8s集群
在master节点上执行命令进行集群的拉起就好了
——》–apiserver-advertise-address=192.168.100.30 # 指定master地址
——》–kubernetes-version=v1.33.2 # 指定版本号-我镜像导入的都是1.33.2的
——》–pod-network-cidr=10.244.0.0/16 # 指定pod子网范围我这里网络插件选择的flannel在部署时候需要指定
kubeadm init --apiserver-advertise-address=192.168.100.30 --kubernetes-version=v1.33.2 --pod-network-cidr=10.244.0.0/16
初始化过程中可以看到一些master节点上pod创建的信息
这里可以看到集群创建成功了,
还有输出显示如果我们是普通用户或者是root用户应该指定参数,不然无法通过kubectl执行命令。
还有最下面的添加node的命令,这个命令有效期是24小时,如果超时了需要自己生成拼接组装下。
3、将node添加到集群中
使用我们初始化集群时候输出的命令就好
kubeadm join 192.168.100.30:6443 --token 9j1g7l.0pqhmwd13iju5sud \
--discovery-token-ca-cert-hash sha256:b3d203b15d6d0983510bd7b80ea19c0da844981aa45c07023bbe961673127a8d
node节点加进来之后我们可以上master节点上查看下pod状态——》这个报错就是我们没有执行环境变量导致命令找不到api报错的
将环境变量设置了,为了避免每次执行加到登录用户执行的家目录文件中。
export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bashrc
kubectl get pods -A
kubectl get pods -A -owide
kubectl get nodes # 看下node状态是notread的
这里我们可以看到pod都是正常启动的,但是两个coredns是Pending状态,这是因为网络组件没有部署,他们这个状态是正常的。
4、部署flannel网络插件
还是下载的压缩包中,执行flannel的yaml文件进行创建就好了
pwd——》/home/secure/kubeadmin-kubernetes-v1.33
kubectl apply -f kube-flannel.yml
这里他会自动创建namespace命名空间+svc+集群角色+集群角色绑定+configmap+DaemonSet
我们在查看flannel的pod都启动了,三个机器上都启动了一个
——》这里少个现象,应该在没有部署flannel的时候查看下node状态,可以看到notready;
——》还有就是这里查看coredns启动失败了,看报错是找不到镜像,查看启动节点实在node02上,我之前实验时候这个coredns是在master节点上启动的,我这里在导入镜像的时候就没有往两台coredns容器镜像,这里也没事手动导入下就好了
两个node节点都执行下命令导入下coredns的容器镜像
ll /tmp/docker-images/kubernetes-master-1.33/registry.k8s.io-coredns-coredns_v1.12.0.tar
ctr -n=k8s.io images import /tmp/docker-images/kubernetes-master-1.33/registry.k8s.io-coredns-coredns_v1.12.0.tar
crictl images
在node节点导入coredns容器镜像之后我们上master查看两个pod状态是正常的了,但是这里查看两个pod都在一个节点node02上,这就有点不安全的(它不去node01我容器镜像不是白导入了!)
这里我们可以手动删除一个coredns的pod,集群会在node01将它创建起来的,这里可以注意下pod启动时间,我们就是执行命令的空挡pod就在node01上重建完成了。
kubectl -n kube-system delete pods coredns-674b8bbfcf-59phk
现在查看那node节点状态都是ready的,正常我们初始化集群之后可以看到是notready,
这里我尝试卸载了flannel——》node状态没变;
查看coredns状态还是running的——》刚部署完他是pending的,这里手动把两个coredns删除了,看node状态还是没变;
pwd——》/home/secure/kubeadmin-kubernetes-v1.33
kubectl delete -f kube-flannel.yml
kubectl -n kube-system delete pods coredns-674b8bbfcf-j4k22
kubectl -n kube-system delete pods coredns-674b8bbfcf-84ss4
所幸看不到了,这里将flannel创建回来。
pwd——》/home/secure/kubeadmin-kubernetes-v1.33
kubectl apply -f kube-flannel.yml
删除两个coredns之后还把一个逼到了master节点,这就厉害了!
5、制作虚机快照
到现在我们使用kubeadm拉起了1.33.2版本的k8s集群,虽然有点简陋是1个master两个node节点的,我这笔记本电脑就这配置了。下面我会进行一些k8s的基础操作,创建pod添加nodeport外部端口然后浏览器访问,下一篇文档还会将其他的可选组件部署下,所以现在这个状态可以做个快照,避免我们后续有什么破坏性的操作,还能回来。
将三台机器进行关机
pwd——》/home/secure/xylong/ansible-2.14.8-playbook
ansible test -m shell -a "init 0"
这时候关机会慢一点,现在上面运行了容器的,系统需要将数据都同步完成才能进行关机操作,稍等一会就好。
都关机之后我们将三台机器当前状态做个快照就好了
最后我们将三台机器都启动了,然后登录查看pod状态——》他恢复的很快,这就是容器的优势啊!
kubectl get pods -A
kubectl get pods -A -owide
四、基础操作
现在k8s集群已经部署好了,有两个node节点可以初步的玩一玩了,看看部署这个集群到底有什么用?
导入容器镜像
还是老样子,做实验前将所需的容器镜像导入,我们压缩包已经分发到两个node节点了,直接使用命令导入镜像就好了。
ls /tmp/docker-images/docker.io_library_nginx_1.2* | awk '{print "ctr -n=k8s.io images import " $1}' | bash
crictl images
操作步骤:
- 创建一个命名空间【demo-ns】
- 创建deploy-deploy名称【nginx-app】replica副本数位【3】镜像使用nignx:1.27.0;
- 创建svc-给【nginx-app】创建一个外部nodeport接口,让我可以通过外部浏览器访问nginx的页面;
- 扩缩容-将【nginx-app】的副本数从3设置为2;然后在从2设置为5;
- 升级-将【nginx-app】的nginx镜像版本指定为nginx:1.28.0;再指定为nginx:1.29.0;
- 回滚-将【nginx-app】的版本从1.29.0回滚到1.27.0;
- 删除-将deployment+svc+namespace都删除;
kubectl create namespace demo-ns
kubens demo-ns
kubectl create deployment nginx-app --image nginx:1.27.0 --replicas 3
kubectl expose deployment nginx-app --type NodePort --port 80
kubectl get svc ——》 80:32693/TCP
kubectl scale deployment nginx-app --replicas 2
kubectl scale deployment nginx-app --replicas 5
kubectl set image deployments nginx-app nginx=nginx:1.28.0
kubectl set image deployments nginx-app nginx=nginx:1.29.0
kubectl exec pods/nginx-app-855856d7fb-4z7z7 -- nginx -v
kubectl rollout history deployment nginx-app
kubectl rollout undo deployment nginx-app --to-revision 1
按照上面步骤我们创建一个demo-ns的命名空间然后创建deployment,创建之后我们查看那三个pod是启动状态,看分布一个node01;两个在node02上。
接着我们创建一个service指定类型是nodeport外部端口——》这里我们没有指定所以随机分配端口是【32693】
现在我们就可以通过浏览器来访问下这三个pod的nginx页面了——》http://192.168.100.30:32693/
接着我们通过命令设置下副本数,这个的修改是非常快的,因为我们容器镜像已经提前准备好,执行完命令查看pod就已经重建完成了!
这里我们指定下nginx的容器镜像版本模拟下升级操作-nginx:1.27.0——》1.28.0——》1.29.0,这里也是为了演示回滚方便进行操作
我们先查看下回滚历史记录这里有三个,这就是我们镜像的三个版本
1 ——》就是创建deployment的时候镜像1.27.0
2 ——》我们手动升级到1.28.0
3 ——》就是现在的1.29.0版本
我们通过命令指定回滚到【1】那就是1.27.0版本,这里可以登录重建的pod看下没得问题
到这里我们演示了k8s集群中通过deployment创建pod,然后添加外部端口方便浏览器访问。接着演示了通过设置deployment的副本数来控制pod的数量,然后通过指定容器镜像版本来进行升级操作,还有通过rollout来查看历史记录【这里只能保存三个】指定记录进行回滚操作。
现象-service负载均衡
我们在删除之前还可以看个现象,第二步我们创建了svc指定外部接口可以通过浏览器访问了,那么我们访问的是哪一个pod呢?——》这里我们修改下nginx浏览的默认页面不然他就是后台刷新了我们也看不到。
kubectl get pods
kubectl exec pods/nginx-app-67668f975-8q42f -- bash -c "echo 'nginx-app-1.27.0-1111111111' > /usr/share/nginx/html/index.html"
kubectl exec pods/nginx-app-67668f975-9qbn2 -- bash -c "echo 'nginx-app-1.27.0-2222222222' > /usr/share/nginx/html/index.html"
kubectl exec pods/nginx-app-67668f975-fpdjc -- bash -c "echo 'nginx-app-1.27.0-3333333333' > /usr/share/nginx/html/index.html"
kubectl exec pods/nginx-app-67668f975-lqc6j -- bash -c "echo 'nginx-app-1.27.0-4444444444' > /usr/share/nginx/html/index.html"
kubectl exec pods/nginx-app-67668f975-rggbn -- bash -c "echo 'nginx-app-1.27.0-5555555555' > /usr/share/nginx/html/index.html"
接着打开无痕浏览器,我们多开几个窗口,刷新——》浏览器有时候会有缓存
清理环境
清理环境我们先从demo-ns命名空间出来毕竟最后是要连命名空间也删除的,这里挨个执行就好了,svc-deployment-namespace
kubens defaults
kubectl -n demo-ns delete svc nginx-app
kubectl -n demo-ns delete deployments.apps nginx-app
kubectl -n demo-ns delete namespaces demo-ns
kubectl get namespaces
kubectl get deployments.apps -A
kubectl get svc -A
kubectl get pods -A
哦了,到这里这篇文章就完成了,我们创建三台虚机从无到有拉起了一个1.33版本的k8s环境,然后简单的实验的k8s的基本功能。