Kubernetes安装以及yaml文件编写部署(v1.30)

简介


Kubernetes 简称 k8s。是用于自动部署,扩展和管理容器化应用程序的开源系统。
中文官网:https://kubernetes.io/zh/ 
中文社区:https://www.kubernetes.org.cn/
官方文档:https://kubernetes.io/zh/docs/home/
社区文档:http://docs.kubernetes.org.cn/


 

Kubernetes核心组件

分类

组件名称

核心作用

关键功能/备注

控制平面
(Master节点)

kube-apiserver

集群网关

所有内外通信的唯一入口,负责认证、鉴权、API 注册与发现。

etcd

数据存储

分布式数据库,存储集群的所有状态数据(Pod、Service、配置等)

kube-scheduler

调度器

监控新创建的 Pod,根据资源需求、亲和性规则等算法,决策将其调度到哪个具体的 Node 节点上运行。

kube-controller-manager

状态维护

运行多种控制器(如Deployment、Node控制器),通过循环监控确保集群当前状态期望状态一致(例如维持Pod副本数)。

网络组件

calico-node

节点网络

负责为每个Pod分配IP,维护节点间的路由规则,实现跨节点Pod通信。

calico-kube-controllers

网络策略控制

监听K8s API,根据NetworkPolicy资源动态配置Calico底层的防火墙规则(ACL)。

coredns

DNS服务

集群内部的DNS服务器,为Service和Pod提供域名解析服务(服务发现),允许通过服务名互相访问。

kube-proxy

流量转发

运行在每个节点上,维护网络规则(iptables/IPVS),负责将Service的虚拟IP流量转发到后端Pod,实现负载均衡。

节点代理

kubelet

节点管家

节点必备,负责Pod生命周期管理,接收API Server指令,通过CRI接口管理容器运行时(如Containerd),上报节点状态。

系统资源要求

节点类型

数量

最低配置

备注

系统

控制平面(Master)

1

2 vCPU / 2GB(生产建议 4 vCPU / 8GB)

运行 API Server、etcd、Scheduler、Controller Manager

Kylin v10 sp3

工作节点(Worker)

1

2 vCPU / 2GB

运行业务 Pod

Centos 7.6

系统初始化配置

加载内核模块和网络参数

所有主机均执行:

# 为了让底层支持流量转发
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.ipv4.tcp_tw_recycle = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
 
cat > /etc/modules-load.d/k8s.conf << EOF
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

 
sysctl --system    



关闭防火墙及swap分区

systemctl stop firewalld && systemctl disable  firewalld
 
setenforce 0
sed -i s/SELINUX=enforcing/SELINUX=disabled/ /etc/selinux/config
 
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab

配置hosts解析

cat >> /etc/hosts << EOF
192.168.1.128 k8s-master
192.168.1.100 k8s-worker
EOF

安装containerd


containerd版本建议1.6以上,版本太低初始化会报错:相关插件加载失败

curl -LO https://mirrors.huaweicloud.com/docker-ce/linux/centos/7/x86_64/stable/Packages/containerd.io-1.6.21-3.1.el7.x86_64.rpm

rpm -ivh containerd.io-1.6.21-3.1.el7.x86_64.rpm --nodeps

cp /usr/bin/containerd /usr/local/bin/

或者yum -y install containerd

systemctl restart containerd
systemctl enable --now containerd




