Kubernetes(k8s) 详细笔记

目标 :安装一主二从集群
途径:采用 vmware,ubuntu,2核,2G内存,50G硬盘

一、vmware安装:

1、为了避免大一安装vmware导致电脑格式化 并重置的悲剧,所以安装时,直接默认选项,并安置到C盘。

2、镜像文件 ISO:https://old-releases.ubuntu.com/releases/,直接在官网下载24.04版本,放到E盘下的resource文件夹中。

3、在虚拟网络编辑器里,创建两个网络格式:VMnet0(自动桥接模式)、VMnet8(NAT模式),

4、针对VMnet8,选择NAT模式 ,让虚拟机把宿主机当作中转翻墙去上网,IP可由内部自定义。

5、选择NAT模式后(网络地址转接),不要让DHCP协议自动分发IP,而是采用静态IP,确保可以搭建集群。不建议 选择 自动桥接模式,他是自动分配IP,IP分配不稳定。

6、我为 vmware 中的 VMnet8网络 分配的子网IP为 192.168.100.0、子网掩码为 255.255.255.0。

其实,vm 的 NAT 功能,在这里就相当于一个路由,负责监听 如下的固定网段。

go 复制代码
VMnet8 (虚拟网段) ──> IP池:192.168.100.0/24
     │
     ├── Master1 (主动设计静态 IP 192.168.100.111)
     ├── Node1 (主动设计静态 IP 192.168.100.112)
     └── Node2 (主动设计静态 IP 192.168.100.113)

7、一主:Master

进入 etc/netplan/ 中,

并创建yaml文件:99-k8s-static.yaml,并写入:
切记yaml文件的格式,一定要对齐,否则会解析出错

yaml 复制代码
network:                         # Netplan 网络配置的根节点
  version: 2                     # Netplan 配置版本,固定写 2
  renderer: networkd             # 使用 systemd-networkd 管理网络,适合 Ubuntu Server
  ethernets:                     # 配置以太网网卡
    ens33:                       # 网卡名称,你当前虚拟机的网卡叫 ens33
      dhcp4: no                  # 关闭 DHCP,表示不自动获取 IP,改为手动静态 IP
      addresses:                 # 配置静态 IP 地址
        - 192.168.100.111/24     # 当前虚拟机的 IP,/24 等于子网掩码 255.255.255.0
      gateway4: 192.168.100.2    # 默认网关,指向 VMware NAT 网关
      nameservers:               # DNS 服务器配置
        addresses:               # DNS 地址列表
          - 8.8.8.8              # Google DNS,用于解析域名
          - 223.5.5.5            # 阿里 DNS,用于解析域名

分配权限:sudo chmod 600 /etc/netplan/99-k8s-static.yaml

之后执行:sudo netplan apply,确保执行并应用

8、二从:Node1、Node2

这两个只需要改变 addresses 即可。

node1 - 192.168.100.112/24

node2 - 192.168.100.113/24

9、隐私设计:

主name:zhumo,密码:w1***53

从1name:***, 密码:1***6

从2name:***, 密码:1***7

10、我采用的是 WindTerm 进行的远程连接。所以需要本地vmware中的虚拟机,打开openssh这中对外连接,否则ping通过了,也无法通过ssh通道连接上。

二、环境搭建-环境初始化(一主多从)

注:若用 WindTerm 这种配置进行操作,会非常方便。因为 vmware 无法粘贴复制,会显示的很局促。

1、检查 Ubuntu 版本

尽量保证各个版本之间一致,可以避免兼容性问题。可以少踩坑。

复制代码
cat /etc/os-release

2、配置主机名

注:配置主机名,为每个服务器起个名字,之后的k8s就是靠这个,进行识别的。

分别在三台机器执行。

master 执行:

复制代码
sudo hostnamectl set-hostname master-k8s

node1 执行:

复制代码
sudo hostnamectl set-hostname node1-k8s

node2 执行:

复制代码
sudo hostnamectl set-hostname node2-k8s

查看是否成功:

复制代码
hostname

3、配置 hosts 解析

三台机器都执行:

复制代码
sudo vim /etc/hosts

添加:

