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节点,基于资源需求和约束。
  • 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。
  • 软件版本:您指定的版本(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
    

验证:运行hostnameping 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.15
4. 常见问题解决
  • 镜像拉取失败:如果卡在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.15
4. 常见问题解决
  • 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通信。CIDR 10.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 created
3. 验证网络插件

检查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.15
4. 网络测试

部署测试应用验证网络:

# 创建测试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 wide
3. 集群管理命令
  • 查看节点资源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架构适合测试环境。

更多推荐