Bootstrap

架构学习第五周--Kubernetes(一)

目录

一、Kubernetes介绍

1.1,基本概念

1.2,集群组成

二、Kubernetes集群部署

三、Pod资源管理介绍

3.1,资源管理基础

3.2,Pod资源管理

四、Kubernetes存储卷

4.1,存储卷

4.2,持久卷

五、应用配置

5.1,ConfigMap

5.2,Secret

一、Kubernetes介绍

1.1,基本概念

        Kubernetes是一个开源的容器编排系统,以应用为中心通过大量容器承载应用管理应用的全生命周期,并且可以实现容器集群的自动化部署、自动扩缩容、维护等功能。

        通过多台服务器组成Kubernetes集群可以整合各节点上的CPU和内存资源进行统一分配,实现容器,网络和存储的编排。

容器编排遵循CRI(Container Runtime Interface)协议--如Docker, Containerd, CRI-O

网络编排遵循CNI(Container Network Interface)协议--如CoreOS Flannel, ProjectCalico

存储编排遵循CSI(Container Storage Interface)协议--如In-Tree Driver

1.2,集群组成

        Kubernetes集群主要由Master节点和Worker节点(也叫node节点)构成,通常还有Addons(插件)以pod的形式托管运行在集群上。提供其他功能,如Prometheus监控系统、ELK日志系统等。

Master组件--提供集群的管理控制中心

-API service:用于暴露API接口,任何集群的请求、调用操作均通过该组件提供的接口

-Scheduler:调度器,为pod选择最佳运行节点

-Etcd:默认键指存储系统,存储API service上的接各类信息

-Controller-Manager:运行管理控制器,用于统一管控该组件下的各类控制器

  --节点(Node)控制器

  --副本(Replication)控制器:负责维护系统中每个副本中的pod

  --端点(Endpoints)控制器:负责连接service和pod

  --.........

Worker组件--提供Kubernetes运行时环境,以及维护Pod

-kubelet:接收并执行Master指令,管理由Scheduler绑定至当前节点上pod的容器

-kubel proxy:在节点上将service资源的定义通过iptables规则实现

Addons组件--为集群提供其他功能,如Prometheus监控系统、ELK日志系统等

-Network Plugin(必装):网络插件,经由CNI接口,负责为pod提供专用的通信网络

  --常使用CoreOs Flannel,ProjectCalico

-Cluster DNS(必装):集群DNS服务器,负责服务注册,发现和名称解析

  --常使用CoreDNS

        Pod是Kubernetes中运行应用及应用调度的最小逻辑单元,一个Pod代表集群上正在运行的一个进程;Pod具有动态性,其IP地址在配置清单重构后重新分配。

        Service资源能够为一组提供相同服务的Pod提供负载均衡,其IP地址或名称会作为客户端的流量入口

Kubernetes网络模型

节点网络:集群节点间的通信网络,并负责打通与集群外部端点间的通信

Pod网络:经由CNI网络插件实现,为集群上的Pod对象提供的网络

Service网络:在部署集群时指定,各Service对象使用的地址将从该网络中分配,由集群自行管理

Kubernetes四种主要通信流量:

  --同一Pod内的容器间通信

  --Pod间的通信

  --Pod与Service间的通信

  --集群外部流量与Service间的通信

Pod网络需要第三方兼容CNI规范的网络插件实现,插件需要满足以下要求:

  --所有Pod间均可不经NAT机制而直接通信

  --所有节点均可不经NAT机制直接与所有Pod通信

  --所有Pod对象都位于同一平面网络中

二、Kubernetes集群部署

#Kubernetes集群(v1.29)

#部署环境:虚拟机系统--ubuntu2204,Docker CE 25.0.3,cri-dockerd v0.3.10

#部署预设系统环境:

#(1)使用chronyd服务同步节点 时间

#(2)在本地hosts文件解析各节点

#(3)禁用所有Swap设备

#(4)禁用默认的iptables策略

#172.29.7.10--k8s-master01

#172.29.7.11--k8s-master02

#172.29.7.12--k8s-master03

