当前位置: 首页 > article >正文

k8s黑科技:Linux+Vagrant+VirtualBox开启Kubernetes奇幻之旅

在这里插入图片描述

文章目录

    • 1. 准备硬件
    • 2. 安装系统
    • 3. 安装 VNC
    • 4. 基础配置
      • 4.1 路由转发
      • 4.2 防火墙
      • 4.3 selinux
      • 4.4 安装包
      • 4.5 重启
    • 5. 配置代理
    • 6. 安装 virtuabox
    • 7. 安装 vagrant
    • 8. 配置 kubespray
      • 8.1 安装依赖工具
      • 8.2 定制 Vagrantfile
      • 8.3 配置代理与时间同步
      • 8.4 配置私有镜像仓库
    • 9. 安装虚拟机与 kubernetes
    • 10. 卸载

1. 准备硬件

  • 一台服务器:
    • disk:1T + 256G
    • cpu:36
    • mem:128G
  • 交换机:万兆
  • 移动硬盘:30G+
  • HDK显示器 :4k(为了方便当服务器放置机房可以远程电脑控制界面)

在这里插入图片描述

  • 开启VT-D
  • 开启VMX
  • 开启SR-IOV

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2. 安装系统

  • 引导工具: https://www.ventoy.net/cn/
  • u盘引导安装启动盘
  • 下载 Rocky Linux 9.4
  • 安装带界面的操作系统
  • 系统分区:/、/boot、/boot/efi
  • 创建用户:root/root、admin/admin
  • 时区:shanghai
  • 配置ip:192.168.21.95

在这里插入图片描述

配置ip:
在这里插入图片描述

安装操作系统后,下一步安装VNC,为了方便远程。

配置地址ip

3. 安装 VNC

参考:在Rocky Linux 8上设置RealVNC服务器和客户端|AlmaLinux 8

下载:VNC-Server-6.11.0-Linux-x64.rpm

yum -y install VNC-Server-6.11.0-Linux-x64.rpm

VNC 安装完成后,停止服务器,拔掉占用空间的显示器,换成HDK 4k转换器。就可以将服务器放到机房,我们通过自己的电脑就可以桌面远程该服务器了。

在这里插入图片描述
打开vnc ,注册

$ cat vnc.lic 
VND7Z-M22AB-MQD7R-GAAKF-2B4BA

在这里插入图片描述

测试通过客户端电脑远程该机器。

在这里插入图片描述
连接成功,代表vnc server 安装成功。

4. 基础配置

  • 终端远程工具:https://termius.com/
  • xshell

4.1 路由转发

$ modprobe br_netfilter
$ cat <<EOF>> /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
$ sysctl -p

4.2 防火墙

systemctl stop firewalld
systemctl disable firewalld
systemctl status firewalld

4.3 selinux

setenforce 0 && getenforce
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

4.4 安装包

$ dnf update
dnf -y install zsh git vim rsync net-tools epel-release wget python3.12 python3.12-pip

4.5 重启

reboot

5. 配置代理

注意:仅面向中国大陆客户需要配置代理,在配置代理时,请根据您的实际网络环境和业务需求进行调整,确保代理服务能够稳定、高效地工作。

  • 配置代理

6. 安装 virtuabox

VirtualBox 是一款由 Oracle 开发和维护的开源虚拟化软件,支持在 Windows、macOS、Linux 等主流操作系统上运行多个虚拟机(VM)。它允许用户在同一台物理计算机上同时运行多个不同的操作系统,如 Windows、Linux、BSD 甚至 macOS,广泛应用于开发、测试和学习环境。
VirtualBox 具备完整的虚拟化功能,包括快照管理、虚拟网络配置、硬件加速(VT-x/AMD-V)、共享文件夹和远程桌面访问等。

安装 Virtuabox 请参考这篇文档:

  • Rocky Linux 9.4 安装 VirtualBox 7.1

7. 安装 vagrant

Vagrant 是一个开源虚拟化管理工具,专为自动化和简化虚拟机环境的创建、配置和管理而设计。它通过 Vagrantfile 统一定义虚拟机的配置,支持 VirtualBox、VMware、KVM、Hyper-V 等多个虚拟化平台,并与 Ansible、Docker 及 Kubernetes 等工具无缝集成。

  • 安装手册:https://developer.hashicorp.com/vagrant/downloads
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install vagrant

8. 配置 kubespray

Kubespray 是一个基于 Ansible 的 Kubernetes 集群自动化部署工具,支持在多种基础设施(如裸金属服务器、公有云、私有云等)上快速搭建高可用集群。它兼容 kubeadm,提供灵活的配置选项,支持多种网络插件(如 Calico、Flannel、Cilium),并具备负载均衡、持久化存储集成等功能。
Kubespray 通过 Ansible Playbook 实现无代理(Agentless)部署,简化了 Kubernetes 安装和管理,使用户能够以基础设施即代码(IaC)的方式定制集群配置。适用于需要自定义集群架构的大规模生产环境。

下载 kubespray

$ wget https://github.com/kubernetes-sigs/kubespray/archive/refs/tags/v2.26.0.tar.gz
$ tar zxvf v2.26.0.tar.gz

8.1 安装依赖工具

$ cd kubespray-2.26.0
$ dnf -y install  python3.12
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3.12 get-pip.py
$ pip3.12 --version
pip 25.0.1 from /usr/local/lib/python3.12/site-packages/pip (python 3.12)
$ pip --version
pip 25.0.1 from /usr/local/lib/python3.12/site-packages/pip (python 3.12)
$ pip install -r requirements.txt

8.2 定制 Vagrantfile

