当前位置:首页 » 网站资讯 » k8s怎么设置多个网站
扩展阅读
手机做身份证软件 2025-09-26 05:51:12
对网络安全宣传周的发言 2025-09-26 05:03:40

k8s怎么设置多个网站

发布时间: 2023-04-11 23:53:16

㈠ K8S安装和创建集群终极教程(单master多worker)

本文会以 最简单 最直接 最完整 的方式记录kubernetes(下面统称K8S)单master多工作节点(worker nodes)的集群步骤

首先要简单了解一下本文的3个核心概念:

内存建议至少4G

问:如何查看主机名?

答:执行命令hostname

问:如何修改主机名?

答:永久生效的做法:执行命令vi /etc/hostname,把第一行去掉(不能注释掉,要去掉)雹岩,然后重新写上自定义的主机名(注意命名规范),保存并重启后生效;

临时生效的做法:执行以下命令

问:如何查看MAC地址?

答悄旦:执行命令ip link,然后看你的第一网卡

问:如何查看proct_uuid?

答:执行命令sudo cat /sys/class/dmi/id/proct_uuid

注意:30000-32767这个端口范围是源运御我们创建服务的端口必须要设置的一个范围(如果设置范围以外的会有限制提示并创建失败),这是K8S规定的。

另外,如果你要直接关闭防火墙可以执行

⑥必须禁用Swap

Swap total大于0,说明Swap分区是开启的

问:如何关闭Swap?

答:编辑文件/etc/fstab,在swap行前面加上#号注释, 保存并重启服务器

再次查看分区状态,已生效

常见的容器引擎(Container runtime,简称runtime):

本文使用的容器引擎是Docker

安装完成后查看版本:

当出现可能跟Docker引擎相关的奇怪异常时可以尝试把Docker卸载干净并重新安装,但一定要注意镜像、容器、卷或配置文件这些是否需要备份。

下面记录卸载Docker引擎的步骤:

①卸载 Docker Engine、CLI 和 Containerd 包:

②主机上的映像、容器、卷或自定义配置文件不会自动删除。删除所有镜像、容器和卷:

③配置文件如果有不合法的字符时会导致启动失败,我们需要将其删除然后重建

此时Docker引擎已卸载干净

官网用的是谷歌的yum源,因为国内是连不上的,所以这里替换成阿里提供的yum源

①安装

从安装信息中可以看到版本号是1.22

Installing:

kubeadm x86_64 1.22.4-0 kubernetes 9.3 M

kubectl x86_64 1.22.4-0 kubernetes 9.7 M

kubelet x86_64 1.22.4-0 kubernetes 20 M

②启动



这就是一个驱动程序,注意cgroup和cgroupfs不要混淆了

引用官方的一段话

“由于 kubeadm 把 kubelet 视为一个系统服务来管理,所以对基于 kubeadm 的安装, 我们推荐使用 systemd 驱动,不推荐 cgroupfs 驱动。”

kubeadm默认是使用systemd 驱动,而我们的Docker默认驱动是cgroupfs(docker info可以查看),所以需要将Docker的驱动改成systemd

①编辑Docker配置文件

②重启Docker服务

再次docker info查看驱动信息已变成了systemd

工作节点(worker nodes)的最小配置就到这里了

①镜像源参数说明

默认情况下, kubeadm 会从 k8s.gcr.io 仓库拉取镜像,国内是拉不了的。官方文档明确表示允许你使用其他的 imageRepository 来代替 k8s.gcr.io。

--image-repository 你的镜像仓库地址

接下来我找了一些国内的镜像源,并简单做了下分析

综合上述统计,我选择阿里云的镜像源

②ip地址范围参数说明

--pod-network-cidr =192.168.0.0/16

注意:如果192.168.0.0/16已经在您的网络中使用,您必须选择一个不同的pod网络CIDR,在上面的命令中替换192.168.0.0/16。

集群初始化命令:

因为我用的是演示机器,所以这里把完整的执行信息都贴出来方便查阅,平时工作中一定要注意保护好敏感的信息(我的ip地址范围是自定义的便于下面的功能演示,另外初次init需要下载镜像文件,一般需要等几分钟)

如上所示,集群初始化成功,此时一定要注意看上面执行结果最后的那部分操作提示,我已用标明了初始化成功后还需要执行的3个步骤

注意:如果init成功后发现参数需要调整,可以执行kubeadm reset,它的作用是尽最大努力恢复kubeadm init 或者 kubeadm join所做的更改。

To start using your cluster, you need to run the following as a regular user:

翻译:开始使用集群前,如果你是普通用户(非root),你需要执行以下的命令:

Alternatively, if you are the root user, you can run:

翻译:或者,如果你使用的是root,你可以执行以下命令:

(注意:export只是临时生效,意味着每次登录你都需要执行一次)

网络配置配的就是Pod的网络,我的网络插件选用calico

cidr就是ip地址范围,如果您使用 pod CIDR 192.168.0.0/16,请跳到下一步。

但本文中使用的pod CIDR是192.100.0.0/16,所以我需要取消对清单中的 CALICO_IPV4POOL_CIDR 变量的注释,并将其设置为与我选择的 pod CIDR 相同的值。(注意一定要注意好格式,注意对齐)

可根据需求自定义清单,一般不需要的就直接跳过这步

在所有的工作节点上执行join命令(复制之前初始化成功后返回的加入集群命令到所有的工作节点执行即可)

master上查看所有节点的状态

到这里集群已经创建完成

最后我再安装K8S的可视化界面kubernetes-dashboard,方便我们日常使用

①下载yaml文件

②修改yaml文件,新增type和nodePort,使服务能够被外部访问

③安装并查看运行情况

④新建用户

文件创建完成后保存并apply

⑤获取Token,用于界面登录

⑥登录dashboard

192.168.189.128是我的master服务器ip,另外要注意必须使用https,并且不能使用ie内核模式

复制⑤生成的token到输入框,点击登录

dashboard安装配置完成

问:如何在查看资源情况?

答:在master上执行以下命令可查看资源情况(-o wide是显示更详细的信息),

①查看所有节点

②查看所有命名空间

③查看命名空间下的pod

④查看所有命名空间的pod

⑤实时查看查看命名空间下的pod运行情况

问:kubeadm join 出现异常[ERROR Port-10250]: Port 10250 is in use,如何解决?

答:这是因为你之前join失败过了,需要先执行kubeadm reset再重新join

问:虚拟机上测试时网卡突然消失如何解决(题外问题记录)?

答:

①确认丢失的网卡信息,ens开头(可选步骤)

ifconfig -a

②执行以下命令解决

问:如何查看K8S版本?

答:kubectl version

问:join命令忘记或者过期了怎么办?

答:

生成永不过期的

生成时效24小时的

问:Pod不断重启并且无其它报错信息时怎么办?

答:这种情况通常是因为你的集群中只有master,没有worker节点,master的创建默认是有污点的,即不允许调度新的Pod,如果你需要(当然这并不推荐),就需要删除 master 上的污点。删除污点可以执行以下命令,

它应该返回以下内容。

计算机网络-k8s网络

K8S网络模型设计:扁平的可连通的网络

K8S的网络是一个极其复杂的网络,如果想要用两个简单的词来描述K8S网络,那么我觉得扁平和可连通是K8S网络最大的特点(不懂隔离性)。

何为连通呢?

二层网络的连通:如果能够直接通过MAC帧直接通信的网络便是二层连通的网络,LAN就是这种网络

比如无限WIFI网络,比如以太网

三层网络的连通:如果能够通过IP报直接通信的网络便是三层连通的网络,便是三层连通

三层网络的连通分为两个部分,第一个部分是三层网络中的每一个LAN都是二层连通的,其次需要存在能够连通的路由来保证;这里可以简单回顾下三层网络通信的流程

