当前位置: 首页 > article >正文

Kubernetes完整详细学习笔记

文章目录

一.Kubernetes集群介绍与搭建

二.资源管理

2.1 命令式对象管理

2.2 命令式对象配置

2.3 声明式对象配置

三.Namespace

3.1 Namespace介绍

3.2 Namespace使用

3.2.1 查看命名空间

3.2.2 创建与删除

四.Pod

4.1 Pod介绍

4.2 Pod基本管理

4.3 Pod 配置

4.3.1 Pod的基本使用

4.3.2 Pod启动

4.3.3 环境变量

4.3.4 端口配置

4.4 容器探测

4.4.1 exec模式实例:

4.4.2 TCPSocket模式实例

4.4.3 HTTPGet模式实例

4.4.4 重启策略

4.5 Pod调度

4.5.1 定向调度

4.5.2 亲和性调度

五.Pod控制器

5.1 Pod控制器介绍

5.2 Pod控制器:ReplicaSet

5.2.1 ReplicaSet介绍

5.2.2 RS实例测试

5.2.3 弹性扩缩容

5.3 Pod控制器:Deployment

5.3.1 Deployment介绍

5.3.2 Deployment实例测试

5.3.3 弹性扩缩容

5.4 Pod控制器:DaemonSet

5.4.1 DaemonSet介绍

5.4.2 DaemonSet实例测试

六.Service

6.1 Service介绍

6.2 ClusterIP 模式

6.2.1 ClusterIP 模式介绍

6.2.2 ClusterIP模式实例测试

6.3 NodePort模式

6.3.1 NodePort介绍

6.3.2 NodePort模式实例测试

七.数据存储

7.1 数据存储介绍

7.2 EmptyDir模式

7.2.1 EmptyDir模式介绍

7.2.2 EmptyDir模式实例测试

7.3 HostPath模式

7.3.1 HostPath模式介绍

7.3.2 HostPath模式实例测试

7.4 NFS模式

7.4.1 NFS模式介绍

7.4.2 NFS模式实例测试

7.5 PV与PVC模式

7.5.1 PV与PVC模式介绍

7.5.2 创建PV

7.5.3 创建PVC

7.5.4 创建Pod使用存储

7.6 ConfigMap模式

7.6.1 ConfigMap模式介绍

7.6.2 ConfigMap模式实例测试

7.7 Secret模式

7.7.1 Secret模式介绍

7.7.2 Secret模式实例测试

小结


一.Kubernetes集群介绍与搭建

搭建过程参考我的另一篇博客完成搭:

 Kubernetes详细介绍及平台搭建_kubernetes 开源平台-CSDN博客

二.资源管理

在kubernetes中,所有的内容都被抽象为资源,而用户则需要通过操作资源的方式来管理kubernetes;kubernetes实质上就是一个集群系统,我们可以在集群上面进行各种服务的部署,所有部署的服务事实上就是在kubernetes上运行的容器,并将指定的程序在容器中运行,但kubernetes中最小的管理单元不是容器,是pod,所以只能将容器放在pod当中;Pod可以提供服务之后,就要考虑如何访问Pod中服务,kubernetes提供了Service资源实现这个功能。kubernetes的核心,就是学习如何对集群上的Pod、Pod控制器、Service、存储等各种资源进行操作

Kubernetes的资源管理方式分为三类:

(1)陈述式命令(命令式对象管理) 直接去管理kubernetes,类似于我们直接在docker 中 docker run 命令;
例:kubectl run nginx-pod --image=nginx:latest --port=80
(2)陈述式对象配置(命令式对象配置) 通过命令配置和配置文件去管理kubernetes的资源,类似于类似于 docker-compose.yml;
例:kubectl create/patch -f nginx-pod.yaml
(3)声明式对象配置(声明式对象配置) 通过apply命令和配置文件去管理资源;
例:kubectl apply -f nginx-pod.yaml

类型

操作对象

适用环境

优点

缺点

命令式对象管理

对象

测试

简单

只能操作活动对象,无法审计、跟踪

命令式对象配置

文件

开发

可以审计、跟踪

项目大时,配置文件多,操作麻烦

声明式对象配置

目录

开发

支持目录操作

意外情况下难以调试

2.1 命令式对象管理

kubectl是kubernetes集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。格式为:

kubectl [command] [type] [name] [flags]

comand:指定要对资源执行的操作,例如create、get、delete
type:指定资源类型,比如deployment、pod、service
name:指定资源的名称,并且名称大小写敏感
flags:指定额外的可选参数

例如:

查询k8s集群节点

[root@master ~]# kubectl get nodes
[root@master ~]# kubectl get nodes 
NAME     STATUS   ROLES                  AGE    VERSION
master   Ready    control-plane,master   142m   v1.23.0
node     Ready    <none>                 141m   v1.23.0

在这里可以查看到节点的状态,持续时间,以及kubernetes版本信息

查询所有的pod

[root@master ~]# kubectl get pods
[root@master ~]# kubectl get pods 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-5c4c85f44b-pw8tq   1/1     Running   0          140m
volume-hostpath          2/2     Running   0          85m

在这里可以查看到pod的具体名称,状态,重启此时,持续时间。

查询k8s集群信息

[root@master ~]# kubectl cluster-info
想查看更详细的信息可以在后面加上一个dump,但是会非常冗长
[root@master ~]# kubectl cluster-info
Kubernetes control plane is running at https://192.168.100.110:6443
CoreDNS is running at https://192.168.100.110:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

内容反馈为kubernetes集群的master节点IP,kubeDNS服务地址,调试信息等;

查询kubernetes版本信息

[root@master ~]# kubectl version
[root@master ~]# kubelet --version 
Kubernetes v1.23.0

2.2 命令式对象配置

命令式对象配置就是使用命令配合配置文件一起来操作kubernetes资源

创建一个nginxpod.yaml

内容:

apiVersion: v1
kind: Namespace
metadata:
  name: base
---
apiVersion: v1
kind: Pod
metadata:
  name: nginxpod
  namespace: base
spec:
  containers:
  - name: nginx-containers
    image: nginx:latest

保存后使用create命令进行创建资源

[root@master ~]# kubectl apply -f nginxpod.yaml 
namespace/base configured
pod/nginxpod created

创建完成后,我们发现一共创建了两个资源,一个namespace,一个pod

使用命令查看我们创建的资源:

[root@master ~]# kubectl get -f nginxpod.yaml
NAME             STATUS   AGE
namespace/base   Active   111m

NAME           READY   STATUS    RESTARTS   AGE
pod/nginxpod   1/1     Running   0          46s

使用delete命令删除资源:

[root@master ~]# kubectl delete -f  nginxpod.yaml
namespace "base" deleted
pod "nginxpod" deleted

命令式对象配置的方式操作资源,可以简单的认为:命令 + yaml配置文件(里面是命令需要的各种参数)

2.3 声明式对象配置

声明式对象配置跟命令式对象配置很相似,但是它只有一个命令apply。

[root@master ~]# kubectl apply -f nginxpod.yaml
namespace/base configured
pod/nginxpod created

实声明式对象配置就是使用apply描述一个资源最终的状态(在yaml中定义状态) 使用apply操作资源: 如果资源不存在,就创建,相当于 kubectl create 如果资源已存在,就更新

三.Namespace

3.1 Namespace介绍

Namespace 提供了一个隔离的环境,使得不同的用户、团队或项目可以在同一个物理集群上运行,而不会相互干扰。Namespace 可以看作是一种资源命名空间,它允许集群管理员对资源进行分组和管理。Namespace 是 Kubernetes 集群管理的重要组成部分,它提供了一种灵活、高效的方式来组织和隔离资源,使得集群的管理和使用更加方便和安全。

