目录
2.3.2、安装 kubeadm,kubelet 和 kubectl
1.使用 kubeadm 部署
kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的客户端工具。
这个工具能通过两条指令完成一个 kubernetes 集群的部署:
# 创建一个 Master 节点 kubeadm init # 将一个 Worker node 节点加入到当前集群中 kubeadm join < Master 节点的 IP 和端口 >
1.1安装要求
在开始之前,部署 Kubernetes 集群机器需要满足以下几个条件:
- 一台或多台机器,操作系统 CentOS7.9。
- 硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 20GB 或更多。
- 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点。
- 禁止 swap 分区。
1.2安装步骤
- 准备虚拟机:准备三台虚拟机,并安装操作系统 CentOS 7.9。
- 系统初始化:对三个刚安装好的操作系统进行初始化操作。
- 安装 k8s 组件:在三台虚拟机上安装
docker
kubelet
kubeadm
kubectl
。- kubeadm init:使用
kubeadm init
命令,创建一个 Master 节点。- kubeadm join :使用
kubeadm join
命令,将一个 Worker node 节点加入到当前集群中。- 集群联网测试:配置 CNI 网络插件,拉取 nginx 进行网络测试。
2.安装
2.1准备虚拟机
如果不会创建虚拟机,可以查看 如何创建虚拟机?https://gitee.com/bbigsun/k8s/blob/master/pre-linux.md
主机名称 | IP | 配置 |
---|---|---|
k8smaster1 | 192.168.60.151 | 2U 2G 20G |
k8snode1 | 192.168.60.152 | 2U 2G 20G |
k8snode2 | 192.168.60.153 | 2U 2G 20G |
# 根据规划设置主机名【k8smaster1 节点上操作】
hostnamectl set-hostname ks8master1
# 根据规划设置主机名【k8snode1 节点上操作】
hostnamectl set-hostname k8snode1
# 根据规划设置主机名【k8snode2 节点操作】
hostnamectl set-hostname k8snode2
# 在主机名静态查询表中添加 3 台主机
cat >> /etc/hosts << EOF
192.168.60.151 k8smaster1
192.168.60.152 k8snode1
192.168.60.153 k8snode2
EOF
2.2系统初始化
对三台虚拟机进行初始化操作:
设置防火墙为 Iptables 并设置空规则
systemctl stop firewalld && systemctl disable firewalld
yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save
# 关闭 selinux
# 临时关闭【立即生效】告警,不启用,Permissive,查看使用 getenforce 命令
setenforce 0
# 永久关闭【重启生效】
sed -i 's/SELINUX=enforcing/\SELINUX=disabled/' /etc/selinux/config
# 关闭 swap
# 临时关闭【立即生效】查看使用 free 命令
swapoff -a
# 永久关闭【重启生效】
sed -ri 's/.*swap.*/#&/' /etc/fstab
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192 fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf
调整系统时区
# 设置系统时区为 中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond
安装依赖包
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git
关闭系统不需要服务
systemctl stop postfix && systemctl disable postfix
设 置 rsyslogd 和 systemd journald
mkdir /var/log/journal # 持久化保存日志的目录
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m RateLimitInterval=30s RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
升级系统内核
CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定,例如: rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
# 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装一次!
yum --enablerepo=elrepo-kernel install -y kernel-lt # 设置开机从新内核启动
grub2-set-default 'CentOS Linux (4.4.189-1.el7.elrepo.x86_64) 7 (Core)'
2.3安装 k8s 组件
- kubeadm:k8s 集群部署客户端工具
- kubelet:k8s 集群核心组件
- kubectl:k8s 集群命令行工具
- docker:k8s 集群默认 CRI(容器运行时)
kube-proxy开启ipvs的前置条件
modprobe br_netfilter
$cat > /etc/sysconfig/modules/ipvs.modules <<EOFmodprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules &&lsmod | grep -e ip_vs -e nf_conntrack_ipv4
2.3.1、安装 docker
# 配置 docker 的 yum 源【阿里云】
cat >/etc/yum.repos.d/docker.repo<<EOF
[docker-ce-edge]
name=Docker CE Edge - \$basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/\$basearch/edge
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
EOF
# yum 方式安装 docker
yum -y install docker-ce
# 查看 docker 版本
docker --version
# 配置 docker 的镜像源【阿里云】
cat >> /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
# 运行 docker 自启
systemctl enable docker
# 启动 docker
systemctl start docker
# 查看 docker 状态
systemctl status docker
2.3.2、安装 kubeadm,kubelet 和 kubectl
# 配置 k8s 的 yum 源【阿里云】
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
# 安装 kubelet、kubeadm、kubectl,同时指定版本 1.18.0
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
# 设置开机自启【这里暂时先不启动 kubelet】
systemctl enable kubelet
2.3.3kubeadm init
在 k8smaster1
上执行 kubeadm init
命令:
# 安装 kubelet、kubeadm、kubectl,同时指定版本 1.18.0
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
# 设置开机自启【这里暂时先不启动 kubelet】
systemctl enable kubelet
参数说明:
- --apiserver-advertise-address:当前主机 IP
- --image-repository:指定镜像源仓库
- --kubernetes-version:指定安装版本
- --service-cidr:service 可用 IP 范围
- --pod-network-cidr:pod 可用 IP 范围
由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址,【执行上述命令会比较慢,因为后台其实已经在拉取镜像了】,我们 可以使用 docker images 命令查看已经拉取的镜像。
部署成功后,系统提示运行以下命令使用 kubectl
:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
执行完成后,我们使用下面命令,查看我们正在运行的节点:
kubectl get nodes
2.3.4kubeadm join
在 k8snode1
和 k8snode2
上,执行 kubeadm join
命令向集群中添加新节点:
注意,以下的命令是在 k8smaster1
上执行 kubeadm init
命令后给出的,需要复制自己机器上生成的
kubeadm join 192.168.60.151:6443 --token 8j6ui9.gyr4i156u30y80xf \
--discovery-token-ca-cert-hash sha256:eda1380256a62d8733f4bddf926f148e57cf9d1a3a58fb45dd6e80768af5a500
如果你未保存 join 命令或者 token 过期(默认 token 有效期为 24 小时)导致 node 节点无法加入集群。这时就需要在 k8smatser1
上重新创建 token,命令如下:
kubeadm token create --print-join-command
当我们把两个 node 节点都加入集群后,在 k8smaster1
节点上执行下面命令查看 node 节点情况:
kubectl get nodes
2.3.5集群联网测试
查看 node 节点状态后,发现 node 节点状态是 NotReady,因为此时集群还未联网,下面我们需要部署网络插件,来进行联网访问:
# 下载网络插件 flannel
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 使用 yml 文件部署 flannel。执行命令后,需要耐心的等待一会儿...
kubectl apply -f kube-flannel.yml
# 查看 pods 状态。运行成功后的结果为 Ready 状态
kubectl get pods -n kube-system
【提示】如果上述操作完成后,还存在某个节点处于 NotReady 状态,可以在 Master 将该节点删除,重新加入集群。
### 将 k8snode1 删除后重新加入集群 ###
# 在 k8smaster1 节点上操作,删除 k8snode1 节点
kubectl delete node k8snode1
# 在 k8snode1 节点上操作,重置 k8snode1 节点
kubeadm reset
# 在 k8snode1 节点上操作,k8snode1 节点加入集群
kubeadm join 192.168.60.151:6443 --token 8j6ui9.gyr4i156u30y80xf --discovery-token-ca-cert-hash sha256:eda1380256a62d8733f4bddf926f148e57cf9d1a3a58fb45dd6e80768af5a500
创建一个 nginx pod,测试网络是否联通:
# 使用 nginx 镜像创建一个 pod
kubectl create deployment nginx --image=nginx、
# 查看 pod 状态,如果出现 Running 状态的时候,表示已经成功运行了
kubectl get pod
# 下面我们就需要将端口暴露出去,让其它外界能够访问
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看容器对外映射的本地端口,容器的 80 端口映射到了本地的 30529 端口
kubectl get pod,svc
# 通过 curl 命令测试网络
curl http://192.168.60.151:30529/
使用宿主机浏览器,访问如下地址,查看 nginx 是否成功启动:
http://192.168.60.151:30529/
3.错误汇总
错误一
在执行 Kubernetes init 方法的时候,出现这个问题
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR NumCPU]: the number of available CPUs 1 is less than the required 2
是因为 VMware 设置的核数为 1,而 K8S 需要的最低核数应该是 2,调整核数重启系统即可
错误二
我们在给 k8snode1 节点使用 kubernetes join 命令的时候,出现以下错误
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR Swap]: running with swap on is not supported. Please disable swap
错误原因是我们需要关闭 swap【可能是永久关闭 swap 时没有重启生效】
# 关闭 swap
# 临时关闭【立即生效】
swapoff -a
# 永久关闭【重启生效】
sed -ri 's/.*swap.*/#&/' /etc/fstab
错误三
在给 k8snode1 节点使用 kubernetes join 命令的时候,出现以下错误
The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp [::1]:10248: connect: connection refused
解决方法,首先需要到 k8smaster1 节点,创建一个文件
# 创建文件夹
mkdir /etc/systemd/system/kubelet.service.d
# 创建文件
vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 添加如下内容
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --fail-swap-on=false"
# 重置
kubeadm reset
接着删除刚刚创建的配置目录
rm -rf $HOME/.kube
然后在 k8smaster1 重新初始化
kubeadm init --apiserver-advertise-address=92.168.60.151:6443 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16
初始完成后,我们再到 k8snode1 节点,执行 kubeadm join 命令,加入到 k8smaster1【下面这条命令是 k8smaster1 初始化后自动生成的】
kubeadm join 192.168.60.151:6443 --token c7a7ou.z00fzlb01d76r37s \
--discovery-token-ca-cert-hash sha256:9c3f3cc3f726c6ff8bdff14e46b1a856e3b8a4cbbe30cab185f6c5ee453aeea5
添加完成后,我们使用下面命令,查看节点是否成功添加
kubectl get nodes
错误四
我们再执行查看节点的时候, kubectl get nodes 会出现问题
Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
这是因为我们之前创建的配置文件还存在,也就是这些配置
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
我们需要做的就是把配置文件删除,然后重新执行一下
rm -rf $HOME/.kube
然后再次创建一下即可
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
这个问题主要是因为我们在执行 kubeadm reset 的时候,没有把 $HOME/.kube 给移除掉,再次创建时就会出现问题了
错误五
安装的时候,出现以下错误
Another app is currently holding the yum lock; waiting for it to exit...
是因为 yum 上锁占用,解决方法
yum -y install docker-ce
错误六
在使用下面命令,添加 k8snode1 节点到集群上的时候
kubeadm join 192.168.60.151:6443 --token jkcz0t.3c40t0bqqz5g8wsb --discovery-token-ca-cert-hash sha256:bc494eeab6b7bac64c0861da16084504626e5a95ba7ede7b9c2dc7571ca4c9e5
然后出现了这个错误
[root@k8smaster1 ~]# kubeadm join 192.168.60.151:6443 --token jkcz0t.3c40t0bqqz5g8wsb --discovery-token-ca-cert-hash sha256:bc494eeab6b7bac64c0861da16084504626e5a95ba7ede7b9c2dc7571ca4c9e5
W1117 06:55:11.220907 11230 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
出于安全考虑,Linux 系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的 ip 地址将包发往本机另一网卡,该网卡根据路由表继续发送数据包。这通常就是路由器所要实现的功能。也就是说 /proc/sys/net/ipv4/ip_forward 文件的值不支持转发
- 0:禁止
- 1:转发
所以我们需要将值修改成 1 即可
echo “1” > /proc/sys/net/ipv4/ip_forward
修改完成后,重新执行命令即可
4、测试 kubernetes 集群
在 Kubernetes 集群中创建一个 pod,验证是否正常运行:
$ kubectl create deployment nginx --image=nginx #看下图1,有running就成功了
$ kubectl expose deployment nginx --port=80 --type=NodePort #暴露端口
$ kubectl get pod,svc #见图2
访问地址:http://NodeIP:Port #port就是图二中白色部分
图1
图2
图3
5. 使用源码部署
参考资料:https://blog.csdn.net/qq_40942490/article/details/114022294