使用 Vagrant 搭建一个 Kubernetes 开发测试环境,需要定义集群节点的 CPU、内存、磁盘、网络 等关键参数,并使用 VirtualBox 作为虚拟化后端。

$ cd kubespray-2.26.0
$ vim Vagrantfile
# -*- mode: ruby -*-
# # vi: set ft=ruby :# For help on using kubespray with vagrant, check out docs/vagrant.mdrequire 'fileutils'Vagrant.require_version ">= 2.0.0"CONFIG = File.join(File.dirname(__FILE__), ENV['KUBESPRAY_VAGRANT_CONFIG'] || 'vagrant/config.rb')SUPPORTED_OS = {"ubuntu2204"          => {box: "generic/ubuntu2204",         user: "vagrant"},"ubuntu2404"          => {box: "bento/ubuntu-24.04",         user: "vagrant"},"rockylinux8"         => {box: "bento/rockylinux-8",         user: "vagrant"},"rockylinux9"         => {box: "bento/rockylinux-9",         user: "vagrant"},"opensuse"            => {box: "opensuse/Leap-15.4.x86_64",  user: "vagrant"},"opensuse-tumbleweed" => {box: "opensuse/Tumbleweed.x86_64", user: "vagrant"},"oraclelinux8"        => {box: "generic/oracle8",            user: "vagrant"},"rhel8"               => {box: "generic/rhel8",              user: "vagrant"},
}if File.exist?(CONFIG)require CONFIG
end# Defaults for config options defined in CONFIG
$num_instances ||= 3
$instance_name_prefix ||= "k8s"
$vm_gui ||= false
$vm_memory ||= 16384
$vm_cpus ||= 8
$vm_network ||= "private_network"
$kube_master_vm_memory ||= 4096
$kube_master_vm_cpus ||= 4
$upm_control_plane_vm_memory ||= 32768
$upm_control_plane_vm_cpus ||= 8
$shared_folders ||= {}
$forwarded_ports ||= {}
$subnet ||= "172.18.8"
$subnet_split4 ||=100
$subnet_ipv6 ||= "fd3c:b398:0698:0756"
$netmask ||= "255.255.255.0"
$gateway ||= "172.18.8.1"
$dns_server ||= "8.8.8.8"
$bridge_nic ||= "en0" # 当是public_network时,这里填写网卡名称,如"en0"
$time_zone ||= "Asia/Shanghai"
$os ||= "rockylinux9"
$network_plugin ||= "calico"
# Setting multi_networking to true will install Multus: https://github.com/k8snetworkplumbingwg/multus-cni
$multi_networking ||= "False"
$download_run_once ||= "True"
$download_force_cache ||= "False"
$kube_version ||= "v1.29.7"
# The first three nodes are etcd servers
$etcd_instances ||= [$num_instances, 3].min
# The first two nodes are kube masters
$kube_master_instances ||= [$num_instances, 2].min
# All nodes are kube nodes
$kube_node_instances ||= $num_instances
# UPM controller nodes
$upm_ctl_instances ||= 1
# The following only works when using the libvirt provider
$kube_node_instances_with_disks ||= false
$kube_node_instances_with_disks_size ||= "20G"
$kube_node_instances_with_disks_number ||= 2
$kube_node_instances_with_disk_dir ||= ENV['HOME']
$kube_node_instances_with_disk_suffix ||= 'xxxxxxxx'
$local_path_provisioner_enabled ||= "False"
$local_path_provisioner_claim_root ||= "/opt/local-path-provisioner/"
$libvirt_nested ||= false
# boolean or string (e.g. "-vvv")
$ansible_verbosity ||= false
$ansible_tags ||= ENV['VAGRANT_ANSIBLE_TAGS'] || ""
$provider ||= ENV['VAGRANT_DEFAULT_PROVIDER'] || ""$vagrant_pwd ||= "root"
$vagrant_dir ||= File.join(File.dirname(__FILE__), ".vagrant")$playbook ||= "cluster.yml"
$extra_vars ||= {}node_instances_begin = [$etcd_instances, $kube_master_instances].max
host_vars = {}# throw error if os is not supported
if ! SUPPORTED_OS.key?($os)puts "Unsupported OS: #{$os}"puts "Supported OS are: #{SUPPORTED_OS.keys.join(', ')}"exit 1
end$box = SUPPORTED_OS[$os][:box]
# if $inventory is not set, try to use example
$inventory = "inventory/sample" if ! $inventory
$inventory = File.absolute_path($inventory, File.dirname(__FILE__))# if $inventory has a hosts.ini file use it, otherwise copy over
# vars etc to where vagrant expects dynamic inventory to be
if ! File.exist?(File.join(File.dirname($inventory), "hosts.ini"))$vagrant_ansible = File.join(File.absolute_path($vagrant_dir), "provisioners", "ansible")FileUtils.mkdir_p($vagrant_ansible) if ! File.exist?($vagrant_ansible)$vagrant_inventory = File.join($vagrant_ansible,"inventory")FileUtils.rm_f($vagrant_inventory)FileUtils.ln_s($inventory, $vagrant_inventory)
endif Vagrant.has_plugin?("vagrant-proxyconf")$no_proxy = ENV['NO_PROXY'] || ENV['no_proxy'] || "localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,::1,.bsgchina.com"(1..$num_instances).each do |i|$no_proxy += ",#{$subnet}.#{i+$subnet_split4}"end
endVagrant.configure("2") do |config|config.vm.box = $boxif SUPPORTED_OS[$os].has_key? :box_urlconfig.vm.box_url = SUPPORTED_OS[$os][:box_url]endconfig.ssh.username = SUPPORTED_OS[$os][:user]# plugin conflictif Vagrant.has_plugin?("vagrant-vbguest") thenconfig.vbguest.auto_update = falseend# always use Vagrants insecure keyconfig.ssh.insert_key = false(1..$num_instances).each do |i|config.vm.define vm_name = "%s-%01d" % [$instance_name_prefix, i] do |node|node.vm.hostname = vm_nameif Vagrant.has_plugin?("vagrant-proxyconf")node.proxy.http     = ENV['HTTP_PROXY'] || ENV['http_proxy'] || ""node.proxy.https    = ENV['HTTPS_PROXY'] || ENV['https_proxy'] ||  ""node.proxy.no_proxy = $no_proxyendif i <= node_instances_beginmemory_size = "#{$kube_master_vm_memory}"cpu_num = "#{$kube_master_vm_cpus}"elsif i > node_instances_begin && i <= node_instances_begin + $upm_ctl_instancesmemory_size = "#{$upm_control_plane_vm_memory}"cpu_num = "#{$upm_control_plane_vm_cpus}"elsememory_size = "#{$vm_memory}"cpu_num = "#{$vm_cpus}"end["vmware_fusion", "vmware_workstation"].each do |vmware|node.vm.provider vmware do |v|v.vmx['memsize'] = memory_sizev.vmx['numvcpus'] = cpu_numendendnode.vm.provider "parallels" do |prl|prl.memory = memory_sizeprl.cpus = cpu_numprl.linked_clone = trueprl.update_guest_tools = falseprl.check_guest_tools = falseendnode.vm.provider :virtualbox do |vb|vb.memory = memory_sizevb.cpus = cpu_numvb.gui = $vm_guivb.linked_clone = truevb.customize ["modifyvm", :id, "--vram", "8"] # ubuntu defaults to 256 MB which is a waste of precious RAMvb.customize ["modifyvm", :id, "--audio", "none"]endnode.vm.provider :libvirt do |lv|lv.nested = $libvirt_nestedlv.cpu_mode = "host-model"lv.memory = memory_sizelv.cpus = cpu_numlv.default_prefix = 'kubespray'# Fix kernel panic on fedora 28if $os == "fedora"lv.cpu_mode = "host-passthrough"endendif $kube_node_instances_with_disks && i > node_instances_begin# install lvm2 packagenode.vm.provision "shell", inline: "sudo dnf install -y lvm2"# Libvirtdriverletters = ('a'..'z').to_adisk_dir = "#{$kube_node_instances_with_disk_dir}"node.vm.provider :libvirt do |lv|# always make /dev/sd{a/b/c} so that CI can ensure that# virtualbox and libvirt will have the same devices to use for OSDs(1..$kube_node_instances_with_disks_number).each do |d|disk_path = "#{disk_dir}/disk-#{i}-#{driverletters[d]}-#{$kube_node_instances_with_disk_suffix}.disk"lv.storage :file, :device => "hd#{driverletters[d]}", :path => disk_path, :size => $kube_node_instances_with_disks_size, :bus => "scsi"endendnode.vm.provider :virtualbox do |vb|# always make /dev/sd{a/b/c} so that CI can ensure that# virtualbox and libvirt will have the same devices to use for OSDs(1..$kube_node_instances_with_disks_number).each do |d|disk_path = "#{disk_dir}/disk-#{i}-#{driverletters[d]}-#{$kube_node_instances_with_disk_suffix}.disk"if !File.exist?(disk_path)vb.customize ['createhd', '--filename', disk_path, '--size', $kube_node_instances_with_disks_size] # 10GB diskendvb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', d, '--device', 0, '--type', 'hdd', '--medium', disk_path, '--nonrotational', 'on', '--mtype', 'normal']endendnode.vm.provider :parallels do |prl|(1..$kube_node_instances_with_disks_number).each do |d|prl.customize ['set', :id, '--device-add', 'hdd', '--iface', 'nvme', '--size', $kube_node_instances_with_disks_size, '--type', 'expand']endendend$forwarded_ports.each do |guest, host|node.vm.network "forwarded_port", guest: guest, host: host, auto_correct: trueendif ["rhel8"].include? $os# Vagrant synced_folder rsync options cannot be used for RHEL boxes as Rsync package cannot# be installed until the host is registered with a valid Red Hat support subscriptionnode.vm.synced_folder ".", "/vagrant", disabled: false$shared_folders.each do |src, dst|node.vm.synced_folder src, dstendelsenode.vm.synced_folder ".", "/vagrant", disabled: false, type: "rsync", rsync__args: ['--verbose', '--archive', '--delete', '-z'] , rsync__exclude: ['.git','venv']$shared_folders.each do |src, dst|node.vm.synced_folder src, dst, type: "rsync", rsync__args: ['--verbose', '--archive', '--delete', '-z']endendip = "#{$subnet}.#{i+$subnet_split4}"if $vm_network == "public_network"node.vm.network :public_network,:ip => ip,:netmask => $netmask,:bridge => $bridge_nic,:libvirt__guest_ipv6 => 'yes',:libvirt__ipv6_address => "#{$subnet_ipv6}::#{i+100}",:libvirt__ipv6_prefix => "64",:libvirt__forward_mode => "none",:libvirt__dhcp_enabled => falseif ["rockylinux8","rockylinux9"].include? $os# Set default gatewaynode.vm.provision "shell", inline: <<-SHELLsudo nmcli connection modify "eth0" ipv4.gateway ""sudo nmcli connection modify "eth0" ipv4.never-default yessudo nmcli connection modify "System eth1" +ipv4.routes "0.0.0.0/0 #{$gateway}"sudo nmcli connection modify "System eth1" ipv4.gateway "#{$gateway}"sudo nmcli connection up "eth0"sudo nmcli connection up "System eth1"sudo echo -e "[main]\ndns=default\n\n[global-dns-domain-*]\nservers=#{$dns_server}" | sudo tee /etc/NetworkManager/conf.d/dns.confsudo systemctl restart NetworkManagerSHELLendelse $vm_network == "private_network"node.vm.network :private_network,:ip => ip,:netmask => $netmask,:libvirt__guest_ipv6 => 'yes',:libvirt__ipv6_address => "#{$subnet_ipv6}::#{i+100}",:libvirt__ipv6_prefix => "64",:libvirt__forward_mode => "none",:libvirt__dhcp_enabled => falseif ["rockylinux8","rockylinux9"].include? $os# Set default gatewaynode.vm.provision "shell", inline: <<-SHELLsudo nmcli connection modify "System eth1" ipv4.gateway "#{$gateway}"sudo nmcli connection up "System eth1"sudo echo -e "[main]\ndns=default\n\n[global-dns-domain-*]\nservers=#{$dns_server}" | sudo tee /etc/NetworkManager/conf.d/dns.confsudo systemctl restart NetworkManagerSHELLendend# if provider = virtualbox , set ethtool -K net device tx-checksum-ip-generic offif $provider == "virtualbox"if ["rockylinux8","rockylinux9"].include? $osnode.vm.provision "shell", inline: <<-SHELLsudo ethtool -K eth0 tx-checksum-ip-generic offsudo ethtool -K eth1 tx-checksum-ip-generic offsudo nmcli conn modify eth0 ethtool.feature-tx-checksum-ip-generic offsudo nmcli conn modify 'System eth1' ethtool.feature-tx-checksum-ip-generic offSHELLendend# Disable swap for each vmnode.vm.provision "shell", inline: "swapoff -a"# Set password for vagrant usernode.vm.provision "shell", inline: "echo 'vagrant:#{$vagrant_pwd}' | sudo chpasswd"# link kubectl to /usr/bin/kubectlnode.vm.provision "shell", inline: <<-SHELLsudo ln -s /usr/local/bin/kubectl /usr/bin/kubectlsudo ln -s /usr/local/bin/helm /usr/bin/helmsudo ln -s /usr/local/bin/nerdctl /usr/bin/nerdctlsudo ln -s /usr/local/bin/crictl /usr/bin/crictlSHELL# ubuntu2004 and ubuntu2204 have IPv6 explicitly disabled. This undoes that.if ["ubuntu2204"].include? $osnode.vm.provision "shell", inline: "rm -f /etc/modprobe.d/local.conf"node.vm.provision "shell", inline: "sed -i '/net.ipv6.conf.all.disable_ipv6/d' /etc/sysctl.d/99-sysctl.conf /etc/sysctl.conf"end# Rockylinux boxes needs UEFIif ["rockylinux8", "rockylinux9"].include? $osconfig.vm.provider "libvirt" do |domain|domain.loader = "/usr/share/OVMF/x64/OVMF_CODE.fd"endend# Disable firewalld on oraclelinux/redhat vmsif ["oraclelinux","oraclelinux8","rhel7","rhel8","rockylinux8","rockylinux9"].include? $osnode.vm.provision "shell", inline: "systemctl stop firewalld; systemctl disable firewalld"end# Set timezonenode.vm.provision "shell", inline: "timedatectl set-timezone #{$time_zone}"host_vars[vm_name] = {"ip": ip,"flannel_interface": "eth1","kube_network_plugin": $network_plugin,"kube_network_plugin_multus": $multi_networking,"download_run_once": $download_run_once,"download_localhost": "False","download_cache_dir": ENV['HOME'] + "/kubespray_cache",# Make kubespray cache even when download_run_once is false"download_force_cache": $download_force_cache,# Keeping the cache on the nodes can improve provisioning speed while debugging kubespray"download_keep_remote_cache": "False","docker_rpm_keepcache": "1",# These two settings will put kubectl and admin.config in $inventory/artifacts"kubeconfig_localhost": "True","kubectl_localhost": "True","local_path_provisioner_enabled": "#{$local_path_provisioner_enabled}","local_path_provisioner_claim_root": "#{$local_path_provisioner_claim_root}","helm_enabled": "True","ansible_ssh_user": SUPPORTED_OS[$os][:user],"ansible_ssh_private_key_file": File.join(Dir.home, ".vagrant.d", "insecure_private_key"),"unsafe_show_logs": "True","kube_version": "#{$kube_version}"}# Only execute the Ansible provisioner once, when all the machines are up and ready.# And limit the action to gathering facts, the full playbook is going to be ran by testcases_run.shif i == $num_instancesnode.vm.provision "ansible" do |ansible|ansible.playbook = $playbookansible.compatibility_mode = "2.0"ansible.verbose = $ansible_verbosity$ansible_inventory_path = File.join( $inventory, "hosts.ini")if File.exist?($ansible_inventory_path)ansible.inventory_path = $ansible_inventory_pathendansible.become = trueansible.limit = "all,localhost"ansible.host_key_checking = falseansible.raw_arguments = ["--forks=#{$num_instances}", "--flush-cache", "-e ansible_become_pass=vagrant"]ansible.host_vars = host_varsansible.extra_vars = $extra_varsif $ansible_tags != ""ansible.tags = [$ansible_tags]endansible.groups = {"etcd" => ["#{$instance_name_prefix}-[1:#{$etcd_instances}]"],"kube_control_plane" => ["#{$instance_name_prefix}-[1:#{$kube_master_instances}]"],"kube_node" => ["#{$instance_name_prefix}-[1:#{$kube_node_instances}]"],"k8s_cluster:children" => ["kube_control_plane", "kube_node"],}endendendend
end
$ mkdir vagrant
$ vim vagrant/config.rb
$instance_name_prefix = "94node-k8s"
$vm_cpus = 8
$vm_memory = 16384
$kube_node_instances_with_disks = true
$kube_node_instances_with_disks_size = 102400
$kube_node_instances_with_disks_number = 1
$kube_node_instances_with_disk_dir = "/home/admin/VirtualBox VMs/disks"
$override_disk_size = true
$disk_size = "80GB"
$num_instances = 6
$etcd_instances = 1
$kube_master_instances = 1
$os = "rockylinux9"
$subnet = "192.168.24"
$netmask = "255.255.240.0"
$bridge_nic = "enp2s0f0"
$network_plugin = "calico"
$multi_networking = "False"
$inventory = "inventory/94node"
$shared_folders = { 'temp/docker_rpms' => "/var/cache/yum/x86_64/7/docker-ce/packages" }

