Kubernetes

初始化

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

kubeadm安装

root用户执行以下命令

#yum -y install socat conntrack-tools
kubeadm init --image-repository registry.aliyuncs.com/google_containers \
             --pod-network-cidr=10.244.0.0/16 \
             --ignore-preflight-errors=Swap

执行完后,可以看到已经安装成功


kubeadm安装

切换到非root用户

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#此时非root用户可以执行kubelet命令
#安装flannel网络附加组件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

此时kubernate启动成功
到其他节点,以root用户,使用kubeadm join加入集群

kubeadm join 10.150.31.115:6443 --token doz94r.6xebnfstr9nfz7tg \
    --discovery-token-ca-cert-hash sha256:a5e181604418fc6531e928e3a614c3b4882598f2de1a13efbdc8d939945ca5b7

此时节点加入成功。如果该节点要执行kubelet命令,可以把上面.kube/config文件复制到本节点的对应路径

minkube

curl -LO [https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64](https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64)

sudo install minikube-linux-amd64 /usr/local/bin/minikube

minikube start

yum install conntrack

镜像处理:

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/echoserver:1.4

docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/echoserver:1.4 k8s.gcr.io/echoserver:1.4

docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/echoserver:1.4

作者将gcr.io相关镜像pull下来,然后push到docker官方仓库

gcr.io/namespace/image_name:image_tag
# 等价于
anjia0532/namespace.image_name:image_tag

eg.

gcr.io/google-samples/node-hello:1.0
-> anjia0532/google-samples.node-hello:1.0

Demo

创建Deployment

Deployment指挥k8s如何创建和更新应用程序的实例。创建Deployment后,k8s master将应用程序实例调度到集群中的各个节点上。

创建应用程序实例后,k8s Deployment控制器会持续监视这些实例。如果托管实例的节点关闭或被删除,则Deployment控制器会将实例替换为集群中另一个节点上的实例。这提供了一种自我修复机制来解决机器故障维护问题。

创建管理Pod的Deployment,该Pod根据提供的Docker镜像运行Container

kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4
#kubectl create deployment hello-node --image=registry.aliyuncs.com/google_containers/echoserver:1.4 

查看Deployment

kubectl get deployments

查看Pod

kubectl get pods

查看集群事件

kubectl get events

查看kubectl配置

kubectl config view

创建Service

Service下的一组Pod通常由LabelSelector来标记。
尽管每个Pod都有一个唯一的IP地址,但是如果没有Service,这些IP不会暴露在集群外部。Service运行应用程序接收流量
类型:

  • ClusterIP (默认) - 在集群的内部IP上公开Service。这种类型使得Service只能从集群内访问
    -- Headless (无头服务) spec.clusterIP: None。服务DNS名称会直接解析为Pod的IP地址
  • NodePort - 使用NAT在集群中每个选定Node的相同端口上公开Service。使用<NodeIP>:<NodePort>从集群外部访问Service。是ClusterIP的超集
  • LoadBalancer - 在当前云中创建一个外部负载均衡器(如果支持),并为Service分配一个固定的外部IP。是NodePort的超集
  • ExternalName - 通过返回带有该名称的CNAME记录,使用任意名称(spec中的externalName指定)公开Service。不使用代理
    headless示例
image

默认情况下,Pod只能通过k8s集群中的内部IP地址访问,要使得hello-node容器可以从k8s虚拟网络的外部访问,必须将Pod暴露为k8s Service

使用kubectl expore将Pod暴露给公网

kubectl expose deployment hello-node --type=LoadBalancer --port=8080

--type=LoadBalancer表示希望将Service暴露到集群外部
镜像k8s.gcr.io/echoserver中的应用程序代码仅监听TCP8080端口

查看创建的Service

kubectl get services

打标签

kubectl label pod $POD_NAME app=v1

根据标签获取pods

kubectl get pods -l app=v1

清理

kubectl delete service hello-node
kubectl delete deployment hello-node

缩放应用

查看Deployment创建的ReplicaSet(副本集),会展示:[DEPLOYMENT-NAME]-[RANDOM-STRING]。例如:kubernetes-bootcamp-765bf4c7b4

kubectl get rs

扩展到4倍

kubectl scale deployments/kubernetes-bootcamp --replicas=4

滚动更新应用

