k8s核心资源对象一(入门到精通)

发布于:2025-04-10 ⋅ 阅读:(33) ⋅ 点赞:(0)

        本文将深入探讨Kubernetes中的核心资源对象,包括Pod、Deployment、Service、Ingress、ConfigMap和Secret,详细解析其概念、功能以及实际应用场景,帮助读者全面掌握这些关键组件的使用方法。

一、pod

1 pod概念

       k8s最小调度单元,可以包含一个或多个容器。同一个pod的容器可以共享网络和存储。

2 pod示例

[root@master-1 pod]# cat 02-pods-nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: linux86-web
spec:
  containers:
  - name: web
    image: nginx:1.24.0-alpine
    ports:
    - containerPort: 80
[root@master-1 pod]# kubectl apply -f 02-pods-nginx.yaml
[root@master-1 pod]# kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
linux86-web   1/1     Running   0          82s   10.100.2.4   worker233   <none>           <none>
[root@master-1 pod]# curl -I  10.100.2.4

二、deployment

1 介绍

Deployment是用于部署服务的资源,是最常用的控制器

  • 管理RS,通过RS资源创建Pod;
  • 具有上线部署,副本设置,滚动升级,回滚等功能;
  • 提供声明式更新,即可以使用apply命令进行更新镜像版本之类的;

2 更新策略

蓝绿发布:不停止旧版本,直接部署新版本,新版本测试没有问题,就切换到新版本。
       优点:无需停机,风险较小
       缺点:切换是全量的,如果新版本有问题,则对用户体验有直接影响,需要双倍机器资源
灰度发布:旧版本和新版本共存
    将新版本部署到一部分生产环境,让一部分用户先试用,如果没有问题,再逐步扩大范围,把全部服务都切换到新环境。
        优点:用户体验影响小,灰度发布过程出现问题只影响部分用户
滚动更新:平滑地将服务更新

3  Deployment滚动发布

[root@master231 deployments]# cat 02-deploy-nginx-strategy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx-strategy
spec:
  # 定义升级策略
  strategy:
    # 指定升级类型,有效值为Recreate和RollingUpdate.
    #    Recreate:
    #       先删除所有旧的Pod,再创建新的Pod。
    #    RollingUpdate:
    #       先删除部分旧的Pod,滚动更新旧的Pod,逐步使用新的Pod替代旧的Pod。
    #       默认就是基于滚动更新类型。
    # type: Recreate
    type: RollingUpdate
    # 滚动更新
    rollingUpdate:
      # 在升级过程中,在原有旧的Pod基础之上启动的Pod数量。
      maxSurge: 2
      # 在升级过程中,指定最大不可用的数量。
      maxUnavailable: 1
      #maxSurge: "20%"
      #maxUnavailable: "10%"
  replicas: 5
  selector:
    matchExpressions:
    - key: apps
      values: 
      - "v1"
      - "v2"
      operator: In
  template:
    metadata:
      labels:
        apps: v1
        school: liux
    spec:
      containers:
      - name: v1
        # image: harbor.liux.com/liux-apps/apps:v1
        image: harbor.liux.com/liux-apps/apps:v2
        imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: deploy-strategy
spec:
  type: NodePort
  selector:
    apps: v1
    school: liux
  ports:
  - port: 8888
    targetPort: 80
    nodePort: 30000
[root@master231 deployments]# 
升级过程
-------------> 第一波
旧的pod: 4
新的pod: 3 

-------------> 第二波
旧的pod: 1
新的新的: 3  + 2

[root@master231 deployments]# kubectl apply -f 02-deploy-nginx-strategy.yaml 
deployment.apps/deploy-nginx configured
service/deploy-strategy unchanged
[root@master231 deployments]# kubectl get po,svc -o wide
#切换版本
[root@master231 deployments]# vim 02-deploy-nginx-strategy.yaml 
   #image: harbor.liux.com/liux-apps/apps:v1
   image: harbor.liux.com/liux-apps/apps:v2

4.Deloyment蓝绿发布

4.1 部署蓝环境