kubernetes集群中的所有的Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互相的访问,那此时就可以将两个Pod划分到不同的namespace下。kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的"组",以方便不同的组的资源进行隔离使用和管理。

3.2 Namespace使用

3.2.1 查看命名空间

查看所有命名空间:

[root@master ~]# kubectl get ns 
NAME              STATUS   AGE
default           Active   12m
kube-node-lease   Active   12m
kube-public       Active   12m
kube-system       Active   12m

default 所有未指定Namespace的对象都会被分配在default命名空间

kube-node-lease  集群节点之间的心跳维护,v1.13开始引入

kube-public 此命名空间下的资源可以被所有人访问(包括未认证用户)

kube-system所有由Kubernetes系统创建的资源都处于这个命名空间

[root@master ~]# kubectl get ns default 
NAME      STATUS   AGE
default   Active   16m
[root@master ~]# kubectl get ns kube-system
NAME          STATUS   AGE
kube-system   Active   16m

以指定格式进行查看:

[root@master ~]# kubectl get ns default -o yaml 
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2025-02-05T05:13:43Z"
  labels:
    kubernetes.io/metadata.name: default
  name: default
  resourceVersion: "206"
  uid: 91fc2241-733f-4b2f-bede-972a1f32cbb1
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

查看详细信息:

[root@master ~]# kubectl describe ns default 
Name:         default
Labels:       kubernetes.io/metadata.name=default
Annotations:  <none>
Status:       Active

No resource quota.

No LimitRange resource.

3.2.2 创建与删除

命令形式创建:

[root@master ~]# kubectl create namespace hello
namespace/hello created
[root@master ~]# kubectl get ns 
NAME              STATUS   AGE
default           Active   20m
hello             Active   5s
kube-node-lease   Active   20m
kube-public       Active   20m
kube-system       Active   20m

Yaml文件格式创建:

[root@master ~]# vi world.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: world

[root@master ~]# kubectl apply -f world.yaml 
namespace/world created
[root@master ~]# kubectl get ns 
NAME              STATUS   AGE
---
world             Active   5s

命令删除命名空间:

[root@master ~]# kubectl delete ns hello 
namespace "hello" deleted
[root@master ~]# kubectl get ns 
NAME              STATUS   AGE
default           Active   23m
kube-node-lease   Active   23m
kube-public       Active   23m
kube-system       Active   23m
world             Active   112s

删除yaml文件创建的命名空间:delete -f +文件路径
[root@master ~]# kubectl delete -f world.yaml 
namespace "world" deleted
[root@master ~]# kubectl get ns 
NAME              STATUS   AGE
default           Active   24m
kube-node-lease   Active   24m
kube-public       Active   24m
kube-system       Active   24m

四.Pod

4.1 Pod介绍

Pod是在K8s集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务.比如你运行一个操作系统发行版的软件仓库,一个Nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。

Pod创建过程:

用户通过kubectl或其他api客户端提交需要创建的pod信息给apiServer,apiServer开始生成pod对象的信息,并将信息存入etcd,然后返回确认信息至客户端,apiServer开始反映etcd中的pod对象的变化,其它组件使用watch机制来跟踪检查apiServer上的变动,scheduler发现有新的pod对象要创建,开始为Pod分配主机并将结果信息更新至apiServer,node节点上的kubelet发现有pod调度过来,尝试调用docker启动容器,并将结果回送至apiServer,apiServer将接收到的pod状态信息存入etcd中。

Pod的生命周期:

在整个生命周期中,Pod会出现5种状态,分别如下:

挂起(Pending):apiserver已经创建了pod资源对象,但它尚未被调度完成或者仍处于下载镜像的过程中

运行中(Running):pod已经被调度至某节点,并且所有容器都已经被kubelet创建完成

成功(Succeeded):pod中的所有容器都已经成功终止并且不会被重启

失败(Failed):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态

未知(Unknown):apiserver无法正常获取到pod对象的状态信息,通常由网络通信失败所导致

4.2 Pod基本管理

命令式创建pod并运行:

nginx pod名

--namespace 指定命名空间

--image 指定镜像

--port 指定端口

[root@master ~]# kubectl run nginx --namespace default --image=nginx:latest --port=80
pod/nginx created
查看Pod:#default是默认命名空间,查看时可以不加-n 选项
[root@master ~]# kubectl get pod 
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          66s

查看Pod详细信息:

#如果需要指定命名空间就加-n namespace 选项即可。

[root@master ~]# kubectl describe pod nginx 
Name:         nginx
Namespace:    default
Priority:     0
Node:         node/192.168.100.120
Start Time:   Wed, 05 Feb 2025 13:52:37 +0800
Labels:       run=nginx
Annotations:  cni.projectcalico.org/containerID: b67fbb2f171ecff0707601143e4b624303f58aaf5e0faa6b4d71bd29675cea26
              cni.projectcalico.org/podIP: 10.244.167.129/32
              cni.projectcalico.org/podIPs: 10.244.167.129/32
Status:       Running
IP:           10.244.167.129
IPs:
  IP:  10.244.167.129
