侧边栏壁纸
博主头像
蜉蝣的博客博主等级

行动起来,活在当下

  • 累计撰写 39 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Kubernetes 集群部署

蜉蝣
2024-07-06 / 0 评论 / 0 点赞 / 38 阅读 / 14512 字

Kubernetes 集群部署

虚拟机配置

网络配置

NAT模式

  • NATNetwork Address Translation)

  • 虚拟机网络的NAT模式

    • 当NAT用在虚拟机领域的时候,原理是类似的。只不过一台PC上的若干虚拟机相当于若干内网用户,而宿主机PC充当路由器的角色,虚拟机会在PC上虚拟化一个网络环境:也就是每个虚拟机通过一个无形的网线连接到了无形的路由器上,仅此而已。每个虚拟机实例会通过PC上的虚拟路由器获取DHCP分配的局域网IP,但是这只是本机虚拟出来的局域网,并不是物理局域网。那么,现在虚拟机想访问外网,只需要配置默认网关为PC上虚拟路由器,那么数据包经过虚拟路由器的时候,会将源IP修改为PC的物理网卡的物理局域网IP,发送给物理路由器,之后的事情和之前描述的一样。上面的虚拟路由器其实是宿主机上一张虚拟的网卡,而虚拟机则将默认网关指向了这张网卡,从而有机会进行IP篡改。NAT模式实际是虚拟了一个网卡出来,虚拟机直接链接这个虚拟网卡,每次访问和交互通过这个虚拟网卡交换数据。
    • 虚拟机发送数据给宿主机:虚拟机系统->虚拟机网卡->宿主机系统
    • 虚拟机访问外网:虚拟机系统->虚拟机网卡->宿主机系统->物理网卡->路由器->外网
  • 注意

    • 宿主机上的若干虚拟机之间,可以互相通讯,中介就是虚拟路由器。
    • 虚拟机可以访问外网,也可以访问物理局域网,但是无法访问其他宿主机上的虚拟机。
    • 外部(物理局域网其他主机)无法直接访问虚拟机,这和物理路由器外网的用户无法直接访问内网用户一个道理。(反向进入内网需要DNAT)
    • 虚拟机可以访问宿主机的物理IP,流程是先经过宿主NAT修改源IP和源PORT,通过物理网卡发出到局域网络中,又被物理网卡接收处理。
    • 宿主机无法访问虚拟机,这是因为宿主机的物理网卡和内网其他网卡的角色一样,对于虚拟路由器来说都是”外部”。

桥接模式

  • 网桥(Network Bridge)

    • 网桥是一种网络设备,负责网络桥接(network bridging)。桥接器将网络的多个网段数据链路层OSI模型第2层)连接起来(即桥接)。桥接器有别于路由器。路由器允许多网络之间的独立通信,但又保持区隔,而桥接器则是将两个独立的网络连接起来,就如同单一网络。
  • 虚拟机网络的桥接模式

    • 桥接模式下,虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问网内任何一台机器。 **在桥接模式下,需要手工为虚拟系统配置IP地址、子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主机器进行通信。**同时,由于这个虚拟系统是局域网中的一个独立的主机系统,那么就可以手工配置它的TCP/IP配置信息,以实现通过局域网的网关或路由器访问互联网。使用桥接模式的虚拟系统和宿主机器的关系,就像连接在同一个Hub上的两台电脑。想让它们相互通讯,你就需要为虚拟系统配置IP地址和子网掩码,否则就无法通信。
    • 假设br0是一个网桥,br0相当于虚拟交换机,物理网卡eth0和虚拟机网卡vnet0都通过虚拟的网线连接到br0上,这样eth0vnet0之间可以互相交换数据。我们把br0叫做桥,其实在宿主机上也是一张虚拟的网卡,作为虚拟交换机角色,而传统交换机本身就是按目标的mac地址将数据转发到正确的网线出口上,并不会做什么事情。配置虚拟机采用桥接模式并指定br0后,数据从虚拟机的网卡vnet0发出到br0br0会将数据转发给另一端的eth0,源mac是虚拟机的随机MAC地址,源IP是虚拟机的IP地址,桥并没有做中间修改,数据仅仅通过eth0网卡直接发到链路上,eth0只是充当一个发送的物理介质。当应答回来的时候,物理网卡eth0会在混杂模式捕获包并交给br0处理,如果目标mac地址等于eth0或者vnet0,则进一步处理。如果是eth0的包那么直接宿主机处理,如果是vnet0的包则转发给虚拟机处理,整个过程无需对包做出修改,因为br0仅仅是一个交换机,而eth0vnet0是连在上面的2个网卡而已。
    • 虚拟机发送数据给宿主机:虚拟机系统->虚拟机网卡->网桥->物理网卡->路由器->物理网卡->宿主机系统
    • 虚拟机访问外网:虚拟机系统->虚拟机网卡->网桥->物理网卡->路由器->外网
  • 注意

    • 无论是虚拟机还是物理机,大家都在一个网段里,都指向同一个默认网关(物理路由器)。
    • 虚拟机通过桥,可以向物理路由器申请dhcp,分配得到局域网IP。
    • 挂在桥上的虚拟机,可以直接被局域网其他用户访问,因为eth0混杂模式+桥可以转发到虚拟机。
    • 混杂模式的网卡只是一个物理介质,它监听所有的包,只留下自己关注的包(比如目的mac地址是eth0h或者vnet0的包),也可以发送任意的包,无论包的源mac地址到底是不是物理网卡自身的(vnet0的假mac地址)
  • 配置网桥
    需要将物理网卡添加到网桥上,并将物理网卡的ip转移到网桥上(学校服务器ip不能变),同时添加mac地址,具体原因见:Linux虚拟网络设备之bridge(桥)

    #!/bin/bash
    if [ "$#" -ne 2 ]; then
        exit 1
    fi
    br="$1"
    dev="$2"
    sudo ip link add $br type bridge
    sudo ip link set $dev master $br
    dev_ip=$(ip addr show $dev | awk '/inet / {print $2}')
    sudo ip addr del $dev_ip dev $dev
    sudo ip addr add $dev_ip dev $br
    dev_mac=$(ip link show $dev | awk '/ether/ {print $2}')
    sudo ip link set dev $br address $dev_mac
    sudo ip link set dev $br up
    sudo ip route add default via 10.10.1.1 dev $br
    
    sleep 5m
    sudo ip link set dev $br down
    sudo ip link delete $br type bridge
    sudo ip addr add $dev_ip dev $dev
    
  • Vagrant桥接模式创建虚拟机

    config.vm.network :public_network, dev: "vagrant-br0", mode: "bridge", type: "bridge", auto_config: true
    
  • Ubuntu22.04虚拟机配置静态IP

    进入/etc/netplan/,找到某个yaml文件,按下面的例子进行修改

    ---
    network:
      version: 2
      renderer: networkd
      ethernets:
        eth1:
          dhcp4: false
          addresses: 
            # - [宿主机网络号].[虚拟机主机号]/[子网掩码位数]
            - 10.10.1.233/24  
    
    sudo netplan apply
    