[root@master231 blue-green]# cat 01-blue.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: liux-blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: blue
  template:
    metadata:
      labels:
        app: blue
    spec:
      containers:
      - name: v1
        image: harbor.liux.com/liux-apps/apps:v1

---

kind: Service
apiVersion: v1
metadata:
  name: liux-app-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  selector:
    app: blue
[root@master231 blue-green]# 
[root@master231 blue-green]#  kubectl apply -f 01-blue.yaml 
deployment.apps/liux-blue created
service/liux-app-svc created
[root@master231 blue-green]#
#测试访问
[root@master231 blue-green]# while true ; do sleep 0.5;curl 10.0.0.233:30080; done

4.2 部署绿环境

[root@master231 blue-green]# cat 02-green.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: liux-green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: green
  template:
    metadata:
      labels:
        app: green
    spec:
      containers:
      - name: myweb
        image: harbor.liux.com/liux-apps/apps:v2
[root@master231 blue-green]# 
[root@master231 blue-green]#  kubectl apply -f 02-green.yaml 
deployment.apps/liux-green created

4.4 切换svc的标签

[root@master231 blue-green]# cat 03-switch-svc-selector.yaml 
kind: Service
apiVersion: v1
metadata:
  name: liux-app-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  selector:
    # app: blue
    app: green
[root@master231 blue-green]# 
[root@master231 blue-green]# kubectl apply -f 03-switch-svc-selector.yaml 
service/liux-app-svc configured

5.Deployment灰度发布

5.1 部署旧版本

 先将副本数设置为3,随着新版本的创建,将副本逐渐调低到0

[root@master231 canary-huidu]# cat 01-old.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: liux-old
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: myweb
        image: harbor.liux.com/liux-apps/apps:v1
---
kind: Service
apiVersion: v1
metadata:
  name: liux-web-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  selector:
    app: web
[root@master231 canary-huidu]# 
[root@master231 canary-huidu]# kubectl apply -f 01-old.yaml 
deployment.apps/liux-old created
service/liux-web-svc created

5.2 部署新版本

  先将副本数设置为1,随着新版本的稳定,将副本逐渐调高到3

[root@master231 canary-huidu]# cat 02-new.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: liux-new
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: myweb
        image: harbor.liux.com/liux-apps/apps:v2
[root@master231 canary-huidu]# 
[root@master231 canary-huidu]# 
[root@master231 canary-huidu]# kubectl apply -f 02-new.yaml 
deployment.apps/liux-new created

5.3 修改副本数量以及测试结果

  将旧的副本数量手动修改从3-0,与此同时,将新的副本数量从1-3

[root@master231 canary-huidu]# kubectl edit deploy liux-old 
deployment.apps/liux-old edited
[root@master231 canary-huidu]# kubectl edit deploy liux-new
deployment.apps/liux-new edited

#测试访问
[root@master231 ~]# while true ; do sleep 0.5;curl  10.0.0.233:30080; done

三、service

1.概述

        service 用于服务发现和负载均衡。基于labels标签关联后端pod列表,以实现后端节点得动态发现,从而管理endpoints资源;负载均衡,底层借助于kube-proxy组件实现,基于iptables或者ipvs将用户请求转发给不同的Pod以均衡流量。

       Service配置Selector标签, Endpoints Controller(controller manager)会自动创建对应的endpoint对象,否则.不会生成endpoint对象。

2.service类型

  • ClusterIP(默认):集群内部访问,自动分配一个仅 Cluster 内部可以访问的虚拟 IP;
  • NodePort:通过节点IP和端口暴露服务,在ClusterIP基础上为service在所有worker节点绑定一个端口,通过nodeport端口来访问服务;
  • LoadBalancer:集成云厂商的负载均衡器(如AWS ELB);
  • ExternalName:映射到外部DNS。用于将K8S集群外部的服务映射至K8S集群内部访问,让集群内部的Pod能够通过固定的service名称访问集群外部的服务。

3.service示例