设置镜像
镜像和之前不一样的话,会触发重新部署

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2

回滚到上个版本

kubectl rollout undo deployments/kubernetes-bootcamp

配置

k8s设置docker容器环境变量的方式:
Dockerfile、kubernetes.yml、Kubernetes ConfigMaps和Kubernetes Secrets

环境变量的值将会注入到微服务里
使用ConfigMaps和Secrets的好处是他们能在多个容器间复用,比如赋值给不同的容器中的不同环境变量

ConfigMaps是存储非机密键值对的API对象
Secrets针对机密/敏感数据存储键值对,存储格式为Base64编码

创建ConfigMap(名称为sys-app-name,--from-literal直接指定键值对,还有--from-file和 --from-env-file)

kubectl create configmap sys-app-name --from-literal name=my-system

创建Secret(generic表示不是一个特定类型的secret)

kubectl create secret generic sys-app-credentials --from-literal username=bob --from-literal password=bobpwd

配置文件(configMapKeyRef,secretKeyRef)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-deployment
  labels:
    app: system
spec:
  selector:
    matchLabels:
      app: system
  template:
    metadata:
      labels:
        app: system
    spec:
      containers:
      - name: system-container
        image: system:1.0-SNAPSHOT
        ports:
        - containerPort: 9080
        # Set the APP_NAME environment variable
        env:
        - name: APP_NAME
          valueFrom:
            configMapKeyRef:
              name: sys-app-name
              key: name
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inventory-deployment
  labels:
    app: inventory
spec:
  selector:
    matchLabels:
      app: inventory
  template:
    metadata:
      labels:
        app: inventory
    spec:
      containers:
      - name: inventory-container
        image: inventory:1.0-SNAPSHOT
        ports:
        - containerPort: 9080
        # Set the SYSTEM_APP_USERNAME and SYSTEM_APP_PASSWORD environment variables
        env:
        - name: SYSTEM_APP_USERNAME
          valueFrom:
            secretKeyRef:
              name: sys-app-credentials
              key: username
        - name: SYSTEM_APP_PASSWORD
          valueFrom:
            secretKeyRef:
              name: sys-app-credentials
              key: password
---
apiVersion: v1
kind: Service
metadata:
  name: system-service
spec:
  type: NodePort
  selector:
    app: system
  ports:
  - protocol: TCP
    port: 9080
    targetPort: 9080
    nodePort: 31000
---
apiVersion: v1
kind: Service
metadata:
  name: inventory-service
spec:
  type: NodePort
  selector:
    app: inventory
  ports:
  - protocol: TCP
    port: 9080
    targetPort: 9080
    nodePort: 32000

删除旧的deployment,部署更新后的deployment

kubectl replace --force -f kubernetes.yaml

使用ConfigMap配置Redis
创建kustomization.yaml文件,包含一个ConfigMap生成器,一个使用ConfigMap的Pod资源配置
使用kubectl apply -k ./ 应用整个路径的配置
验证配置
redis-config

maxmemory 2mb
maxmemory-policy allkeys-lru

redis-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis:5.0.4
    command:
      - redis-server
      - "/redis-master/redis.conf"
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: "0.1"
    volumeMounts:
    - mountPath: /redis-master-data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: example-redis-config
        items:
        - key: redis-config
          path: redis.conf

kustomization.yaml

configMapGenerator:
- name: example-redis-config
  files:
  - redis-config
resources:
- redis-pod.yaml

应用整个文件夹以创建ConfigMap和Pod对象

kubectl apply -k .

检查

> kubectl get -k .
NAME                                        DATA   AGE
configmap/example-redis-config-dgh9dg555m   1      52s

NAME        READY   STATUS    RESTARTS   AGE
pod/redis   1/1     Running   0          52s

验证配置

kubectl exec -it redis -- redis-cli
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "2097152"
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"

删除

kubectl delete pod redis

无状态应用程序

  • 运行Hello World应用程序的五个实例
  • 创建一个公开外部IP地址的Service对象
  • 使用Service对象访问正在运行的应用程序
load-balancer-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: load-balancer-example
  name: hello-world