通过路由表确定目标ip是否在链路上

如果在链路上,通过arp协议获取对应主机的mac地址,发送mac帧到链路上;

如果不在同一个链路上,通过本地路由表发送mac帧给下一跳,然后下一跳解析mac帧,分析ip报,继续路由直到最终跳到目标网络再次通过mac帧发送到目标主机或者到达ttl消失。

假如其中任何一个步骤不满足或者出问题,三层网络就无法连通

何为扁平呢?

就是希望可以在pod内直接通过IP进行互相通信而不需要在pod内部使用vpn之类的东西来连接其他pod(基础架构化),具体的可以看下k8s对网络的设计与要求。

k8s在设计其网络时,就希望网络对运行在其中的pod是透明的,因此提出了以下的一些要求与原则

k8s组网要求

所有的Pods之间可以在不使用 NAT网络地址转换 的情况下相互通信

所有的Nodes之间可以在不使用NAT网络地址转换的情况下相互通信

每个Pod自己看到的自己的ip和其他Pod看到的一致

k8s网络模型设计原则

每个Pod都拥有一个独立的 IP地址,而且 假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中 。

不管它们是否运行在同 一 个 Node (宿主机)中,都要求它们可以直接通过对方的 IP 进行访问。

设计这个原则的原因 是,用户不需要额外考虑如何建立 Pod 之间的连接,也不需要考虑将容器端口映射到主机端口等问题。

而要想深入了解K8S的网络,就不得不去了解Linux操作系统中的网络以及计算机网络协议栈和一些网络技术

其中关于计算机网络协议栈道部分上次分享已经分享过了,所以本次的主题更多是Linux操作系统的网络以及一些网络技术

Linux操作系统中的网络

首先,我们来看下基本的linux网络,如下图所示

一个APP生成socket数据,然后经过网络协议栈包装IP报文,然后封装成MAC帧,在经过网络协议栈的过程中,会存在netfilters对数据进行一定的处理,同时也会存在路由的过程,

如果在同一个物理链路内,将直接通过ARP协议获取目标IP地址的MAC地址最终发送出去;

如果不在同一个物理链路则通过路由表确定下一跳的MAC地址,封装成MAC帧发送到目标地址。

在这个过程中,会根据路由表选择对应的端口,如果是lo端口,则会将帧原封不动的返回计算机网络协议栈,然后回到监听对应端口的SOCKET里。

如果是以太网端口则走以太网端口,如果是蓝牙或者无线网端口同理。

iptables与netfilters

iptables是一个用户空间的应用程序,通过该程序可以修改一些配置文件,这些文件定义了防火墙的一些行为,netfilters是操作系统内核的一部分,netfilters里有5个回调钩子会触发iptables里的规则;iptables只是Linux防火墙的管理工具而已,位于/sbin/iptables。真正实现防火墙功能的是

netfilter,它是Linux内核中实现包过滤的内部结构。

这里不具体讲述其实现的原理,仅仅列出netfilters的一些功能:

1)filter表——三个链:INPUT、FORWARD、OUTPUT

作用:过滤数据包 内核模块:iptables_filter.

2)Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT

作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat

3)Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD

作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它)

4)Raw表——两个链:OUTPUT、PREROUTING

作用:决定数据包是否被状态跟踪机制处理 内核模块:iptable_raw

虚拟网络设备 tap/tun

TUN 和 TAP 设备是 Linux 内核虚拟网络设备,纯软件实现。TUN(TUNnel)设备模拟网络层设备,处理三层报文如 IP

报文。TAP 设备模拟链路层设备,处理二层报文,比如以太网帧。TUN 用于路由,而 TAP 用于创建网桥。OS 向连接到 TUN/TAP

设备的用户空间程序发送报文;用户空间程序可像往物理口发送报文那样向 TUN/TAP 口发送报文,在这种情况下,TUN/TAP