以下是各参数的详细说明:

  • instance_name_prefix:设置集群实例的前缀,所有节点的名称将以 “94node-k8s” 开头。
  • num_instances:定义集群总共 6 台 虚拟机(Kubernetes 节点)。
  • etcd_instances:单独部署 1 台 etcd 实例,用于存储 Kubernetes 集群数据。
  • kube_master_instances:配置 1 台 Master 节点,其余节点默认为 Worker 节点。
  • vm_cpus:每个虚拟机分配 8 核 CPU。
  • vm_memory:每个虚拟机分配 16GB 内存。
  • kube_node_instances_with_disks:启用 附加数据盘,用于持久化存储(如 PV、日志等)。
  • kube_node_instances_with_disks_size:附加磁盘大小 100GB(102400MB)。
  • kube_node_instances_with_disks_number:每个节点附加 1 块磁盘。
  • kube_node_instances_with_disk_dir:指定虚拟磁盘存储路径 /home/admin/VirtualBox VMs/disks。
  • override_disk_size:是否覆盖默认磁盘大小(启用)。
  • disk_size:根磁盘大小 80GB。
  • os:指定操作系统为 Rocky Linux 9。
  • subnet:Kubernetes 集群的 子网前缀,IP 规划范围为 192.168.24.0/20。
  • netmask:子网掩码 255.255.240.0,支持 4096 个 IP 地址。
  • bridge_nic:设置 桥接网络接口,指定宿主机上的物理网卡 enp2s0f0 作为桥接设备,使虚拟机能直接访问外部网络。
  • network_plugin:选择 Calico 作为 Kubernetes CNI 网络插件,提供高效的 网络策略管理 和 BGP 路由支持。
  • multi_networking:设置是否启用多网络(此处 禁用)。
  • inventory:定义 Ansible 需要使用的 Kubernetes 目标清单文件。
  • shared_folders:挂载本地目录 temp/docker_rpms 至虚拟机 /var/cache/yum/x86_64/7/docker-ce/packages,方便 离线安装 Docker 相关 RPM 包。

