- minikube:简单快速部署单节点的kubernetes工具。没啥用,官网说可以快速学习使用,但是很多命令没法用,鸡肋得很
- kubeadm:简单快速部署kubernetes集群的工具。
- 二进制包:从官网上下载每个组件的二进制包,依次去安装,此方式对于理解kubernetes组件更加有效。但是安装起来超级复杂,就不介绍了。
kubeadm安装方式
环境准备
主机环境
三台主机必须为2两核以上,要不然压根起不来,master建议分40G,此为最低配置,后面装的kubesphere也是最小化配置,要不然压根起不来,建议增加CPU核数以及内存,本次使用的centos7 安装,其他发行版安装,基本大差不差,需要改动就是内核、镜像源什么的
| 角色 | IP | 操作系统 | 配置 |
|---|---|---|---|
| Master | 192.168.52.131 | CentOS7.5+ | 4核CPU,8G内存,40G硬盘 |
| Node1 | 192.168.52.132 | CentOS7.5+ | 2核CPU,4G内存,20G硬盘 |
| Node1 | 192.168.52.133 | CentOS7.5+ | 2核CPU,4G内存,20G硬盘 |
设置主机名
#192.168.52.131 执行
hostnamectl set-hostname k8s-master
#192.168.52.132 执行
hostnamectl set-hostname k8s-node1
#192.168.52.133 执行
hostnamectl set-hostname k8s-node2
系统初始化
安装k8s需要高版本系统内核,centos7的那个3点几的有bug漏洞
升级系统内核
#入elrepo gpg key
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
#安装elrepo YUM源仓库
yum -y install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
#安装kernel-ml版本,ml为长期稳定版本,lt为长期维护版本
yum --enablerepo="elrepo-kernel" -y install kernel-ml.x86_64
#--#下载安装比较慢,可以直接从阿里云下载,https://mirrors.aliyun.com/
#--#https://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/下的kernel-ml-6.1.3-1.el7.elrepo.x86_64.rpm
#wget https://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-6.1.3-1.el7.elrepo.x86_64.rpm
#安装 rpm -ivh kernel-ml-6.1.3-1.el7.elrepo.x86_64.rpm
#设置grub2默认引导为0
grub2-set-default 0
#重新生成grub2引导文件
grub2-mkconfig -o /boot/grub2/grub.cfg
#更新后,需要重启,使用升级的内核生效。
reboot
#重启后,需要验证内核是否未更新对应的版本
uname -r
初始化
#三台主机都执行
#关闭防火墙
systemctl stop firewalld
#禁止开机启动防火墙
systemctl disable firewalld
#主机名解析
cat >> /etc/hosts << EOF
192.168.52.131 k8s-master
192.168.52.132 k8s-node1
192.168.52.133 k8s-node2
EOF
#时间同步
yum install ntpdate -y
ntpdate time.windows.com
#关闭selinux
#查看selinux是否开启
getenforce
#永久关闭,需要重启
sed -i 's/enforcing/disabled/' /etc/selinux/config
#临时关闭,重启后无效
setenforce 0
#关闭swap分区
#永久关闭,需要重启
sed -ri 's/.*swap.*/#&/' /etc/fstab
#临时关闭
swapoff -a
将桥接的IPv4流量传递到iptables的链
#三台主机都执行
#在每个节点上将桥接的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
开启ipvs
在kubernetes中service有两种代理模型,一种是基于iptables,另一种是基于ipvs的。ipvs的性能要高于iptables的,但是如果要使用它,需要手动载入ipvs模块。 在每个节点安装ipset和ipvsadm 默认使用的iptables,(iptables也挺好的,开启ipvs方法:待补充)
#安装ipset及ipvsadm
yum -y install ipset ipvsadm
cat > /etc/sysconfig/modules/ipvs.module <<EOF
modprobe -- ip_vs
modprobe -- ip_vs_sh
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- nf_conntrack
EOF
#授权、运行、检查是否加载
chmod 755 /etc/sysconfig/modules/ipvs.module && /etc/sysconfig/modules/ipvs.module
lsmod | grep -e ip_vs -e nf_conntrack
重启
#三台都执行
reboot
Docker安装
docker -v
#Docker version 20.10.22, build 3a2c30b
部署cri-dockerd
从 k8s 1.24开始,dockershim已经从kubelet中移除,但因为历史问题docker却不支持kubernetes主推的CRI(容器运行时接口)标准,所以docker不能再作为k8s的容器运行时了,即从k8s v1.24开始不再使用docker了但是如果想继续使用docker的话,可以在kubelet和docker之间加上一个中间层cri-docker。cri-docker是一个支持CRI标准的shim(垫片)。一头通过CRI跟kubelet交互,另一头跟docker api交互,从而间接的实现了kubernetes以docker作为容器运行时。但是这种架构缺点也很明显,调用链更长,效率更低。总的来说,k8s只负责接口,其他容器厂商作为实现。
#三台都执行
#到下面的链接下载最新版cri-docker,https://github.com/Mirantis/cri-dockerd/tags
#此处下载cri-dockerd-0.3.0.amd64
tar -zxvf cri-dockerd-0.3.0.amd64.tgz
cp cri-dockerd/cri-dockerd /usr/bin/
chmod +x /usr/bin/cri-dockerd
#配置启动文件
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
# 生成socket 文件
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.socket
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF
# 启动cri-docker并设置开机自动启动
systemctl daemon-reload
systemctl enable cri-docker --now
#显示 active
systemctl is-active cri-docker
安装kubernetes
当前最新版本是1.26.0(2023-01-12),本次安装1.25.0
#三台都执行
#阿里云YUM源
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 clean all && yum makecache
#查看所有的可用版本
yum list kubeadm kubelet kubectl --showduplicates | sort -r
#这里安装1.25.0
yum install -y kubeadm-1.25.0 kubelet-1.25.0 kubectl-1.25.0
#查看kubadm版本
kubeadm version
#为了实现docker使用的cgroupdriver与kubelet使用的cgroup的一致性,建议修改如下文件内容
#cat <<EOF > /etc/sysconfig/kubelet
#KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
#EOF
#设置kubelet为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动
systemctl enable --now kubelet
#查看可用状态
systemctl is-active kubelet #显示active ,如果显示inactive可以重启后再看
初始化集群
#192.168.52.131(master) 执行
#需要指定k8s版本
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.25.0 --pod-network-cidr=10.244.0.0/16 --cri-socket /var/run/cri-dockerd.sock
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.52.131:6443 --token kai6zh.gb8d4vjove0vjznn \
--discovery-token-ca-cert-hash sha256:d2c8c9f6ad64d04824a7a8afceac081b4518451437c25cd5633dacab3068c489
##192.168.52.131(master) 执行
#普通用户需要执行以下命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#root 用户执行
export KUBECONFIG=/etc/kubernetes/admin.conf
192.168.52.132(node1),192.168.52.133(node2) 执行,token 有效期两个小时,过期自己再生成
#为防止kubeadm join报以下错误
#[preflight] Some fatal errors occurred:
# [ERROR CRI]: container runtime is not running: output: time="2023-01-04T12:51:02+08:00" level=fatal msg="unable to #determine runtime API version: rpc error: code = DeadlineExceeded desc = context deadline exceeded"
#, error: exit status 1
mv /etc/containerd/config.toml /etc/containerd/config.toml.bak
systemctl restart containerd
#需要加--cri-socket unix:///var/run/cri-dockerd.sock
kubeadm join 192.168.52.131:6443 --token kai6zh.gb8d4vjove0vjznn \
--discovery-token-ca-cert-hash sha256:d2c8c9f6ad64d04824a7a8afceac081b4518451437c25cd5633dacab3068c489 \
--cri-socket unix:///var/run/cri-dockerd.sock
#为了让node节点也能执行kubectl命令
echo "export KUBECONFIG=/etc/kubernetes/kubelet.conf" >> /etc/profile
source /etc/profile
验证
#192.168.52.131(master) 执行
kubectl get node
[root@k8s-master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane 86m v1.25.0
k8s-node1 NotReady <none> 47s v1.25.0
k8s-node2 NotReady <none> 43s v1.25.0
安装 calico 网络插件
#三台机器 执行
wget https://docs.projectcalico.org/manifests/calico.yaml --no-check-certificate
vim calico.yaml
# no effect. This should fall within `--cluster-cidr`.
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
# Disable file logging so `kubectl logs` works.
##192.168.52.131(master) 执行
#下载镜像
cat calico.yaml |grep image
docker pull docker.io/calico/cni:v3.24.5
docker pull docker.io/calico/node:v3.24.5
docker pull docker.io/calico/kube-controllers:v3.24.5
##192.168.52.131(master) 执行
kubectl apply -f calico.yaml
kubectl get pod -n kube-system
[root@k8s-master opt]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-798cc86c47-v246b 1/1 Running 0 7m29s
calico-node-dwg8f 1/1 Running 0 7m29s
calico-node-wj2bb 1/1 Running 0 7m29s
calico-node-xt5pb 1/1 Running 0 7m29s
coredns-c676cc86f-sf99p 1/1 Running 0 102m
coredns-c676cc86f-vcxjk 1/1 Running 0 102m
etcd-k8s-master 1/1 Running 0 102m
kube-apiserver-k8s-master 1/1 Running 0 102m
kube-controller-manager-k8s-master 1/1 Running 0 102m
kube-proxy-2k955 1/1 Running 0 102m
kube-proxy-gpn45 1/1 Running 0 16m
kube-proxy-l4jz5 1/1 Running 0 16m
kube-scheduler-k8s-master 1/1 Running 0 102m
####三台 执行
kubectl get node
[root@k8s-master opt]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 103m v1.25.0
k8s-node1 Ready <none> 17m v1.25.0
k8s-node2 Ready <none> 17m v1.25.0
#192.168.52.131(master) 执行
#去掉master 节点的污点
kubectl describe node k8s-master | grep -i taint
[root@k8s-master opt]# kubectl describe node k8s-master | grep -i taint
Taints: node-role.kubernetes.io/control-plane:NoSchedule
#192.168.52.131(master) 执行
#去除污点
kubectl taint node k8s-master node-role.kubernetes.io/control-plane:NoSchedule-
#可以不执行,集群不受影响
#192.168.52.131(master) 执行
#给节点打标签(可选)
kubectl label node k8s-master node-role.kubernetes.io/master=master
kubectl label node k8s-node1 node-role.kubernetes.io/worker=worker
kubectl label node k8s-node2 node-role.kubernetes.io/worker=worker