k8s - 02

发布时间 2023-08-30 19:35:25作者: 某某人8265

容器控制器

Controller Manager 由 kube-controller-manager 和 cloud-controller-manager 组成, 是Kubernetes 的大脑, 它通过 apiserver 监控整个集群的状态, 并确保集群处于预期的工作状态。 

kube-controller-manager 包括一系列控制器:

1 Replication Controller
2 Node Controller
3 CronJob Controller
4 DaemonSet Controller
5 Deployment Controller
6 Endpoint Controller
7 Garbage Collector
8 Namespace Controller
9 Job Controller
10 Pod AutoScaler
11 RelicaSet
12 Service Controller
13 ServiceAccount Controller
14 StatefulSet Controller
15 Volume Controller
16 Resource quota Controller

cloud-controller-manager 用于配合云服务商的控制,在启用 cloud provider 时才需要,包括一系列控制器:

1 Node Controller
2 Route Controller
3 Service Controller

Pod 控制器及含义

  1. ReplicaSet:适合无状态的服务部署
    用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。帮助用户管理无状态的pod资源,精确反应用户定义的目标数量。无需自定义时应使用deployment而非ReplicaSet
    1. 用户期望的pod副本数量
    2. 标签选择器,判断哪个pod归自己管理
    3. 当现存的pod数量不足,会根据pod资源模板进行新建
  2. deployment:适合无状态的服务部署
    工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。 
  3. StatefullSet:适合有状态的服务部署。
  4. DaemonSet:一次部署,所有的node节点都会部署。服务必须是守护进程,服务是无状态的。
    用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务
    例如一些典型的应用场景:
    1. 运行集群存储 daemon,例如在每个Node上运行 glusterd、ceph
    2. 在每个Node上运行日志收集 daemon,例如 fluentd、 logstash
    3. 在每个Node上运行监控 daemon,例如 Prometheus Node Exporter
  5. Job:一次性的执行任务。 只要完成就立即退出,不需要重启或重建。
  6. Cronjob:周期性的执行任务。 周期性任务控制,不需要持续后台运行。

Replication Controller & ReplicaSet

Replication Controller简称RC,是k8s的核心概念之一。定义一个期望的场景,即声明pod的副本数在任意时刻都符合某个预期值。RC主要包括:

  1. 期待的pod副本数量
  2. 用于筛选pod的Label Selector
  3. 用于创建新pod的pod模板

ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,并且ReplicaSet支持集合式的selector。

# ReplicaSet 模板
apiVersion: apps/v1 #api版本定义
kind: ReplicaSet #定义资源类型为ReplicaSet
metadata: #元数据定义
  name: myapp
  namespace: default
spec: #ReplicaSet的规格定义
  replicas: 2 #定义副本数量为2个
  selector: #标签选择器,定义匹配pod的标签
    matchLabels:
      app: myapp
      release: canary
  template: #pod的模板定义
    metadata: #pod的元数据定义
      name: myapp-pod #自定义pod的名称
      labels: #定义pod的标签,需要和上面定义的标签一致,也可以多出其他标签
        app: myapp
        release: canary
        environment: qa
    spec: #pod的规格定义
      containers: #容器定义
        - name: myapp-container #容器名称
          image: nginx:1.17.10-alpine #容器镜像
          ports: #暴露端口
            - name: http
              containerPort: 80

可通过kubectl查看详情

kubectl explain rs          # 帮助信息
kubectl explain rs.spec
kubectl explain rs.spec.template.spec

部署

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicasetdemo
  labels:
    app: replicasetdemo
spec:
  replicas: 3
  template:              # 用于描述新建的pod模式
    metadata:
      name: replicasetdemo
      labels:
        app: replicasetdemo
    spec:
      containers:
        - name: replicasetdemo
          image: nginx:1.17.10-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
      restartPolicy: Always
  selector:
    matchLabels:
      app: replicasetdemo

运行