创建inventory清单目录:

$ cp -r inventory/sample inventory/94node

8.3 配置代理与时间同步

注意:仅面向中国大陆客户需要配置代理,在配置代理时,请根据您的实际网络环境和业务需求进行调整,确保代理服务能够稳定、高效地工作。

$ vim /home/admin/mg-95node/kubespray-2.26.0/inventory/95node/group_vars/all/all.yml
http_proxy: "http://192.168.21.101:7890"
https_proxy: "http://192.168.21.101:7890"## Refer to roles/kubespray-defaults/defaults/main/main.yml before modifying no_proxy
# no_proxy: ""
no_proxy: "localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,::1,.bsgchina.com"## Some problems may occur when downloading files over https proxy due to ansible bug
## https://github.com/ansible/ansible/issues/32750. Set this variable to False to disable
## SSL validation of get_url module. Note that kubespray will still be performing checksum validation.
# download_validate_certs: False## If you need exclude all cluster nodes from proxy and other resources, add other resources here.
# additional_no_proxy: ""
additional_no_proxy: "localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,::1,.bsgchina.com"ntp_enabled: true
ntp_manage_config: true
ntp_servers:- "cn.pool.ntp.org iburst"- "ntp1.aliyun.com iburst"- "ntp2.aliyun.com iburst"- "ntp3.aliyun.com iburst"- "ntp4.aliyun.com iburst"