spec:
  replicas: 5
  selector:
    matchLabels:
      app.kubernetes.io/name: load-balancer-example
  template:
    metadata:
      labels:
        app.kubernetes.io/name: load-balancer-example
    spec:
      containers:
      - image: anjia0532/google-samples.node-hello:1.0
        name: hello-world
        ports:
        - containerPort: 8080

显示Deployment的信息

kubectl get deployments hello-world
kubectl describe deployments hello-world

显示ReplicaSet对象的信息

kubectl get replicasets
kubectl describe replicasets

创建公开Deployment的Service对象

kubectl expose deployment hello-world --type=LoadBalancer --name=my-service

显示有关Service的信息

kubectl get services my-service
kubectl describe services my-service

清理

kubectl delete services my-service
kubectl delete deployment hello-world

解决k8s.gcr.io无法拉取镜像问题

docker pull registry.cn-hangzhou.aliyuncs.com/go ogle_containers/{}
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/{} k8s.gcr.io/{}
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/{}

Kubernates

可移植,可扩展的开源平台,管理容器化的工作负载和服务,方便了声明式配置和自动化。

组件

image

控制平面组件(Control Plane Components)

对集群作出全局决策(e.g.调度),检测和响应集群事件(e.g. 不满足部署的replicas时,启动新的pod)

kube-apiserver

k8s控制面的前端

etcd

键值数据库,保存k8s所有集群数据的后台数据库

kube-scheduler

监视那些新创建的未指定运行节点的Pod,并选择节点让Pod在上面运行

kube-controller-manager

在主节点上运行控制器的组件
包括:
节点控制器(Node Controller)、副本控制器(Replication Controller)、端点控制器(Endpoints Controller)、服务账号和令牌控制器(Service Account & Token Controllers)

cloud-controller-manager

Node组件

在每个节点上运行,维护运行的Pod并提供Kubernetes运行环境

kubelet

在集群中每个节点上运行的代理。保证容器都运行在Pod中

kube-proxy

集群中每个节点上运行的网络代理。维护节点上的网络规则
kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式

容器运行时(Container Runtime)

负责容器运行的软件。Docker、containerd、CRI-O

插件(Addons)

插件使用k8s资源(DaemonSet、Deployment等)实现集群功能
DNS
Web界面(仪表盘 Dashboard)
容器资源监控
集群层面日志

关系

image
  • Pod
    一个或多个容器的组合,这些容器共享存储、网络和命名空间,以及如何运行的规范。是k8s的最小可部署单元
    Pod的中文为豌豆荚,docker容器就像豆子运行在豌豆荚内
  • ReplicaSet
    Replication Controller的作用是确保Pod以指定的副本个数运行。ReplicaSet是Replication Controller的升级版。Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持新的,基于集合的selector(version in (v1,v2))
  • Deployment
    用于管理Pod、ReplicaSet,可实现滚动升级和回滚应用、扩容和缩容
  • Service
    每个Pod都有自己的ip,前端请求不知道这个pod的ip是什么,Service定义了一个服务的访问入口地址,前端的应用通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,来自外部的访问请求被负载均衡到后端的各个容器应用上。Service与后端Pod副本集群之间通过Label Selector实现关联。

前端请求不是直接发送给Pod,而是发送给Service,Service再将请求转发给Pod

  • 总结
    Pod被ReplicaSet管理,ReplicaSet控制Pod的数量;ReplicaSet被Deployment管理,Deployment控制Pod应用的升级、回滚,当然也能控制Pod的数量。Service提供一个统一固定入口,负责将前端请求转发给Pod

port, targetPort, nodePort的关系

  • port
    k8s中服务之间访问的端口
  • targetPort
    容器暴露出来的端口
    targetPort是pod上的端口,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上
  • nodePort
    外部机器可以访问的端口

port和nodePort都是service的端口,前者暴露给集群内客户访问服务,后者暴露给集群外客户访问服务。从这两个端口到来的数据都需要经过反向代理kube-proxy流入后端pod的targetPort,从而到达pod上的容器内

Pods

Pod是可以在k8s中创建和管理的、最小的可部署的计算单元

Pod是一组(一个或多个)容器;这些容器共享存储、网络以及怎样运行这些容器的声明。Pod中的内容总是并置的并且一同调度,在共享的上下文中运行

Pod的共享上下文包括一组Linux命名空间、控制组(cgroup)和可能一些其他的隔离方面,即用来隔离Docker容器的技术