[root@master-1 nfs]# vim  nginx-demo.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
spec:
  # 指定svc的类型为NodePort,也就是在默认的ClusterIP基础之上多监听所有worker节点的端口而已。
  type: NodePort
  # 配置端口映射
  ports:
  - nodePort: 30698
    # 指定Service服务本身的端口号
    port: 88
    protocol: TCP
    # 后端Pod提供服务的端口号
    targetPort: 80
  # 基于标签选择器关联Pod
  selector:
    app: nginx-demo

[root@master-1 nfs]# kubectl  apply -f nginx-demo.yaml
[root@master-1 nfs]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP        16d
nginx-demo   NodePort    10.0.0.187   <none>        88:30698/TCP   2d
[root@master-1 nfs]#  kubectl get endpoints
NAME             ENDPOINTS                                                  AGE
nginx-demo       172.17.1.3:80,172.17.77.11:80                              2d1h

[root@master-1 nfs]# kubectl describe svc nginx-demo
Name:                     nginx-demo
Namespace:                default
Labels:                   app=nginx-demo
Annotations:              <none>
Selector:                 app=nginx-demo
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.0.0.187
IPs:                      10.0.0.187
Port:                     <unset>  88/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30698/TCP
Endpoints:                172.17.1.3:80,172.17.77.11:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

#访问
http://192.168.91.22:30698

4.endpoints

       Endpoint是Kubernetes集群中的一个资源对象,存储在etcd中,用来记录一个Service对应的所有pod的访问地址.

       Service配置Selector, 创建service时Endpoints Controller(controller manager)会自动创建对应的endpoint对象,否则.不会生成endpoint对象.

#查看endpoints
[root@master-1 nfs]#  kubectl get endpoints
NAME             ENDPOINTS                                                  AGE
fuseim.pri-ifs   <none>                                                     13d
kubernetes       192.168.91.18:6443,192.168.91.19:6443,192.168.91.20:6443   16d
nginx-demo       172.17.1.3:80,172.17.77.11:80                              2d1h
#查看etcd数据
[root@master-1 nfs]#  export ETCDCTL_API=3
[root@master-1 nfs]# export ETCD_ENDPOINTS=http://192.168.91.19:2390
[root@master-1 nfs]# etcdctl --endpoints=${ETCD_ENDPOINTS} get / --prefix --keys-only | grep 'endpoints/default/nginx-demo'
/registry/services/endpoints/default/nginx-demo


四、Ingress

1.概念

          Ingress是k8s中管理外部流量的核心组件,通过灵活的路由规则和丰富的控制器生态满足多样化需求。

        k8s使用ingress和ingress controller两者结合实现了完整的ingress负载均衡器。 负载分发时,ingress controller基于ingress规则将请求转发到service对应的endpoint上,用于将不同URL的访问请求转发到后端不同的service,以实现http层的业务路由机制。

        全过程:ingress controller-->ingress规则-->services-->endpoints(pod)

2.示例 编写ingress规则

访问nginx.liux.com,将会代理到svc中名称nginx.liux.com端口88上去
[root@master-1 ingress]# cat nginx-route-https.yaml 
#注意命名空间 namespace与要代理的服务需要在同一个名称空间
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: nginx-route
  namespace: kube-system
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`nginx.liux.com`)
      kind: Rule
      services:
        - name: nginx-demo
          port: 88

3.Ingress与service的区别

       在 K8s 中,Ingress 和 Service 都是用于管理网络流量的核心组件,但它们的职责和使用场景有显著区别。

  • Service 是基础网络抽象,确保 Pod 的可访问性。
  • Ingress 是高级流量网关,专注于 HTTP 路由和集中管理。
  • 两者通常结合使用:Ingress 处理外部请求的路由,Service 负责内部流量的分发。

