kubernetes简单使用之服务发现与配置管理

一、服务发现

1. Service:为 Pod 提供固定访问入口与负载均衡。

Service在Kubernetes中是一个核心抽象,简写为“svc”,用于定义Pod的逻辑集合及其访问策略。Pod不能直接提供给外网访问,需要通过Service实现k8s集群内部网络调用。Service实现了Pod的抽象和访问控制,使得应用服务更加灵活和可靠,通过Service可以方便地管理和访问集群中的Pod资源。它将Pod集合暴露出来,作为服务提供给外部访问。对外表现为一个统一的访问入口,请求会经过负载均衡机制,然后转发到后端具体的Pod容器。

2. Ingress:管理 HTTP/HTTPS 路由规则(需配合 Ingress Controller),用于将K8s内部服务安全地暴露给外部网络访问,通过反向代理和七层负载均衡技术,实现外部流量的高效分发。常用于Web应用的入口,提供稳定的访问入口和智能的流量调度能力。

Ingress 与 Service 在 Kubernetes 中虽然都用于服务暴露和流量管理,但定位和功能有本质区别,以下是核心差异的总结。

‌1、Service‌

‌1. 核心作用‌:实现 Pod 集群的内部服务发现与负载均衡,提供稳定的虚拟 IPClusterIP)和端口,屏蔽后端 Pod 的变动

‌2. 通信场景‌:

  • 集群内服务间通信(ClusterIP 类型)
  • 通过 NodePort/LoadBalancer 向外暴露基础服务(TCP/UDP 协议)。

‌2、Ingress‌

‌1. 核心作用‌:作为 ‌HTTP/HTTPS 流量的统一入口,提供基于域名、路径的路由规则,支持 SSL 终止、重定向等高级功能

‌2. 依赖组件‌:必须配合 Ingress Controller(如 Nginx、Traefik)实现实际流量转发。

‌特性‌

‌Service‌

‌Ingress‌

‌工作层级‌

传输层(TCP/UDP)

应用层(HTTP/HTTPS)

‌负载均衡‌

基于 IP + 端口的轮询

基于域名/URL 路径的智能路由

‌外部暴露能力‌

需 NodePort/LoadBalancer 类型支持

天然设计为外部流量入口

‌SSL 支持‌

不支持终止 HTTPS

支持 SSL 证书管理与终止

‌配置复杂度‌

简单(无额外依赖)

较高(需独立部署 Ingress Controller)

Service 是 Ingress 的‌基础设施‌:Ingress 规则最终将流量导向后端 Service,由 Service 完成最终到 Pod 的负载均衡。逻辑链:外部请求 → Ingress 按规则路由 → Service 负载均衡 → Pod‌

总结:

  • ‌Service = 内部通信管家‌:专注解决 Pod 间的稳定访问与基础负载均衡。
  • ‌Ingress = 外部流量指挥官‌:提供精细化 HTTP 路由与安全控制,依赖 Controller 实现。

两者协同工作,共同构建 Kubernetes 服务网络体系‌。

1、Service

1、创建Service

编写一个nginx-svc.yaml文件,用于创建Service对象。

apiVersion: v1  # Service api的版本
kind: Service  # 资源类型,此处是Service,即创建Service类型的对象
metadata:  # Service对象的元数据信息
  name: nginx-svc  # Service对象的名称
  labels:  # 标签配置,以key: value的形式给Service对象打标签
    app: nginx
spec:  # Service对象的期望状态
  selector:  # 标签选择器,用于匹配哪些Pod会被该Service对象代理
    app: nginx-deploy  # 匹配到这些标签的Pod都可以通过该Service进行访问
  ports:  # 定义端口配置
  - port: 80#Service对象的端口,集群内其他服务通过<service-name>.<namespace>:port访问
    targetPort: 80  # 目标Pod的实际端口,可以是数字或Pod中定义的端口名称
    name: web  # 为端口起个名字,当Pod暴露多个端口时特别有用
  type: NodePort  # 服务类型,默认为ClusterIP

服务类型NodePort表示随机启动一个端口(30000-32767),映射到ports中的端口,该端口是直接绑定在node上的,且集群中的每个node都会绑定这个端口。

服务类型

描述

典型使用场景

ClusterIP

默认类型,分配集群内IP

内部服务通信

NodePort

在ClusterIP基础上增加节点端口

