1. Centos7 使用 kubeadm 安装 k8s

本文参考了官方文档k8s官方文档-安装kubeadm和知乎文章《k8s集群搭建》不要让贫穷扼杀了你学k8s的兴趣!。其中知乎文章写的很好,图文并茂,从创建虚拟机到部署程序都介绍了,很完整,自己在笔记本就可以照着做。不过它使用docker而不是containerd,因此可以参考本文。

先配置好一台虚拟机做主节点,后面直接克隆3台做工作节点。如果虚拟机都已经建好,那每台都需要执行一下1.1到1.4的内容。

1.1. 准备工作

1.1.1. 配置主机名

hostnamectl set-hostname k8s-master

1.1.2. 关闭系统服务

为什么要关闭?请参考知乎问题部署 Kubernetes(k8s)时,为什么要关闭 swap、selinux、防火墙?

Note:关闭后需要重启服务器

  • 关闭防火墙:执行命令systemctl disable firewalld && systemctl stop firewalld
  • 关闭selinux:编辑文件/etc/selinux/config,修改SELINUX为SELINUX=disabled
  • 关闭swap:编辑文件/etc/fstab,注释swap分区那一行

1.1.3. 同步时间

集群内的时间需要一致,因此需要使用同步时间工具

systemctl enable chronyd && systemctl start chronyd
# 查看时间同步状态
chronyc sources -v

1.2. 安装容器运行时

k8s支持多种容器运行时,本文选择安装containerd。当然安装docker也是可以的,因为安装时也会安装containerd

centos7 的安装很简单,按照官网的教程Install Docker Engine on CentOS来即可。

1.2.1. 配置yum源

docker官方的软件源地址在国外,这里改成了腾讯镜像的。

cat <<EOF | tee /etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - 7
baseurl=https://mirrors.cloud.tencent.com/docker-ce/linux/centos/7/x86_64/stable/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.cloud.tencent.com/docker-ce/linux/centos/gpg
EOF

1.2.2. 安装containerd

配置好源后直接使用 yum 安装即可。

yum install containerd.io -y
# 初始化配置文件,默认生成的会禁用cri
containerd config default > /etc/containerd/config.toml
# 启动程序
systemctl start containerd
# 配置为开机启动
systemctl enable containerd

1.2.3. 配置containerd

docker镜像服务器在国外,因此国内访问会很慢。好在阿里推出镜像加速器,在阿里云的容器镜像服务可以找到教程。

当systemd是初始化系统时,k8s需要使用systemd作为cgroup驱动,因此需要修改配置。

默认情况下,containerd的相关元数据存储在/var/lib/containerd,最好将其改为大空间的路径。

使用命令修改配置文件/etc/containerd/config.toml,将对应处修改为下面的值:

root = "/home/containerd"
[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = ["https://a79n7bst.mirror.aliyuncs.com"]

修改好配置后,需要重启使配置生效:

systemctl restart containerd

1.3. 配置 iptables

k8s 需要使用 iptables 转发流量,可以通过命令查看是否正确配置。

# 查看模块是否被加载
lsmod | grep br_netfilter
lsmod | grep overlay
# 查看sysctl参数是否都为1
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

如果没有被配置好,可以使用下面命令配置:

cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# 重新加载
sysctl --system

1.4. 安装 kubeadm、kubelet 和 kubectl

需要在集群内所有机器安装以下软件:

  • kubeadm:用来初始化集群
  • kubelet:在集群中的节点上用来启动 pod 和容器等
  • kubectl:用来与集群通信的命令行工具

1.4.1. 配置 yum 源

k8s 官网的文档用的是 google 的源,因此需要改成国内的源。

cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.cloud.tencent.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
EOF

1.4.2. 安装软件

Note:安装完不需要重启服务器,否则会出现网卡没启动问题

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet

1.5. 克隆虚拟机

首先关闭现在的虚拟机,然后克隆3台虚拟机做工作节点(分别是k8s-node1、k8s-node2和k8s-node3)。

根据官网文档安装kubeadm介绍,集群内的节点不允许重复的主机名、MAC地址和product_uuid,因此在克隆时要选中为所有网卡重新生成MAC地址

克隆完成后,依次启动4台虚拟机。

1.5.1. 配置主机名

使用root用户分别登录3台虚拟机设置主机名:

# 登录k8s-node1
hostnamectl set-hostname k8s-node1
# 登录k8s-node2
hostnamectl set-hostname k8s-node2
# 登录k8s-node3
hostnamectl set-hostname k8s-node3

1.5.2. 配置名称解析

为了集群内节点的直接调用,需要配置主机名解析,可以将机器加入DNS服务器,或者将所有节点写入/etc/hosts文件。本文是直接修改/etc/hosts文件,使用root用户分别登录4台虚拟机:

192.168.56.157 k8s-master
192.168.56.159 k8s-node1
192.168.56.160 k8s-node2
192.168.56.161 k8s-node3

1.6. 创建集群(只需要在master服务器上执行)

1.6.1. 使用kubeadm init初始化集群

使用 kubeadm 命令即可创建一个主节点:

根据flannel 文档说明,flannel 和 kubeadm 一起使用需要配置pod-network-cidr

NOTE: If kubeadm is used, then pass --pod-network-cidr=10.244.0.0/16 to kubeadm init to ensure that the podCIDR is set.

kubeadm使用到的镜像可以通过命令查看:

kubeadm config images list
# 默认镜像地址是谷歌的,需要替换为国内镜像地址
kubeadm init --apiserver-advertise-address=192.168.56.157 --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16

修改配置文件,使得特定用户可以运行 kubectl:

# 这里是给普通用户sun设置运行kubectl
su - sun
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

如果是root用户,切换到root用户执行以下命令:

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

1.6.2. 添加节点

将 node 节点加入到集群中,分别登录到node 服务器kubeadm join命令可在kubeadm init命令的输出日志中找到:

kubeadm join 192.168.56.157:6443 --token jrq00m.hzj55l0z3ski71tg --discovery-token-ca-cert-hash sha256:9763c5343efde595c3020d7ba92ac4c35449033b9f78c45744edf18f9980f0f4

命令执行好了后,可以登录 master 服务器查看到所有节点:

kubectl get nodes

1.6.3. 安装网络附加组件

k8s 支持多种网络组件,这里选择flannel

访问网站下载 docker 镜像https://github.com/flannel-io/flannel/releases,下载完成后上传到master服务器,导入镜像:

sudo ctr -n k8s.io images import flanneld-v0.22.1-amd64.docker

下载 flannel 配置文件kube-flannel.yml:到flannel官网https://github.com/flannel-io/flannel下载zip包(这样比clone仓库速度快),下载后上传到master服务器

Note: VirtualBox默认的网卡地址为10.0.2.15,用来获取NATed的外部流量。Flannel默认使用主机上的第一个接口,这会导致所有主机认为它们具有相同的ip地址。为防止这种情况,需要添加--iface=eth1标志给flannel,用来选择第二个网卡。下文引用来自flannel的故障排查

Vagrant typically assigns two interfaces to all VMs. The first, for which all hosts are assigned the IP address 10.0.2.15, is for external traffic that gets NATed.

This may lead to problems with flannel. By default, flannel selects the first interface on a host. This leads to all hosts thinking they have the same public IP address. To prevent this issue, pass the --iface=eth1 flag to flannel so that the second interface is chosen.

解决方法是在kube-flannel.yml里的spec.template.spec.containers[0].args下新添加一行- --iface=enp0s8,其中的网卡名可以通过ip a获得。

kubectl apply -f flannel-master/Documentation/kube-flannel.yml

等待一会再次查看集群节点状态:

[sun@k8s-master ~]$ kubectl get nodes
NAME         STATUS   ROLES           AGE    VERSION
k8s-master   Ready    control-plane   147m   v1.28.0
k8s-node1    Ready    <none>          19m    v1.28.0
k8s-node2    Ready    <none>          19m    v1.28.0
k8s-node3    Ready    <none>          19m    v1.28.0

1.7. 部署服务验证功能

此处参考开头的知乎文章,使用 k8s 部署一个 nginx,来验证集群是否正常。

  • 创建一个 deployment
[root@k8s-master ~]# kubectl create deployment nginx --image=nginx:alpine
deployment.apps/nginx created

[root@k8s-master ~]# kubectl get deploy
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           51s

Note: 如果READY不为1/1,可使用kubectl describe pod查看日志。

  • 创建一个 service 使 nginx 可以被访问
[root@k8s-master ~]# kubectl expose deploy nginx --port=80 --target-port=80 --type=NodePort
service/nginx exposed

[sun@k8s-master ~]$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        155m
nginx        NodePort    10.109.124.154   <none>        80:31243/TCP   6s

创建好service后,就可以在集群外部访问了,由于kube-proxy的存在,访问集群内任意ip都可以。在集群内部服务器也可以使用CLUSTER-IP。

[root@master ~]# curl -s http://192.168.56.157:31243
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

[root@master ~]# curl -s http://192.168.56.159:31243
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

[root@master ~]# curl -s http://192.168.56.160:31243
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

[root@master ~]# curl -s http://192.168.56.161:31243
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

[sun@k8s-master ~]$ curl -s http://10.109.124.154
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
Logo

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

更多推荐