kubectl apply -f replicasetdemo.yml
kubectl get rs   # 查看rs控制器
kubectl describe pod replicasetdemo-7fdd7b86-8db3a

kubectl scale replicaset replicasetdemo --replicas=8 # 通过命令行修改pod副本数
kubectl edit replicasets.apps replicasetdemo         # 通过资源清单修改pod副本数

kubectl get pod --show-labels
kubectl label pod replicasetdemo-652lc app=lagou --overwrite=True # 修改pod的标签。会发现pod的数量多一个,因为rs通过label管理pod,新启动的pod用于保证副本数量符合要求

Deployment

一般使用Deployment管理ReplicaSet。

  • 创建Deployment对象来生成ReplicaSet和完成Pod副本创建
  • 可回滚到前一个Deployment版本
  • 暂停Deployment以便一次性修改多个PodTemplateSpec配置型,之后恢复Deployment,进行新的发布
  • 扩展Deployment以应对高负载
kubectl explain deploy
kubectl explain deploy.spec
kubectl explain deploy.spec.template.spec

部署

# kubectl apply -f deploymentdemo.yml 进行部署
# kubectl get deploy 会看到1个 deployment
# kubectl get rs     会看到1个 ReplicaSet
# kubectl get pod    会看到3个 pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploymentdemo1
  labels:
    app: deploymentdemo1
spec:
  replicas: 3
  template:
    metadata:
      name: deploymentdemo1
      labels:
        app: deploymentdemo1
    spec:
      containers:
        - name: deploymentdemo1
          image: nginx:1.17.10-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
      restartPolicy: Always
  selector:
    matchLabels:
      app: deploymentdemo1

更新镜像

# 通过命令行更新
kubectl set image deployment deploymentdemo1 deploymentdemo1=nginx:1.18.0-alpine
kubectl get pods -w
kubectl exec -it deploymentdemo1-584f6b54dd-53c6a -- nginx -v

# 通过yml文件更新
kubectl edit deployments.apps deploymentdemo1  # 修改配置文件中镜像名称和版本
kubectl get pods -w
kubectl exec -it deploymentdemo1-584f6b54dd-4l62t -- nginx -v

扩容

# 通过命令行
kubectl scale deployment deploymentdemo1 --replicas=15
kubectl get pods

# 通过配置文件
kubectl edit deployments.apps deploymentdemo1  # 修改副本数
kubectl get pods

滚动发布

  1. 蓝绿部署是不停老版本,部署新版本然后进行测试,确认OK,将流量切到新版本,然后老版本同时也升级到新版本。 蓝绿部署无需停机,并且风险较小。
  2. 滚动发布:一般是取出一个或者多个服务器停止服务,执行更新,并重新将其投入使用。周而复始,直到集群中所有的实例都更新成新版本。 这种部署方式相对于蓝绿部署,更加节约资源——它不需要运行两个集群、两倍的实例数。我们可以部分部署,例如每次只取出集群的20%进行升
    级。
  3. 灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度,而我们平常所说的金丝雀部署也就是灰度发布的一种方式。

 Deployment控制器支持自定义控制更新过程中的滚动节奏,如“暂停(pause)”或“继续(resume)”更新操作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布(Canary Release)

# 跟新镜像版本,并暂停deployment
kubectl set image deployment deploymentdemo1 deploymentdemo1=nginx:1.18.0-alpine && \
kubectl rollout pause deployment deploymentdemo1

# 查看更新状态
kubectl rollout status deployments deploymentdemo1

# 监控更新过程,因为使用了pause操作,只进行了部分的更新操作
kubectl get pods -l app=deploymentdemo1 -w

# 继续更新
kubectl rollout resume deploy deploymentdemo1

版本回退

默认保存前两次的Deployment的rollout记录,以便随时回退。只要Deployment的rollout被触发就会创建一个revision,当Deployment的 Pod template 被修改时,创建新的revision。扩容等其他操作不会产生新版本。