8.4 配置私有镜像仓库

在开发测试环境中部署 Kubernetes 时,配置私有镜像仓库至关重要。私有仓库不仅能够提升镜像拉取速度,减少对外部网络的依赖,还可以提高镜像管理的安全性和可控性。

$ vim /home/admin/mg-95node/kubespray-2.26.0/inventory/95node/group_vars/all/containerd.yml
# Registries defined within containerd.
containerd_registries_mirrors:- prefix: quay.iomirrors:- host: http://harbor.bsgchina.comcapabilities: ["pull", "resolve"]skip_verify: true# containerd_max_container_log_line_size: -1containerd_registry_auth:- registry: harbor.bsgchina.comusername: adminpassword: Harbor12345

在 Kubespray 中,可以通过 containerd.yml 配置文件定义 containerd 镜像仓库镜像加速(Registry Mirrors) 及 私有仓库认证信息(Registry Authentication)。例如,配置 containerd_registries_mirrors 使 quay.io 的镜像请求重定向至 Harbor,从而优化拉取体验。同时,通过 containerd_registry_auth 配置 Harbor 认证信息,确保 Kubernetes 节点能够访问私有镜像。

9. 安装虚拟机与 kubernetes

从创建虚拟机到安装kubernetes完成。

$ vagrant up