#172.29.7.13--k8s-work01

#172.29.7.14--k8s-work02

#172.29.7.15--k8s-work03

#禁用所有节点的swap并配置本地解析

root@k8s-master01:~# vim /etc/fstab

#/swap.img      none    swap    sw      0       0

root@k8s-master01:~# systemctl --type swap                                     #查询所有swap设备

root@k8s-master01:~# systemctl mask swap.img.swap                    #禁用swap设备

root@k8s-master01:~# swapoff -a                                                        #关闭所有swap

root@k8s-master01:~# cat /etc/hosts
127.0.0.1 localhost

172.29.7.10 k8s-master01.wlm.com k8s-master01 kubeapi.wlm.com kubeapi
172.29.7.11 k8s-master02.wlm.com k8s-master02
172.29.7.12 k8s-master03.wlm.com k8s-master03
172.29.7.13 k8s-work01.wlm.com k8s-work01
172.29.7.14 k8s-work02.wlm.com k8s-work02
172.29.7.15 k8s-work03.wlm.com k8s-work03

#各节点按照阿里云配置命令安装docker-ce 25.0.3版本和cri-dockerd_0.3.10.3

root@k8s-master01:~# apt-get -y install apt-transport-https ca-certificates curl software-properties-common                                            #参考阿里云官网配置apt源

root@k8s-master01:~# curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
root@k8s-master01:~# add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
root@k8s-master01:~# apt-get -y update

root@k8s-master01:~# apt-get install docker-ce=5:25.0.3-1~ubuntu.22.04~jammy -y

root@k8s-master01:~# vim /etc/docker/daemon.json                  #对docker进行优化
{
"registry-mirrors": [
        "https://docker.m.daocloud.io",
        "http://docker.udayun.com",
        "https://ccr.ccs.tencentyun.com"
        ],
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5,
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
        "max-size": "300m"
        },
"storage-driver": "overlay2",
"live-restore": true
}

root@k8s-master01:~# dpkg -i ./cri-dockerd_0.3.10.3-0.ubuntu-jammy_amd64.deb       #在github下载安装包至本地并进行安装
root@k8s-master01:~# systemctl daemon-reload
root@k8s-master01:~# systemctl restart docker.service

#安装kubelet,kubeadm和kubectl

root@k8s-master01:~# apt-get update && apt-get install -y apt-transport-https        #参考阿里云官网配置apt源
root@k8s-master01:~# curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/deb/Release.key |
    gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

root@k8s-master01:~# echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/deb/ /" |
    tee /etc/apt/sources.list.d/kubernetes.list

root@k8s-master01:~# apt-get update
root@k8s-master01:~# apt-get install -y kubelet kubeadm kubectl

#整合kubelet和cri-dockerd

root@k8s-master01:~# vim /usr/lib/systemd/system/cri-docker.service

......

ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --cni-bin-dir=/opt/cni/bin --cni-cache-dir=/var/lib/cni/cache --cni-conf-dir=/etc/cni/net.d --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9

......
root@k8s-master01:~# systemctl daemon-reload
root@k8s-master01:~# systemctl restart cri-docker.service

root@k8s-master01:~# mkdir /etc/sysconfig
root@k8s-master01:~# vim /etc/sysconfig/kubelet             #为kubelet添加调用容器的参数
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=/run/cri-dockerd.sock"

#下载Kubernetes部署必要的镜像

root@k8s-master01:~# kubeadm config images list                                  #列出所需镜像
root@k8s-master01:~# kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --cri-socket=unix:///var/run/cri-dockerd.sock                                                                           #指定阿里云作为源拉取镜像
root@k8s-master01:~# docker image pull registry.aliyuncs.com/google_containers/pause:3.6
root@k8s-master01:~# docker image tag registry.aliyuncs.com/google_containers/pause:3.6 registry.k8s.io/pause:3.6

#初始化Kubernetes集群

root@k8s-master01:~# kubeadm init --control-plane-endpoint="kubeapi.wlm.com" --kubernetes-version=v1.29.10 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --token-ttl=0 --upload-certs --image-repository=registry.aliyuncs.com/google_containers --cri-socket unix:///run/cri-dockerd.sock                                                                                #初始化Kubernetes

