上一节学习了k8s的基础概念,对k8s有了基本的认识。这一节,来搭建一下k8s集群环境。我能写出来,就代表这已经是一个成功的案例了(我自己起码做了2遍),坑都被我给踩过了,所以大家请放心食用。


一.安装前的环境规划

1.集群类型

● Kubernetes集群大致分为两类:一主多从和多主多从。
● 一主多从:一个Master节点和多台Node节点,搭建简单,但是有单机故障风险,适合用于测试环境。
● 多主多从:多台Master和多台Node节点,搭建麻烦,安全性高,适合用于生产环境。
在这里插入图片描述
为了测试方便,本次搭建的是一主多从类型的集群。

2.安装方式

● kubernetes有多种部署方式,目前主流的方式有kubeadm、minikube、二进制包。
● ① minikube:一个用于快速搭建单节点的kubernetes工具。
● ② kubeadm:一个用于快速搭建kubernetes集群的工具。
● ③ 二进制包:从官网上下载每个组件的二进制包,依次去安装,此方式对于理解kubernetes组件更加有效。

我们需要安装kubernetes的集群环境,但是又不想过于麻烦,所以选择kubeadm方式。

3.主机规划

本案例做一主两从的k8s集群。我买不起服务器,所以创了3台虚拟机来学习。大家要进行学习的话,创建好3台虚拟机,并且选择NAT连接。

下面的一些配置根据自己电脑vMnet8的网段(NAT模式需要保证虚拟机网段与VMnet 8一致!!!)来配置,不然无法上网,就更别谈安装k8s集群了。

我查看虚拟机的网络配置(你们可能会不一样,请按如下方式查看):
在这里插入图片描述
在这里插入图片描述
我们上面显示网段为192.168.172.0,所以配置网络时要把IP地址设为这个网段下的IP地址,网关也是如此。
(比如IP地址可以设置192.168.172.2 ~ 192.168.172.254之间的IP地址,默认网关为192.168.172.1,子网掩码255.255.255.0)

网关是不能随便配置的!比如你的网关是192.168.0.1,那么局域网内可设的ip就是192.168.0.2~192.168.0.254
如果你的网关是192.168.1.1,那么局域网内可设的ip就是192.168.1.2~192.168.1.254。

为了方便操作,我下面3台机器的IP地址和其他信息如下,供大家参考:

角色IP地址操作系统配置
Master192.168.172.101CentOS7,基础设施服务器2核CPU,2G内存,40G硬盘
Node1192.168.172.102CentOS7,基础设施服务器2核CPU,2G内存,40G硬盘
Node2192.168.172.103CentOS7,基础设施服务器2核CPU,2G内存,40G硬盘

下面教大家如何安装时配置虚拟机的网络:

(1)点击网络和主机名
在这里插入图片描述
(2)点击配置按钮
在这里插入图片描述
(3)选择ipv4设置,进行如下的配置(再次提醒,下面的设置一定要根据自己电脑vMnet8的网段来设置,不要抄我的),然后保存。
在这里插入图片描述
223.5.5.5是阿里云的DNS。

(4)保存后如下,然后更改主机名:
在这里插入图片描述
在这里插入图片描述
然后就可以开始安装了。

其他两台以此类推,自己安装一下吧,有什么问题,我们评论区互动。

4.搭建流程

● ① 准备 3 台机器,要求网络互通(如果是云服务器,要求私网互通;如果是虚拟机,要求网络互通)。
● ② 在 3 台机器上安装 Docker 容器化环境。
● ③ 安装 Kubernetes :
○ 3 台机器安装核心组件:kubeadm(创建集群的引导工具)、kubelet 、kubectl(程序员使用的命令行)。
○ kubelet 可以直接通过容器化的方式创建出 Kubernetes 的核心组件,如:Controller Manager、Scheduler 等。
○ 由 kubeadm 引导创建 Kubernetes 集群。


二.Kubernetes集群的安装

1.Kubernetes 和 Docker 之间的版本对应关系

Kubernetes 和 Docker 之间是有版本对应关系的,这也是一开始我踩的坑之一。下面就教大家如何查看Kubernetes 和 Docker 之间的版本对应关系。

打开官方的文档,我们这次要安装kubernetes的版本是v1.21的版本。
在这里插入图片描述
我们找到点进去就能查看到对应安装的docker版本了。
在这里插入图片描述
从文档中,我们可以知道 Docker 的版本是 v20.10 ,对应的 Kubernetes 的版本是 v1.21 。

2.准备工作

(1)检查操作系统的版本和内核

cat /etc/redhat-release

用 kubeadm安装k8s集群,centos的版本得是7.5以上,不然可能会出问题。
在这里插入图片描述
查看当前系统的内核:

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

③设置默认的内核版本:

vim /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

⑤重启系统:

reboot

在这里插入图片描述

(2)如果是虚拟机则需要让三台机器互通,最简单的做法就是关闭防火墙。