特性 Service Ingress
层级 L4(TCP/UDP) L7(HTTP/HTTPS
核心功能 服务发现、基础负载均衡 高级路由、SSL 终止、流量管理
外部暴露方式 NodePort、LoadBalancer 通过 Ingress Controller + 规则
路由规则 仅 IP/端口 域名、路径、请求头等
资源成本 每个 LoadBalancer 独立实例 单一入口点管理多个服务
依赖组件 无需额外组件

需要 Ingress Controller

示例:一个 Web 应用服务包含frontend-service(前端)和backend-service(后端 API),可进行如下配置:

配置方式:

  • Service:为 frontend-service 和 backend-service 创建 ClusterIP 类型的 Service,供集群内访问。
  • Ingress:定义规则将 www.example.com/ 路由到 frontend-service,将 www.example.com/api 路由到 backend-service,并启用 HTTPS。

       这样外部用户通过统一的域名访问,而 Ingress 根据路径将请求分发到不同的 Service,再由 Service 负载均衡到具体的 Pod。

五. ConfigMap 和 Secret

       ConfigMap 和 Secret 都是用于管理应用配置的核心资源,但它们的用途和安全性有显著区别。

1. ConfigMap

作用:

  • 存储 非敏感 的配置数据(如环境变量、配置文件、命令行参数等
  • 将配置与容器镜像解耦,便于应用配置的灵活管理

数据格式:

  • 数据以 明文 形式存储(如键值对、JSON、YAML 或纯文本文件)

典型场景:

  • 存储应用的配置文件(如 nginx.conf、application.properties)。
  • 定义环境变量(如 LOG_LEVEL=debug)。
  • 共享配置给多个 Pod 或多个容器。

安全性:

  • 不加密,数据对集群内用户可见,不适合存储敏感信息。

使用方式:

  • 通过环境变量注入容器。
  • 挂载为卷(Volume)到 Pod 的文件系统中。

示例:

#编写cm资源
[root@master231 cm]#  cat 02-cm-games.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf
# 指定cm的数据
data:
  games.conf: |
      server {
          listen        0.0.0.0:99;
          root          /usr/local/nginx/html/bird/;
          server_name   game01.liux.com;
      }


#编写pod资源清单(在此引用cm资源)
[root@master231 pod]# vim 16-pods-volumes-configMap-games.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liux-games-cm-008
spec:
  nodeName: worker233
  # hostNetwork: true
  volumes:
  - name: data01
    # 指定存储卷类型是configMap
    configMap:
     # 指定configMap的名称
      name: nginx-conf
      # 引用configMap中的某个key,若不指定,则引用configMap资源的所有key。
      #items:
        # 指定configMap的key
      #- key: student.info
        # 暂时理解为在容器挂载点的文件名称。
        #path: banzhan.info
  containers:
  - name: games
    image: harbor.liux.com/liux-games/games:v0.5
    volumeMounts:
    - name: data01
      #mountPath: /liux-linux86
      mountPath: /etc/nginx/conf.d/
      

2.Secret

作用:

  • 存储 敏感信息(如密码、API 密钥、TLS 证书、SSH 密钥等)。
  • 提供一定程度的安全保护(非完全加密,需结合其他机制增强安全性)。

数据格式:

  • 数据以 Base64 编码 形式存储(非加密,仅防意外泄露)。
  • 支持 stringData 字段直接写入明文(自动转换为 Base64)。

典型场景:

  • 存储数据库密码(如 mysql-password)。
  • 存储 TLS 证书(如 tls.crt 和 tls.key)。
  • 容器镜像仓库的认证信息(如 Docker harbor 凭据)。

安全性:

  • Base64 编码仅防止明文暴露,仍需配合以下措施
  • 启用 Kubernetes 的 Secret 加密机制(如使用 KMS、Vault)。
  • 限制集群内 RBAC 权限(避免未授权访问)。

使用方式:

  • 通过环境变量注入容器(不推荐,可能被日志记录)。
  • 挂载为卷到 Pod 的文件系统中(更安全)。

示例一创建:

#1.声明式创建
[root@master231 secrets]# echo admin |base64
YWRtaW4K
[root@master231 secrets]# echo 12366 |base64
MTIzNjYK
[root@master231 secrets]# vim 01-secret-userinfo.yaml 

apiVersion: v1
kind: Secret
metadata:
  name: my-secrets-01
data:
  # 对于Secret的值进行base64编码,当Pod的容器使用secret时会自动对数据进行解码
  username: YWRtaW4K
  password: MTIzNjYK
[root@master231 secrets]# kubectl apply -f 01-secret-userinfo.yaml 
secret/my-secrets-01 created
[root@master231 secrets]# kubectl get secrets
NAME                                 TYPE                                  DATA   AGE
my-secrets-01                        Opaque                                2      82s

#2. 响应式创建
 # - 基于命令行key=value的方式创建
[root@master231 secrets]# kubectl create secret generic my-secrets-02 --from-literal=username='admin' --from-literal=password='12366'
 # - 基于命令行读取文件的方式创建
[root@master231 secrets]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q
[root@master231 secrets]# kubectl create secret generic my-secrets-03 --from-file=ssh-privatekey=/root/.ssh/id_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub 

#响应式创建harbor的认证信息
[root@master231 secrets]#  kubectl create secret docker-registry liux-harbor --docker-username=admin --docker-password=12366 --docker-email=admin@liux.com --docker-server=harbor.liux.com

示例二引用:

#3.在pod中引用  基于存储卷、环境变量的方式挂载
 [root@master231 pod]# cat 31-pods-secrets-env-volumes.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: linux86-web-secrets-env-cm-001
spec:
  volumes:
  - name: data01
    # 指定存储卷类型为secret
    secret:
      # 指定secret的名称
      secretName: my-secrets-01
  - name: data02
    secret:
      secretName: my-secrets-01
      items:
      - key: username
        path: username.info
      - key: password
        path: password.txt
  containers:
  - name: web
    image: harbor.liux.com/liux-web/nginx:1.25.1-alpine
    #基于存储卷的方式挂载
    volumeMounts:
    - name: data01
      mountPath: /liux-linux86-secrets
    - name: data02
      mountPath: /liux-linux86-secrets-2
    #基于环境变量的方式挂载
    env:
    - name: liux_USERNAME
      valueFrom:
        # 值引用自某个secret
        secretKeyRef:
          # 指定secret的名称
          name: my-secrets-01
          # 指定引用secret对应的key
          key: username
    - name: liux_SSH_PRIVATEKEY
      valueFrom:
        secretKeyRef:
          name: my-secrets-03
          key: ssh-privatekey
[root@master231 pod]# 
[root@master231 pod]# kubectl apply -f 31-pods-secrets-env-volumes.yaml 
pod/linux86-web-secrets-env-cm-001 created
[root@master231 pod]# kubectl get pods
NAME                               READY   STATUS        RESTARTS      AGE
linux86-web-secrets-env-cm-001     1/1     Running       0             8s
[root@master231 pod]# kubectl exec -it linux86-web-secrets-env-cm-001 -- env

#在pod中引用harbor登录信息 注意,请确保你创建的用户必须在harbor中对相应的项目有访问权限!
[root@master231 pod]# cat 32-pods-harbor-secrets.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: linux86-secrets-harbor-001
spec:
  # 指定harbor的secret认证信息,可以指定多个。
  imagePullSecrets:
  - name: harbor-liuxing
 # - name: liux-harbor
  containers:
  - name: web
    image: harbor.liux.com/liux-apps/apps:v1
     # 指定镜像的拉取策略,若不指定,当tag为latest时,默认是Always,当tag非latest时,则默认策略为IfNotPresent
    imagePullPolicy: Always
    # imagePullPolicy: IfNotPresent

3.总结

特性 ConfigMap Secret
数据类型 非敏感配置(明文) 敏感信息(Base64 编码)
安全性 无加密,明文存储 Base64 编码(非加密),需额外安全措施
典型用途 配置文件、环境变量、命令行参数 密码、密钥、证书
存储限制 无大小限制 每个 Secret 最大 1MiB
更新与热加载 支持更新,挂载为卷时可自动同步 同 ConfigMap,但需注意敏感数据更新策略


网站公告

今日签到

点亮在社区的每一天
去签到