root@k8s-master01:~# mkdir ~/.kube
root@k8s-master01:~# cp /etc/kubernetes/admin.conf  .kube/config        #将认证Kubernetes集群的配置文件拷贝至管理员目录下
root@k8s-master01:~# kubectl get nodes                 #查看当前集群节点,确认初始化成功
NAME           STATUS   ROLES           AGE   VERSION
k8s-master01   Ready    control-plane   24m   v1.29.10

root@k8s-master01:~# kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml                #为集群部署网络插件
root@k8s-master01:~# kubectl get pods -n kube-flannel            #确保网络插件运行
NAME                    READY   STATUS    RESTARTS      AGE
kube-flannel-ds-bb6z7   1/1     Running   0             16h

root@k8s-master02:~# kubeadm join kubeapi.wlm.com:6443 --token nktlkd.df4k5be854hi7l8u         --discovery-token-ca-cert-hash sha256:2311eef192ada03ba17e2e1535bf365fd9faa4d3a4486013d13802244e78ee64         --control-plane --certificate-key d8508a027f95cabcee529c068b6bdcf64fc7544ee0a245c526559456ca0252b3 --cri-socket unix:///run/cri-dockerd.sock                                        #按照提示添加master节点

root@k8s-work01:~# kubeadm join kubeapi.wlm.com:6443 --token nktlkd.df4k5be854hi7l8u         --discovery-token-ca-cert-hash sha256:2311eef192ada03ba17e2e1535bf365fd9faa4d3a4486013d13802244e78ee64 --cri-socket unix:///run/cri-dockerd.sock                                   #按照提示添加work节点

root@k8s-master01:~# kubectl get nodes                                #加入所有节点后运行命令可查看所有节点信息
NAME           STATUS   ROLES           AGE   VERSION
k8s-master01   Ready    control-plane   16h   v1.29.10
k8s-master02   Ready    control-plane   15h   v1.29.10
k8s-master03   Ready    control-plane   16h   v1.29.10
k8s-work-02    Ready    <none>          16h   v1.29.10
k8s-work01     Ready    <none>          16h   v1.29.10
k8s-work03     Ready    <none>          16h   v1.29.10

root@k8s-master01:~# kubectl config view                                #可查询集群信息

#Addons附件安装

#MetaILB部署

root@k8s-master01:~# kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl apply -f - -n kube-system             #配置kube-proxy启动strictARP模式

root@k8s-master01:~# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.3/config/manifests/metallb-native.yaml                                                                                              #部署metallb

root@k8s-master01:~# kubectl get pods -n metallb-system                #确认metallb的Pod正常运行
NAME                          READY   STATUS    RESTARTS   AGE
controller-5f56cd6f78-mf5mp   1/1     Running   0          3m22s
speaker-9jsjw                 1/1     Running   0          3m22s
speaker-mv459                 1/1     Running   0          3m22s
speaker-tzcsf                 1/1     Running   0          3m22s
speaker-v49ld                 1/1     Running   0          3m22s
speaker-w5jlx                 1/1     Running   0          3m22s
speaker-w6t29                 1/1     Running   0          3m22s

root@k8s-master01:~# cat eip-pool.yaml                                             #创建地址池
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: localip-pool
  namespace: metallb-system
spec:
  addresses:
    - 172.29.7.51-172.29.7.80
  autoAssign: true
  avoidBuggyIPs: true
root@k8s-master01:~# cat L2.yaml                                                         #创建二层公告机制
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: localip-pool-l2a
  namespace: metallb-system
spec:
  ipAddressPools:
    - localip-pool
  interfaces:
    - eth0
root@k8s-master01:~# kubectl apply -f eip-pool.yaml
root@k8s-master01:~# kubectl apply -f L2.yaml

#测试MetaILB

