Kubernetes技术入门与实践(一):单Master集群部署详解
欢迎来到Kubernetes技术入门系列的第一部分!在本教程中,我将详细讲解如何在OpenEuler 24.03 SP3系统上部署一个单Master Kubernetes集群。Kubernetes(简称K8S)是一个开源的容器编排系统,用于自动化容器化应用的部署、扩展和管理。
单Master集群是最简单的生产级架构,包括一个Master节点(负责集群控制)和多个Worker节点(运行应用负载)。基于您提供的配置(IP地址:192.168.64.128为Master,192.168.64.129和192.168.64.130为Worker节点),我将结合理论知识和实际操作代码,逐步指导您完成部署。整个过程包括准备工作、软件安装、集群初始化、网络插件配置及验证,确保您能全面掌握。
第一部分:Kubernetes核心理论知识
在部署前,理解Kubernetes的基本概念至关重要。这有助于后续操作的理解和问题排查。
1. Kubernetes架构概述
Kubernetes采用主从架构:
- Master节点:集群的“大脑”,包含以下核心组件:
- API Server:处理所有REST操作,是集群通信的入口。例如,当您运行
kubectl命令时,它会与API Server交互。 - etcd:分布式键值存储,存储集群状态(如节点信息、Pod定义)。它保证数据一致性和高可用性。
- Controller Manager:运行控制器逻辑,监控集群状态并确保实际状态匹配期望状态(如自动修复失败的Pod)。
- Scheduler:将Pod分配到合适的Worker节点,基于资源需求和约束。
- API Server:处理所有REST操作,是集群通信的入口。例如,当您运行
- Worker节点:运行应用负载的节点,包含:
- kubelet:节点代理,负责启动和停止Pod,并与Master通信。
- kube-proxy:管理网络规则,实现Service的负载均衡和网络路由。
- Container Runtime:运行容器的引擎(如Docker),通过CRI(Container Runtime Interface)与kubelet集成。
在单Master集群中,Master节点承担所有控制平面角色,Worker节点执行任务。这种架构简单易部署,但存在单点故障风险;生产环境建议使用多Master高可用方案。
2. Kubernetes核心概念
- Pod:最小部署单元,包含一个或多个容器(如Docker容器)。Pod共享网络和存储资源,是调度的基础单位。
- Service:抽象层,为Pod提供稳定的网络端点。Service使用ClusterIP(内部IP)或NodePort(外部访问),通过负载均衡路由流量到后端Pod。IP地址范围由
--service-cidr参数定义(如您指定的10.96.0.0/12)。 - Deployment:声明式管理Pod副本集,支持滚动更新和回滚。
- 网络模型:Kubernetes要求所有Pod能相互通信。网络插件(如Flannel)实现Overlay网络,为每个Pod分配唯一IP。
--pod-network-cidr参数(如10.244.0.0/16)定义了Pod IP范围,确保不冲突。 - CRI(Container Runtime Interface):标准接口,允许kubelet与不同容器运行时(如Docker、containerd)交互。Docker原生不支持CRI,因此需要适配器如cri-dockerd。
3. 部署准备工作理论
- 系统要求:OpenEuler 24.03 SP3基于CentOS,兼容性强。节点需满足:
- CPU:2核以上,内存:2GB+(Master建议4GB)。
- 网络:所有节点需互通,禁用防火墙和SELinux。
- 存储:建议20GB+磁盘空间。
- 网络配置:集群IP范围需规划:
- Pod网络:
10.244.0.0/16(CIDR表示法),可分配65536个IP。 - Service网络:
10.96.0.0/12(CIDR表示法),范围更大。 计算子网掩码:对于10.244.0.0/16,掩码为255.255.0.0,IP范围从10.244.0.1到10.244.255.254。
- Pod网络:
- 软件版本:您指定的版本(Kubernetes v1.28.15、Docker CE 28.5.2、cri-dockerd 0.3.8)经过测试兼容。Kubeadm是官方部署工具,简化集群初始化。
接下来,我们将进入实操部分。确保所有节点(k8s-master, k8s-node1, k8s-node2)已完成系统安装并联网。
第二部分:部署准备工作
在开始集群部署前,所有节点需进行基础配置,包括主机名设置、网络优化和软件安装。本节基于OpenEuler 24.03 SP3系统。
1. 配置主机名和hosts文件
所有节点需设置主机名,并更新/etc/hosts文件确保名称解析。这避免IP变动导致的通信问题。
在k8s-master节点(192.168.64.128)执行:
# 设置主机名 hostnamectl set-hostname k8s-master # 编辑hosts文件 cat <<EOF >> /etc/hosts 192.168.64.128 k8s-master 192.168.64.129 k8s-node1 192.168.64.130 k8s-node2 EOF在k8s-node1节点(192.168.64.129)执行:
hostnamectl set-hostname k8s-node1 cat <<EOF >> /etc/hosts 192.168.64.128 k8s-master 192.168.64.129 k8s-node1 192.168.64.130 k8s-node2 EOF在k8s-node2节点(192.168.64.130)执行:
hostnamectl set-hostname k8s-node2 cat <<EOF >> /etc/hosts 192.168.64.128 k8s-master 192.168.64.129 k8s-node1 192.168.64.130 k8s-node2 EOF
验证:运行hostname和ping k8s-master,确保响应正常。
2. 系统优化
为减少干扰,需关闭防火墙、禁用SELinux,并配置内核参数。
- 所有节点执行:
# 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 禁用SELinux(临时生效) setenforce 0 # 永久禁用(编辑配置文件) sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 配置内核参数(避免swap影响性能) swapoff -a sed -i '/ swap / s/^/#/' /etc/fstab # 加载内核模块(用于网络和存储) cat <<EOF > /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # 设置sysctl参数(启用IP转发) cat <<EOF > /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 sysctl --system
3. 安装Docker容器运行时
Docker是运行容器的基础。您指定安装docker-ce-28.5.2版本,需配置yum源。
- 所有节点执行:
# 安装依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加Docker CE仓库(OpenEuler兼容CentOS源) yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装指定版本Docker yum install -y docker-ce-28.5.2 docker-ce-cli-28.5.2 containerd.io # 启动Docker并设置开机自启 systemctl start docker systemctl enable docker # 验证安装 docker --version # 应输出 Docker version 28.5.2
4. 安装cri-dockerd适配器
由于Docker不支持原生CRI,需安装cri-dockerd作为桥接。您指定rpm包cri-dockerd-0.3.8-3.el8.x86_64.rpm。
- 所有节点执行:
# 下载rpm包(假设已下载到当前目录) # wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.8/cri-dockerd-0.3.8-3.el8.x86_64.rpm # 安装rpm包 rpm -ivh cri-dockerd-0.3.8-3.el8.x86_64.rpm # 启动cri-dockerd并设置开机自启 systemctl start cri-docker systemctl enable cri-docker # 验证:检查socket文件 ls /var/run/cri-dockerd.sock # 应存在
5. 安装Kubernetes组件
安装kubelet、kubeadm和kubectl。kubeadm用于初始化集群,kubelet是节点代理,kubectl是命令行工具。
- 所有节点执行:
# 添加Kubernetes仓库(使用阿里云镜像加速) cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=0 EOF # 安装指定版本(您指定v1.28.15) yum install -y kubelet-1.28.15 kubeadm-1.28.15 kubectl-1.28.15 # 启动kubelet并设置开机自启 systemctl start kubelet systemctl enable kubelet # 验证版本 kubeadm version # 应输出 v1.28.15 kubectl version --client # 应输出 v1.28.15
准备工作完成!所有节点现在具备运行集群的基础。接下来,在Master节点初始化集群。
第三部分:Master节点初始化
在k8s-master节点(192.168.64.128)执行kubeadm init命令初始化集群。我将详细解释每个参数并执行。
1. kubeadm init命令详解
您提供的命令:
kubeadm init --apiserver-advertise-address=192.168.64.128 --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.28.15 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --cri-socket=unix:///var/run/cri-dockerd.sock| 参数 | 说明 | 值/示例 |
|---|---|---|
--apiserver-advertise-address | 指定 API Server 监听的 IP 地址,确保 Worker 节点能连接。 | 192.168.64.128 |
--image-repository | 使用阿里云镜像仓库,避免从 Google 官方仓库下载(国内访问慢)。 | registry.aliyuncs.com/google_containers |
--kubernetes-version | 指定 Kubernetes 版本,需与安装的组件版本一致。 | v1.28.15 |
--pod-network-cidr | 设置 Pod 网络范围,为 Flannel 网络插件的默认 CIDR。 | 10.244.0.0/16 |
--service-cidr | 设置 Service 网络范围,范围较大,避免 IP 耗尽。 | 10.96.0.0/12 |
--cri-socket | 指定 CRI socket 路径,指向 cri-dockerd 适配器。 | unix:///var/run/cri-dockerd.sock |
2. 执行初始化命令
在k8s-master节点运行命令:
kubeadm init --apiserver-advertise-address=192.168.64.128 --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.28.15 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --cri-socket=unix:///var/run/cri-dockerd.sock初始化过程可能持续2-5分钟,输出类似:
[init] Using Kubernetes version: v1.28.15 [preflight] Running pre-flight checks [preflight] Pulling images required for setting up a Kubernetes cluster ... Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.64.128:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef关键输出解释:
- 成功消息表示控制平面已启动。
kubeadm join命令用于Worker节点加入,包含token和CA证书哈希(实际输出会不同)。- 需配置kubectl访问权限。
3. 配置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验证Master状态:
kubectl get nodes # 输出应显示k8s-master为NotReady(因网络插件未装) NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane 1m v1.28.154. 常见问题解决
- 镜像拉取失败:如果卡在Pulling images,检查网络或手动拉取:
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.28.15 - 端口冲突:确保6443、10250等端口空闲。
- cri-dockerd问题:检查服务状态
systemctl status cri-docker,确保socket存在。
Master节点初始化完成!现在添加Worker节点。
第四部分:Worker节点加入集群
在k8s-node1和k8s-node2节点执行kubeadm join命令加入集群。基于Master输出的join命令。
1. 获取join命令
在Master节点,如果忘记join命令,可重新生成:
kubeadm token create --print-join-command # 输出类似:kubeadm join 192.168.64.128:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:0123456789abcdef...2. 在Worker节点执行join
在k8s-node1(192.168.64.129)和k8s-node2(192.168.64.130)分别运行:
kubeadm join 192.168.64.128:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef输出应显示成功加入:
This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details.3. 在Master节点验证节点状态
回到Master节点:
kubectl get nodes # 输出示例(所有节点为NotReady,因网络插件未装) NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane 10m v1.28.15 k8s-node1 NotReady <none> 1m v1.28.15 k8s-node2 NotReady <none> 1m v1.28.154. 常见问题解决
- Token过期:默认token有效期24小时。过期后,在Master节点生成新token:
kubeadm token create --print-join-command - 网络不通:确保Worker节点能ping通Master IP。
- cri-dockerd问题:在Worker节点检查
systemctl status cri-docker。
Worker节点加入完成!现在安装网络插件。
第五部分:安装网络插件
Kubernetes需要网络插件实现Pod间通信。您指定的--pod-network-cidr=10.244.0.0/16兼容Flannel,我将使用Flannel部署。
1. Flannel插件简介
Flannel是一个简单Overlay网络方案,为每个Pod分配唯一IP。它使用VXLAN或host-gw模式,确保跨节点Pod通信。CIDR10.244.0.0/16是Flannel默认范围。
2. 安装Flannel
在Master节点执行:
# 下载Flannel配置文件 wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml # 应用配置 kubectl apply -f kube-flannel.yml输出:
podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created ... daemonset.apps/kube-flannel-ds created3. 验证网络插件
检查Pod状态:
kubectl get pods -n kube-system # 输出应包含kube-flannel-ds-* Pods,状态为Running NAME READY STATUS RESTARTS AGE kube-flannel-ds-abcde 1/1 Running 0 1m ... # 检查节点状态(应变为Ready) kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 15m v1.28.15 k8s-node1 Ready <none> 6m v1.28.15 k8s-node2 Ready <none> 6m v1.28.154. 网络测试
部署测试应用验证网络:
# 创建测试Deployment kubectl create deployment nginx-test --image=nginx:alpine --replicas=2 # 暴露Service kubectl expose deployment nginx-test --port=80 --type=NodePort # 获取Service信息 kubectl get svc nginx-test # 输出示例 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-test NodePort 10.96.123.45 <none> 80:30001/TCP 1m # 测试访问(在任意节点curl) curl http://10.96.123.45 # 应返回Nginx欢迎页5. 常见问题解决
- Pod卡在Pending:检查网络插件日志
kubectl logs -n kube-system kube-flannel-ds-abcde。 - IP冲突:确保
--pod-network-cidr不与现有网络重叠。
网络插件安装完成!集群已就绪。
第六部分:集群验证与基本操作
部署后,需全面验证集群功能。
1. 核心组件检查
在Master节点运行:
# 检查Master组件状态 kubectl get pods -n kube-system # 输出应包含:etcd-k8s-master, kube-apiserver-k8s-master, kube-controller-manager-k8s-master, kube-scheduler-k8s-master,状态为Running # 检查kubelet日志(所有节点) journalctl -u kubelet -f # 无错误日志2. 部署示例应用
部署一个简单应用测试调度:
cat <<EOF > nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:alpine ports: - containerPort: 80 EOF # 应用配置 kubectl apply -f nginx-deployment.yaml # 查看Pod分布(应均匀在Worker节点) kubectl get pods -o wide3. 集群管理命令
- 查看节点资源:
kubectl top nodes - 查看事件:
kubectl get events - 备份etcd(重要!):
# 在Master节点 docker run --rm -v /etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd -v /backup:/backup registry.aliyuncs.com/google_containers/etcd:3.5.9 etcdctl snapshot save /backup/etcd-snapshot.db
4. 常见问题排查
- 节点NotReady:检查网络插件或kubelet日志。
- Service无法访问:验证kube-proxy和网络策略。
- 资源不足:使用
kubectl describe node查看资源分配。
集群已验证可用,但单Master架构适合测试环境。