其他配置

apt换源

mv /etc/apt/sources.list /etc/apt/sources.list.bak
vim /etc/apt/sources.list

容器运行时

介绍

  • Docker
    • Docker 利用Linux核心中的资源分离机制,例如cgroups,以及Linux核心命名空间(namespaces),来建立独立的容器(containers)。这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担。Linux核心对命名空间的支持完全隔离了工作环境中应用程序的视野,包括行程树、网络、用户ID与挂载文件系统,而核心的cgroup提供资源隔离,包括CPU存储器、block I/O与网络。从0.9版本起,Dockers在使用抽象虚拟是经由libvirtLXC与systemd - nspawn提供界面的基础上,开始包括libcontainer函式库做为以自己的方式开始直接使用由Linux核心提供的虚拟化的设施。
  • CRI-O
  • Containerd

配置

Docker添加镜像源

sudo echo "{\"registry-mirrors\": [\"https://dockerhub.icu\"]}" > /etc/docker/daemon.json
sudo systemctl daemon-reload
sudo systemctl restart docker.service

Kubeadm、Kubectl、Kubelet

Kubeadm:安装工具

  • Kubeadm 是一个提供了 kubeadm initkubeadm join 的工具, 作为创建 Kubernetes 集群的 “快捷途径” 的最佳实践。
  • kubeadm 通过执行必要的操作来启动和运行最小可用集群。 按照设计,它只关注启动引导,而非配置机器。同样的, 安装各种 “锦上添花” 的扩展,例如 Kubernetes Dashboard、 监控方案、以及特定云平台的扩展,都不在讨论范围内。
  • 相反,我们希望在 kubeadm 之上构建更高级别以及更加合规的工具, 理想情况下,使用 kubeadm 作为所有部署工作的基准将会更加易于创建一致性集群。

Kubectl:命令行工具

  • Kubernetes 提供 kubectl 是使用 Kubernetes API 与 Kubernetes 集群的控制面进行通信的命令行工具。这个工具叫做 kubectl
  • 针对配置信息,kubectl$HOME/.kube 目录中查找一个名为 config 的配置文件。 你可以通过设置 KUBECONFIG 环境变量或设置 --kubeconfig

Kubelet:节点上的代理

  • kubelet 是在每个节点上运行的主要 “节点代理”。它可以使用以下方式之一向 API 服务器注册:

    • 主机名(hostname);
    • 覆盖主机名的参数;
    • 特定于某云驱动的逻辑。
  • kubelet 是基于 PodSpec 来工作的。每个 PodSpec 是一个描述 Pod 的 YAML 或 JSON 对象。 kubelet 接受通过各种机制(主要是通过 apiserver)提供的一组 PodSpec,并确保这些 PodSpec 中描述的容器处于运行状态且运行状况良好。 kubelet 不管理不是由 Kubernetes 创建的容器。除了来自 API 服务器的 PodSpec 之外,还可以通过以下两种方式将容器清单(manifest)提供给 kubelet。

    • 文件(File):利用命令行参数传递路径。kubelet 周期性地监视此路径下的文件是否有更新。 监视周期默认为 20s,且可通过参数进行配置。
    • HTTP 端点(HTTP endpoint):利用命令行参数指定 HTTP 端点。 此端点的监视周期默认为 20 秒,也可以使用参数进行配置。