Containers:
  nginx:
    Container ID:   docker://a6cddb73578647cda67ed1c0865807c38c298f7ee55ebe56b3c39a7b219c6365
    Image:          nginx:latest
    Image ID:       docker-pullable://nginx@sha256:bc2f6a7c8ddbccf55bdb19659ce3b0a92ca6559e86d42677a5a02ef6bda2fcef
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Wed, 05 Feb 2025 13:52:57 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-dgctz (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-dgctz:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m45s  default-scheduler  Successfully assigned default/nginx to node
  Normal  Pulling    2m44s  kubelet            Pulling image "nginx:latest"
  Normal  Pulled     2m25s  kubelet            Successfully pulled image "nginx:latest" in 19.705450711s
  Normal  Created    2m25s  kubelet            Created container nginx
  Normal  Started    2m25s  kubelet            Started container nginx

访问Pod:

获取Pod的IP:
[root@master ~]# kubectl get pod nginx -o wide 
NAME    READY   STATUS    RESTARTS   AGE     IP               NODE   NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          4m53s   10.244.167.129   node   <none>           <none>
访问Pod:
[root@master ~]# curl 10.244.167.129 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

删除Pod:

[root@master ~]# kubectl delete pod nginx 
pod "nginx" deleted
[root@master ~]# kubectl get pod 
No resources found in default namespace.

当前Pod并不是使用控制器创建,所以并没有容器的重启策略与重建策略。

4.3 Pod 配置

使用kubectl get explain pod.spec.containers可以查询到所有有关Pod的所有配置选项。

Pod资源配置清单:

# yaml格式的pod定义文件完整内容:
apiVersion: v1       #必选,api版本号,例如v1
kind: Pod           #必选,Pod
metadata:           #必选,元数据
  name: string       #必选,Pod名称
  namespace: string    #Pod所属的命名空间,默认在default的namespace
  labels:              # 自定义标签
    name: string     #自定义标签名字
  annotations:        #自定义注释列表
    name: string
spec:         #必选,Pod中容器的详细定义(期望)
  containers:      #必选,Pod中容器列表
  - name: string     #必选,容器名称
    image: string    #必选,容器的镜像名称
    imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
    command: [string]    #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]     #容器的启动命令参数列表
    workingDir: string     #容器的工作目录
    volumeMounts:    #挂载到容器内部的存储卷配置
    - name: string     #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
      mountPath: string    #存储卷在容器内mount的绝对路径,应少于512字符
      readOnly: boolean    #是否为只读模式
    ports:       #需要暴露的端口库号列表
    - name: string     #端口号名称
      containerPort: int   #容器需要监听的端口号
      hostPort: int    #容器所在主机需要监听的端口号,默认与Container相同
      protocol: string     #端口协议,支持TCP和UDP,默认TCP
    env:       #容器运行前需设置的环境变量列表
    - name: string     #环境变量名称
      value: string    #环境变量的值
    resources:       #资源限制和请求的设置
      limits:      #资源限制的设置
        cpu: string    #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
        memory: string     #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
      requests:      #资源请求的设置
        cpu: string    #Cpu请求,容器启动的初始可用数量
        memory: string     #内存清求,容器启动的初始可用数量
    livenessProbe:     #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
      exec:      #对Pod容器内检查方式设置为exec方式
        command: [string]  #exec方式需要制定的命令或脚本
      httpGet:       #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0  #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0   #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0    #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged:false
    restartPolicy: [Always | Never | OnFailure] # Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
    nodeSelector: obeject  # 设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
    imagePullSecrets:    #Pull镜像时使用的secret名称,以key:secretkey格式指定
    - name: string
    hostNetwork: false     #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
    volumes:       #在该pod上定义共享存储卷列表
    - name: string     #共享存储卷名称 (volumes类型有很多种)
      emptyDir: {}     #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
      hostPath: string     #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
        path: string     #Pod所在宿主机的目录,将被用于同期中mount的目录
      secret:      #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
        scretname: string  
        items:     
        - key: string
          path: string
      configMap:     #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
        name: string
        items:
        - key: string
          path: string

在kubernetes中基本所有资源的一级属性都是一样的,主要包含5部分:

apiVersion 版本,由kubernetes内部定义,版本号必须可以用 kubectl api-versions 查询

kind 类型,由kubernetes内部定义,版本号必须可以用 kubectl api-resources 查询

metadata 元数据,主要是资源标识和说明,常用的有name、namespace、labels等

spec 描述,这是配置中最重要的一部分,里面是对各种资源配置的详细描述

status 状态信息,里面的内容不需要定义,由kubernetes自动生成

在上面的属性中,spec是接下来研究的重点,继续看下它的常见子属性:

containers <[]Object> 容器列表,用于定义容器的详细信息

nodeName 根据nodeName的值将pod调度到指定的Node节点上

nodeSelector <map[]> 根据NodeSelector中定义的信息选择将该Pod调度到包含这些label的Node 上

hostNetwork 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络

volumes <[]Object> 存储卷,用于定义Pod上面挂在的存储信息

restartPolicy 重启策略,表示Pod在遇到故障的时候的处理策略

4.3.1 Pod的基本使用

编写一个yaml文件:

[root@master ~]# vi nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f nginx.yaml 
pod/nginx-base created
[root@master ~]# kubectl get pods -n base 
NAME         READY   STATUS    RESTARTS   AGE
nginx-base   1/1     Running   0          9s

创建一个名为nginx的Pod,在base命名空间之下,镜像使用nginx:latest,镜像策略为本地不存在则去镜像仓库拉取。

三种镜像策略:

imagePullPolicy,用于设置镜像拉取策略,kubernetes支持配置三种拉取策略:

Always:总是从远程仓库拉取镜像(一直远程下载)

IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像

Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错 (一直使用本地)

4.3.2 Pod启动

busybox是类似于一个工具类的集合,kubernetes集群启动管理后,它会自动关闭。解决方法就是让其一直在运行,这就用到了command配置。

我们增加busybox,并为busybox添加command字段:

# 进入pod中的busybox容器,查看文件内容

# kubectl exec  pod名称 -n 命名空间 -it -c 容器名称 /bin/sh  在容器内部执行命令

#使用这个命令就可以进入某个容器的内部,然后进行相关操作了

[root@master ~]# vi nginx_busybox.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
  - name: busybox
    image: busybox:latest
    command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]

[root@master ~]# kubectl apply -f nginx_busybox.yaml 
pod/pod-base created

[root@master ~]# kubectl exec pod-base -n base -it -c busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cat /tmp/hello.txt 
06:37:46
06:37:49
06:37:52

4.3.3 环境变量

创建pod-env.yaml,执行文件:

[root@master ~]# vi pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-env
  namespace: base
spec:
  containers:
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
    env:
    - name: "username"
      value: "admin"
    - name: "password"
      value: "123456"

[root@master ~]# kubectl apply -f pod-env.yaml 
pod/pod-env created
#进入容器内查看:
[root@master ~]#  kubectl exec pod-env -n base -c busybox -it /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo $username
admin
/ # echo $password
123456
/ # 

4.3.4 端口配置

常见配置:

name         <string>  # 端口名称,如果指定,必须保证name在pod中是唯一

containerPort<integer> # 容器要监听的端口(0<x<65536)

protocol     <string>  # 端口协议。必须是UDP、TCP或SCTP。默认为“TCP”。

测试案例:##注意缩进##

apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginxport
      containerPort: 80
      protocol: TCP

查看nginx的详细信息,可以查看到端口设置为了80:

[root@master ~]# kubectl describe pod nginx-base -n base 
Name:         nginx-base
Namespace:    base
------
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running

4.3.5 资源配额

容器中的程序要运行,肯定是要占用一定资源的,比如cpu和内存等,如果不对某个容器的资源做限制,那么它就可能吃掉大量资源,导致其它容器无法运行。针对这种情况,kubernetes提供了对内存和cpu的资源进行配额的机制

这种机制主要通过resources选项实现

limits:用于限制运行时容器的最大占用资源,当容器占用资源超过limits时会被终止,并进行重启。

requests :用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动。

可配置的参数有:

resources: # 资源配额

limits:  # 限制资源(上限)

cpu: "2" # CPU限制,单位是core数

memory: "10Gi" # 内存限制 可以使用Gi、Mi、G、M等形式

requests: # 请求资源(下限)

cpu: "1"  # CPU限制,单位是core数

memory # 内存限制

测试实例: 

apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    resources: 
      limits:
        memory: "5Gi"
      requests:
        memory: "10Mi"

执行文件并查看:

[root@master ~]# kubectl describe pod -n base nginx-base 
Name:         nginx-base
Namespace:    base
------
    Restart Count:  0
    Limits:
      memory:  5Gi
    Requests:
      memory:     10Mi

4.4 容器探测

容器探测用于检测容器中的应用实例是否正常工作,是保障业务可用性的一种传统机制。如果经过探测,实例的状态不符合预期,那么kubernetes就会把该问题实例" 摘除 ",不承担业务流量。kubernetes提供了两种探针来实现容器探测,分别是:

liveness probes:存活性探针,用于检测应用实例当前是否处于正常运行状态,如果不是,k8s会重启容器

readiness probes:就绪性探针,用于检测应用实例当前是否可以接收请求,如果不能,k8s不会转发流量

为了使健康检查能够对Pod的运行状况进行诊断,kubelet会调用容器中为探针实现的处理程序,这些处理程序分为三大类:

Exec:在容器内执行命令。

TCPSocket:对指定端口上,容器的IP地址执行TCP检查。

HTTPGet:在容器的IP上执行HTTP GET请求。

处理程序的返回状态也分为三种:

Success:容器通过诊断。

Failed:容器无法通过诊断。

Unknown:诊断失败,状态不确定,将不采取任何措施。


无论使用哪种类型的探针(tcpSocket、httpGet 或 exec),如果 livenessProbe 失败,Kubernetes 会重启容器(而不是整个 Pod)。Pod 内的其他容器如果没有失败,通常不会受影响。tcpSocket:检查是否能够通过指定端口与容器建立 TCP 连接。httpGet:检查是否能够通过 HTTP 请求访问容器的指定路径(如 /health)。exec:执行指定的命令,若命令返回非零状态,认为探针失败。如果一个 Pod 中的多个容器都不断失败,或者容器在 重启后依然无法恢复健康,Kubernetes 会根据其 Pod 的重启策略(restartPolicy)决定是否继续重启容器,或者 删除 Pod 重新创建。默认情况下,Pod 的 restartPolicy 是 Always,这意味着如果容器失败,Kubernetes 会不断重启该容器,直到容器变为健康为止。