复制代码
192.168.100.111 master-k8s
192.168.100.112 node1-k8s
192.168.100.113 node2-k8s

保存后测试:

复制代码
ping master-k8s
ping node1-k8s
ping node2-k8s

只要能 ping 通,说明主机名解析正常。

之后,各个服务器之间,就可以靠着名字,相互通信了。

当然,其实就是个域名解析而已。

4、时间同步

Ubuntu 24.04 默认一般用 systemd-timesyncd,不一定要装 chrony。

先查看:

复制代码
timedatectl

开启时间同步:

复制代码
sudo timedatectl set-ntp true

查看状态:

复制代码
timedatectl status

你重点看这一行:

复制代码
System clock synchronized: yes

如果是 yes,就可以。

各个集群之间,需要统一时区。

5、关闭防火墙

Ubuntu 一般是 ufw。

查看状态:

复制代码
sudo ufw status

关闭:

复制代码
sudo ufw disable

再次查看:

复制代码
sudo ufw status

看到这个就行:

复制代码
Status: inactive

k8s和容器网络会管理大量的 iptables/nftables 规则,我现在的学习初期阶段,关闭防火墙可以有效避免被网络拦截。

6、关闭 swap

必须要执行,不执行,后面初始化master的时候,会报错。因为kubelet默认不允许开启swap。

在 master-k8s、node1-k8s、node2-k8s 都执行:

复制代码
sudo swapoff -a

这句是临时关闭 swap,马上生效。

然后永久关闭 swap:

复制代码
sudo sed -i.bak '/ swap / s/^/#/' /etc/fstab

7、加载内核模块

三台机器都执行:

复制代码
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

立即加载:

复制代码
sudo modprobe overlay
sudo modprobe br_netfilter

查看是否加载成功:

复制代码
lsmod | grep br_netfilter
lsmod | grep overlay

overlay 是容器文件系统所需要的,br_netfilter 是让 Linux 网桥流量可以被 iptables/nftables 处理。

8、配置 Linux 内核网络参数

三台机器都执行:

复制代码
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

让配置立即生效:

复制代码
sudo sysctl --system

检查:

复制代码
sysctl net.bridge.bridge-nf-call-iptables
sysctl net.bridge.bridge-nf-call-ip6tables
sysctl net.ipv4.ip_forward

应该看到:

复制代码
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1

K8s 的 Pod 网络本质上需要跨节点转发流量,所以必须开启 ip_forward 和网桥流量处理。

9、配置 IPVS,可选但推荐

kubernetes 中的 service 转发有几种模式,长江的是 iptablesipvs

其中,ipvs 性能更高些。

现在初学可以先配上,不吃亏。

安装工具:

复制代码
sudo apt update
sudo apt install -y ipset ipvsadm

创建模块加载文件:

复制代码
cat <<EOF | sudo tee /etc/modules-load.d/ipvs.conf
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF

立即加载:

复制代码
sudo modprobe ip_vs
sudo modprobe ip_vs_rr
sudo modprobe ip_vs_wrr
sudo modprobe ip_vs_sh
sudo modprobe nf_conntrack

查看:

复制代码
lsmod | grep -e ip_vs -e nf_conntrack

IPVS 是 Linux 内核里的高性能负载均衡能力,K8s 的 Service 可以用它做流量转发。

10、安装基础工具

复制代码
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg vim net-tools lrzsz

工具作用:

复制代码
curl:下载配置和密钥
gpg:验证软件源签名
vim:编辑配置文件
net-tools:提供 ifconfig、netstat 等命令
ca-certificates:HTTPS 证书
apt-transport-https:让 apt 支持 HTTPS 源

提前把工具准备好,后期可能需要用

11、检查网络 IP

大致就是用 ip addr 测网卡

ping baidu.com 测联通性

12、重启机器

复制代码
sudo reboot

重启,确保配置生效。

三、环境搭建-集群安装

我当前的环境配置:

系统:Ubuntu 24.04

环境:VMware 三台虚拟机

master-k8s:192.168.100.111

node1-k8s: 192.168.100.112

node2-k8s: 192.168.100.113

容器运行时:containerd

Kubernetes:v1.36 系列

网络插件:Flannel