root@k8s-master01:~# kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=2                                       #创建测试
deployment.apps/demoapp created
root@k8s-master01:~# kubectl create service loadbalancer demoapp --tcp=80:80
service/demoapp created
root@k8s-master01:~# kubectl get service demoapp
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
demoapp   LoadBalancer   10.110.34.72   172.29.7.51   80:30559/TCP   8s
root@k8s-master01:~# kubectl delete service/demoapp deployment/demoapp        #删除测试

#Ingress Nginx部署(可选,需在所有节点部署clash代理获取官网镜像)

root@k8s-master01:~# kubectl apply -f https://github.com/kubernetes/ingress-nginx/blob/release-1.10/deploy/static/provider/cloud/deploy.yaml

root@k8s-master01:~# kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-284dr        0/1     Completed   0          22h
ingress-nginx-admission-patch-29qb7         0/1     Completed   0          22h
ingress-nginx-controller-8556f68c99-4mrxc   1/1     Running     0          22h

#Metrics Server部署(可选,需要clash服务)
root@k8s-master01:~# wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.0/components.yaml

root@k8s-master01:~# vim components.yaml                                        #添加下列参数

- args:
        - --kubelet-insecure-tls

root@k8s-master01:~# kubectl apply -f components.yaml
root@k8s-master01:~# kubectl get pods -n kube-system -l k8s-app=metrics-server
NAME                             READY   STATUS    RESTARTS   AGE
metrics-server-98bc7f888-krggf   1/1     Running   0          7h3m
 

#Kuboard部署

root@k8s-master01:~# kubectl apply -f https://github.com/iKubernetes/learning-k8s/tree/master/Kuboard/kuboard-ephemeral/kuboard-v3.yaml

root@k8s-master01:~# cat software/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kuboard-v3
  namespace: kuboard
spec:
  ingressClassName: nginx
  rules:
  - host: kuboard.wlm.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: kuboard-v3
            port:
              number: 80
        pathType: Prefix
root@k8s-master01:~# kubectl apply -f ingress.yaml
root@k8s-master01:~# kubectl get services -n kuboard
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                                        AGE
kuboard-v3   LoadBalancer   10.97.53.44   172.29.7.51   80:30080/TCP,10081:30081/TCP,10081:30081/UDP   2d22h
#使用web端即可访问域名或IP,账号密码为admin:Kuboard123

#以下为高危操作,请在测试环境谨慎使用,请勿在生产环境操作

#集群初始化时需要一次成功,若失败需先解决失败报错并重置该节点,最后重新加入集群

root@k8s-master01:~# kubeadm reset --cri-socket unix:///run/cri-dockerd.sock

root@k8s-master01:~# rm -rf /etc/kubernetes/ /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni /etc/cni/net.d /var/lib/etcd /run/flannel/                #删除残留文件

#若拆除整个集群,需先拆除work节点,再拆除master节点,直接执行reset命令即可

#若拆除单个已然加入集权的节点,需要先排空该节点

root@k8s-master01:~# kubectl cordon k8s-work01                    #禁止该节点作为调度目标

root@k8s-master01:~# kubectl drain k8s-work01                       #排空该节点容器

root@k8s-master01:~# kubectl delete nodes k8s-work01          #再控制平面上删除该节点

root@k8s-master01:~# kubeadm reset  --cri-socket unix:///run/cri-dockerd.sock       #重置该节点

#若拆除单个节点未排空时直接执行rest命令,控制节点上etcd会残留旧节点信息导致无法成功加入,清除残留etcd信息操作如下:

root@k8s-master01:~# kubectl get pods -n kube-system | grep etcd                       #查看现有集群的etcd

root@k8s-master01:~# kubectl exec -it etcd-k8s-master1 sh -n kube-system          #进入容器并进行etcd删除操作

#配置环境

$ export ETCDCTL_API=3
$ alias etcdctl='etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key'

# 查看 etcd 集群成员列表
$ etcdctl member list                                            #列出etcd各节点的ID

$ etcdctl member remove ID                                #删除残留节点的ID

$ etcdctl member list                                             #检测信息

$ exit

#重置需要加入的节点并重新执行join命令

三、Pod资源管理介绍

3.1,资源管理基础