4.4.1 exec模式实例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports: 
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      exec:
        command: ["/bin/cat","/tmp/hello.txt"]

我们使用的是liveness probe,并且在command字段查看了一个完全不存在的文件,这就会导致liveness probe 会检测到我们的Pod是异常状态,那么就会导致Pod会被删除,重新进行相关操作:

Events:
  Type     Reason     Age                 From               Message
  ----     ------     ----                ----               -------
  Normal   Scheduled  118s                default-scheduler  Successfully assigned base/nginx-base to node
  Normal   Pulled     98s                 kubelet            Successfully pulled image "nginx:latest" in 19.759000548s
  Normal   Pulled     46s                 kubelet            Successfully pulled image "nginx:latest" in 21.551206926s
  Normal   Created    46s (x2 over 98s)   kubelet            Created container nginx
  Normal   Started    46s (x2 over 98s)   kubelet            Started container nginx
  Warning  Unhealthy  18s (x6 over 88s)   kubelet            Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory
#检测到Pod异常,重启策略
  Normal   Killing    18s (x2 over 68s)   kubelet            Container nginx failed liveness probe, will be restarted
  Normal   Pulling    18s (x3 over 117s)  kubelet            Pulling image "nginx:latest"

当我们将command字段查看的文件换成一个存在的文件:

    livenessProbe:
      exec:
        command: ["/bin/ls","/tmp/"]

将Pod创建之后将不会出现Pod异常,Pod被正常创建不会被重启:

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  69s   default-scheduler  Successfully assigned base/nginx-base to node
  Normal  Pulling    68s   kubelet            Pulling image "nginx:latest"
  Normal  Pulled     49s   kubelet            Successfully pulled image "nginx:latest" in 19.705980073s
  Normal  Created    49s   kubelet            Created container nginx
  Normal  Started    49s   kubelet            Started container nginx

4.4.2 TCPSocket模式实例

tcpSocket 就是访问某个端口,看是不是通的:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      tcpSocket:
        port: 8080 #访问8080测试端口异常情况

此时我们查看容器详情可以发现:

Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  52s               default-scheduler  Successfully assigned base/nginx-base to node
  Normal   Pulled     32s               kubelet            Successfully pulled image "nginx:latest" in 19.788718541s
  Normal   Created    32s               kubelet            Created container nginx
  Normal   Started    32s               kubelet            Started container nginx
  Normal   Pulling    2s (x2 over 52s)  kubelet            Pulling image "nginx:latest"
  Warning  Unhealthy  2s (x3 over 22s)  kubelet            Liveness probe failed: dial tcp 10.244.167.138:8080: connect: connection refused
  Normal   Killing    2s                kubelet            Container nginx failed liveness probe, will be restarted
[root@master ~]# kubectl get pods -n base 
NAME         READY   STATUS             RESTARTS     AGE
nginx-base   0/1     CrashLoopBackOff   5 (1s ago)   4m51s

由于端口异常在这里的反馈信息为访问8080端口失败,并一直在重启pod,重启次数会不断增长。当重启次达到一定次数后,状态信息会变为CrashLoopBackOff,意为表示 Pod 中的一个容器启动后遇到问题,然后不断尝试重启但失败,解决办法也很简单,我们还需要将端口改为我们设置的正确的映射端口即可。

4.4.3 HTTPGet模式实例

apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports: 
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      httpGet:
        scheme: HTTP  
        port: 80
        path: /abc  #访问一个不存在的路径观察效果

此时查看Pod的详细信息可以发现:

Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  62s                default-scheduler  Successfully assigned base/nginx-base to node
  Normal   Pulled     42s                kubelet            Successfully pulled image "nginx:latest" in 19.307081658s
  Normal   Created    42s                kubelet            Created container nginx
  Normal   Started    42s                kubelet            Started container nginx
  Normal   Pulling    12s (x2 over 62s)  kubelet            Pulling image "nginx:latest"
  Warning  Unhealthy  12s (x3 over 32s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404

发现了错误代码404,尝试访问路径,但是未找到因为我们指定的是一个不错在的路径,于是Pod就会触发机制。

4.4.4 重启策略

在上一节中,所有的Pod发生问题时,它们都进入了重启策略当中,而重启策略是我们可以自行设置的:

  • Always :容器失效时,自动重启该容器,这也是默认值。
  • OnFailure : 容器终止运行且退出码不为0时重启
  • Never : 不论状态为何,都不重启该容器

在containers字段下进行设置:

  restartPolicy: Never # 设置重启策略为Never

设置之后创建Pod就会对应其设置的重启策略进行。

4.5 Pod调度

在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的。但是在实际使用中,这并不满足的需求,因为很多情况下,我们想控制某些Pod到达某些节点上,那么应该怎么做呢?这就要求了解kubernetes对Pod的调度规则,kubernetes提供了四大类调度方式:

自动调度:运行在哪个节点上完全由Scheduler经过一系列的算法计算得出

定向调度:NodeName、NodeSelector

亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity

污点(容忍)调度:Taints、Toleration

4.5.1 定向调度

定向调度,指的是利用在pod上声明nodeName或者nodeSelector,以此将Pod调度到期望的node节点上。注意,这里的调度是强制的,这就意味着即使要调度的目标Node不存在,也会向上面进行调度,只不过pod运行失败而已。

nodeName模式:

nodeName定向调度值得是我在创建pod的yaml文件中直接声明nodeName,以此期望pod调度到指定的node的节点上,这里的调度是强制性的,就算node不是真实存在的,也会被调度过去,但是pod会运行报错。

测试实例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
  nodeName: node

将Pod定向调度为node节点,进行查看:

[root@master ~]# kubectl get pods -n base nginx-base 
NAME         READY   STATUS    RESTARTS   AGE
nginx-base   1/1     Running   0          27s
[root@master ~]# kubectl describe pod -n base nginx-base 
Name:         nginx-base
Namespace:    base
Priority:     0
Node:         node/192.168.100.120  ##Pod被调度到node节点
Start Time:   Wed, 05 Feb 2025 18:30:57 +0800
Labels:       <none>

测试当node不存在时,会如何调度:

[root@master ~]# vi nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
  nodeName: node100

[root@master ~]# kubectl apply -f nginx.yaml 
pod/nginx-base created
[root@master ~]# kubectl get pods -n base nginx-base 
NAME         READY   STATUS    RESTARTS   AGE
nginx-base   0/1     Pending   0          2s
[root@master ~]# kubectl describe pod -n base nginx-base 
Name:         nginx-base
Namespace:    base
Priority:     0
Node:         node100/
Labels:       <none>
Annotations:  <none>
Status:       Pending
IP:           
IPs:          <none>

此时我们可以查看到,Pod状态是被挂起的状态,这就意味着,虽然node100不存在,但Pod仍然被算法调度过去了,这证明nodeName定向调度是强制性的。

NodeSelector

NodeSelector用于将pod调度到添加了指定标签的node节点上。它是通过kubernetes的label-selector机制实现的,也就是说,在pod创建之前,会由scheduler使用MatchNodeSelector调度策略进行label匹配,找出目标node,然后将pod调度到目标节点,该匹配规则是强制约束。

测试实例:

将master节点标签定义为node=10,将node节点定义为node=11

[root@master ~]# kubectl label node master node=10
node/master labeled
[root@master ~]# kubectl label node node node=11
node/node labeled

编写文件,将Pod调度到node=10节点上(master)

apiVersion: v1
kind: Pod
metadata:
  name: nginx-base
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
  nodeSelector:
    node: "10"

但在这里可能会发生报错,原因为Unschedulable 错误,可能是 master 节点 taint 了(默认情况下,Kubernetes 通常会 taint master 以防止调度非控制平面 Pod)。

执行命令后即恢复正常:

[root@master ~]# kubectl taint nodes master node-role.kubernetes.io/master-

查看Pod是否被正常调度:

[root@master ~]# kubectl get pods -n base -o wide 
NAME         READY   STATUS    RESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
nginx-base   1/1     Running   0          3m42s   10.244.219.68   master   <none>           <none>

4.5.2 亲和性调度

定向调度的两种定向调度的方式,使用起来非常方便,但是也有一定的问题,那就是如果没有满足条件的Node,那么Pod将不会被运行,即使在集群中还有可用Node列表也不行,这就限制了它的使用场景。基于上面的问题,kubernetes还提供了一种亲和性调度(Affinity)。它在NodeSelector的基础之上的进行了扩展,可以通过配置的形式,实现优先选择满足条件的Node进行调度,如果没有,也可以调度到不满足条件的节点上,使调度更加灵活。

亲和性调度分为三类:

nodeAffinity(node亲和性): 以node为目标,解决pod可以调度到哪些node的问题

podAffinity(pod亲和性) : 以pod为目标,解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题

podAntiAffinity(pod反亲和性) : 以pod为目标,解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题

NodeAffinity:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        -  matchExpressions:
           - key: node
             operator: In
             values: ["11"]

requiredDuringSchedulingIgnoredDuringExecution:Pod 只有在满足这些条件时才会被调度;nodeSelectorTerms:至少需要满足列表中的一个条件。matchExpressions:节点必须匹配的标签表达式。key:要匹配的标签的键;operator:这是匹配操作符,In 表示节点的标签值必须在 values 列表中。values:一个字符串列表,包含了 key 可能的值。

在执行完文件后我们查看该Pod的详细信息,我们可以观察到,在pod创建之初就被分到了标签为11的node节点上面。

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  19s   default-scheduler  Successfully assigned base/nginx to node
  Normal  Pulling    18s   kubelet            Pulling image "nginx:latest"

五.Pod控制器

5.1 Pod控制器介绍

Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod。

在kubernetes中,有很多类型的pod控制器,每种都有自己的适合的场景,常见的有:

ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级

Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、回退版本

Horizontal Pod Autoscaler:可以根据集群负载自动水平调整Pod的数量,实现削峰填谷

DaemonSet:在集群中的指定Node上运行且仅运行一个副本,一般用于守护进程类的任务

5.2 Pod控制器:ReplicaSet

5.2.1 ReplicaSet介绍

ReplicaSet会确保Pod副本数在任一时刻都精确满足期望值。用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收。虽然ReplicaSet可以独立使用,但一般还是建议使用 Deployment 来自动管理ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)。也就是说Replicaset通常不会直接创建,而是在创建最高层级的deployment资源时自动创建。