国内环境:软件包走中科大/清华镜像,K8s 镜像走阿里云/DaoCloud 镜像方案

1、安装 containerd

1.1 三台机器都执行
复制代码
sudo apt update
sudo apt install -y containerd

检查版本:

复制代码
containerd --version

其中,containerd 是 Kubernetes 真正用来拉镜像、创建容器、启动容器的组件。

它大致是如此起作用的:

复制代码
kubectl 发送命令
↓
kube-apiserver 接收命令
↓
kubelet 在节点上执行
↓
containerd 真正启动容器

sudo apt update 表示更新 Ubuntu 的软件包索引。

复制代码
sudo:用管理员权限执行
apt:Ubuntu 的软件包管理工具
install:安装软件
-y:自动回答 yes
containerd:要安装的软件名
1.2 生成 containerd 配置文件
复制代码
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null

将containerd的默认配置信息,通过管道写入 config.toml中,方便后续修改配置,而不是一直用containerd这种默认方式。

tee 是将内容写入指定文件。
> 代表不用将输入内容输出,写入一个空文件就行。防止内容太多,而导致刷屏。

1.3 修改 containerd 的 cgroup 为 systemd
复制代码
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml # 替换管理进程的方式,保证各个节点一致
grep -n "SystemdCgroup" /etc/containerd/config.toml # 查看修改是否正确

sed:替换操作

i:直接修改文件

s/旧内容/新内容/:替换方式

1.4 国内环境:修改 pause 镜像地址

替换一波,k8s.io 在中国内网络太慢。

复制代码
sudo sed -i "s#sandbox = 'registry.k8s.io/pause:3.10.1'#sandbox = 'registry.aliyuncs.com/google_containers/pause:3.10'#" /etc/containerd/config.toml
grep -nE "pinned_images|sandbox|pause" /etc/containerd/config.toml

应该会输出:

复制代码
sandbox = 'registry.aliyuncs.com/google_containers/pause:3.10'

代表替换成功。

pause其实是,必不可少的。

复制代码
Pod
├── pause 容器:负责 Pod 的基础网络环境
├── nginx 容器:负责运行网站
└── log-agent 容器:负责收集 nginx 日志

然后重启一波,才生效:

复制代码
sudo systemctl restart containerd
sudo systemctl enable containerd

2、安装 kubeadm、kubelet、kubectl

2.1 三台机器都执行:添加 Kubernetes 国内软件源

我用的是中科大 Kubernetes 镜像源。

三台机器都执行:

复制代码
K8S_MINOR=v1.36

创建 keyring 目录:

复制代码
sudo mkdir -p -m 755 /etc/apt/keyrings

导入 Kubernetes GPG key:

复制代码
curl -fsSL https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/deb/Release.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

添加中科大 Kubernetes 源:

复制代码
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.ustc.edu.cn/kubernetes/core:/stable:/${K8S_MINOR}/deb/ /" \
| sudo tee /etc/apt/sources.list.d/kubernetes.list

更新软件源:

复制代码
sudo apt update

如果失败的化,可以换成其他源。

2.2 安装 kubelet / kubeadm / kubectl

三台机器都执行:

复制代码
sudo apt install -y kubelet kubeadm kubectl

在锁定版本:

复制代码
sudo apt-mark hold kubelet kubeadm kubectl

查看版本:

复制代码
kubeadm version
kubectl version --client

启动 kubelet:

复制代码
sudo systemctl enable --now kubelet

这三个组件要分清楚:

复制代码
kubeadm:用来初始化集群、加入节点
kubelet:每台机器上的节点代理,真正负责管理 Pod
kubectl:你操作 Kubernetes 的命令行工具

安装后先 hold 是为了防止系统自动升级它们。Kubernetes 升级需要按控制面、节点、kubelet 的顺序来,所以不能随便被 apt upgrade 升级。

并且,官方安装文档也要求安装后锁定 kubelet kubeadm kubectl。

2.3 配置 crictl,方便排查 containerd

三台机器都执行:

复制代码
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

测试:

复制代码
sudo crictl info

如果能输出一大段 JSON 信息,说明 crictl 能连上 containerd。

安装:

复制代码
sudo apt install -y cri-tools

看版本:

复制代码
crictl --version

测信息:

复制代码
sudo crictl info

crictl 其实就是为了看,containerd这种容器运行时的内部信息,方便排错。

如果以后pod容器跑不起来了,可以:

复制代码
sudo crictl ps -a
sudo crictl images
sudo crictl logs 容器ID

3、初始化 master

下面只在 master-k8s 执行。

3.1 确认 master IP
复制代码
ip addr show ens33
确认你看到:
```cmd
192.168.100.111
3.2 创建 kubeadm 初始化配置文件

只在 master 执行:

cmd 复制代码
K8S_VERSION=$(kubeadm version -o short)
echo $K8S_VERSION

然后创建配置文件:

复制代码
cat <<EOF | sudo tee /root/kubeadm-init.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.100.111
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: ${K8S_VERSION}
imageRepository: registry.aliyuncs.com/google_containers
networking:
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/12
  dnsDomain: cluster.local
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF

检查配置文件:

复制代码
cat /root/kubeadm-init.yaml
3.3 预拉取 Kubernetes 镜像

只在 master 执行:

复制代码
sudo kubeadm config images list --config /root/kubeadm-init.yaml

然后拉取:

复制代码
sudo kubeadm config images pull --config /root/kubeadm-init.yaml

主要是测试网络连通性的。

3.4 初始化 master

只在 master 执行:

复制代码
sudo kubeadm init --config /root/kubeadm-init.yaml

成功后,你会看到类似:

复制代码
Your Kubernetes control-plane has initialized successfully!

并且最后会输出一段 kubeadm join ... 命令。

一定要保存这段命令,后面 node1 / node2 要用。

复制代码
kubeadm join 192.168.100.111:6443 --token ctp40n.gpp714i8mtchfjcb \
        --discovery-token-ca-cert-hash sha256:e24ee795ce05f9a88cb4a22f9f7714b5ed4897c1a31957e160362f445e0e769d 

一般,生效周期是24小时,之后就会失效,

复制代码
kubeadm token create --print-join-command

可以采用这个,进行重新生成。

这一步的意义:

kubeadm init 会把 master 控制面搭起来。它会做预检、生成证书、生成 kubeconfig、创建 etcd、kube-apiserver、kube-controller-manager、kube-scheduler 等静态 Pod,并生成 worker 节点加入集群用的 token。官方文档也明确说明 kubeadm init 是初始化 Kubernetes control plane node 的命令。

一句话理解:

kubeadm init = 把 master 节点初始化成 Kubernetes 控制中心。

3.5 配置 kubectl

只在 master 执行:

复制代码
	mkdir -p $HOME/.kube
	sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
	sudo chown $(id -u):$(id -g) $HOME/.kube/config

测试:

复制代码
kubectl get nodes

此时你可能看到:

复制代码
master-k8s   NotReady

这是正常的,因为网络插件还没装。

这一步的意义

kubectl 需要知道连接哪个 Kubernetes API Server,也需要证书权限。/etc/kubernetes/admin.conf 就是 master 初始化后生成的管理员配置文件。

4、安装 Flannel 网络插件

下面只在 master 执行。

4.1 下载 Flannel 配置
复制代码
curl -L -o kube-flannel.yml https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
4.2 国内环境:替换 Flannel 镜像源

Flannel 官方 YAML 当前使用 ghcr.io/flannel-io/... 镜像,国内可能拉不下来。Flannel 官方说明它是一个给 Kubernetes 使用的三层网络方案,并且会在每个节点上运行 flanneld 来分配和管理 Pod 子网。

先查看镜像:

复制代码
grep "image:" kube-flannel.yml

如果里面是:

复制代码
ghcr.io/flannel-io/...

可以替换成 DaoCloud 的 GHCR 镜像代理:

复制代码
sed -i 's#ghcr.io/#ghcr.m.daocloud.io/#g' kube-flannel.yml

再检查:

复制代码
grep "image:" kube-flannel.yml

应该变成类似:

复制代码
ghcr.m.daocloud.io/flannel-io/flannel
ghcr.m.daocloud.io/flannel-io/flannel-cni-plugin
4.3 安装 Flannel
复制代码
kubectl apply -f kube-flannel.yml

观察:

复制代码
kubectl get pods -n kube-flannel -w

如果你的 Flannel Pod 在 kube-system,就用:

复制代码
kubectl get pods -n kube-system -w

等它变成:

复制代码
Running

然后检查节点:

复制代码
kubectl get nodes

master 应该慢慢从:

复制代码
NotReady

变成:

复制代码
Ready

这一步的意义:

Kubernetes 本身不负责打通 Pod 网络。CNI 插件负责让不同节点上的 Pod 可以通信。

现在选 Flannel,是因为它简单,适合初学。它会在每个节点上跑一个网络代理,负责给每个节点分配 Pod 子网,并用 VXLAN 等方式转发跨节点 Pod 流量。

5、node1 / node2 加入集群

下面在 node1-k8s 和 node2-k8s 执行。

5.1 使用 master 输出的 join 命令

master 初始化成功后,会输出类似:

复制代码
kubeadm join 192.168.100.111:6443 --token xxxxxx.xxxxxxxxxxxxxxxx \
  --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxx

你在 node1 和 node2 上执行时,前面加 sudo:

复制代码
sudo kubeadm join 192.168.100.111:6443 --token xxxxxx.xxxxxxxxxxxxxxxx \
  --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxx \
  --cri-socket unix:///run/containerd/containerd.sock
5.2 如果 join 命令丢了

在 master 上重新生成:

复制代码
kubeadm token create --print-join-command

然后复制到 node1 / node2 执行。

这一步的意义

复制代码
kubeadm join 的作用是让 worker 节点加入 master 管理的集群。

它会做几件事:

  1. 连接 master 的 6443 端口
  1. 用 token 做第一次认证
  2. 校验 CA 证书 hash,防止连到假的 master
  3. 注册 kubelet
  4. 让这个节点成为 Kubernetes Node

6、最终验证,查看节点

复制代码
kubectl get nodes -o wide

你最终要看到类似:

复制代码
NAME         STATUS   ROLES           INTERNAL-IP
master-k8s   Ready    control-plane    192.168.100.111
node1-k8s    Ready    <none>           192.168.100.112
node2-k8s    Ready    <none>           192.168.100.113

7、部署nginx测试

国内环境下,nginx:latest 可能因为 Docker Hub 网络问题拉不下来。这里用 DaoCloud 镜像代理:

复制代码
kubectl create deployment nginx --image=docker.m.daocloud.io/library/nginx:latest --replicas=3

查看 Pod:

复制代码
kubectl get pods -o wide
```
暴露服务:
```
kubectl expose deployment nginx --port=80 --type=NodePort
```
查看 Service:
```
kubectl get svc
```
你会看到类似:
```
nginx   NodePort   10.96.xxx.xxx   <none>   80:30xxx/TCP
```
然后在宿主机浏览器访问:
```
http://192.168.100.111:30xxx
http://192.168.100.112:30xxx
http://192.168.100.113:30xxx
```
能看到 nginx 页面,就说明集群基本成功。
相关推荐
江屿风1 小时前
【c++笔记】类和对象流食般投喂(中)
开发语言·c++·笔记
许长安1 小时前
Kafka 架构讲解:从提交日志到分区副本机制
c++·经验分享·笔记·分布式·架构·kafka
小袁说公考1 小时前
2026广东公考培训标杆深度解析:广东粉笔——科技赋能本土,领跑粤考赛道
大数据·人工智能·经验分享·笔记·科技·其他
袁煦丞 cpolar内网穿透实验室2 小时前
出差路上,服务器在我手机里
运维·服务器·docker·容器·智能手机·远程工作·cpolar
智者知已应修善业10 小时前
【51单片机89C51及74LS273、74LS244组成】2022-5-28
c++·经验分享·笔记·算法·51单片机
奋斗的小乌龟11 小时前
langchain4j笔记-06
笔记
·醉挽清风·11 小时前
学习笔记—MySQL—库表操作
笔记·学习·mysql
weixin_4514315612 小时前
【学习笔记】微博视频页面ajax请求与响应数据分析
笔记·学习·音视频
快乐得小萝卜14 小时前
OpenVLA 论文精读笔记
笔记