Kubernetes内存在多种资源均遵循RESTful  API资源规范:

            apiVersion: GROUP/VERSION                       
            kind:KIND                                                      
            metadata:                                                         
                name: <NAME>                                           
                namespace: <NAMESPACE>
                labels: 
                    key1: val1
                annotations:
                    key1: val1
            spec: 

            status:

apiVersion-------所属资源组名称和版本

kind----------------资源类型

metadata---------元数据,只有4个(name,namespace,labels,annotations)

name--------------名称,对于名称空间级别的资源:同一名称空间下,同一类型中,必须惟一
namespace------名称空间
labels:-------------标签,可被标签选择器过滤和筛选
annotations-----注解,不可被筛选

spec---------------期望状态,由用户创建时定义的目标状态

status-------------实际状态,由控制平面组件负责维护和更

root@k8s-master01:~# kubectl api-versions                          #列出资源组和版本

root@k8s-master01:~# kubectl api-resources                        #列出所有支持的资源类型
NAME                             SHORTNAMES       APIVERSION        NAMESPACED         KIND
componentstatuses         cs                             v1                         false        ComponentStatus

#namespaces为true代表只能运行在名称空间的资源,false代表只能运行在集群资源内,即使指定名称空间也无效

root@k8s-master01:~# kubectl explain Deployment                   #打印说明文档

root@k8s-master01:~# kubectl explain Deployment.spec          #展示嵌套的说明文档

 对于资源对象的基本管理操作--CRUD

Create-----kubectl create
Read-------kubectl get/describe
Update----kubectl edit/patch/replace/set
Delete-----kubectl delete

Namespace

        名称空间是Kubernetes集群提供对内部资源进行“软隔离”的机制,以方便用户管理和组织集群资源,主要分为两类:

--系统级名称空间:由Kubernetes集群默认创建,主要用来隔离系统级的资源对象

--自定义名称空间:由用户按需创建

系统级名称空间

--default:默认的名称空间,为任何名称空间级别的资源提供的默认设定

--kube-system:Kubernetes集群自身组件及其它系统级组件使用的名称空间,Kubernetes自身的关键组件均部署在该名称空间中

--kube-public:公众开放的名称空间,所有用户都可以读取内部的资源

--kube-node-lease:节点租约资源所用的名称空间,节点心跳和组件领导选举在该空间

root@k8s-master01:~# kubectl get ns
root@k8s-master01:~# kubectl get leases -n kube-node-lease
NAME           HOLDER         AGE
k8s-master01   k8s-master01   6d1h
k8s-master02   k8s-master02   6d1h
k8s-master03   k8s-master03   6d1h
k8s-work01     k8s-work01     6d1h
k8s-work02     k8s-work02     6d1h
k8s-work03     k8s-work03     6d1h

        所有的系统级名称空间均不能进行删除操作,除default外,其它三个也不应该用作业务应用的部署目标

3.2,Pod资源管理

 Pod资源类型
        --静态Pod:由kubelet加载配置信息后,自动在节点级创建的Pod
        root@k8s-master01:~# ls /etc/kubernetes/manifests/
        etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yaml
        --自主式Pod:由用户直接定义并提交给API Server创建的Pod。由于没有工作负载控制器管控,一旦删除或节点宕机,将不会被重建
        --由工作负载控制器管控的Pod

为方便平台对Pod状态进行检测,会使用三种探针:

        --startup Probe(启动时探测是否启动成功,返回成功后结束)

        --liveness Probe(周期性探测,判断Pod是否处于running)

        --readiness Probe(周期性探测,判断Pod是否提供了服务)

同时对于每种探针可以使用三种检测机制和五种配置参数:

--三种机制

Exec Action:根据指定命令的结果状态码判定

TcpSocket Action:根据相应TCP套接字连接建立状态判定

HTTPGet Action:根据指定https/http服务URL的响应结果判定

--五种参数:

initialDelaySeconds------首次探测延迟,避免初始化未造成探测结果未失败

periodSeconds------------每次探测的间隔时间

timeoutSeconds----------探测超时时间