开发测试环境

LoadBalancer

集成云厂商LB服务

生产环境公网暴露

ExternalName

返回CNAME记录

集成外部服务

Pod、Deployment 和 Service 的协作:

‌1. 使用Deployment 创建和管理 Pod‌:

  • Deployment 通过 ReplicaSet 确保指定数量的 Pod 副本运行。
  • 负责 Pod 的创建、更新、扩缩容和自愈。

‌2. Service 暴露 Pod‌:

  • Service 通过标签选择器(Label Selector)关联到 Pod。
  • 提供稳定的访问入口(ClusterIP/NodePort/LoadBalancer)。
  • 实现负载均衡,将请求分发到后端 Pod。

‌3. 协作流程示例‌:

# 1. 创建 Deployment

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:1.23
        ports:
        - containerPort: 80

# 2. 创建 Service

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

4. 工作流程‌:

  • 用户创建 Deployment。
  • Deployment 创建 ReplicaSet,ReplicaSet 创建 Pod。
  • Service 通过标签选择器发现并关联这些 Pod。
  • 外部请求到达 Service,Service 负载均衡到后端 Pod。

2、代理kubernetes外部服务

集群内部的服务如何访问集群外部的服务呢?可以通过Service反向代理集群外部服务来实现集群内部服务访问集群外部服务,常用的实现方式有以下两种。

实现方式一

1. 编写Service配置文件时,不指定selector属性(指定selector属性时会自动创建Endpoints)。

2. 自己手动编写yaml文件创建Endpoints。

编写一个nginx-svc-external.yaml文件,用于创建不带selector选择器的Service对象。

apiVersion: v1  # Service api的版本
kind: Service  # 资源类型,此处是Service,即创建Service类型的对象
metadata:  # Service对象的元数据信息
  name: nginx-svc- external  # Service对象的名称
  labels:  # 标签配置,以key: value的形式给Service对象打标签
    app: nginx
spec:  # Service对象的期望状态
  ports:  # 定义端口配置
  - port: 80#Service对象的端口,集群内其他服务通过<service-name>.<namespace>:port访问
    targetPort: 80  # 目标Pod的实际端口,可以是数字或Pod中定义的端口名称
    name: web  # 为端口起个名字,当Pod暴露多个端口时特别有用
  type: ClusterIP  # 服务类型,默认为ClusterIP

编写一个nginx-ep-external.yaml文件创建Endpoints对象。

apiVersion: v1
kind: Endpoints  # 资源类型,Endpoints表示端点资源,用于存储服务的实际IP地址和端口
metadata:  # Endpoints对象的元数据信息,包含对象的标签、名称和命名空间等
  labels:
    app: nginx  # 给Endpoints对象打标签,必须与Service保持一致
  name: nginx-svc-external  # Endpoints对象名称,必须与Service对象名称一致
  namespace: default  # 命名空间,必须与Service保持一致
subsets:  # 子网配置信息
- addresses:
    - ip: 120.78.159.117  # 目标IP地址,服务访问的实际集群外部地址
  ports:  # 端口配置,必须与Service保持一致
  - name: web        # 端口名称,用于标识服务访问的端口
    port: 80         # 端口号,服务监听的端口
    protocol: TCP    # 协议类型,TCP表示传输控制协议

使用kubectl apply(或create) -f nginx-ep-external.yaml命令创建Endpoints对象。

实现方式二

上面那种反向代理集群外部服务的方式需要在创建Endpoints的配置文件中写上外部服务的IP地址,下面这种方式是在Service配置文件中写上外部服务的域名,通过域名访问外部服务。

apiVersion: v1  # Kubernetes的API版本,v1表示核心组的核心版本
kind: Service    # 资源类型,这里表示定义一个Service资源
metadata:
  labels:
    app: wolfcode-external-domain  # 标签,用于标识该Service对象 
  name: wolfcode-external-domain  # Service对象的名称
spec:
  type: ExternalName  # Service的类型,ExternalName表示这是一个指向外部资源的Service
  externalName: www.wolfcode.cn  # 外部资源的名称,Service会将请求转发到这个域名

2、Ingress

参考:Ingress | Kubernetes (k8s中文文档)

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。Ingress 提供从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源所定义的规则来控制。