ReplicaSet 主要功能
确保Pod数量:它会确保Kubernetes中有指定数量的Pod在运行,如果少于指定数量的Pod,RC就会创建新的,反之这会删除多余的,保证Pod的副本数量不变。

确保Pod健康:当Pod不健康,比如运行出错了,总之无法提供正常服务时,RC也会杀死不健康的Pod,重新创建新的。

弹性伸缩:在业务高峰或者低峰的时候,可以用过RC来动态的调整Pod数量来提供资源的利用率,当然我们也提到过如果使用HPA这种资源对象的话可以做到自动伸缩。

滚动升级:滚动升级是一种平滑的升级方式,通过逐步替换的策略,保证整体系统的稳定性。

5.2.2 RS实例测试

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:latest

本yaml定义了在default命名空间中始终有 4个标签为 app: nginx-pod 的 nginx:latest Pod 副本处于运行状态。如果这些 Pod 中的任何一个失败或被删除,ReplicaSet 会创建新的 Pod 来替换它们,以保持4个副本的总数。

查看pod与rs:

[root@master ~]# kubectl get pods 
NAME          READY   STATUS    RESTARTS   AGE
nginx-6fv4l   1/1     Running   0          113s
nginx-t5fb8   1/1     Running   0          113s
nginx-vllmp   1/1     Running   0          113s
nginx-xvfx5   1/1     Running   0          113s
[root@master ~]# kubectl get rs 
NAME    DESIRED   CURRENT   READY   AGE
nginx   4         4         4       2m8s

5.2.3 弹性扩缩容

缩容:(扩容与更换镜像同理)

[root@master ~]# kubectl edit rs nginx

edit 是 kubectl 命令行工具的一个命令,它允许用户直接编辑 Kubernetes 资源对象的配置。当你想要修改一个已经存在的资源系统会打开一个文本编辑器,允许你直接编辑 pod-rs ReplicaSet 的 YAML 或JSON 配置文件。

编辑文件,将replicas数值,保存退出数据自动更新。

[root@master ~]# kubectl edit rs nginx
---
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod

replicaset.apps/nginx edited

此时查看资源:

[root@master ~]# kubectl get pods 
NAME          READY   STATUS    RESTARTS   AGE
nginx-6fv4l   1/1     Running   0          5m40s
nginx-t5fb8   1/1     Running   0          5m40s
nginx-xvfx5   1/1     Running   0          5m40s
[root@master ~]# kubectl get rs
NAME    DESIRED   CURRENT   READY   AGE
nginx   3         3         3       5m42s

5.3 Pod控制器:Deployment

5.3.1 Deployment介绍

Deploy:为了更好的管理kubernetes的服务编排问题,在1.2后续的kubernetes版本中就加入了Deployment控制器,但这种控制器并不是直接管理pod,而是通过管理ReplicaSet来更加简介的管理pod,简单的说就是Deployment管理ReplicaSet,ReplicaSet来管理pod。

Deployment功能:

支持ReplicaSet的所有功能

支持发布的停止、继续

支持滚动升级和回滚版本

5.3.2 Deployment实例测试

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:latest

查看资源:

[root@master ~]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE    IP               NODE     NOMINATED NODE   READINESS GATES
nginx-7d4578b56c-lc9bs   1/1     Running   0          109s   10.244.167.144   node     <none>           <none>
nginx-7d4578b56c-lll86   1/1     Running   0          109s   10.244.219.71    master   <none>           <none>
[root@master ~]# kubectl get rs -o wide
NAME               DESIRED   CURRENT   READY   AGE    CONTAINERS   IMAGES         SELECTOR
nginx-7d4578b56c   2         2         2       118s   nginx        nginx:latest   app=nginx-pod,pod-template-hash=7d4578b56c

如此看一查看到,创建的deoloyment给我们创建了一个ReplicaSet,并在replicaset下进行创建pod。

5.3.3 弹性扩缩容

扩容:

[root@master ~]# kubectl scale deploy nginx  --replicas=6
deployment.apps/nginx scaled
[root@master ~]# kubectl get rs 
NAME               DESIRED   CURRENT   READY   AGE
nginx-7d4578b56c   6         6         2       4m37s
[root@master ~]# kubectl get pods 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7d4578b56c-7grgl   1/1     Running   0          43s
nginx-7d4578b56c-jvrvz   1/1     Running   0          43s
nginx-7d4578b56c-lc9bs   1/1     Running   0          5m14s
nginx-7d4578b56c-lll86   1/1     Running   0          5m14s
nginx-7d4578b56c-q5rjj   1/1     Running   0          43s
nginx-7d4578b56c-r5kgd   1/1     Running   0          43s

(也可以使用edit进入文件进行更改)