systemctl stop firewalld
systemctl disable firewalld

如果是云厂商提供的云服务器则需要让三台机器的私有 IP 互通,还需要设置安全组策略放行指定的端口。
在这里插入图片描述

① Master 节点:

协议方向端口范围目的使用者
TCP入站6443Kubernetes API server所有
TCP入站2379-2380etcd server client APIkube-apiserver, etcd
TCP入站10250Kubelet API自身, 控制面
TCP入站10259kube-scheduler自身
TCP入站10257kube-controller-manager自身

② Node 节点:

协议方向端口范围目的使用者
TCP入站10250Kubelet API自身, 控制面
TCP入站30000-32767NodePort Services+所有

(3)设置主机名
命令:

hostnamectl set-hostname <hostname>

示例如下:

# 192.168.172.101
hostnamectl set-hostname k8s-master
# 192.168.172.102
hostnamectl set-hostname k8s-node1
# 192.168.172.103
hostnamectl set-hostname k8s-node2

在这里插入图片描述

(4)主机名解析

分别进行如下操作:

为了方便后面集群节点间的直接调用,需要配置一下主机名解析,企业中推荐使用内部的 DNS 服务器。

cat >> /etc/hosts << EOF
127.0.0.1   $(hostname)
192.168.172.101 k8s-master
192.168.172.102 k8s-node1
192.168.172.103 k8s-node2
EOF

在这里插入图片描述

(5)时间同步
Kubernetes 要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步:

yum install ntpdate -y
ntpdate time.windows.com

(6)关闭 SELinux

分别进行如下操作:

查看 SELinux 是否开启:

getenforce

永久关闭 SELinux ,需要重启:

sed -i 's/enforcing/disabled/' /etc/selinux/config

关闭当前会话的 SELinux ,重启之后无效:

setenforce 0

(7)关闭 swap 分区
永久关闭 swap ,需要重启:

sed -ri 's/.*swap.*/#&/' /etc/fstab

关闭当前会话的 swap ,重启之后无效:

swapoff -a

(8)将桥接的 IPv4 流量传递到 iptables 的链

分别进行如下操作:

修改 /etc/sysctl.conf 文件:

# 如果有配置,则修改
sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g"  /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g"  /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g"  /etc/sysctl.conf
# 可能没有,追加
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1"  >> /etc/sysctl.conf

在这里插入图片描述
加载 br_netfilter 模块:

modprobe br_netfilter

持久化修改(保留配置包本地文件,重启系统或服务进程仍然有效):

sysctl -p

在这里插入图片描述

(9) 开启 ipvs
● 在 Kubernetes 中 service 有两种代理模型,一种是基于 iptables ,另一种是基于 ipvs 的。ipvs 的性能要高于 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

在这里插入图片描述

(10)重启
重启三台机器:

reboot

3.安装docker

三台机子都要操作!
●卸载旧版本docker:

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

●yum 安装 gcc 相关:

yum -y install gcc
yum -y install 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 的版本:

yum list docker-ce --showduplicates | sort -r

●安装指定版本的 Docker(v20.10) :

yum -y install docker-ce-3:20.10.8-3.el7.x86_64 docker-ce-cli-3:20.10.8-3.el7.x86_64 containerd.io

●启动 Docker:

# 启动 Docker 
systemctl start docker
# 开启自动启动
systemctl enable docker

在这里插入图片描述
●开启阿里云的镜像加速
打开阿里云官网,然后搜索容器镜像服务。
在这里插入图片描述
根据文档一步步操作:
在这里插入图片描述
到这里,恭喜你,docker安装好了!


4.添加阿里云的 Kubernetes 的 YUM 源

由于kubernetes的镜像源在国外,非常慢,这里切换成国内的阿里云镜像源:

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
5.安装kubeadm、kubelet和kubectl

由于版本更新频繁,这里指定版本号部署:

yum install -y kubelet-1.21.10 kubeadm-1.21.10 kubectl-1.21.10

为了实现 Docker 使用的 cgroup drvier 和 kubelet 使用的 cgroup drver 一致,建议修改/etc/sysconfig/kubelet 文件的内容:

vim /etc/sysconfig/kubelet
# 修改
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
vim /etc/docker/daemon.json

添加:

{
 "exec-opts":["native.cgroupdriver=systemd"]
}

重启:

systemctl restart docker
docker info | grep -i cgroup

设置为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动:

systemctl enable kubelet
6.查看并安装Kubernetes所需镜像

查看 Kubernetes 安装所需镜像:

kubeadm config images list

在这里插入图片描述
下载 Kubernetes 安装所需镜像

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.13
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.21.13
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.21.13
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.21.13
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

给 coredns 镜像重新打 tag :

docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
7.部署 Kubernetes 的 Master 节点

在 192.168.172.101 机器上部署 Kubernetes 的 Master 节点:
由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址