Ingress控制器负责完成 Ingress 的工作,具体实现上通常会使用某个负载均衡器,不过也可以配置边缘路由器或其他前端来帮助处理流量。必须拥有一个Ingress控制器(如 ingress-nginx)才能满足Ingress的要求,仅创建Ingress资源本身没有任何效果。

1Ingress控制器

在安装Ingress控制器(ingress-nginx)之前需要先安装Helm,Helm是kubernetes中的包管理器。

安装Helm的步骤:

1. 下载helm压缩包并解压,官网下载地址:https://github.com/helm/helm/releases

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

可以通过wget命令在线下载,或者打开官网地址手动下载之后上传到Linux服务器上。

2. 将解压后目录下的helm程序复制到/usr/local/bin/目录下,并通过helm version验证是否安装成功。

Helm安装成功之后,接下来安装ingress-nginx控制器。

1. 首先将ingress-nginx的官网URL添加到Helm仓库:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

2. 查看仓库列表,搜索ingress-nginx,并拉取ingress-nginx,得到一个压缩包

helm repo list
helm search repo ingress-nginx
helm pull ingress-nginx/ingress-nginx
mv ingress-nginx-4.4.2.tgz /opt/k8s/helm/
cd /opt/k8s/helm

3. 解压之后修改values.yaml文件

tar -xf ingress-nginx-4.4.2.tgz
cd ingress-nginx
vim values.yaml

在values.yaml文件中修改如下内容:

(1)修改controller的仓库和镜像,并将哈希值校验注释掉

registry: registry.cn-hangzhou.aliyuncs.com
image: google_containers/nginx-ingress-controller

(2)按照下图所示修改kube-webhook

registry: registry.cn-hangzhou.aliyuncs.com
image: google_containers/kube-webhook-certgen
tag: v1.5.1

(3)给DaemonSet的nodeSelector添加ingress: "true"

(4)将hostNetwork的值修改成true,并将dnsPolicy的值修改成ClusterFirstWithHostNet。

(5)将Service的type改成ClusterIP,并将admissionWebhooks的enabled属性改成false。

4. values.yaml文件修改完成之后,为ingress单独创建一个命名空间,并为需要部署ingress的节点(不是主节点)添加标签。由于Kubernetes 污点(Taints)的原因,不能在Master节点上创建Pod,所以即使给Master节点添加标签,也没有任何效果。

kubectl create ns ingress-nginx

kubectl label node k8s-node1 ingress=true

5. 安装ingress-nginx,并指定上面刚创建的命名空间ingress-nginx(注意:最后有个点)

helm install ingress-nginx -n ingress-nginx .

6. 验证是否安装成功,查看命名空间ingress-nginx中是否有名称以ingress-nginx-controller为前缀的Pod对象被创建,如果有,则说明ingress-nginx控制器安装成功。