输出:

vagrant up
Bringing machine '94node-k8s-1' up with 'virtualbox' provider...
Bringing machine '94node-k8s-2' up with 'virtualbox' provider...
Bringing machine '94node-k8s-3' up with 'virtualbox' provider...
Bringing machine '94node-k8s-4' up with 'virtualbox' provider...
Bringing machine '94node-k8s-5' up with 'virtualbox' provider...
Bringing machine '94node-k8s-6' up with 'virtualbox' provider...
==> 94node-k8s-1: Checking if box 'bento/rockylinux-9.4' version '202407.23.0' is up to date...
==> 94node-k8s-1: Clearing any previously set forwarded ports...
==> 94node-k8s-1: Clearing any previously set network interfaces...
==> 94node-k8s-1: Preparing network interfaces based on configuration...94node-k8s-1: Adapter 1: nat94node-k8s-1: Adapter 2: bridged
==> 94node-k8s-1: Forwarding ports...94node-k8s-1: 22 (guest) => 2222 (host) (adapter 1)
==> 94node-k8s-1: Running 'pre-boot' VM customizations...
==> 94node-k8s-1: Booting VM...
==> 94node-k8s-1: Waiting for machine to boot. This may take a few minutes...94node-k8s-1: SSH address: 127.0.0.1:222294node-k8s-1: SSH username: vagrant94node-k8s-1: SSH auth method: private key
==> 94node-k8s-1: Machine booted and ready!
==> 94node-k8s-1: Checking for guest additions in VM...
==> 94node-k8s-1: Setting hostname...
==> 94node-k8s-1: Configuring and enabling network interfaces...
==> 94node-k8s-1: Rsyncing folder: /home/admin/kubespray/ => /vagrant
==> 94node-k8s-1:   - Exclude: [".vagrant/", ".git", "venv"]
==> 94node-k8s-1: Rsyncing folder: /home/admin/kubespray/temp/docker_rpms/ => /var/cache/yum/x86_64/7/docker-ce/packages
==> 94node-k8s-1: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> 94node-k8s-1: flag to force provisioning. Provisioners marked to run always will still run.
==> 94node-k8s-2: Checking if box 'bento/rockylinux-9.4' version '202407.23.0' is up to date...
==> 94node-k8s-2: Clearing any previously set forwarded ports...

如果出现报错,修复完成后继续执行剩余任务,执行以下命令:

$ vagrant provision

在这里插入图片描述

提示:第一次安装过程中,vagrant up会执行创建虚拟机并进行基础配置,然后通过kubespray 安装部署 kubernetes,
后续执行vagrant up只会执行启动虚拟机。

安装完成后,远程至创建的虚拟机 master 节点,拷贝/etc/kubernetes/admin.conf至跳板机 /root/.kube/config

$ vagrant ssh 94node-k8s-1 
$ sudo -i
$ sudo cat /etc/kubernetes/admin.conf

跳板机安装 kubectl

$ curl -LO https://dl.k8s.io/release/$(curl -LS https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl
$ mv kubectl /usr/local/bin/
$ chmod 755 /usr/local/bin/kubectl

virtualbox 虚拟机创建中,并自动进行基础配置。

$ kubectl get node
NAME    STATUS   ROLES           AGE   VERSION
k8s-1   Ready    control-plane   15m   v1.29.7
k8s-2   Ready    <none>          14m   v1.29.7
k8s-3   Ready    <none>          14m   v1.29.7
k8s-4   Ready    <none>          14m   v1.29.7
k8s-5   Ready    <none>          14m   v1.29.7
k8s-6   Ready    <none>          14m   v1.29.7

10. 卸载

删除虚拟机操作

$ vagrant destroyk8s-6: Are you sure you want to destroy the 'k8s-6' VM? [y/N] y
==> k8s-6: Forcing shutdown of VM...
==> k8s-6: Destroying VM and associated drives...k8s-5: Are you sure you want to destroy the 'k8s-5' VM? [y/N] y
==> k8s-5: Forcing shutdown of VM...
==> k8s-5: Destroying VM and associated drives...k8s-4: Are you sure you want to destroy the 'k8s-4' VM? [y/N] y
==> k8s-4: Forcing shutdown of VM...
==> k8s-4: Destroying VM and associated drives...k8s-3: Are you sure you want to destroy the 'k8s-3' VM? [y/N] y
==> k8s-3: Forcing shutdown of VM...
==> k8s-3: Destroying VM and associated drives...k8s-2: Are you sure you want to destroy the 'k8s-2' VM? [y/N] y
==> k8s-2: Forcing shutdown of VM...
==> k8s-2: Destroying VM and associated drives...k8s-1: Are you sure you want to destroy the 'k8s-1' VM? [y/N] y
==> k8s-1: Forcing shutdown of VM...
==> k8s-1: Destroying VM and associated drives...

参考:

  • https://github.com/kubernetes-sigs/kubespray.git

相关文章:

k8s黑科技:Linux+Vagrant+VirtualBox开启Kubernetes奇幻之旅

文章目录 1. 准备硬件2. 安装系统3. 安装 VNC4. 基础配置4.1 路由转发4.2 防火墙4.3 selinux4.4 安装包4.5 重启 5. 配置代理6. 安装 virtuabox7. 安装 vagrant8. 配置 kubespray8.1 安装依赖工具8.2 定制 Vagrantfile8.3 配置代理与时间同步8.4 配置私有镜像仓库 9. 安装虚拟机…...