successThreshold--------判断成功的探测阈值,连续成功探测规定次数后,将状态转为成功

failureThreshold-----------判断失败的探测阈值,连续失败探测规定次数后,将状态转为失败

Pod内关于CPU,Memory和Hugepages的requests和limits

资源需求(requests)

--定义需要系统预留给该容器使用的资源最小可用值

--容器运行时可能用不到这些额度的资源,但用到时必须确保有相应数量的资源可用

--资源需求的定义会影响调度器的决策

资源限制(limits)

--定义该容器可以申请使用的资源最大可用值,超出该额度的资源使用请求将被拒绝

--该限制需要大于等于requests的值,但系统在其某项资源紧张时,会从容器那里回收超出其requests值的部分

单节点多容器的Pod设计

Sidecar模式----Pod由主应用程序和一个Sidecar容器组成,辅助容器负责为主容器提供辅助服务以增强主容器的功能,对于主应用程序是必须的,但是不必运行在同一容器内

Ambassador模式----由主应用程序和Ambassador容器组成,辅助容器代替主应用向外部发送请求

Adapter模式----由主应用程序和Adapter容器组成,辅助容器代替主应用向外部响应请求

Init Container模式----在Pod创建后串行运行初始化容器,正常运行后容器自动删除,主应用程序开始运行

Pod状态

状态含义及可能的原因

Pending

Pod未能由Scheduler完成调度,通常由于资源依赖、资源不足和调度策略无法满足等原因导致

Init:N/M

Pod中定义了M个Init容器,其中N个已经运行完成,目前仍处于初始化过程中

Init:Error

Init容器运行失败,需借助日志排查具体的错误原因

Init:CrashLoopBackOff

Init容器启动失败,且在反复重启中,一般应该先确认配置方面的问题,再借助于日志进行排查

Completed

Pod中的各容器已经正常运行完毕,各容器进程业已经终止

CrashLoopBackOff

Pod启动失败,且处于反复重启过程中,通常是容器中的应用程序自身运行异常所致,可通过查看Pod事件、容器日志和Pod配置等几方面联合排查问题

ImagePullBackOff

Image拉取失败,检查Image URL是否正确,或手动测试拉取是否能够正常完成

Running

Pod运行正常;但也额外存在其内部进程未正常工作的可能性,此种情况下,可通过查看Pod事件、容器日志、Pod配置等几方面联合排查问题,或通过交互式测试验证问题所在

Terminating

Pod正处于关闭过程中,若超过终止宽限期仍未能正常退出,可使用命令强制删除该Pod (命令:kubectl delete pod [$Pod] -n [$namespace] --grace-period=0 --force)

Evicted

Pod被节点驱逐,通常原因可能是由节点内存、磁盘空间、文件系统的inode、PID等资源耗尽所致,可通过Pod的status字段确定具体的原因所在,并采取有针对性的措施扩充相应的资源

四、Kubernetes存储卷

4.1,存储卷

         存储卷是可供Pod中的所有容器访问的目录,为容器提供独立于容器生命周期的数据存取能力。存储卷对象并非Kubernetes系统一等公民,它定义在Pod上,因而卷本身的生命周期同Pod,一旦Pod删除卷的定义就同步消失,但其后端的存储及相关数据的生命周期通常要取决于存储介质。

Out-of-Tree存储卷插件:经由CSI接口扩展出的存储系统称为Out-of-Tree类的存储插件(CSI本身属于树内卷插件)

In-Tree存储卷插件

临时存储卷(emptyDir):直接定义于Pod内,临时设定存储空间由Pod管理,删除Pod定义的存储上的数据也会直接清空

节点本地存储卷(hostPath, local):Pod调度到哪个节点数据便存在该节点上,Pod删除后卷也会删除,但是数据依旧存储在该节点上

网络存储卷(NFS,iSCSI等):可以跨节点通过网络共享的卷

特殊存储卷(Secret、ConfigMap):集中式的为Pod提供配置文件

扩展接口(CSI):为扩展树外卷而存在的卷插件

4.2,持久卷