Kubernetes污点(Taints:污点是定义在节点上的键值型属性数据(格式为 key=value:effect),用于控制 Pod 调度策略‌。其核心作用是通过以下三种排斥等级(effect)实现节点对 Pod 的筛选:

  1. NoSchedule‌:禁止新 Pod 调度到该节点(已有 Pod 不受影响)‌。
  2. ‌PreferNoSchedule‌:尽量避免调度,属于柔性限制‌。
  3. ‌NoExecute‌:不仅禁止新调度,还会驱逐已运行但不满足容忍的 Pod‌。

Maste节点默认污点‌:Kubernetes 集群初始化时,Master 节点会自动添加 node-role.kubernetes.io/master:NoSchedule 污点‌,主要出于以下原因考虑:

  • ‌安全隔离‌:防止业务 Pod 访问控制平面组件(如 etcd、kube-apiserver)‌。
  • ‌资源保障‌:避免业务负载抢占Master节点的 CPU/内存资源,导致集群控制面不稳定‌。
  • ‌职责分离‌:Master 节点应专注运行集群核心组件(如 scheduler、controller-manager)‌。

禁止在Master节点部署 Ingress-Nginx 的原因

‌1. 污点冲突‌

Ingress-Nginx 的 Pod 默认不带容忍 Master 污点的配置,导致调度失败。虽然可通过添加以下容忍强制部署,但会违反最佳实践:

tolerations:
- key: "node-role.kubernetes.io/master"
  operator: "Exists"
  effect: "NoSchedule"

2. 架构风险‌

  • 单点故障‌:Master节点本身具有高可用要求,叠加 Ingress 流量会放大故障影响‌。
  • ‌性能瓶颈‌:Ingress作为流量入口需要较高网络带宽,可能干扰控制面组件的网络通信‌。
  • ‌安全暴露‌:Master节点通常位于内网隔离区,直接暴露 Ingress 会扩大攻击面‌。

‌3. 替代方案‌

  • ‌专用节点‌:通过节点选择器将 Ingress 部署到指定 Worker 节点‌。
  • ‌DaemonSet 模式‌:配合节点亲和性在所有 Worker 节点均匀部署‌。
  • ‌云厂商方案‌:如 AWS ALB Ingress Controller 直接集成云负载均衡器‌。

# 检查Master节点污点

kubectl describe node <master-node-name> | grep Taints

# 安全移除污点(仅测试环境)

kubectl taint nodes <master-node-name> node-role.kubernetes.io/master:NoSchedule-

2Ingress

在上面成功安装Ingress控制器ingress-nginx之后,下面开始创建并使用ingress。

编写一个yaml文件用于创建Ingress对象。

apiVersion: networking.k8s.io/v1  # API版本,指定使用Kubernetes网络扩展API的v1版本
kind: Ingress  # 资源类型,声明这是一个Ingress资源
metadata:
  name: wolfcode-nginx-ingress  # 资源名称,Ingress资源的唯一标识
  annotations:  # 注解,用于存储额外的非标识性元数据
    kubernetes.io/ingress.class: "nginx"  # Ingress类型注解,指定使用nginx Ingress控制器
	nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:  # 规则列表,定义Ingress的路由规则
  - host: k8s.wolfcode.cn  # 域名配置,指定该规则适用于哪个域名
    http:
      paths:  # 路径列表,定义具体的路由路径
      - pathType: Prefix  # 路径类型,Prefix表示前缀匹配
	    backend:  # 后端配置,指定请求转发到的后端服务
          service:
		    name: nginx-svc  # 服务名称,指定代理到哪个Service对象
            port:  # 服务端口,Service对象的端口
			  number: 80
        path: /api  # 路径前缀,匹配请求的URL路径部分,类似于nginx的路径前缀匹配

也可以使用多域名和多路径的配置:

路径类型

Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 pathType 的路径无法通过合法性检查。当前支持的路径类型有三种:

  • ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者作与 Prefix 或 Exact 类型相同的处理。
  • Exact:精确匹配 URL 路径,且区分大小写。
  • Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写, 并且对路径中各个元素逐个执行匹配操作。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。

类型

路径

请求路径

匹配与否?

Prefix

/

(所有路径)

Exact

/foo

/foo

Exact

/foo

/bar

Exact

/foo

/foo/

Exact

/foo/

/foo

Prefix

/foo

/foo, /foo/

Prefix

/foo/

/foo, /foo/

Prefix

/aaa/bb

/aaa/bbb

Prefix

/aaa/bbb

/aaa/bbb

Prefix

/aaa/bbb/

/aaa/bbb

是,忽略尾部斜线

Prefix

/aaa/bbb

/aaa/bbb/

是,匹配尾部斜线

Prefix

/aaa/bbb

/aaa/bbb/ccc

是,匹配子路径

Prefix

/aaa/bbb

/aaa/bbbxyz

否,字符串前缀不匹配

Prefix

/, /aaa

/aaa/ccc

是,匹配 /aaa 前缀

Prefix

/, /aaa, /aaa/bbb

/aaa/bbb

是,匹配 /aaa/bbb 前缀

Prefix

/, /aaa, /aaa/bbb

/ccc

是,匹配 / 前缀

Prefix

/aaa

/ccc

否,使用默认后端

混合

/foo (Prefix), /foo (Exact)

/foo

是,优选 Exact 类型

修改Windows上的etc/hosts文件,添加ingress-nginx控制器的Pod对象所在节点IP与域名(k8s.wolfcode.cn)的映射关系。

在Windows浏览器上访问k8s集群中在k8s-node1节点上创建的Pod对象中的nginx服务。路径中的/api就是在创建Ingress的yaml文件中配置的path。

二、配置管理

ConfigMap:Kubernetes 中用于存储‌非敏感配置数据(如环境变量)‌的 API 对象,通过键值对(key-value)形式管理配置信息。与 Secret 不同,ConfigMap ‌禁止存储密码、密钥等敏感数据‌(敏感数据需使用 Secret)‌。其主要特性包括:

  • 运行时更新‌:修改 ConfigMap 数据后,关联的 Pod 会自动同步更新(无需重启容器),适用于动态调整参数。
  • ‌多环境适配‌:同一镜像通过不同 ConfigMap 配置,可快速部署到开发、测试、生产环境‌。
  • 数据解耦‌:将应用程序配置(如环境变量、配置文件、命令行参数)与容器镜像分离,避免硬编码配置,提升镜像的可移植性。
  • ‌数据类型支持‌:存储纯文本、JSON、YAML 等格式的数据,支持直接挂载为文件或注入为环境变量。
  • ‌命名空间隔离‌:属于命名空间(Namespace)级别资源,仅限同一命名空间内的 Pod 访问。

Secret:存储敏感数据(如密码、密钥),无需将密码、token、密钥等敏感数据暴露到镜像或Pod Spec中,可以以Volume或环境变量的方式被Pod使用。Secret有三种加密方式:

  • Service Account‌:自动创建并挂载,用于访问Kubernetes API。
  • ‌Opaque‌:存储base64编码的密码、密钥等。
  • ‌kubernetes.io/dockerconfigjson‌:用于存储私有Docker仓库的配置信息。

1、ConfigMap

在Kubernetes中,创建ConfigMap对象的方式有以下几种:

1. 基于文件夹创建‌:

使用--from-file参数指定文件夹路径,如kubectl create configmap my-config --from-file=path/to/bar。

2. 基于某个或某些文件创建‌:

使用--from-file参数指定文件路径,如kubectl create configmap my-config --from-file=/path/to/bar/application.yaml。

可以明确指定文件与ConfigMap中的键值对应关系,如kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt。

‌3. 从字面值创建‌:

直接使用--from-literal参数指定键值对,如kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2。

‌4. 从文件中的键值对创建‌:

如果文件内容本身就是key=value键值对格式,可以直接使用--from-file参数,如kubectl create configmap my-config --from-file=path/to/bar(注意与第一种方式区分文件内容)。

‌5. 从环境文件创建‌:

使用--from-env-file参数指定包含环境变量的文件,如kubectl create configmap my-config --from-env-file=path/to/foo.env --from-env-file=path/to/bar.env。

在Pod和Deployment中使用环境变量的方式主要有以下三种方式:

1. 通过envFrom或configMapKeyRef引用ConfigMap/Secret的变量

  • 单个变量引用‌:通过configMapKeyRef或secretKeyRef指定来源:
env:
  - name: DB_TIMEOUT
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: db.timeout
  • 批量注入‌:使用envFrom导入全部变量:
envFrom:
  - configMapRef:
      name: app-config

2. 将ConfigMap/Secret中的变量定义为数据卷,通过volumeMounts‌挂载到Pod/Deployment:

spec:
  containers:
  - name: config-test  # 容器名称,Pod 中容器的名字
    image: alpine      # 容器镜像,容器使用的镜像
    volumeMounts:  # 数据卷挂载配置
    - name: db-config  # 数据卷名称,引用volumes中定义的数据卷
      mountPath: "/usr/local/mysql/conf"  # 挂载路径,数据卷挂载到容器内的路径
  volumes:  # 定义数据卷
  - name: db-config  # 数据卷名称,定义数据卷的名称
    configMap:  # 数据卷类型为ConfigMap
      name: test-dir-config  # ConfigMap名称,表示从哪个ConfigMap中读取环境变量
      items:
      - key: "db.properties"  # ConfigMap中的key,指定ConfigMap中的键
        path: "db.properties"  # 将键的值作为文件内容,文件名为path指定的名称

例如,下面这个创建Pod的yaml文件,基于方式一,从名为test-env-config的ConfigMap中获取键为JAVA_OPTS_TEST的值赋给环境变量JAVA_VM_OPTS,并获取键为APP_NAME的值赋给环境变量APP。另外,基于方式二,从名为test-dir-config的ConfigMap中获取环境变量定义为数据卷,再通过volumeMounts挂载到容器内某个路径,从而可以被容器使用。

apiVersion: v1  # Kubernetes API 版本,定义了使用的 Kubernetes API 的版本。
kind: Pod       # 资源类型,指明这是一个 Pod 资源。
metadata:
  name: test-configfile-po  # Pod 名称,用于唯一标识这个 Pod。
spec:
  containers:
  - name: config-test  # 容器名称,Pod 中容器的名字。
    image: alpine      # 容器镜像,容器使用的镜像。
    command: ["/bin/sh", "-c", "sleep 3600"]  # 容器启动命令,容器启动时执行的命令。
    imagePullPolicy: IfNotPresent  # 镜像拉取策略,如果不存在镜像则拉取。
    env:
    - name: JAVA_VM_OPTS  # 环境变量名,设置环境变量JAVA_VM_OPTS
      valueFrom:
        configMapKeyRef:
          name: test-env-config  # ConfigMap名称,从名为test-env-config的ConfigMap中获取值
          key: JAVA_OPTS_TEST  #获取键为JAVA_OPTS_TEST的值赋给变量JAVA_VM_OPTS
    - name: APP  # 环境变量名,设置环境变量APP
      valueFrom:
        configMapKeyRef:
          name: test-env-config  # ConfigMap名称,从名为test-env-config的ConfigMap中获取值
          key: APP_NAME   # 从ConfigMap中获取键为APP_NAME的值赋给环境变量APP
    volumeMounts:  # 数据卷挂载配置
    - name: db-config  # 数据卷名称,引用volumes中定义的数据卷
      mountPath: "/usr/local/mysql/conf"  # 挂载路径,数据卷挂载到容器内的路径
      readOnly: true  # 是否只读(默认为false),数据卷以只读方式挂载
  volumes:  # 定义数据卷
  - name: db-config  # 数据卷名称,定义数据卷的名称
    configMap:  # 数据卷类型为ConfigMap
      name: test-dir-config  # ConfigMap名称,指定数据卷使用的ConfigMap 
      items: #若不配置items,会将ConfigMap中所有键的值保存到与键同名的文件中
      - key: "db.properties"  # ConfigMap中的key,指定ConfigMap中的键
        path: "db.properties"  # 将键的值作为文件内容,文件名为path指定的名称
  restartPolicy: Never  # 重启策略,Pod 失败后不重启

下面这个名为test-dir-config的ConfigMap中包含两个key,分别是dp.properties和redis.properties,也就是两个配置文件,这两个配置文件中分别配置了环境变量。如果只想从ConfigMap中加载一个文件中的环境变量,就通过volumes.configMap.items.key指定使用哪个配置文件,例如上面方式二中通过key: "db.properties"指定使用db.properties文件中的环境变量。如果没有配置volumes.configMap.items,就会从ConfigMap中加载所有文件的环境变量,会自动生成与key同名的文件保存每个配置文件中的环境变量,再通过容器中的volumeMounts挂载这些文件在容器中使用。

3. 在Pod/Deployment中直接定义环境变量‌

通过env字段显式设置键值对:

env:
  - name: LOG_LEVEL
    value: "INFO"

这种方式适用于静态配置场景‌。

subPath的作用:

假设Pod或Deployment的容器挂载路径/etc/nginx/目录下有多个子目录和文件,通过ConfigMap挂载的方式会将volumes.configMap.items.path中配置的文件完全替换掉容器内/etc/nginx/目录下的所有子目录和文件,可以通过在volumeMounts中添加subPath解决这个问题。subPath的值与volumes.configMap.items.path的值保持一致,且不能以/开头,这样只会精准替换掉容器内/etc/nginx/目录下与volumes.configMap.items.path配置的同名文件,不会对其他文件和目录产生影响。

但是,如果使用subPath,更新ConfigMap中的环境变量配置不会自动更新到Pod中。

subPath 方式为何不会更新?

‌1. 独立副本机制‌

subPath 挂载时,Kubernetes 会在 Pod 启动时将 ConfigMap/Secret 文件‌拷贝一份‌到容器的本地文件系统(通常是临时目录),后续 ConfigMap 的更新不会影响这份独立副本‌。

设计目的‌:防止多个 subPath 指向同一份数据时的冲突,并确保容器文件的独立性‌。

‌2. 与目录挂载的差异‌

直接挂载整个目录(非 subPath)会通过符号链接动态更新,而 subPath 是静态文件拷贝‌。

更新ConfigMap中的配置是否会更新到Pod中,主要取决于以下几种情况:

  • ‌默认挂载方式‌(不带subPath):会更新,更新周期是更新时间加上缓存时间。
  • ‌subPath挂载方式‌:不会更新。如需更新,可取消subPath使用,将配置文件挂载到不存在目录,再利用软连接链接到目标位置。
  • ‌引用变量形式‌:如果Pod中的变量是从ConfigMap或Secret中获取,同样不会更新。

方式

是否支持动态更新

注意事项

‌目录挂载‌

✅ 是

需应用监听文件变化或工具配合‌

‌引用变量‌

❌ 否

必须重启 Pod‌

‌subPath 挂载‌

❌ 否

需重建 Pod‌

配置的热更新方式:

更新ConfigMap中的配置之后,若要使得变更自动更新到Pod中,可以通过volumes和volumeMounts这种默认挂载方式实现。更新ConfigMap配置实现Pod的热更新有两种方式。

1. 通过kubectl edit cm <ConfigMap对象名称> 命令直接修改ConfigMap中的配置

2. 先修改创建ConfigMap对象的文件,然后通过kubectl create cm <ConfigMap对象名称> --from-file=<yaml文件或yaml文件所属目录> --dry-run -o yaml | kubectl replace -f- 命令将修改的yaml文件内容替换已创建的<ConfigMap对象名称>对应属性的值。

例如:kubectl create cm test-dir-config --from-file=./test/ --dry-run -o yaml | kubectl replace -f-

上面这条命令通过管道符(|)连接两个命令,左边的命令会将创建test-dir-config使用的文件内容输出到一个yaml文件中,右边的命令-f后面还有一个-,用于接收左边命令输出的yaml文件。

名称为test-dir-config的ConfigMap对象是通过test目录下的db.properties和redis.properties文件创建的,先修改db.properties文件中的环境变量,然后执行上述命令就可以修改test-dir-config中对应属性的值,进而修改挂载这个ConfigMap的Pod中变量的值。

2、Secret

Kubernetes中创建Secret的方式有以下几种:

‌1. 从字面值创建‌:使用kubectl create secret generic命令,直接指定用户名和密码等字面值。

密码最好用单引号包起来。

kubectl create secret generic <Secret对象名称> --from-literal=key1=value1 --from-literal=key2= value2

说明‌:generic 表示通用类型 Secret,--from-literal 直接注入明文值(自动 Base64 编码)。

例如:

kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password= 'S3cr3tP@ss'

2. 从文件创建‌:同样使用kubectl create secret generic命令,但指定文件路径来创建Secret。

将文件内容作为 Secret 的值,适用于证书或配置文件:

kubectl create secret generic <Secret对象名称> --from-file=db-password=<文件>

例如:kubectl create secret generic file-secret --from-file=db-password=./password.txt

说明‌:文件内容会被自动编码,键名可自定义(如 db-password)。

3. 从目录创建‌:也是通过kubectl create secret generic命令,不过是指定目录路径。

批量导入目录下的所有文件:

kubectl create secret generic <Secret对象名称> --from-file=<目录>

例如:kubectl create secret generic dir-secret --from-file=./configs/

说明‌:目录内每个文件生成一个键值对,键名为文件名‌。

4. Docker注册表Secret‌:使用kubectl create secret docker-registry命令,专为Docker注册表创建。

存储私有镜像仓库认证信息,专用于拉取私有镜像,类型为 kubernetes.io/dockerconfigjson。

例如:

kubectl create secret docker-registry reg-secret \
  --docker-username=user \
  --docker-password=pass \
  --docker-server=registry.example.com

5. TLS Secret‌:使用kubectl create secret tls命令,用于创建TLS类型的Secret。

存储 HTTPS 证书和私钥,类型为 kubernetes.io/tls,证书和私钥需预先准备‌。

例如:

kubectl create secret tls tls-secret \
  --cert=./tls.crt \
  --key=./tls.key

6. 通过YAML 声明式创建

通过yaml配置文件定义 Secret(以 Opaque 类型为例):

apiVersion: v1
kind: Secret
metadata:
  name: yaml-secret
type: Opaque
data:
  username: YWRtaW4=  # admin 的 Base64 编码
  password: UzNjcjN0UHBzcw==  # S3cr3tP@ss 的编码

说明‌:需手动对值进行 Base64 编码(如 echo -n "admin" | base64)。

非 YAML 方式创建的 Secret 会自动编码,YAML 需手动编码处理‌。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值