Pod类似共享命名空间和文件系统卷的一组Docker容器

使用Pod

不需要直接创建Pod,使用诸如Deployment或Job这类工作负载资源来创建Pod。如果Pod需要跟踪状态,可以考虑StatefulSet资源
用法:

  • 运行单个容器的Pod。“每个Pod一个容器”模型是最常见的k8s用例;可以将Pod看作单个容器的包装器,并且k8s直接管理Pod,而不是容器
  • 运行多个协同工作的容器的Pod。Pod封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序。这些位于同一位置的容器可能形成单个内聚的服务单元--一个容器将文件从共享卷提供给公众,而另一个单独的“挂斗”(sidecar)容器则刷新或更新这些文件。Pod将这些容器和存储资源打包成一个可管理的实体

每个Pod都旨在运行给定应用程序的单个实例。如果希望横向扩展应用程序,则应该使用多个Pod,每个实例使用一个Pod

Pod天生地为其成员容器提供了两种共享资源:网络和存储

Pod不是进程,而是容器运行的环境

Pod模板

负载资源的控制器通常使用Pod模板(Pod Template)来创建Pod并管理它们

Pod模板是包含在工作负载对象中的规范,用来创建Pod。这些负载资源包括Deployment、Job和DaemonSets等

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # 这里是 Pod 模版
    spec:
      containers:
      - name: hello
        image: busybox
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure
    # 以上为 Pod 模版

修改Pod模板或者切换到新的Pod模板都不会对已存在的Pod起作用

e.g. Demployment控制器针对每个Deployment对象确保运行中的Pod与当前的Pod模板匹配。如果模板被更新,则Deployment必须删除现有的Pod,基于更新后的模板创建新的Pod

资源共享和存储

Pod使它的成员容器间能够进行数据共享和通信

一个Pod可以设置一组共享的存储卷,Pod中的所有容器都可以访问该共享卷,从而允许这些容器共享数据

每个Pod都在每个地址族中获得一个唯一的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用localhost互相通信

Pod的生命周期

起始于Pending阶段,如果至少有一个主要容器正常启动,则进入Running,之后取决于是否有容器以失败状态结束而进入Succeeded或者Failed阶段

Pod在其生命周期中只会被调度一次。一旦Pod被调度(分派)到某个节点,会一直在该节点运行,直到Pod停止或被终止

Pod生命期

Pod和一个个独立的应用容器一样,也被认为是相对临时性的实体。Pod会被创建、赋予一个唯一的ID(UID),并被调度到节点,并在终止或删除之前一个运行在该节点

Pod自身不能自愈,如果被调度到某节点而该节点之后失效,或者调度操作本身失效,Pod会被删除;Pod无法在节点资源耗尽或者节点维护期间继续存活。k8s使用控制器,来管理这些相对而言可随时丢弃的Pod实例

任何给定的Pod(由UID定义)不会被重新调度到不同的节点;相反,这Pod可以被一个新的、几乎完全相同的Pod替换掉。新Pod的名字可以不变,但UID会不同

Pod阶段

status字段是一个PodStatus对象,其中包含一个phase字段。是Pod在其生命周期中所处位置的简单宏观概述

取值 描述
Pending(悬决) Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间
Running(运行中) Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态
Succeeded(成功) Pod 中的所有容器都已成功终止,并且不会再重启
Failed(失败) Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止
Unknown(未知) 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败

如果某节点死掉或者与集群中其他节点失联,k8s会将失去的节点上运行的所有Pod的phase置为Failed

容器状态

可以使用容器生命周期回调来在容器生命周期中的特定时间点触发事件

一个调度器将Pod分派给某个节点,kubelet就通过容器运行时开始为Pod创建容器。

检查Pod中容器的状态:kubectl describe pod <pod 名称>

容器的状态有三种:

  • Waiting (等待)
    如果容器不处在Running或Terminated状态之一,它就处于Waiting状态。处于Waiting状态的容器仍在运行它完成启动所需要的操作
  • Running (运行中)
    表明容器正在执行状态并且没有问题发生。如果配置了postStart回调,那么该回调已经执行且已完成
  • Terminated (已终止)
    已经开始执行并且或者正常结束或者因为某些原因失败。如果配置了preStop回调,则该回调会在容器进入Terminated状态之前执行

