基于Ubuntu 24.04 快速部署K8S 1.31.0集群 1. K8S集群主机准备 主机操作系统版本: Ubuntu 24.04
硬件配置说明: master 2核 4G内存 20GB硬盘 node1 2核 4G内存 20GB硬盘 node2 2核 4G内存 20GB硬盘
1.1 主机名配置 master: hostnamectl set-hostname k8s-master01 node1: hostnamectl set-hostname k8s-worker01 node2: hostnamectl set-hostname k8s-worker02
1.2 主机IP地址配置 vim /etc/netplan/50-cloud-init.yaml
欲使其生效, 使用命令netplan apply
查看IP地址: ip a s
使用动态分配时, 修改hosts即可
vim /etc/hosts
1 2 3 192.168.64.15 k8s-master01 192.168.64.16 k8s-worker01 192.168.64.17 k8s-worker02
1.3 时间同步 apt install ntpsec-ntpdate
1 2 0 0 * * *ntpdate ntp.aliyun.com # 每天0点0分时间同步
1.4 配置内核转发和网桥过滤 如果不配置会导致K8S集群的网络通信不流畅
创建加载内核模块文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 # 手动加载overlay和br_netfilter, 为了避免重启系统, 本文采用手动加载 modprobe overlay modprobe br_netfilter # modprobe overlay 是用于在 Linux 系统中加载 overlay 文件系统模块的命令。具体来说: # modprobe:是一个工具,用于加载或卸载内核模块。它会自动处理模块间的依赖关系。 # overlay:指的是 overlay 文件系统模块,是一种联合文件系统(union filesystem),允许你将一个文件系统(通常是只读的)与另一个 # 文件系统(通常是可写的)合并,使之对外表现为单一的文件系统。 # 作用: # 运行 modprobe overlay 后,系统会尝试加载 overlay 模块,提供支持 联合挂载,这种挂载方式允许: # 存储层的组合:将多个文件系统(或称层)“叠加”成一个文件系统。 # Docker和Kubernetes等容器技术使用:容器中使用 overlayfs 提供文件隔离和更高效的存储管理。 # 这种联合文件系统特别适用于容器技术,比如 Docker,它利用 overlayfs 来高效管理镜像层和容器层。 # #自动加载overlay和br_netfilter cat << EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF # 这个命令的整体作用是在 /etc/modules-load.d/k8s.conf 文件中添加以下内容 # 这样,系统每次启动时都会自动加载 overlay 和 br_netfilter 模块,从而满足 Kubernetes 和其他容器服务的网络要求。 # 添加网桥过滤及内核转发配置文件 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 # net.bridge.bridge-nf-call-ip6tables = 1:这个参数允许 IPv6 的网络桥接流量被 ip6tables 进行处理。设为 1 表示开启。 # net.bridge.bridge-nf-call-iptables = 1:这个参数允许 IPv4 的网络桥接流量被 iptables 进行处理。设为 1 表示开启。这对于 Kubernetes 的网络策略和防火墙规则是必要的。 # net.ipv4.ip_forward = 1:这个参数启用 IPv4 的转发功能。设为 1 表示开启。这对于容器间的网络通信以及外部访问容器的服务是必需的。 # 欲使之生效, 还需键入命令 sysctl --system
1.5 安装ipset和ipvsadm 后续在使用kubeproxy的代理模式时, 会用到ipvs的配置 ipset 和 ipvsadm 是用于网络流量管理和负载均衡的重要工具,特别是在 Linux 环境中 ipset 是一个用于管理 IP 集合的工具。它可以创建和维护多个 IP 地址的集合,以便于快速地在防火墙(如 iptables)中进行匹配。ipset 的主要用途包括: 性能优化:通过将多个 IP 地址组合成集合,ipset 提供了比单独规则更高效的匹配方式,减少了 iptables 规则的数量,从而提高了性能。 动态管理:可以在运行时添加、删除或修改 IP 集合,便于对大规模流量的快速响应。
ipvsadm(“IP Virtual Server Administration”) 是 IP 虚拟服务器(IPVS)的管理工具,用于实现 Linux 的负载均衡。它主要用于以下方面: 负载均衡:ipvsadm 允许用户配置和管理 IPVS,以实现对传入流量的负载均衡。通过将请求分发到多个后端服务器,提供高可用性和高性能。 调度算法:支持多种负载均衡算法(如轮询、最少连接、基于权重等),使得流量分发更加灵活。 高可用性:配合 Linux 虚拟服务器(如 LVS),能够实现高可用性架构,支持多种网络协议(如 TCP、UDP)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # 安装 ipset 和 ipvsadm apt install ipset ipvsadm # 配置ipvsadm模块加载 # 添加需要加载的模块 cat << EOF | tee /etc/modules-load.d/ipvs.conf ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack EOF # 创建加载模块脚本文件, 立即使用 cat << EOF | tee ipvs.sh # ! /bin/sh modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack EOF # 执行脚本 sh ipvs.sh # 查看模块加载情况 lsmod | grep "ip_vs"
1.6 关闭SWAP分区 1 2 3 4 5 6 7 8 9 # 如果不重启式的关闭swap分区, 可以临时关闭, 关闭命令为 swapoff -a # 永远关闭swap分区, 需要重启系统 vim /etc/fstab # 注释掉如下内容 # /swap.img none swap sw 0 0
2. K8S集群节点容器管理工具准备 2.1 Containerd 部署文件获取 1 2 3 4 5 6 7 8 # 通过wget命令下载 # wget https://github.com/containerd/containerd/releases/download/v1.7.20/cri-containerd-1.7.20-linux-amd64.tar.gz # 本文使用Macbook M1芯片, 所以使用arm版本 wget https://github.com/containerd/containerd/releases/download/v1.7.20/cri-containerd-1.7.20-linux-arm64.tar.gz # 解压并合并到根目录 tar xfv cri-containerd-1.7.20-linux-arm64.tar.gz -C /
Containerd配置文件生成和修改 默认情况下, 没有containerd配置文件, 我们需要使用命令生成并进行自定义修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 # 创建配置文件目录 mkdir /etc/containerd # 生成配置文件 containerd config default > /etc/containerd/config.toml # 修改第67行 vim /etc/containerd/config.toml sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.10" # 修改为阿里云镜像 # sandbox_image = "registry.k8s.io/pause:3.9" # 修改第139行, runc的operation vim /etc/containerd/config.toml SystemdCgroup = true # 由false修改为true # containerd启动及开机自启动设计 # 设置开机自启动, 并现在启动 systemctl enable --now containerd # 验证启动成功 ls /var/run/containerd/ -l # 如果成功, 则有以下内容 # srw-rw---- 1 root root 0 Nov 4 10:17 containerd.sock # srw-rw---- 1 root root 0 Nov 4 10:17 containerd.sock.ttrpc # drwx--x--x 2 root root 40 Nov 4 10:17 io.containerd.runtime.v1.linux # drwx--x--x 2 root root 40 Nov 4 10:17 io.containerd.runtime.v2.task # 验证版本 containerd --version
3. K8S 集群部署 3.1 安装源: apt 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 下载用于Kubernetes软件包仓库的公共签名密钥, 如果没有此密钥, 则无法完成软件安装包的安装 curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg # 添加Kubernetes apt源仓库 echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list # yum源操作: https://mirrors.tuna.tsinghua.edu.cn/help/kubernetes/ # /etc/yum.repos.d/kubernetes.repo # 更新apt包索引 sudo apt-get update # rm -rf /var/cache/yum# yum makecache
3.2 Kubernetes软件安装及kubelet配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # 查看当前软件列表, 是否有kubeadm apt-cache policy kubeadm # yum list kubeadm # 安装指定版本 apt install kubeadm=1.31.0-1.1 kubelet=1.31.0-1.1 kubectl=1.31.0-1.1 -y # yum install -y kubeadm kubelet kubectl # !!!注意: 安装完成后不能立即启动 # 首先锁定这些应用的版本, 保证后续使用过程中不会自动更新, 取消锁定使用unhold sudo apt-mark hold kubeadm kubelet kubectl # # 配置kubelet # 为实现Kubernetes使用的cgroup与容器运行时使用的cgroupdriver的一致性, 建议修改如下内容 vim /etc/default/kubelet KUBELET_EXTRA_ARGS="--cgroup-driver=systemd" # 设置为开机自启动即可, 由于没有生成配置文件, 集群初始化后自动启动 systemctl enable kubelet systemctl start kubelet # 准备初始化的配置文件, 只需要在master节点中准备即可 ******************************************************** # 查看版本 kubeadm version # 生成部署配置文件 kubeadm config print init-defaults > kubeadm-config.yaml # 修改配置文件 vim kubeadm-config.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 1 apiVersion: kubeadm.k8s.io/v1beta4 2 bootstrapTokens: 3 - groups: 4 - system:bootstrappers:kubeadm:default-node-token 5 token: abcdef.0123456789abcdef 6 ttl: 24h0m0s 7 usages: 8 - signing 9 - authentication 10 kind: InitConfiguration 11 localAPIEndpoint: 12 advertiseAddress: 1.2 .3 .4 13 bindPort: 6443 14 nodeRegistration: 15 criSocket: unix:///var/run/containerd/containerd.sock 16 imagePullPolicy: IfNotPresent 17 imagePullSerial: true 18 name: k8s-master01 19 taints: null 20 timeouts: 21 controlPlaneComponentHealthCheck: 4m0s 22 discovery: 5m0s 23 etcdAPICall: 2m0s 24 kubeletHealthCheck: 4m0s 25 kubernetesAPICall: 1m0s 26 tlsBootstrap: 5m0s 27 upgradeManifests: 5m0s 28 --- 29 apiServer: {} 30 apiVersion: kubeadm.k8s.io/v1beta4 31 caCertificateValidityPeriod: 87600h0m0s 32 certificateValidityPeriod: 8760h0m0s 33 certificatesDir: /etc/kubernetes/pki 34 clusterName: kubernetes 35 controllerManager: {} 36 dns: {} 37 encryptionAlgorithm: RSA-2048 38 etcd: 39 local: 40 dataDir: /var/lib/etcd 41 imageRepository: registry.aliyuncs.com/google_containers 42 kind: ClusterConfiguration 43 kubernetesVersion: 1.31 .0 44 networking: 45 dnsDomain: cluster.local 46 serviceSubnet: 10.96 .0 .0 /12 podSubnet: 10.244 .0 .0 /16 47 proxy: {} 48 scheduler: {}
3.3 容器镜像下载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 查看当前版本需要的镜像, 指定版本可用kubeadm config images list --kubernetes-version=1.31.0 # kubeadm config images list kubeadm config images list --kubernetes-version=1.31.0 # 1.31.11-150500.1.1 # 普通下载镜像 # kubeadm config images pull # 如果下载失败, 到阿里云上下载, 下载后更改镜像名称 kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=1.31.0 # --kubernetes-version=1.31.11 # 查看下载的镜像 crictl images
3.4 使用 kubeadm 初始化集群
kubeadm init –config kubeadm-config.yaml –upload-certs –v=9
如果init失败, 需要通过kubeadm reset重置操作, 并重启容器运行时systemctl restart containerd
YUM + DOCKER1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 sudo yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine sudo yum install -y \ docker-ce-18.09.9 \ docker-ce-cli-18.09.9 \ containerd.io-1.2.6-3.3.el7 vim /etc/docker/daemon.json { "registry-mirrors" : ["https://odol8len.mirror.aliyuncs.com" ] } systemctl enable docker systemctl start docker kubeadm init \ --apiserver-advertise-address=10.0.2.15 \ --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ --kubernetes-version v1.17.3 \ --service-cidr=10.96.0.0/16 \ --pod-network-cidr=10.244.0.0/16 mkdir -p $HOME /.kubesudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $(id -u):$(id -g) $HOME /.kube/config kubectl describe pod coredns -n kube-system
1 证书过期:https://www.cnblogs.com/du-z/p/17095266.html
3.5 kubectl 配置 1 2 3 4 5 6 7 8 9 10 11 12 mkdir -p $HOME/.kube # 此文件夹用于存放 kubectl 的配置文件 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # 将 Kubernetes 集群初始化时生成的 admin.conf 文件复制到用户的 .kube/config 文件中 sudo chown $(id -u):$(id -g) $HOME/.kube/config # 更改文件的所有者,使其归当前用户所有 # 完成上述操作后, 查看当前节点 kubectl get nodes # 上述命令会查看到结果: k8s-master01 NotReady control-plane 10m v1.31.0
3.6 将其余节点加入集群 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 在主节点上获取加入命令, 包括 IP 地址、端口、token 和 --discovery-token-ca-cert-hash 参数。 kubeadm token create --print-join-command --ttl=0 # 输出示例如下: 192.168.64.15是master节点ip # kubeadm join 192.168.64.15:6443 --token fhgh1q.y3lit9rx5n9g42pc --discovery-token-ca-cert-hash sha256:eb8f1b9449b52c055711922ede6da56fa6606b5e1006bf4d9c0105b34498d025 # 在新节点上执行: sudo kubeadm join 192.168.64.15:6443 --token fhgh1q.y3lit9rx5n9g42pc --discovery-token-ca-cert-hash sha256:eb8f1b9449b52c055711922ede6da56fa6606b5e1006bf4d9c0105b34498d025 # 查看节点 kubectl get nodes # 获取 Kubernetes 集群中的组件状态 component statuses kubectl get cs # NAME STATUS MESSAGE ERROR # scheduler Healthy ok # etcd-0 Healthy ok # controller-manager Healthy ok
4. K8S集群网络插件部署 通过上面的步骤, 集群已经初始化完成, 但是节点都还处于not ready状态, 这是是因为scheduler组件还不能完成相关的pod调度. 而这是因为sheduler缺少一些网络插件. 以下三种网络插件可以任选其一.Flannel: 适用于小规模集群(个位数集群), 适合快速部署和简单网络需求,易于使用,但在安全性和性能上相对较弱Calico: (10~100), 适合需要强大网络策略和安全性的应用,适合大规模部署,但配置较为复杂
Cilium: 多集群使用, 适合现代云原生应用,提供高性能和细粒度的安全策略,但对技术要求较高
本文使用Calico网络插件, Calico有两种安装方式, 一种是yaml, 一种是通过operator方式安装, 本文采用operator方式安装, 较为方便
4.1 Calico 安装 1 2 3 4 5 6 7 8 9 10 11 12 13 # 访问官网 https://docs.tigera.io/calico/3.28/about/ # 安装 Tigera Calico operator, 在master节点上操作 kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.2/manifests/tigera-operator.yaml # 查看calico operator是否是运行的状态, 只有是运行的状态才可进行下一步 kubectl get pods -n tigera-operator # tigera-operator-89c775547-57prb 1/1 Running 0 54s # 下载calico的自定义资源配置到本地 wget https://raw.githubusercontent.com/projectcalico/calico/v3.28.2/manifests/custom-resources.yaml # 如果无法下载, 通过浏览器访问后粘贴
修改custom-resources.yaml的第13行, 应与3.2处配置podSubnet网段保持相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 1 2 3 apiVersion: operator.tigera.io/v1 4 kind: Installation 5 metadata: 6 name: default 7 spec: 8 9 calicoNetwork: 10 ipPools: 11 - name: default-ipv4-ippool 12 blockSize: 26 13 cidr: 10.244 .0 .0 /16 14 encapsulation: VXLANCrossSubnet 15 natOutgoing: Enabled 16 nodeSelector: all() 17 18 --- 19 20 21 22 apiVersion: operator.tigera.io/v1 23 kind: APIServer 24 metadata: 25 name: default 26 spec: {}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 应用配置 kubectl create -f custom-resources.yaml # 查看calico pod运行情况 kubectl get pods -n calico-system -o wide # NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES # calico-kube-controllers-74cc68955d-2smdb 1/1 Running 0 15h 10.244.69.194 k8s-worker02 <none> <none> # calico-node-h5j7d 1/1 Running 0 15h 192.168.64.17 k8s-worker02 <none> <none> # calico-node-n9765 1/1 Running 0 15h 192.168.64.16 k8s-worker01 <none> <none> # calico-node-xwbrm 1/1 Running 0 15h 192.168.64.15 k8s-master01 <none> <none> # calico-typha-5d9f58495d-6nhkt 1/1 Running 0 15h 192.168.64.17 k8s-worker02 <none> <none> # calico-typha-5d9f58495d-brgzw 1/1 Running 0 15h 192.168.64.16 k8s-worker01 <none> <none> # csi-node-driver-f8zgg 2/2 Running 0 15h 10.244.69.193 k8s-worker02 <none> <none> # csi-node-driver-qspfg 2/2 Running 0 15h 10.244.32.129 k8s-master01 <none> <none> # csi-node-driver-rtrl9 2/2 Running 0 15h 10.244.79.65 k8s-worker01 <none> <none>
5. 部署应用验证K8S集群的可用性 5.1 验证Core Dns的可用性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 查看core DNS 服务 `kubectl get service -n kube-system` # 结果 kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 17h # 测试可用性 dig -t a www.baidu.com@10.96.0.10 # 如果能解析出来, 说明core DNS可用 # ;; ANSWER SECTION: # www.baidu.com\@10.96.0.10. 1INA198.18.0.36 # 否则表示core DNS目前无法使用 # 修改如下文件, 修改DNS 服务器地址 vim /etc/resolv.conf
5.2 部署应用验证 本次使用nginx部署验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 apiVersion: apps/v1 kind: Deployment metadata: name: nginxweb spec: selector: matchLabels: app: nginxweb replicas: 2 template: metadata: labels: app: nginxweb spec: containers: - name: nginxwebc image: nginx:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginxweb-service spec: externalTrafficPolicy: Cluster selector: app: nginxweb ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30080 type: NodePort
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # 将上述yaml文件保存为nginx.yaml文件, 并使用kubectl部署 kubectl apply -f nginx.yaml # 有如下结果表示部署成功🏅 # deployment.apps/nginxweb created # service/nginxweb-service created # 查看部署的pod, 这里获取到的一个nginx pod的集群ip是10.244.69.196 kubectl get pods -o wide # 集群内访问nginx, 有nginx的页面结果, 则表示成功 curl 10.244.69.196 # 集群外访问, 使用集群任意一个节点的IP加上30080端口进行访问 # 在浏览器上访问 http://192.168.64.15:30080 # 有nginx的页面结果, 则表示部署成功🏅
6 常见问题 6.1 科学网络 开启科学上网, 下载相关的依赖时, 才更加方便
使用clash代理时, 需要开启Tun Mode
6.2 ssh操作
打开ssh连接服务(慎重)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 sudo apt-get install openssh-server dpkg -l | grep ssh ps -e | grep ssh 如果看到sshd那说明ssh-server已经启动了。 如果没有则可以这样启动:sudo /etc/init.d/ssh start或sudo service ssh start PermitRootLogin yes 删除sshd_config.d中的子配置 sudo /etc/init.d/ssh stop sudo /etc/init.d/ssh start sudo service ssh restart sudo systemctl enable ssh
tips: 使用scp 命令传输文件
1 2 scp root@node2:/home/ubuntu/cni-plugins-linux-amd64-v1.3.0.tgz ./
6.3 学习路径 Kubernetes学习路径
6.4 虚拟机资源准备 安装multipass, 用于准备集群所需虚拟机: brew install multipass
6.5 kubeadm kubectl kubelet 区别
6.6 其他 kubernetes 系统各个组件调用关系:
首先要明确,一旦 kubernetes 环境启动之后,master 和 node 都会将自身的信息存储到 etcd 数据库中;
一个 nginx 服务的安装请求会首先被发送到 master 节点的 apiServer 组件;
apiServer 组件会调用 scheduler 组件来决定到底应该把这个服务安装到哪个 node 节点上,在此时,它会从 etcd 中读取各个 node 节点的信息,然后按照一定的算法进行选择,并将结果告知 apiServer;
apiServer 调用 controller-manager 去调度 Node 节点安装 nginx 服务;
kubelet 接收到指令后,会通知 docker,然后由 docker 来启动一个 nginx 的 pod,pod 是 kubernetes 的最小操作单元,容器必须跑在 pod 中;
当Pod启动后,一个 nginx 服务就运行了,如果需要访问 nginx,就需要通过 kube-proxy 来对 pod 产生访问的代理 这样,外界用户就可以访问集群中的 nginx 服务了