34% 关税冲击下 LabVIEW 开发的变局

2025 年 4 月 4 日&#xff0c;中国国务院关税税则委员会宣布&#xff0c;自 4 月 10 日起对原产于美国的所有进口商品加征 34% 关税。这一举措&#xff0c;给 LabVIEW 开发领域带来显著影响&#xff0c;相关使用者和用户亟需采取应对策略。 ​ 从成本层面看&#xff0c;LabVI…...

42、JavaEE高级主题:WebSocket详解

WebSocket 一、WebSocket协议与实现 WebSocket是一种基于TCP协议的全双工通信协议&#xff0c;能够在客户端和服务器之间建立实时、双向的通信通道。通过WebSocket&#xff0c;客户端和服务器可以在任何时候发送数据&#xff0c;并立即接收到对方的响应。 1.1 WebSocket协议…...

Http代理服务器选型与搭建

代理服务器选型-Squid 缓存加速 缓存频繁访问的网页、图片等静态资源&#xff0c;减少对原始服务器的重复请求&#xff0c;提升响应速度支持HTTP、HTTPS、FTP等协议&#xff0c;通过本地缓存直接响应客户端请求 访问控制 基于ACL&#xff08;访问控制列表&#xff09;实现精细…...

蓝桥杯第十一届省赛C++B组真题解析

蓝桥杯第十一届省赛CB组真题解析 八、回文日期https://www.lanqiao.cn/problems/348/learning 方法一&#xff1a;暴力枚举所有的日期&#xff0c;记录有多少个回文日期。 #include <bits/stdc.h> using namespace std; int month[13]{0,31,28,31,30,31,30,31,31,30,31…...

Linux主要开发工具之gcc、gdb与make

此系列还有两篇&#xff0c;大家想完整掌握可以阅读另外两篇 Linux文本编辑与shell程序设计-CSDN博客 Linux基础知识详解与命令大全&#xff08;超详细&#xff09;-CSDN博客 1.gcc编译系统 1.1 文件名后缀 文件名后缀 文 件 类 型 文件名后缀 文 件 类 型 .c C源…...

排序算法(快速排序,选择排序......)【泪光2929】

hello&#xff0c;大家好&#xff01;今天给大家分享一下各种排序&#xff1a; 1&#xff0c;选择排序 首先从原始数组中 选择最小的1个数据&#xff0c;将其和位于第1个位置的数据交换。接着从剩下的n-1个数据中选择次小的1个元素&#xff0c;将其和第2个位置的数据交换然后…...

Conda使用方法详解

Conda是一个开源的包管理和环境管理系统&#xff0c;主要用于Python/R等科学计算领域&#xff0c;可以轻松管理不同项目的依赖关系。以下是Conda的详细使用方法&#xff1a; 一、安装与配置 1.安装Miniconda/Anaconda Miniconda是精简版&#xff0c;只包含conda和Python Ana…...

数据库的MVCC机制详解

MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09;是数据库系统中常用的并发控制机制&#xff0c;它允许数据库在同一时间点保存数据的多个版本&#xff0c;从而实现非阻塞的读操作&#xff0c;提高并发性能。 MVCC的核心思想是&…...

C++初阶-C++入门基础

目录 ​编辑 1.C的简介 1.1C的产生和发展 1.2C的参考文档 1.3C优势和难度 1.4C学习的建议 2.C的第一个程序 2.1打印Hello world 2.2头文件 2.3namespace命名空间 2.4&#xff1a;&#xff1a;作用域限定符 2.5namespace的延伸 2.6C的输入输出 3.总结 1.C的简介 …...

关于量化交易在拉盘砸盘方面应用的部分思考

关于“砸盘”的深层解析与操盘逻辑 ​​一、砸盘的本质与市场含义​​ ​​砸盘​​指通过集中抛售大量筹码导致价格快速下跌的行为&#xff0c;其核心目标是​​制造恐慌、清洗浮筹或实现利益再分配​​。不同场景下的砸盘含义不同&#xff1a; ​​主动砸盘&#xff08;操控…...

idea手动创建resources文件夹

有时maven没有构建成功可能造成&#xff0c;resources文件夹不创建的现象 此时我们可以手动创建 手动创建...

第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组题目试做(中)【本期题目:回文数组,挖矿】

OK&#xff0c;继续写我们的第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组题目&#xff0c;后面的题目比较麻烦了&#xff0c;所以我们再分两期讲。 这一期的题有 &#xff1a; 回文数组&#xff0c;挖矿 文章目录 回文数组基本思路第一步&#xff0c;获取半个数组每个数需要…...

Qt动画 QAbstractAnimation

文章目录 简介QVariantAnimation 数值动画QPropertyAnimation 属性动画 QAnimationGroup 一组动画QParallelAnimationGroup 并行动画组QSequentialAnimationGroup 串行动画组 简介 QAbstractAnimation 是所有 Qt 动画的基类。 该类定义了所有动画应该都会有的功能函数。 要想实…...

SpringMvc的请求-获得请求参数

客户端请求参数的格式是: namevalue&namevalue..… 服务器端要获得请求的参数&#xff0c;有时还需要进行数据的封装&#xff0c;SpringMVC可以接收如下类型的参数: 基本类型参数 POJO类型参数 数组类型参数 集合类型参数 获得基本类型参数 Controller中的业务方法…...

flutter开发音乐APP(前提准备)

1、项目的一些环境&#xff1a; 2、接口文档&#xff1a; 酷狗音乐 NodeJS 版 API 3、接口数据结构化 Instantly parse JSON in any language | quicktype UI样式借鉴参考&#xff1a; Coffee-Expert/Apple-Music-New-UI: Apple Music Clone on Flutter, with redesigned UI…...