缩容同理,缩容我们实验edit进入文件内部更改:

[root@master ~]# kubectl edit deploy nginx 
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:


deployment.apps/nginx edited
[root@master ~]# kubectl get pods 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7d4578b56c-lc9bs   1/1     Running   0          6m32s
nginx-7d4578b56c-lll86   1/1     Running   0          6m32s
[root@master ~]# kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
nginx-7d4578b56c   2         2         2       6m37s

5.4 Pod控制器:DaemonSet

5.4.1 DaemonSet介绍

DaemonSet 是 Kubernetes 中的一个控制器,它确保在集群中的每个节点上都运行一个指定的 Pod 的副本。这在需要在每个节点上运行守护进程或后台任务时非常有用,比如日志收集、监控、缓存、存储、安全服务等。

Pod:DaemonSet 确保在集群中的每个节点上都运行一个 Pod 的副本。当新的节点加入集群时,DaemonSet 会自动在新节点上创建 Pod。如果 Pod 因为某些原因停止运行,DaemonSet 会自动重启这个 Pod。可以通过节点选择器和节点亲和性来控制哪些节点上运行 Pod。当更新 DaemonSet 的定义时,Kubernetes 会自动更新所有节点上的 Pod。

DaemonSet控制器的特点:每当向集群中添加一个节点时,指定的Pod 副本也将添加到该节点上,当节点从集群中移除时,Pod 也就被垃圾回收了。

5.4.2 DaemonSet实例测试

apiVersion: apps/v1
kind: DaemonSet      
metadata:
  name: nginx
  namespace: default
spec: 
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:latest

查看资源:

[root@master ~]# kubectl get pods -o wide 
NAME          READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
nginx-clfhb   1/1     Running   0          8m29s   10.244.167.147   node     <none>           <none>
nginx-lzvcz   1/1     Running   0          8m29s   10.244.219.74    master   <none>           <none>
[root@master ~]# 

由于我是双节点(一主一从),并且taint master我以关闭;在正常情况下,DaemonSet会去判断集群node的数量进行创建,在我不关闭taint的时候,也就会存在一个pod,他是根据node的数量而不是集群机器总数。

六.Service

6.1 Service介绍

Service:是一种抽象的概念,为一组具有相同功能的 Pod 提供了一个稳定的网络访问入口。Service为Pod提供了一个稳定的网络地址和DNS名称,使得其他应用程序可以通过该地址和名称与Pod进行通信。Kubernetes中的服务用于暴露应用,使得Pod之间或Pod与外部通信能够稳定进行。即使Pod被销毁或重新创建,Service仍然提供稳定的访问地址。在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的pod服务。

Service类型:

ClusterIP:这是默认的 Service 类型。它为 Service 分配一个集群内部的虚拟 IP 地址,只能在集群内部访问。

NodePort:在每个节点上开放一个特定的端口,通过节点的 IP 地址和该端口可以访问 Service 后端的 Pod。这种类型允许从集群外部访问服务。

LoadBalancer:使用云提供商的负载均衡器,为 Service 提供外部可访问的 IP 地址。通常在云环境中使用。

6.2 ClusterIP 模式

6.2.1 ClusterIP 模式介绍

无论后端的 Pod IP 地址如何变化,通过 ClusterIP 都能始终访问到对应的服务。对于运行在 Kubernetes 集群内部的应用程序,ClusterIP 提供了一种方便的方式来进行服务间的通信。各个微服务可以通过 ClusterIP 来访问其他服务,而无需知道具体的 Pod 信息。当有多个 Pod 被同一个 Service 的标签选择器选中时,ClusterIP 会将请求自动分发到这些 Pod 上,实现负载均衡。Kubernetes 会根据一定的负载均衡策略(如轮询、随机等)将请求分配到不同的 Pod 上,从而提高服务的性能和可用性。通过负载均衡,可以有效地利用集群中的资源,避免单个 Pod 过载,同时也提高了系统的容错能力。如果某个 Pod 出现故障,请求会被自动分发到其他正常的 Pod 上,不会影响整个服务的可用性。

6.2.2 ClusterIP模式实例测试

先创建一个Deployment作为实验对象:

[root@master ~]# vi deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec: 
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
[root@master ~]# kubectl apply -f deployment.yaml 
deployment.apps/nginx created
[root@master ~]# kubectl get pods 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-5c4c85f44b-5xgrd   1/1     Running   0          2m54s
nginx-5c4c85f44b-bgk4h   1/1     Running   0          2m54s
nginx-5c4c85f44b-n2gp8   1/1     Running   0          2m54s

创建Service资源:

[root@master ~]# vi service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: clusterip
  namespace: default
spec:
  selector: 
    app: nginx-pod
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80

[root@master ~]# kubectl apply -f service.yaml 
service/clusterip created

部署完成后我们查看pod的IP:

[root@master ~]# kubectl get svc 
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
clusterip    ClusterIP   10.104.230.162   <none>        80/TCP    7s
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   24h
[root@master ~]# kubectl get pods -o wide 
NAME                     READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
nginx-5c4c85f44b-5xgrd   1/1     Running   0          6m17s   10.244.167.149   node     <none>           <none>
nginx-5c4c85f44b-bgk4h   1/1     Running   0          6m17s   10.244.219.75    master   <none>           <none>
nginx-5c4c85f44b-n2gp8   1/1     Running   0          6m17s   10.244.167.148   node     <none>           <none>

我们可以发现,我们并未指定其ClusterIP的具体值,直接帮我们生成了一个随机的IP,我们也可以自己指定IP,增加clusterIP选项添加IP即可。

测试访问:

为了让效果更加明显,修改index.html文件将其设置为各自pod的clusterip:
[root@master ~]#  kubectl exec -it nginx-5c4c85f44b-bgk4h  /bin/sh
# echo "10.244.219.75" > /usr/share/nginx/html/index.html
# exit
...

测试访问:
[root@master ~]# curl 10.244.167.149
10.244.167.149
[root@master ~]# curl 10.244.167.148
10.244.167.148
[root@master ~]# curl 10.244.219.75
10.244.219.75

6.3 NodePort模式

6.3.1 NodePort介绍

在之前的样例中,创建的Service的ip地址只有集群内部才可以访问,如果希望将Service暴露给集群外部使用,那么就要使用到另外一种类型的Service,称为NodePort类型。NodePort的工作原理其实就是将service的端口映射到Node的一个端口上,然后就可以通过NodeIp:NodePort来访问service。

6.3.2 NodePort模式实例测试

部署Pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

部署NodePort:

apiVersion: v1
kind: Service
metadata:
  name: nodeport
  namespace: default
spec:
  selector:
    app: nginx-pod
  type: NodePort
  ports:
  - port: 80
    nodePort: 30001
    targetPort: 80

使用curl命令访问node:nodeport:

[root@master ~]# curl http://192.168.100.120:30001/
10.244.167.132   ##我自己写入的,为了效果明显
[root@master ~]# curl http://192.168.100.120:30001/
10.244.167.132
[root@master ~]# curl http://192.168.100.120:30001/
10.244.167.132

七.数据存储

7.1 数据存储介绍

在kubernetes中的容器的生命周期可能会很短,会被频繁地创建和销毁。那么容器在销毁时,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器的数据,kubernetes引入了Volume的概念。

Volume访问到后面的pod服务。是Pod中能够被多个容器访问的共享目录,它被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下,kubernetes通过Volume实现同一个Pod中不同容器之间的数据共享以及数据的持久化存储。Volume的生命容器不与Pod中单个容器的生命周期相关,当容器终止或者重启时,Volume中的数据也不会丢失。

kubernetes的Volume支持多种类型,比较常见的有下面几个:

简单存储:EmptyDir、HostPath、NFS