容器重启策略

Pod的spec中包含一个restartPolicy字段,可能取值:Always(默认)\OnFailure\Never

Pod状况

Pod有一个PodStatus对象,其中包含一个PodConditions数组

  • PodScheduled: Pod已经被调度到某节点
  • ContainersReady: Pod中所有容器都已就绪
  • Initialized: 所有的Init容器都已成功启动
  • Ready: Pod可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中
字段名称 描述
type Pod 状况的名称
status 表明该状况是否适用,可能的取值有 "True", "False" 或 "Unknown"
lastProbeTime 上次探测 Pod 状况时的时间戳
lastTransitionTime Pod 上次从一种状态转换到另一种状态时的时间戳
reason 机器可读的、驼峰编码(UpperCamelCase)的文字,表述上次状况变化的原因
message 人类可读的消息,给出上次状态转换的详细信息

容器探针

Probe是由kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler(处理程序)。有三种类型的处理程序:

  • ExecAction 在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功
  • TCPSocketAction 对容器的IP地址上的指定端口执行TCP检查。如果端口打开,则诊断被认为是成功的
  • HTTPGetAction 对容器的IP地址上指定端口和路径执行HTTP Get请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的

每次探测都将获得以下三种结果之一:

  • Success (成功):容器通过了诊断
  • Failure (失败):容器未通过诊断
  • Unknown (未知):诊断失败,因此不会采取任何行动

探针类型:

  • livenessProbe :指示容器是否正在运行。如果存活态探测失败,则kubelet会杀死容器,并且容器将根据重启策略决定未来。如果容器不提供存活探针,则默认为Success
  • readinessProbe:指示容器是否准备好为请求提供服务。如果就绪态探测失败,端点控制器将从与Pod匹配的所有服务的端点列表中删除该Pod的IP地址。初始延迟之前的就绪态的状态值默认为Failure。如果不提供就绪态探针,默认为Success
  • startupProbe:指示容器是否已经启动。如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet将杀死容器,而容器根据重启策略进行重启。如果没有提供启动探测,默认为Success

何时使用存活态探针?

如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活态探针;kubelet将根据Pod的restartPolicy自动执行修复操作

如果希望容器在探测失败时被杀死并重新启动,那么请指定一个存活态探针,并制定restartPolicy为"Always"或"OnFailure"

何时使用就绪态探针?

如果要仅在探测成功时才开始向Pod发送请求流量,请指定就绪态探针。规约中的就绪态探针的存在意味着Pod将在启动阶段不接收任何数据,并且只有在探测成功后才开始接收数据

如果容器需要加载大规模的数据、配置文件或在启动期间执行迁移操作,可以添加一个就绪态探针

如果希望容器能够自行进入维护状态,也可以指定一个就绪态探针,检查某个特定于就绪态不同于存活态探测的端点

在删除Pod时,Pod会自动将自身置为未就绪状态,无论就绪态探针是否存在。等待Pod中的容器停止期间,Pod会一直处于未就绪状态

何时该使用启动探针?

对于所包含的容器需要较长时间才能启动就绪的Pod而言,启动探针是有用的。不再需要配置一个较长的存活态探测时间间隔,只需要设置另一个独立的配置选定,对启动期间的容器执行探测,从而允许使用远远超出存活态时间间隔所允许的时长

如果容器启动时间通常超出initialDelaySeconds + failureThreshold × periodSeconds总值,应该设置一个启动探测。periodSeconds的默认值是30秒,应该将failureThreshold设置得足够高,以便容器有充足的时间完成启动,并且避免更改存活态探针所使用的默认值

Pod的终止

Pod所代表的是在集群中节点上运行的进程,当不再需要这些进程时允许其体面地终止是很重要的,不应武断地使用KILL信号终止,导致这些进程没有机会完成清理操作

通常容器运行时会发送一个TERM信号到每个容器中的主进程。很多容器运行时都能注意到容器镜像中STOPSIGNAL的值,并发送该信号而不是TERM。一旦超出了体面终止限期,容器运行时会向所有剩余进程发送KILL信号,之后Pod就会被从API服务器上移除。如果kubelet或者容器运行时的管理服务在等待进程终止期间被重启,集群会从头开始重试,赋予Pod完整的体面终止限期

强制终止Pod