# 如果containerd启动失败是因为配置的插件或者是格式等等问题,可以先清空然后重置在修改
systemctl stop containerd
rm -rf /etc/containerd/config.toml   # 删除旧配置
rm -rf /var/lib/containerd/*        # 清空数据目录
containerd config default | sudo tee /etc/containerd/config.toml    #初始化生成文件
systemctl restart containerd
# 版本1.60以上就行
containerd --version

修改containerd配置文件,添加国内镜像源和开启systemd cgroup

/etc/containerd/config.toml

version = 2

root = "/var/lib/containerd"
state = "/run/containerd"

[grpc]
  address = "/run/containerd/containerd.sock"
  max_recv_message_size = 16777216
  max_send_message_size = 16777216

[debug]
  level = ""

[metrics]
  address = ""

[cgroup]
  path = ""

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    # 配置国内源pause镜像,避免拉取失败
    sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
    stream_server_address = "127.0.0.1"
    stream_server_port = "0"
    stream_idle_timeout = "4h0m0s"

    [plugins."io.containerd.grpc.v1.cri".cni]
      bin_dir = "/opt/cni/bin"
      conf_dir = "/etc/cni/net.d"
      max_conf_num = 1

    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "runc"
      snapshotter = "overlayfs"

      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          runtime_type = "io.containerd.runc.v2"
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            # 关键:开启systemd cgroup,和K8s kubelet保持一致
            SystemdCgroup = true

    # 国内镜像加速配置(避免Calico拉取失败)
    [plugins."io.containerd.grpc.v1.cri".registry]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
          endpoint = [
            "https://docker.mirrors.ustc.edu.cn",
            "https://registry.cn-hangzhou.aliyuncs.com",
            "https://hub-mirror.c.163.com",
            "https://docker.m.daocloud.io",
            "https://huecker.io",
            "https://dockerhub.timeweb.cloud"
          ]
        # K8s官方镜像加速(CoreDNS等组件用)
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
          endpoint = [
            "https://registry.cn-hangzhou.aliyuncs.com/google_containers"
          ]

  [plugins."io.containerd.internal.v1.opt"]
    path = "/opt/containerd"

  [plugins."io.containerd.metadata.v1.bolt"]
    content_shard_size = 2097152

  [plugins."io.containerd.snapshotter.v1.overlayfs"]
    slow_chattr = true

[timeouts]
  "io.containerd.timeout.shim.cleanup" = "5s"
  "io.containerd.timeout.shim.load" = "5s"
  "io.containerd.timeout.task.state" = "2s"

container服务正常启动,info输出无报错基本就没问题

crictl pull docker.io/calico/node:v3.29.4

下载镜像返回Image is up to date for。。。就说明镜像下载也没问题

安装kubelet

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
EOF

yum install -y kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0
systemctl enable --now kubelet

初始化k8s

master执行

Kubeadm init   --apiserver-advertise-address=192.168.1.128   --pod-network-cidr=10.244.0.0/16   --image-repository=registry.aliyuncs.com/google_containers   --kubernetes-version=v1.30.0


# --pod-network-cidr=10.244.0.0/16 指定pod网络
# --image-repository=registry.aliyuncs.com/google_containers 指定阿里云镜像



# 如果初始化失败,可以在修复后执行以下命令清空数据重新执行init初始化
kubeadm reset -f
rm -rf /etc/kubernetes/manifests/*
rm -rf /etc/cni/net.d/*
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

初始化成功会提示如下

提示创建配置文件并使用命令加入到集群

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

worker节点

按照提示加入集群

kubeadm join 192.168.1.128:6443 --token ug4jqv.u7h3xj0k1cn4it2a --discovery-token-ca-cert-hash sha256:7dc37aad305c03516c0d322789f685ccc90e765583faae1c9b4cb3462fbd918d 
  986  systemctl status kublet

部署网络插件calico

企业一般都选择的是calico

Calico

Flannel

核心定位

企业级网络 + 安全方案

轻量级 Pod 网络连通方案

默认转发模式

BGP(无封装,最优)/ IPIP / VXLAN / eBPF

VXLAN(Overlay 封装)/ host-gw

网络性能

 BGP 模式无封装,接近物理网络性能

 VXLAN 有约 50 字节包头开销,延迟增加 10-30%

NetworkPolicy 支持

原生完整支持,还可扩展 GlobalNetworkPolicy、HostEndpoint

不支持,写了策略也不生效,需搭配其他组件

跨子网/跨网段

BGP/IPIP/VXLAN 多模式适应

host-gw 要求同子网;跨子网只能用 VXLAN

大规模集群扩展性

 设计支持万级节点,BGP 路由收敛高效;eBPF 模式消除 iptables O(n) 瓶颈

节点 > 100、Service > 2000 时 iptables 规则线性增长成为瓶颈

资源占用

 较高,单节点约 50-100MB 内存

 极低,单节点约 10-20MB 内存

创建命名空间安装calico

kubectl create namespace calico-system
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.4/manifests/calico.yaml

查看节点全部是Ready状态

核心组件全部是Running'状态

部署集群的时候除了Running以外,会常见以下几种pod状态:

ImagePullBackOff:下载镜像失败,检查网络以及containerd的镜像源、服务等,执行以下命令确保镜像可以正常下载

crictl pull docker.io/calico/node:v3.29.4

ContainerCreating:Pod 已调度到节点,正在创建容器(拉镜像、挂载卷等),如果时间太长了就得看下详情的Events

kubectl describe pod -nkube-system <pod_name>

init:0/1:初始化过程,可能是在等pasue容器,也可能是初始化数据,时间长了也得看

kubectl logs -f pod -nkube-system <pod_name>

部署应用

mysql-pv.yaml

mysql的存储定义,企业存储是NFS、glusterfs等,这里为了方便用的是本地磁盘

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-local-pv  # PV 的名称
spec:
  capacity:
    storage: 5Gi  # 申请的磁盘大小
  accessModes:
  - ReadWriteOnce  # MySQL 只能单节点读写
  persistentVolumeReclaimPolicy: Retain  # 删除 PVC 后保留数据
  storageClassName: local-storage-mysql  # 定义一个StorageClass名称,供 PVC 引用
  local:
    path: /data/mysql-pv  # 宿主机本地目录
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-worker  # 节点名称,kubectl get nodes 查看


 

kubectl apply -f mysql-pv.yaml

kubectl get pv

mysql-secret.yaml

存储敏感信息

apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
type: Opaque
data:
  # 可选:创建一个普通用户
  mysql-user: root
  # echo -n "123456"|base64
  mysql-password: MTIzNDU2
kubectl apply -f mysql-secret.yaml

kubectl get secret

mysql-service.yaml

服务发现映射

映射NodePort端口默认范围是30000-32767,如需修改,需要修改api-server的启动参数

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  labels:
    app: mysql
spec:
  type: NodePort   #定义nodeport类型
  selector:
    app: mysql
  ports:
  - name: mysql
    port: 3306
    targetPort: 3306   # 容器端口
    nodePort: 30036    # 宿主机端口
kubectl apply -f mysql-service.yaml

kubectl get svc -A | grep mysql

mysql-configmap

配置文件资源

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  my.cnf: |
    [mysqld]
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    max_connections=500
    slow_query_log=1
    slow_query_log_file=/var/lib/mysql/slow.log
    long_query_time=2
    innodb_buffer_pool_size=1G
    skip-name-resolve
kubectl apply -f mysql-configmap.yaml

kubectl get configmap | grep mysql

mysql-statefulset.yaml

控制器

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql" 
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 60  # 等待MySQL关机时间
      containers:
      - name: mysql
        image: mysql:5.7.44 
        imagePullPolicy: IfNotPresent
        args:
        - "--default-authentication-plugin=mysql_native_password"
        - "--lower_case_table_names=1"  # 忽略表名大小写
        ports:
        - containerPort: 3306
          name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: mysql-password
        # 可选:初始化数据库
        # - name: MYSQL_DATABASE
        #   value: appdb
        resources:
          requests:
            cpu: 100m
            memory: 512Mi
          limits:
            cpu: "1"
            memory: 1Gi
        # 存货和就绪探针
        livenessProbe:
          exec:
            command: ["mysqladmin", "ping", "-h", "localhost", "-uroot", "-p"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command: ["mysqladmin", "ping", "-h", "localhost", "-uroot", "-p"]
          initialDelaySeconds: 5
          periodSeconds: 10
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql  # MySQL 数据目录
        - name: mysql-conf
          mountPath: /etc/mysql/conf.d  # 配置文件目录
      volumes:
      - name: mysql-conf
        configMap:
          name: mysql-config  # 引用创建的 ConfigMap名字
  volumeClaimTemplates:  # 自动创建 PVC 的模板
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: local-storage-mysql  # 必须与PV定义的storageClassName一致
      resources:
        requests:
          storage: 5Gi

kubectl apply -f mysql-statefulset.yaml

查看deceribe发现报错:

绑定的worker节点没有这个目录,忘了创建了,手动去对应机器创建

mkdir -p /data/mysql-pv

chmod -R 755 /data/mysql-pv

删除pod重启,因为控制器副本的原因(replicas)所以删除后会自动拉起新的服务,相当于重启

kubectl delete pod -ndefault mysql-0

再次查看正在下载镜像

查看pod已完成

进入mysql查看

查看配置文件,确认configmap挂载成功

测试nodeport不通

排查思路:

那说明问题出现在网络这层,主要看service,endpoints,kube-proxy

查看svc正常

查看endpoints不正常,没有显示IP,说明没找到后端服务

查看svc的标签和pod的标签,标签不匹配直接导致了 Service 无法将流量转发至 Pod

kubectl describe svc mysql-service
kubectl get pod mysql-0 -o yaml | grep -A 5 "labels"

解决:

编辑service.yaml,修改Selector为app: mysql

然后重建svc

kubectl delete svc mysql-service
kubectl apply -f mysql-service.yaml 
kubectl get endpoints

显示了后端IP

再次访问nodeport测试成功

创建数据测试

外部连接数据库可以查看到数据

------------------------至此,整个流程从创建到编写yaml部署就基本完成了-----------------------------

追加

pod的各种状态

kubectl get pods 时可以看到Pod 整体生命周期阶段,状态如下:

状态

含义

典型原因

处理方向

Pending

Pod 已被 API Server 接收,但还未调度到节点或容器镜像未拉取完

资源不足、节点有污点、PVC 未绑定、镜像拉取中

describe 看 Events 中的调度失败原因

ContainerCreating

Pod 已调度到节点,正在创建容器(拉镜像、挂载卷等)

正在拉镜像、等待 PV 挂载、CNI 分配 IP 中

一般短暂出现,长时间停留则 describe 查 Events

Running

Pod 已绑定到节点,所有容器已创建,至少一个容器在运行

正常工作状态

配合 READY 列看是否就绪

Succeeded

所有容器正常退出(exit 0)且不再重启

Job/CronJob 执行完成

正常状态,无需处理

Failed

所有容器终止,且至少一个容器以非 0 状态退出

应用错误、OOM、配置错误

看日志和退出码

Unknown

API Server 无法获取 Pod 状态,通常是节点 kubelet 失联

节点 NotReady、kubelet 挂掉、网络分区

检查节点状态 kubectl get nodes

Terminating

Pod 正在被删除,处于终止过程中

执行了 delete、滚动更新、驱逐

一般 30 秒内消失,长时间停留说明优雅停机卡住

CrashLoopBackOff容器反复启动后崩溃,kubelet 退避重试应用配置错误、依赖服务不可用、exit code 非 0看日志
ImagePullBackOff拉取镜像失败,按指数退避重试镜像名/tag 错误、私有仓库无权限、网络不通检查镜像标签,检测网络

三大控制器的区别

为啥mysql要用statefulset,因为它需要固定的网络标识和独立的持久化存储。

Deployment

无状态应用

Web 服务、API、前端

滚动更新、回滚、声明式配置、扩缩容

StatefulSet

有状态应用

MySQL、Redis、Kafka、Zookeeper

稳定的网络标识(固定 Pod 名)、独立 PVC、有序扩缩容

DaemonSet

节点级守护进程

日志采集、监控 Agent、CNI 网络插件

每个节点(或匹配节点)运行且只运行一个 Pod

安装helm

wget https://get.helm.sh/helm-v3.15.3-linux-amd64.tar.gz

tar -zxvf helm-v3.15.3-linux-amd64.tar.gz

sudo mv linux-amd64/helm /usr/local/bin/helm

helm list -A  #查看列表

helm install <业务名> <资源名/目录名>   #以当前目录资源安装

helm uninstall <业务名>   # 卸载

helm template <业务名>    # 模板渲染,检查语法

helm create <资源名/目录名>  # 创建资源

创建nginx资源

helm create nginx

values.yaml:环境变量定义

templates:存放各种资源模板

修改values.yaml,配置nodeport

编辑templates/service.yaml

添加这一行,走向values里定义的nodeport

helm install my-nginx nginx

测试nodeport正常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值