kubectl rollout history deployment deploymentdemo1 # 查看历史
kubectl rollout status deployment deploymentdemo1  # 查看rollout操作状态
kubectl rollout undo deployment deploymentdemo1    # 回滚版本信息

DaemonSet

确保每个 Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有Pod。因为每个节点运行一个,所以无需指定replicas的个数。一般用于日志采集或性能监控。

# 获取详细信息
kubectl explain daemonset
kubectl explain daemonset.spec
kubectl explain daemonset.spec.template.spec
apiVersion: apps/v1
kind: DaemonSet      # 通过此处指定
metadata:
  name: demonsetdemo
  labels:
    app: demonsetdemo
spec:
  template:
    metadata:
      name: demonsetdemo
      labels:
          app: demonsetdemo
    spec:
      containers:
        - name: demonsetdemo
          image: nginx:1.17.10-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
      restartPolicy: Always
  selector:
    matchLabels:
      app: demonsetdemo

其中master默认不是工作节点,所以master上没有pod。

DaemonSet有两种更新策略类型:

  • OnDelete:这是向后兼容性的默认更新策略。使用 OnDelete 更新策略,在更新DaemonSet模板后,只有在手动删除旧的DaemonSet pod时才会创建新的DaemonSet pod。这与Kubernetes1.5或更早版本中DaemonSet的行为相同。
  • RollingUpdate:使用 RollingUpdate 更新策略,在更新DaemonSet模板后,旧的DaemonSetpod将被终止,并且将以受控方式自动创建新的DaemonSet pod。

Job

一次性执行任务,类似Linux中的job。用于离线数据处理等场景。

apiVersion: batch/v1
kind: Job
metadata:
  name: Pi
spec:
  template:
    spec:
      containers:
        - name: Pi
          image: perl:slim  # 求圆周率的容器
          command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(6000)"]
          imagePullPolicy: IfNotPresent
      restartPolicy: Never
  backoffLimit: 4  # Job 的容错次数,默认6次。
                   # 运行Job的pod失败后递增间隔时间重启(10s, 20s, 30s),重试次数到达上限后不再新建pod。

StatefulSet

有状态的服务,如MySQL要保存数据。

Service

可通过Deployment创建一组Pod提供高可用服务,但

  • 每个Pod有仅内部可见的虚拟IP
  • 当Pod扩缩容时pod的IP会随着Pod的销毁重启而变化
  • Service提供负载均衡能力,但只提供4层均衡,没有7层均衡的功能。

 通过Service对象解决问题。有4种类型:

  1. ClusterIP:默认类型,自动分配一个仅Cluster内部可访问的VIP
  2. NodePort:在ClusterIP基础上为每个Service在每台机器上绑定一个端口,可通过此端口访问服务
  3. LoadBalancer:在NodePort基础上借助cloud provider 创建外部负载均衡器,将请求转发到NodePort。(昂贵的付费服务)
  4. ExternalName:将集群外服务引入集群内部,在集群内直接使用

k8s中Pods是提供服务的基本单元,有生命周期,销毁后不再启动。可使用Deployment运行程序。Service是一种抽象,定义一组Pods逻辑集合和访问策略。一个Service的目标Pod集合通常由 Label Selector 决定。Service的IP不通过单机进行应答,使用代理定义一个虚拟地址VIP,按需透明地重定向。客户端连接到VIP时,流量自动传输到一个合适的Endpoint。环境变量和DNS,实际根据Service的VIP和端口进行填充。kube-proxy支持3种代理模式:

  1. userspace:涉及用户态和内核态的切换,因此效率差
  2. iptables
  3. IPVS:现在使用

ClusterIP

此类service有一个Cluster-IP,即一个VIP,依靠 kuberproxy 组件通过 iptables 或 ipvs 实现。

每个node节点通过iptables将发往 cluster IP 对应端口的数据转发到 kube-proxy,然后 kube-proxy 通过内部的负载均衡方法查询service下对应pod地址和端口,进而转发给对应pod。

这种service只能在集群内访问。

 

 

 

 

 

 

NodePort