高级存储:PV、PVC

配置存储:ConfigMap、Secret

7.2 EmptyDir模式

7.2.1 EmptyDir模式介绍

EmptyDir在 Pod 被分配到一个节点上时创建,并且只要该 Pod 在该节点上运行,它就会一直存在。其主要作用是为 Pod 中的容器提供临时存储。EmptyDir是最基础的Volume类型,一个EmptyDir就是Host上的一个空目录。

7.2.2 EmptyDir模式实例测试

创建yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: volume-emptydir
  namespace: base
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: logs-volume
      mountPath: /var/log/nginx

  - name: busybox
    image: busybox:latest
    command: ["/bin/sh", "-c", "tail -f /logs/access.log"]
    volumeMounts:
    - name: logs-volume
      mountPath: /logs

  volumes:
  - name: logs-volume
    emptyDir: {}

在volumes部分定义了一个名为logs-volume的存储卷,类型为emptyDir: {},这直接表明了该存储卷是临时的。定义 volumes 部分并在容器中使用 volumeMounts,可以将存储卷挂载到容器的特定目录,使得容器可以像访问本地文件系统一样访问存储卷中的数据。

Kubernetes使用 EmptyDir 类型的存储卷实现了同一个 Pod 内不同容器之间的数据共享。在这个例子中,nginx 容器产生的日志可以被写入到挂载的 /var/log/nginx 目录,而 busybox 容器通过挂载同一个 EmptyDir 卷到 /logs 目录,可以实时查看 nginx 容器产生的日志文件,实现了不同容器之间的数据传递和共享,体现了 EmptyDir 作为临时存储的用途。由于 EmptyDir 的生命周期与 Pod 绑定,当 Pod 被删除时,存储在其中的数据也会被删除。这适用于存储一些临时数据,比如在这个实验中的日志文件,这些数据在 Pod 的运行期间是有用的,但不需要长期保存。

验证:

[root@master ~]# kubectl exec -it volume-emptydir -n base -c busybox -- ls /logs
access.log  error.log
[root@master ~]# kubectl exec -it volume-emptydir -n base -c nginx -- ls /var/log/nginx
access.log  error.log

7.3 HostPath模式

7.3.1 HostPath模式介绍

HostPath卷将主机节点上的文件或目录挂载到 Pod 中的容器中。这使得容器可以访问主机上的特定文件或目录,通常用于在容器和主机之间共享数据,或者在开发和测试环境中提供特定的配置文件或数据。这样的设计就可以保证Pod销毁了,但是数据依据可以存在于Node主机上。

7.3.2 HostPath模式实例测试

编写文件:

apiVersion: v1
kind: Pod
metadata:
  name: volume-hostpath
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:latest
    command: ["/bin/sh","-c","tail -f /logs/access.log"]
    volumeMounts:
    - name: logs-volume
      mountPath: /logs
  volumes:
  - name: logs-volume
    hostPath:
      path: /root/logs
      type: DirectoryOrCreate

创建完成之后,访问测试,访问nginx,再到node节点查看日志是否生成:

[root@master ~]# kubectl get pods -o wide 
NAME                     READY   STATUS    RESTARTS   AGE   IP               NODE   NOMINATED NODE   READINESS GATES
nginx-5c4c85f44b-pw8tq   1/1     Running   0          55m   10.244.167.132   node   <none>           <none>
volume-hostpath          2/2     Running   0          55s   10.244.167.135   node   <none>           <none>
[root@master ~]# curl 10.244.167.135
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