使用docker搭建redis镜像时云服务器无法访问到国外的docker官网时如何解决

下载redis镜像 docker redis:版本号 此时截图中无法访问到国外的docker官网 解决方案&#xff1a; 通过更换镜像源来正常下载redis镜像 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<EOF {"registry-mirrors": ["https://docker.1…...

双引擎驱动:解密音视频体验的QoS技术底座与QoE感官革命

QoS 定义&#xff1a;QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;衡量音视频传输技术层面的性能表现&#xff0c;聚焦网络传输和系统处理能力&#xff0c;通过客观指标量化服务质量。核心指标 码率/带宽&#xff1a;数据传输速率上限&#xff0c;直接…...

Qt之QNetworkInterface

简介 用于表示网络接口&#xff08;即网卡&#xff09;信息 常用接口 static QList<QNetworkInterface> allInterfaces(); static QList<QHostAddress> allAddresses(); QList<QNetworkAddressEntry> addressEntries() const;接口类型 用枚举InterfaceTy…...

pom导包成功,但是就是无法使用相关类,同时报错:Library:Maven ‘xxx‘ has broken path

开发环境&#xff1a;Intellij 2023 一、问题记录 在maven工程的pom文件导入如下某一依赖(JGit)。没有显示导包的错误&#xff0c;同时在maven仓库里面找到对应的包是正常下载到相应jar的。 但是就是无法引入相关的类。打开Project Structure&#xff0c;在Dependencies中发现…...

大数据技术之Scala

Spark运行架构核心是一个计算引擎 核心组件 1. Driver&#xff08;驱动器&#xff09; 角色&#xff1a;Spark作业的“大脑”&#xff0c;负责解析用户代码、生成任务并调度执行。 功能&#xff1a; 将用户程序转换为作业&#xff08;Job&#xff09;。 …...

LeetCode刷题常见的Java排序

1. 字符串排序(字母排序) 首先,你的代码实现了根据字母表顺序对字符串中的字母进行排序,忽略了大小写并且保留了非字母字符的位置。关键点是: 提取和排序字母:通过 Character.isLetter() 判断是否为字母,并利用 Character.toLowerCase() 来忽略大小写进行排序。保留非字…...

mysql的下载和安装2025.4.8

mysql下载和安装 MySQL的下载网址&#xff1a; https://www.mysql.com/downloads/ 点击进入Windows版本下载&#xff1a;我们可以选择需要的MySQL版本以及所需的操作系统&#xff0c;这里选择离线安装&#xff1a; 注意&#xff1a;MySQL 8.0 是带有 MySQL Installer 的最后一…...

QML Loader:延迟加载与动态切换

目录 引言相关阅读工程结构LoaderDelay.qml - 延迟加载实现完整代码HeavyComponent.qml代码解析运行效果 LoaderSwitch.qml - 动态切换组件完整代码代码解析运行效果 Main.qml - 主界面实现完整代码主界面结构代码解析 总结下载链接 引言 QML的Loader组件提供了一种强大的机制…...

Python和MicroPython的解释器区别

Python和MicroPython的解释器不是同一个&#xff0c;它们在设计目标、实现方式和运行环境上都有显著的区别。以下是它们的主要区别&#xff1a; 1. 底层实现 Python解释器&#xff08;CPython&#xff09;&#xff1a; Python的标准解释器是CPython&#xff08;C语言实现的Pyt…...

Git 的进阶功能和技巧

1、分支的概念和使用 1.1、什么是分支&#xff1f; 分支&#xff08;Branch&#xff09;是在版本控制中非常重要的概念。几乎所有版本控制系统都支持某种形式的分支。在 Git 中&#xff0c;分支是 Git 强大功能之一&#xff0c;它允许我们从主开发线分离出来&#xff0c;在不…...

解析HiveQL的ALTER TABLE ADD/REPLACE COLUMNS语句

阅读以下ALTER TABLE的ADD/REPLACE COLUMNS语句的语法,用C#编写解析函数,一个一个字符解析,所有关键字不区分大小写,一个或多个空格、Tab和换行的组合都可以是关键词之间的分隔,表名和字段名可能包含空格和Tab,语句中可以用`包裹表名和字段名,解析以下HiveQL语句在所有可…...

Spark Core编程

一 Spark 运行架构 1 运行架构 定义 Spark 框架的核心是一个计算引擎&#xff0c;整体来说&#xff0c;它采用了标准 master-slave 的结构 如图所示 2 核心组件 Spark 框架有两个核心组件: 1)Driver 2)Spark 驱动器节点&#xff08;用于执行 Spark 任务中的 main 方法&…...

在Ubuntu内网环境中为Gogs配置HTTPS访问(通过Apache反向代理使用IP地址)

一、准备工作 确保已安装Gogs并运行在HTTP模式(默认端口3000) 确认服务器内网IP地址(如192.168.1.100) 二、安装Apache和必要模块 sudo apt update sudo apt install apache2 -y sudo a2enmod ssl proxy proxy_http rewrite headers 三、创建SSL证书 1. 创建证书存储目录…...

Kafka和RocketMQ相比有什么区别?那个更好用?

Kafka和RocketMQ相比有什么区别?那个更好用? Kafka 和 RocketMQ 都是广泛使用的消息队列系统&#xff0c;它们有很多相似之处&#xff0c;但也有一些关键的区别。具体选择哪个更好用&#xff0c;要根据你的应用场景和需求来决定。以下是它们之间的主要区别&#xff1a; 1. …...