默认所有删除操作都有30秒的宽限期。kubectl delete支持--grace-period=<seconds>选项重载默认值

宽限期设置为0意味着立即从API服务器删除Pod。如果Pod仍然运行于某节点上,强制删除会触发kubelet立即执行清理操作

失效Pod的垃圾收集

对于已失效的Pod,对应的API对象仍然会保留在集群的API服务器上,直到用户或者控制器进程显式将其删除

控制器组件会在Pod个数超出所配置的阈值(kube-controller-manager的terminated-pod-gc-threshold设置)时删除已终止的Pod(阶段值为Succeeded或Failed)

存储

Persistent Volumes

PersistentVolume(PV)是集群里的一部分存储,由管理员或者使用Storage Classes动态供应。它是集群里的一种资源,就像node是一个集群的资源。
PersistentVolumeClaim(PVC)是用户对存储的请求。它类似于Pod。Pods消费节点资源,PVCs消费PV资源。Pods可以请求特定级别的资源(CPU和内存),Claims可以请求特定大小和访问模式(ReadWriteOnce, ReadOnlyManly,ReateWriteMany)

volume和claim的生命周期

PVs是集群里的资源。PVCs是这些资源的请求,还充当对这些资源的检查。

Provisioning 供应

  • Static
    集群管理员创建一定数量的PVs。它们包含真实存储的详细信息,可供集群用户使用
  • Dynamic
    当没有管理员创建的静态PVs匹配用户的PVC,集群可能会动态为PVC提供一个卷。此资源调配基于StorageClasses:PVC必须请求一个存储类,并且管理员必须创建并配置了该类,以便进行动态资源调配。

Binding 绑定

主节点上的控制循环监听新的PVCs,找到一个匹配的PV(如果可以),将它们绑定在一起。如果一个PV是为一个PVC动态供应的,那么循环将始终将该PV绑定到PVC。或者用户将至少获得它们请求的量,volume可能超出请求的量。
PVC到PV的绑定是一对一的映射,使用ClaimRef,它是PersistentVolume和PersistentVolumeClaim的双向绑定
如果没有匹配的volume存在,Claims将一直保持未绑定。

Using 使用

Pods使用claims作为volumes。集群检查claim以找到绑定的volume,并为Pods挂载该volume

Reclaiming 回收

PV的回收策略告诉集群在其claim释放后该如何处理volume。

  • Retain
    之前的数据还保留在volume上
  • Recycled(弃用,推荐使用dynamic provisioning)
  • Deleted

Storage Classes

为管理员提供了一种描述他们提供的存储“类”的方法。不同的类可能映射到服务质量级别、备份策略或集群管理确定的任意策略。Kubernetes本身并不关心类代表什么。其他存储系统中,此概念有时称为“profiles”

StorageClass 资源

包含字段:provisioner、parameters、reclaimPolicy,当需要动态配置属于该类的PV时使用。

Dynamic Volume Provisioning 动态卷供应

允许存储卷按需创建。如果没有动态供应,集群管理员必须手动调用云或存储供应商来创建新的存储卷,然后创建PV对象以在k8s中表示它们。
动态卷供应的实现是基于API组storage.k8s.io中的API对象StorageClass。集群管理员可以定义根据需要定义许多StorageClass对象,每个都指定一个卷插件(provisioner),该插件提供一个卷和一组参数,以便在设置时传给该参数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • kubecon简洁总结 1,kubenets基本使用 [if !supportLists]l[endif]基本单元...
    君子壳Zhu阅读 1,534评论 0 0
  • 1.Kubenetes 命令文档大全:http://docs.kubernetes.org.cn/626.html...
    huxt阅读 445评论 0 0
  • 我们为什么使用容器? 我们为什么使用虚拟机(云主机)? 为什么使用物理机? 这一系列的问题并没有一个统一的标准答案...
    永杰gg阅读 372评论 0 1
  • Kubernetes部属说明 环境准备 资料准备 开始部属 编写yaml文件,用于部属Kubenetes基础容器e...
    俊逸之光阅读 2,599评论 2 0
  • 一、资源含义 k8s中所有的内容都被抽象为资源,资源实例化之后,叫做对象。 二、资源分类 名称空间级别 仅在此名称...
    小波同学阅读 925评论 0 0