kubeadm init \
  --apiserver-advertise-address=192.168.172.101 \
  --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
  --kubernetes-version=v1.21.13 \
  --service-cidr=10.96.0.0/16 \
  --pod-network-cidr=10.244.0.0/16

注意:
apiserver-advertise-address 一定要是主机的 IP 地址。
apiserver-advertise-address 、service-cidr 和 pod-network-cidr 不能在同一个网络范围内。
不要使用 172.17.0.1/16 网段范围,因为这是 Docker 默认使用的。

成功的话,会有如下日志:

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.172.101:6443 --token zrelll.4hcypbur50301tm4 \
        --discovery-token-ca-cert-hash sha256:3c0ea6e5d64d95ec454c4db6f2b88ab50918802845231a334bc7aaef00782c5d

根据日志提示操作,在 192.168.172.101 执行如下命令:

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

默认的 token 有效期为 2 小时,当过期之后,该 token 就不能用了,这时可以使用如下的命令创建 token :

kubeadm token create --print-join-command
# 生成一个永不过期的token
kubeadm token create --ttl 0 --print-join-command
8.部署 Kubernetes 的 Node节点

根据日志提示操作,在 192.168.172.102 和 192.168.172.103 执行如下命令:

kubeadm join 192.168.172.101:6443 --token zrelll.4hcypbur50301tm4 \
        --discovery-token-ca-cert-hash sha256:3c0ea6e5d64d95ec454c4db6f2b88ab50918802845231a334bc7aaef00782c5d
9.部署网络插件

Kubernetes 支持多种网络插件,比如 flannel、calico、canal 等,任选一种即可,本次选择 calico(在 192.168.172.101 节点上执行)
calico 和 k8s 的版本对应

kubectl apply -f https://projectcalico.docs.tigera.io/v3.19/manifests/calico.yaml

查看部署 CNI 网络插件进度:

kubectl get pods -n kube-system
watch kubectl get pods -n kube-system
10.查看节点状态

在 Master(192.168.172.101)节点上查看节点状态:

kubectl get nodes

在这里插入图片描述

11.设置 kube-proxy 的 ipvs 模式

在 Master(192.168.172.101)节点设置 kube-proxy 的 ipvs 模式:

kubectl edit cm kube-proxy -n kube-system
apiVersion: v1
data:
  config.conf: |-
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    bindAddress: 0.0.0.0
    bindAddressHardFail: false
    clientConnection:
      acceptContentTypes: ""
      burst: 0
      contentType: ""
      kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
      qps: 0
    clusterCIDR: 10.244.0.0/16
    configSyncPeriod: 0s
    conntrack:
      maxPerCore: null
      min: null
      tcpCloseWaitTimeout: null
      tcpEstablishedTimeout: null
    detectLocalMode: ""
    enableProfiling: false
    healthzBindAddress: ""
    hostnameOverride: ""
    iptables:
      masqueradeAll: false
      masqueradeBit: null
      minSyncPeriod: 0s
      syncPeriod: 0s
    ipvs:
      excludeCIDRs: null
      minSyncPeriod: 0s
      scheduler: ""
      strictARP: false
      syncPeriod: 0s
      tcpFinTimeout: 0s
      tcpTimeout: 0s
      udpTimeout: 0s
    kind: KubeProxyConfiguration
    metricsBindAddress: ""
    mode: ""
    nodePortAddresses: null
      minSyncPeriod: 0s
      syncPeriod: 0s
    ipvs:
      excludeCIDRs: null
      minSyncPeriod: 0s
      scheduler: ""
      strictARP: false
      syncPeriod: 0s
      tcpFinTimeout: 0s
      tcpTimeout: 0s
      udpTimeout: 0s
    kind: KubeProxyConfiguration
    metricsBindAddress: ""
    mode: "ipvs" # 修改此处
...

删除 kube-proxy ,让 Kubernetes 集群自动创建新的 kube-proxy :

kubectl delete pod -l k8s-app=kube-proxy -n kube-system
12.让 Node 节点也能使用 kubectl 命令

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

# 192.168.172.102 和 192.168.172.103 node子节点
mkdir -pv ~/.kube
touch ~/.kube/config
# 192.168.172.101 master节点
scp /etc/kubernetes/admin.conf root@192.168.172.102:~/.kube/config
scp /etc/kubernetes/admin.conf root@192.168.172.103:~/.kube/config

三.Kubernetes 安装 Nginx

部署 Nginx :

kubectl create deployment nginx --image=nginx:1.14-alpine

暴露端口:

kubectl expose deployment nginx --port=80 --type=NodePort

查看服务状态:

kubectl get pods,svc

在这里插入图片描述

四.安装命令行自动补全功能

官方文档

# 安装 
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集群的搭建就告一段落了,我可能会很长一段时间暂停学习k8s,决定再把其他的一些基础知识再巩固一下,再见。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