Pod级别定义存储卷缺陷

--卷对象的生命周期无法独立于Pod而存在

--使用者必须要足够熟悉可用的存储及其详情才能在Pod上配置和使用卷 

        为了解决存储卷与Pod的强耦合关系,为Pod提供持久化的存储能力,引入了PV(Persistent Volume)和PVC(Persistent Volume Claim)

PV是集群级别的资源,负责将存储空间引入到集群中,通常由管理员定义

PVC是名称空间级别的资源,由用户定义,用于在空闲的PV中申请使用符合过滤条件的PV,与选定的PV是一对一关系

PV是标准的资源类型,通常涉及下列定义

1,支持的存储特性:

--Volume Mode:当前PV卷提供的存储空间模型,分为块设备和文件系统两种

--StorageClassName:当前PV隶属的存储类;

--AccessMode:支持的访问模型,分为单路读写、多路读写和多路只读三种

--Size:当前PV允许使用的空间上限

2,在对象元数据上,根据需要定义标签

3,定义回收策略:Retain(保留但是无法引用,只能由管理员手动介入获取数据)和Delete(直接删除)

PVC也是标准的资源类型,它允许用户按需指定期望的存储特性进行PV过滤

过滤优先级:VolumeMode -> LabelSelector -> StorageClassName -> AccessMode -> Size

同时,PVC支持StorageClass资源的动态预配,还可以根据PVC的条件按需完成PV创建

五、应用配置

        ConfigMap和Secret是Kubernetes系统上两种特殊类型的存储卷,为容器中的应用提供配置据以定制程序的行为,其中敏感的配置信息,例如密钥、证书等则通常由Secret来配置。

         ConfigMap和Secret都属于名称空间级别,只能被同一名称空间中的Pod引用,在Pod对象 上支持以存储卷的形式将其挂载并加载相关的配置,从而降低了配置与镜像文件的耦合关系,提高了镜像复用能力。

        ConfigMap和Secret资源都是数据承载类的组件,是Kubernetes API的标准资源类型,是一等公民,其值支持:

        --单行字符串:常用于保存环境变量值,或者命令行参数等

        --多行字串:常用于保存配置文件的内容

5.1,ConfigMap

        ConfigMap在Pod的引用方式有环境变量和卷挂载两种方式,使用环境变量方式使仅在Pod生成时生效,使用卷挂载方式会在挂载点生成隐藏文件和对应的隐藏链接,在使用kubectl edit configmap 命令编辑ConfigMap参数后,在Pod内会生成新的隐藏文件并随即延迟更新隐藏链接

root@k8s-master01:~# kubectl create configmap demoapp --from-literal=Port=8080 --dry-run=client -o yaml                                                                #创建configmap
apiVersion: v1
data:
  Port: "8080"
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: demoapp
root@k8s-master01:~# cat demoapp.yaml                                    #卷挂载引用
apiVersion: v1
kind: Pod
metadata:
  name: configmaps-demo
  spec:
    containers:
    - image: nginx:alpine
      name: nginx-server
      volumeMounts:
      - name: ngxconfs
        mountPath: /etc/nginx/conf.d/
        readOnly: true
    volumes:
    - name: ngxconfs
      configMap:
        name: demoapp
        optional: false

5.2,Secret

        Secret主要用于存储密钥、令牌和SSH密钥等敏感信息,敏感信息采用base64编码保存。Secret创建方式类似ConfigMap,但是有类型子命令(generic,tls,docker-registry)。在Pod的引用方式也有环境变量和Secret卷挂载两种方式,在Pod上使用envFrom可以一次性导入Secret对象上的所有键值,使用环境变量会将参数打印至日志中,所以不建议使用环境变量引用Secret。

root@k8s-master01:~# kubectl create secret generic mysql-secret --from-literal=username=root --from-literal=password=Wlm123 --dry-run=client -o yaml         #生成Secret
apiVersion: v1
data:
  password: V2xtMTIz
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: null
  name: mysql-secret
root@k8s-master01:~# echo V2xtMTIz | base64 -d                              #使用base64解码
Wlm123

;