设备发送(或注入)报文到 OS 协议栈,就像报文是从物理口收到一样。

虚拟网络设备 veth-pairs

虚拟以太网电缆。使用双向有名管道实现。常用于不同 namespace 之间的通信,即 namespace 数据穿越或容器数据穿越。

虚拟网络设备 bridge

bridge是linux自带的虚拟交换机(网桥),其可以连接多个以太网设备,拥有智能处理MAC帧的能力,流向交换机的MAC帧将智能的被传输到相应的二层链路

网络命名空间

在 Linux 中,网络名字空间可以被认为是隔离的拥有单独网络栈(网卡、路由转发表、iptables)的环境。网络名字空间经常用来隔离网络设备和服务,只有拥有同样网络名字空间的设备,才能看到彼此。

从逻辑上说,网络命名空间是网络栈的副本,有自己的网络设备、路由选择表、邻接表、Netfilter表、网络套接字、网络procfs条目、网络sysfs条目和其他网络资源。

从系统的角度来看,当通过clone()系统调用创建新进程时,传递标志CLONE_NEWNET将在新进程中创建一个全新的网络命名空间。

从用户的角度来看,我们只需使用工具ip(package is iproute2)来创建一个新的持久网络命名空间。

从系统实现来说,就是原本一个数据结构是static公共的,后来变成进程私有的,在PCB里存在一个命名空间的结构,命名空间里有着网络命名空间,网络命名空间拥有着所有跟网络相关的配置数据

默认空的网络命名空间可能只有一个未启动的lo回环网卡。

两个网络命名空间可以通过以太网揽直接连着两个网络命名空间的网卡,也可以通过以太网网桥连接。

通过以太网网桥或者以太网揽连接的两个网络命名空间只能说是在二层连通的,如果希望在三层连通,还需要给每个网络命名空间配置相应的路由表规则以及分配IP地址。

如何使用虚拟网络设备联通网络命名空间

SingleHost容器网络

none模式

本质上就是创建一个网络命名空间,里面没有路由表,也没有通过veths-pair连接任何链路,外部无法访问这个容器,容器也无法访问外部

host模式

本质上就是使用宿主机的默认网络命名空间

container模式

本质上就是将当前容器部署在另一个容器所在的网络命名空间,这样发给本地的报文最终通过回环网卡回到了本机,这是同一个网络命名空间可以互通的原因

bridge模式

桥接模式就是在这些网络命名空间通过veth-pairs连接到同一个虚拟交换机上(二层连通),同时在对应的命名空间配置对应的路由表规则,但是从图片中可以看到交换机另一端连的上网络协议栈。

也就是那些MAC帧都会被宿主机接收,但是宿主机接收并不一定会处理,比如并没有开启ip转发功能(工作于路由器模式还是主机模式),那么不是本地ip的报文都会被丢弃;或者说netfilters拒绝处理

这些奇怪的报文。

理论上,这些容器发送给其他容器的mac报文是会被虚拟交换机智能转发到对应的容器的,这是同一主机不同容器互相连通的原因

假如宿主机配备了相应的路由规则和防火墙规则,那么容器的报文说能够通过路由最终转发出去的,这也是容器访问互联网的原理

但是这种模式是没法运用在多主机的情况下,因为宿主机不知道其他宿主机里的虚拟网络的路由,当相关ip报到达宿主机时,这些ip报将会被宿主机交给默认路由(下一跳:路由器)

最终路由器会把相关的ip报丢失或者到达ttl最终丢失

MultiHost容器网络

路由方案

回顾docker的单机网络模型,我们发现多主机不能通行的原因就在于你只能给当前主机配置路由规则和防火墙规则,而其他主机并不知道这些ip在你的虚拟网络中,假如能够将这些路由信息同步到其他