## 到node节点查看日志:
[root@node ~]# ls logs/
access.log  error.log
[root@node ~]# cat logs/access.log 
10.244.219.64 - - [06/Feb/2025:06:36:24 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"

7.4 NFS模式

7.4.1 NFS模式介绍

在 Kubernetes 中使用 NFS 时,不是创建一个临时的volume,而是创建一个持久化存储卷(PersistentVolume,PV),通过 NFS 协议连接到外部的 NFS 服务器提供的存储资源。这个存储卷可以被多个 Pod 重复使用,并且数据在 Pod 被删除或重新调度后仍然保留在 NFS 服务器上,而不是像临时存储卷(EmptyDir)那样在 Pod 生命周期结束时数据被删除。

NFS服务器介绍:NFS是一个网络文件存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上,这样的话,无论Pod在节点上怎么转移,只要Node跟NFS的对接没问题,数据就可以成功访问。

7.4.2 NFS模式实例测试

在每个节点分别下载nfs-utils,主节点下载nfs作为服务器使用,要在的每个node节点上都安装下nfs,这样的目的是为了node节点可以驱动nfs设备

[root@master yaml]# yum install nfs-utils -y
[root@master yaml]# mkdir -pv  /root/data/nfs
[root@master yaml]# vi /etc/exports
/root/data/nfs 192.168.100.0/24(rw,no_root_squash)
#在配置文件下添加可执行的IP并赋予权限

编写yaml文件

apiVersion: v1
kind: Pod
metadata:
  name: volume-nfs
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:latest
    command: ["/bin/sh","-c","tail -f /logs/access.log"]
    volumeMounts:
    - name: logs-volume
      mountPath: /logs
  volumes:
  - name: logs-volume
    nfs:
      server: 192.168.100.110
      path: /root/data/nfs

执行完成后,查看pod的详细信息查看挂载地址是否生效,访问nginx,查看日志是否正确输出至挂载点:

[root@master ~]# kubectl describe pod volume-nfs 
.......
Volumes:
  logs-volume:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    192.168.100.110
    Path:      /root/data/nfs
    ReadOnly:  false

[root@master ~]# kubectl get pods -o wide 
NAME                     READY   STATUS    RESTARTS   AGE     IP               
volume-nfs               2/2     Running   0          2m23s   10.244.167.136   node   <none>           <none>
[root@master ~]# curl 10.244.167.136
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master ~]# ls data/nfs/
access.log  error.log
[root@master ~]# cat data/nfs/access.log 
10.244.219.64 - - [06/Feb/2025:06:46:25 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"

7.5 PV与PVC模式

7.5.1 PV与PVC模式介绍

PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下PV由kubernetes管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。它代表了实际的存储设备或存储系统中的一块存储区域,例如 NFS 共享、云存储等。

PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC其实就是用户向kubernetes系统发出的一种资源需求申请。它由用户创建,用于向 Kubernetes 集群请求一定数量和特定访问模式的存储。

访问模式:

ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载

ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载

ReadWriteMany(RWX):读写权限,可以被多个节点挂载

回收策略(persistentVolumeReclaimPolicy)

当PV不再被使用了之后,对其的处理方式。三种策略:

Retain (保留) 保留数据,需要管理员手工清理数据

Recycle(回收) 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*

Delete (删除) 与 PV 相连的后端存储完成 volume 的删除操作。

PV资源清单:

apiVersion: v1  
kind: PersistentVolume
metadata:
  name: pv2
spec:
  nfs: # 存储类型,与底层真正存储对应
  capacity:  # 存储能力,目前只支持存储空间的设置
    storage: 2Gi
  accessModes:  # 访问模式
  storageClassName: # 存储类别
  persistentVolumeReclaimPolicy: # 回收策略

PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息。

资源清单:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
  namespace: dev
spec:
  accessModes: # 访问模式
  selector: # 采用标签对PV选择
  storageClassName: # 存储类别
  resources: # 请求空间
    requests:
      storage: 5Gi

7.5.2 创建PV

删除之前创建过的NFS文件下的文件,在重新编写配置文件,在配置文件中写入三个PV,并赋予权限,创建挂载目录:

[root@master yaml]# vi /etc/exports
/root/data/nfs/pv1 192.168.100.0/24(rw,no_root_squash)
/root/data/nfs/pv2 192.168.100.0/24(rw,no_root_squash)
/root/data/nfs/pv3 192.168.100.0/24(rw,no_root_squash)
[root@master yaml]# systemctl restart nfs
[root@master yaml]# mkdir -pv /root/data/nfs/{pv1,pv2,pv3}

创建PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /root/data/nfs/pv1
server: 192.168.100.110
#模版
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
spec:
  capacity:
    storage: 2Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /root/data/nfs/pv2
    server: 192.168.100.110
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv3
spec:
  capacity:
    storage: 3Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /root/data/nfs/pv3
server: 192.168.100.110

[root@master ~]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created
persistentvolume/pv2 created
persistentvolume/pv3 created
[root@master ~]# kubectl get pv 
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    1Gi        RWX            Retain           Available                                   5s
pv2    2Gi        RWX            Retain           Available                                   5s
pv3    3Gi        RWX            Retain           Available                                   5s

PV创建成功。

7.5.3 创建PVC

创建yaml文件创建PVC:

[root@master ~]# cat pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
  namespace: default
spec:
  accessModes:
  - ReadWriteMany  #RWX
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2
  namespace: default
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc3
  namespace: default
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 3Gi
[root@master ~]# kubectl apply -f pvc.yaml 
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
persistentvolumeclaim/pvc3 created
[root@master ~]# kubectl get pvc 
NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc1   Bound    pv1      1Gi        RWX                           6s
pvc2   Bound    pv2      2Gi        RWX                           6s
pvc3   Bound    pv3      3Gi        RWX                           6s

此时查看PV,发现PV的状态信息发生变化:从可用变为了已绑定

Available(可用): 表示可用状态,还未被任何 PVC 绑定

Bound(已绑定): 表示 PV 已经被 PVC 绑定

Released(已释放): 表示 PVC 被删除,但是资源还未被集群重新声明

Failed(失败): 表示该 PV 的自动回收失败

7.5.4 创建Pod使用存储

[root@master ~]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod1
  namespace: default
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["/bin/sh","-c","while true;do echo pod1 >> /root/out.txt; sleep 10; done;"]
    volumeMounts:
    - name: volume
      mountPath: /root/
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: pvc1
        readOnly: false
---
apiVersion: v1
kind: Pod
metadata:
  name: pod2
  namespace: default
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["/bin/sh","-c","while true;do echo pod2 >> /root/out.txt; sleep 10; done;"]
    volumeMounts:
    - name: volume
      mountPath: /root/
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: pvc2
        readOnly: false
[root@master ~]# kubectl apply -f pod.yaml 
pod/pod1 created
pod/pod2 created

查询挂载点是否有日志生成:

[root@master ~]# cat data/nfs/pv2/out.txt 
pod2
pod2
pod2
pod2
pod2
pod2
pod2

7.6 ConfigMap模式

7.6.1 ConfigMap模式介绍

ConfigMap 用于存储非敏感的配置数据。它可以将配置信息从容器化应用的代码中解耦出来,从而使得配置管理更加灵活。

特点:

用途:存储配置数据(例如数据库连接字符串、配置文件、环境变量等)。

存储方式:数据以键值对的形式存储,数据本身是明文的。

灵活性:可以通过环境变量、命令行参数或挂载文件的方式将 ConfigMap 数据传递给应用。

更新:可以在不重新创建 Pod 的情况下更新 ConfigMap,但若是挂载为文件,则需要重启 Pod 才会生效。

7.6.2 ConfigMap模式实例测试

创建实例文件:

[root@master ~]# cat configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap
  namespace: default
data:
  info: |
    username:admin
    password:123456
[root@master ~]# kubectl apply -f configmap.yaml 
configmap/configmap created
[root@master ~]# kubectl describe cm 
Name:         configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
info:
----
username:admin
password:123456

BinaryData
......

创建Pod使用ConfigMap:

[root@master ~]# cat configmap_pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - name: config
      mountPath: /configmap/config
  volumes:
  - name: config
    configMap:
      name: configmap
[root@master ~]# kubectl apply -f configmap_pod.yaml 
pod/pod-configmap created

[root@master ~]# kubectl exec -it pod-configmap  /bin/sh
# cd /configmap
# ls
config
# cd config
# ls
info
# cat info
username:admin
password:123456

# 可以看到映射已经成功,每个configmap都映射成了一个目录

# key--->文件     value---->文件中的内容

#此时如果更新configmap的内容, 容器中的值也会动态更新

7.7 Secret模式

7.7.1 Secret模式介绍

Secret 用于存储敏感信息,如密码、API 密钥、TLS 证书等。它与 ConfigMap 的主要区别是,Secret 默认会对数据进行 Base64 编码,并且可以加密存储。

特点:

用途:存储敏感信息(例如数据库密码、OAuth 令牌、证书等)。

存储方式:数据以 Base64 编码存储,默认不加密,但可以配置加密存储。

安全性:比 ConfigMap 更加安全,支持通过 Kubernetes 的加密机制进行存储和传输。

挂载方式:可以通过环境变量、挂载为文件或在 Pod 的容器中作为文件来使用。

7.7.2 Secret模式实例测试

首先使用base64对数据进行编码:

[root@master ~]# echo 'admin' | base64
YWRtaW4K
[root@master ~]# echo '123456' | base64
MTIzNDU2Cg==

创建secret:

[root@master ~]# cat secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: secret
  namespace: default
type: Opaque
data:
  username: YWRtaW4=
  password: MTIzNDU2
[root@master ~]# kubectl apply -f secret.yaml 
secret/secret created
[root@master ~]# kubectl describe secret secret 
Name:         secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes
username:  5 bytes

创建Pod使用secret:

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - name: config
      mountPath: /secret/config
  volumes:
  - name: config
    secret:
      secretName: secret
[root@master ~]# kubectl apply -f secret_pod.yaml 
pod/pod-secret created
[root@master ~]# kubectl exec -it pod-secret /bin/sh
# cd secret
# ls
config
# cd config
# ls
password  username
# cat password
123456
# cat username
admin

至此,已经实现了利用secret实现了信息的编码。

小结

作品不易,请务必珍惜,会持续更新。


http://www.kler.cn/a/534650.html

相关文章:

  • 【C语言系列】深入理解指针(5)
  • 【重生之学习C语言----杨辉三角篇】
  • oracle 基础语法复习记录
  • Mysql:数据库
  • 机器学习--2.多元线性回归
  • 如何在Window计算机本地部署DeepSeek-r1模型
  • 点(线)集最小包围外轮廓效果赏析
  • 第二个Qt开发实例:在Qt中利用GPIO子系统和sysfs伪文件系统实现按钮(Push Button)点击控制GPIO口(效果为LED2灯的灭和亮)
  • NFT Insider #167:Champions Tactics 角色加入 The Sandbox;AI 助力 Ronin 游戏生态
  • 2025 年前端开发趋势展望,开启新征程
  • PHP-运算符
  • mac下生成.icns图标
  • ubuntu20.04+RTX4060Ti大模型环境安装
  • Rust 核心语法总结
  • PTRACE_TRACEME 与反调试
  • MongoDB管道操作符(二)
  • PHP-回溯
  • HTML中的图片标签详解及路径使用【学术投稿-第五届环境资源与能源工程国际学术会议(ICEREE 2025)】
  • 使用多模态大语言模型进行深度学习的图像、文本和语音数据增强
  • Linux提权--John碰撞密码提权
  • K8S Deployment 实现 金丝雀(灰度) 发布
  • 用pytorch实现一个简单的图片预测类别
  • 原生redis实现分布式锁
  • web 第二次作业
  • 关于Vue.js组件开发
  • 基于keepalived+GTID半同步主从复制的高可用MySQL集群