前言
本文讲述在Linux公网、云服务器搭建K8s集群详细步骤,解决搭建过程中的问题。
脚本基本可以不修改直接使用。
准备工作
需要Linux CentOS 7.x 两台及以上,本文用的 7.6。
主机要求有2个核心及以上。
本文主要针对云服务器公网环境,比如服务器不在一个内网段需要通过公网互通,使用不同云服务商主机等。
云服务器记得提前在安全组中放开使用到的端口 [主节点 6443] [工作节点测试使用的 80]。
安装步骤多个节点可以并行操作,默认所有操作各节点都要执行,某些操作仅主/工作节点执行在标题中有标注(主/工)。
部署成功后可以尝试使用 Kubesphere 或 Rancher 容器管理平台进行管理。
安装步骤
设置主机名
单独为每个服务器设置主机名,格式为hostnamectl set-hostname hostname。一般主节点取名master,从节点取名node.
echo "设置主节点主机名" > /dev/null
hostnamectl set-hostname k8s-master
echo "设置从节点主机名" > /dev/null
hostnamectl set-hostname k8s-node1
配置系统环境
echo "停止、关闭防火墙" > /dev/null
systemctl stop firewalld
systemctl disable firewalld
echo "永久关闭SELinux" > /dev/null
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
echo "临时关闭SELinux" > /dev/null
setenforce 0
echo "查看SELinux状态,显示为[SELinux status: disabled]视为设置成功" > /dev/null
sestatus
echo "永久关闭Swap" > /dev/null
sed -ri 's/.*swap.*/#&/' /etc/fstab
echo "临时关闭Swap" > /dev/null
swapoff -a
echo "安装、配置时间同步" > /dev/null
yum install ntpdate -y
ntpdate time.windows.com
echo "创建/etc/sysctl.d/k8s.conf配置文件,将桥接的 IPv4 流量传递到 iptables 的链" > /dev/null
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
添加 hosts(主)
在主节点配置所有k8s服务器的host,并且host名字跟各服务器的主机名对应。这里配置的是公网IP。
# 追加host
cat >> /etc/hosts << EOF
<主节点公网IP> k8s-master
<工作节点公网IP> k8s-node1
EOF
echo "使host配置生效" > /dev/null
/etc/init.d/network restart
Docker安装
echo "下载安装" > /dev/null
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce-18.06.1.ce-3.el7
echo "设置开机启动并启动" > /dev/null
systemctl enable docker && systemctl start docker
echo "查看Docker版本" > /dev/null
docker --version
设置Docker仓库地址,这个地址是Docker镜像上传/下载源。这个地址可以是自己搭建的私有仓库Harbor,也可以考虑用阿里云等第三方仓库。
echo "创建/etc/docker/daemon.json配置文件并指定镜像仓库" > /dev/null
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
echo "重启Docker使配置生效" > /dev/null
systemctl restart docker
K8s组件安装
添加yum源,并配置为阿里云源,国内下载更快。
echo "创建/etc/yum.repos.d/kubernetes.repo追加yum源配置" > /dev/null
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
echo "安装Kubeadm、Kubelet、Kubectl" > /dev/null
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
echo "设置开机启动" > /dev/null
systemctl enable kubelet
集群初始化(主)
通过kubeadm执行初始化,apiserver-advertise-address填主节点的公网IP。service-cidr是service网段。pod-network-cidr是Pod网段。
kubeadm init
--apiserver-advertise-address=<公网IP>
--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
执行完上面的初始化脚本后会卡在 etcd 初始化的位置,因为 etcd 绑定端口的时候使用外网 IP,而云服务器外网 IP 并不是本机的网卡,而是网关分配的一个供外部访问的 IP,从而导致初始化进程一直重试绑定,长时间卡住后失败。如下图示:
解决办法是在卡住时,另启一个命令行窗口修改初始化生成的 etcd.yaml 中的配置成示例图一样,进程会自动重试并初始化成功。
vim /etc/kubernetes/manifests/etcd.yaml
Kubectl设置。kubeadm初始化完成后,控制台会打印下面一模一样的指令,直接执行。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
工作节点加入集群(工)
主节点通过kubeadm初始化成功后控制台会打印出join脚本,复制到从节点执行。
如果忘记了join脚本,可以在主节点执行以下命令重新生成。
kubeadm token create --print-join-command
安装容器网络插件(主)
容器网络插件CNI(Container Network Interface)这里使用的解决方案为Flannel。
需要插件的配置文件kube-flannel.yml,通过kubectl来应用配置,命令格式为kubectl apply -f加上本地路径或者链接。下面这个是我码云仓库里面的,可直接用。
kubectl apply -f https://gitee.com/www.freeclub.com/blog-images/raw/master/source/kube-flannel.yml
测试
等待集群Ready状态
查看集群节点,可以看到节点从NotReady到Ready的状态变更。等全部Ready再进行下一步测试。
kubectl get nodes
以Nginx为例作测试(主)
创建一个Service和Deployment。
echo "部署 nginx (deployment,pod)" > /dev/null
kubectl create deployment nginx --image=nginx
echo "暴露 nginx 端口给集群外部访问 (service)" > /dev/null
kubectl expose deployment nginx --port=80 --type=NodePort
执行下面指令可获取pod和service信息,可以看到NodePort类型的service在宿主机暴露了随机端口30879供集群外部访问。
访问链接如:http://IP:30879,IP为工作节点外网IP。
echo "获取 service deployment 和 pod 信息" > /dev/null
kubectl get svc,deployment,pod
删除测试的Nginx Service和Deployment
echo "删除nginx service" > /dev/null
kubectl delete service nginx
echo "删除nginx deployment" > /dev/null
kubectl delete deployment nginx
解决公网环境节点间无法互通问题
集群按上面步骤搭建好后,Pod 之间互相访问不了,StatefulSet 也无法通过 <podName.serviceName> 这种方式直接访问,但是通过 NodePort 暴露给外部访问确是可以访问到的目标服务的。
主节点执行 kubectl exec -it
echo "进入Pod" > /dev/null
kubectl exec -it pod/nginx-f89759699-4d4xk bash
如果网络互通,进入 Pod 容器直接 ping 其他 Pod/Service 的 IP 或者 StatefuSet 虚拟 DNS 地址 [PodName].[ServiceName].[Namespace].svc.cluster.local 是可以通的。
解决办法:使用 iptables IP 重定向,如这种情况下让系统访问工作节点内网 IP 时转而访问工作节点的外网 IP。
iptables -t nat -A OUTPUT -d <内网 IP> -j DNAT --to-destination <外网 IP>
内、公网配置差异总结
-
• 主节点配置host的时候IP都是填写公网IP
-
• 主节点执行初始化时,脚本填写的是自己的公网IP
-
• 公网环境主节点初始化期间可能需要在卡住的时候修改etcd配置
-
• 需要解决集群节点不互通问题,不然内部访问不通,主节点无法通过命令kubectl exec进入容器
Rancher安装
Master 节点执行以下指令就行,官网有 快速开始[1] 介绍。
Rancher 是一个容器管理平台,可以直接创建集群,也可以将原有集群添加进去交给它管理。通过UI界面创建集群中各个容器/组件非常方便。
安装好后通过 80/443 端口访问,云服务器记得开放这两个端口
sudo docker run --privileged -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher
参考链接
iptables IP 重定向[2]
Rancher 官网[3]
引用链接
[1]
快速开始: https://rancher.com/quick-start/[2]
iptables IP 重定向: https://www.zhoujiangang.com/p/iptables-redirect-ip/[3]
Rancher 官网: https://rancher.com/
原文始发于微信公众号(我有八千部下):在Linux公网、云服务器搭建K8s集群
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/102523.html