宿主机,那么网络便会打通。比较直接的想法就是给每台宿主机配置路由规则。而路由规则要求下一跳必须在当前网络,所以假如宿主机是二层互联的,那么通过给这些宿主机同步这些路由规则便能够

实现一个扁平的连通的网络。

其中布置在每一台宿主机可以通过k8s的daemonSet实现,而这种数据的管理可以交给etcd来实现。

这类方案便是基于路由,基于这个方案的实现有基于静态路由的flannel的host-gateway,以及基于动态路由的calico(使用边际路由协议以及一堆深奥的名词的实现)。

下面来看看Flannel的host-gateway原理(每一台宿主机都相当于本机容器网络的路由器):

通过路由方案构建的网络,宿主机也能访问这些虚拟网络里的Pod

询问基德大佬得知国际化sit环境的k8s网络接口实现就是Flannel的Host-gateway,而我们的办公网络和集群网络之间的路由是搭建好的,所以我们应该可以直接通过podId访问pod里的服务

下面是sit环境的两个服务

跟踪路由发现符合猜想

其中10.1.9.56和10.1.1.24就是宿主机的ip,这些宿主机在一个LAN里,这些宿主机相当于虚拟网络中的路由器;

猜测我们办公网和qunhe集群在一个VLAN里(二层可达)

隧道方案

隧道方案比较典型的就是UDP和XVLAN,两者都是使用Overlay网络(覆盖网络,所谓的大二层技术);其实用隧道技术最多的是VPN应用

其中UDP是XVLAN的替代品(早期Linux没有支持XVLAN协议,通过tun/tap技术将流量引到用户空间然后解包生成包再发,因为发生在用户空间而且多次导致性能较差,所以一般不推荐,除非你的linux版本比较低没法用xvlan)

下面就简单介绍下XVLAN技术的大概原理,下图是XVLAN的报文格式,可以发现就是在高层协议的报文里塞了二层报文

其中XVLAN头里有一个关键的字段,VNID这是个24位的字段,每个虚拟的网络主机都有一个自身的VNID作为标识,理论上支持2的24次方个虚拟网络。

在docker的桥接网络里,是使用docker0网桥,在Flannel的xvlan方案里则是使用cni0作为网桥(和docker0没啥区别),主要的不同是cni网桥后面连接的是flannel.1这个网络设备,应该是一个虚拟网卡

这个网卡将原始报文包装成XVLAN报文(linux高版本支持xvlan报文)

这时需要的信息有 源nodeId,目标nodeId,源vnid,源macId,目标macId,源podId,目标podId

其中目标nodeId,目标macId这两个信息是不存在的;因此需要有个方式根据目标podId获取目标nodeId以及目标macId

因此需要记录如何根据目标podId获取目标macId以及目标nodeId即可

这些数据是可以托管在某个地方的,Flannel就是将这些信息记录在etcd上

在每个node上的flannel.1网络设备通过etcd来通过对方的podId获取nodeId和macId

这样最终报文就变成了一个源ip是源nodeIp,目标ip是目标nodeIp的IP报文了(两台宿主机三层可达)

原本经过虚拟网桥是直接连接网络协议栈,但在xvlan模式下,则改为连接一个flannel1,在flannel1中将对原始报文封装成overlay报文转发

udp模式类似,只是udp转发报文说通过tap连通到用户空间,用户空间对报文进行处理然后发送(因为多次内核态用户态切换且数据问题,性能较差,仅在不支持xvlan的低版本linux中使用)

当然xvlan是一个技术,上面只是简单介绍最简单的形式

参考:

开发内功修炼之网络篇: https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MjM5Njg5NDgwNA==&action=getalbum&album_id=1532487451997454337&scene=173&from_msgid=2247485270&from_itemidx=1&count=3&nolastread=1#wechat_redirect

K8S知识图谱: https://zhaohuabing.com/post/2020-02-22-k8s-mindmap/

VXLAN协议原理简介: https://cizixs.com/2017/09/25/vxlan-protocol-introction/