初始化控制面、工作节点加入

准备

  • 主机重命名

    sudo hostnamectl set-hostname NAME
    
  • 修改hosts文件:hosts文件记录主机IP与主机名映射,其中主机IP会作为该节点在集群中的IP

    127.0.0.1 localhost
    127.0.1.1 ubuntu.localdomain
    [your IP] [your NAME]
    
  • 开放端口

    #!/bin/bash
    ports=(6443 2379 2380 10250 10259 10257 10248)
    for port in "${ports[@]}"; do
        sudo iptables -A INPUT -p tcp --dport $port -j ACCEPT
    done
    sudo iptables -A INPUT -p tcp --match multiport --dports 30000:32767 -j ACCEPT 
    
  • 关闭swap分区

    sudo swapoff -a
    

初始化控制面:kubeadm init

常用参数

  • --apiserver-advertise-address [string]

    API 服务器所公布的其正在监听的 IP 地址。如果未设置,则使用默认网络接口。

  • --image-repository [string]

    选择用于拉取控制平面镜像的容器仓库,默认值:"registry.k8s.io",可以修改为阿里镜像源:"registry.aliyuncs.com/google_containers"。

  • --cri-socket [string]

    要连接的 CRI 套接字的路径。如果为空,则 kubeadm 将尝试自动检测此值; 仅当安装了多个 CRI 或具有非标准 CRI 套接字时,才使用此选项。

  • --pod-network-cidr [string]

    指明 Pod 网络可以使用的 IP 地址段。如果设置了这个参数,控制平面将会为每一个节点自动分配 CIDR。

  • --token [string]

    这个令牌用于建立控制平面节点与工作节点间的双向通信。 格式为 [a-z0-9]{6}.[a-z0-9]{16} - 示例:abcdef.0123456789abcdef

  • --token-ttl [duration]

    令牌被自动删除之前的持续时间(例如 1s,2m,3h),默认值:24h0m0s。如果设置为 '0',则令牌将永不过期。

su root
kubeadm reset --cri-socket /var/run/dockershim.sock
kubeadm init --cri-socket /var/run/dockershim.sock \
             --apiserver-advertise-address 10.10.1.231 \
             --image-repository registry.aliyuncs.com/google_containers \
             --pod-network-cidr 10.244.0.0/16 \
             --token fedcba.0123456789abcdef \
             --token-ttl 0

配置集群网络:

使用Calico配置

Calico介绍
  • Calico是一个联网和网络安全解决方案,可以让K8s负载或者非K8s/传统负载之间进行无缝且安全地通信
  • Calico两大组件:Calico CNICalico network policy suite
    • Calico CNI 是一个控制面,可以对多个数据平面进行编程,它是一种L3/L4层网络解决方案,可以确保容器、K8s集群、虚拟机和主机本地负载的安全。
    • Calico network policy suiteCalico CNI 的接口,其中包含数据平面要执行的规则。
Calico安装
  • 方法一:官方
  • 方法二:在K8s控制面执行
kubectl apply -f https://docs.tigera.io/archive/v[version]/manifests/calico.yaml

工作节点加入:kubeadm join

kubeadm join 10.10.1.231:6443 \
             --token fedcba.0123456789abcdef \
             --discovery-token-ca-cert-hash [hash] \
             --cri-socket /var/run/dockershim.sock

查看集群状况

查看集群节点状况

sudo kubectl get nodes -n kube-system -o wide

查看集群pod状况

sudo kubectl get pods -n kube-system -o wide

可能遇到的问题

ImagePullBackOff

  • 意思:拉取镜像失败,正尝试重新拉取
  • 解决:去相应节点手动拉取镜像
    • 查找失败镜像名

      kubectl describe pod [NAME] -n kube-system | grep Image:
      
    • 拉取镜像(以docker为例)

      docker pull [IMAGE NAME]
      

控制面系统内核更新重启后kubelet无法启动

  • 解决:重置集群

Pod因为/run/xtables.lock is not a file问题无法启动

  • 解决:手动创建/run/xtables.lock,如果原来是文件夹就删除

先前运行的虚拟机无法连接,状态为paused,无法恢复

  • 可能的问题:宿主机磁盘空间不足
  • 原因:使用Vagrant通过libvirt创建的虚拟机默认存储在/var/lib/libvirt/images/,因此该区域挂载的磁盘空间不足时会导致虚拟机无法正常运行
  • 解决:迁移虚拟机
0

评论区