Kubernetes入门学习(上)

Kubernetes入门学习(上)

介绍

  1. 名称简介

    Kubernetes 是一个开源的容器编排引擎和容器集群管理工具,用来对容器化应用进行自动化部署、 扩缩和管理。

    Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有8个字符。 Google 在 2014 年开源了 Kubernetes 项目。

  2. 优势
    Kubernetes 建立在 Google 大规模运行生产工作负载十几年经验的基础上, 结合了社区中最优秀的想法和实践。它之所以能够迅速流行起来,是因为它的许多功能高度契合互联网大厂的部署和运维需求。

  3. 功能

    • 服务发现和负载均衡
    • 存储编排
    • 自动部署和回滚
    • 自动完成装箱计算
    • 自我修复
    • 密钥与配置管理

云原生

  1. 定义
    • 通俗理解:原生应用是采用特定操作系统的语言针对该操作系统开发的应用,而在设计和开发应用时,让他们能够运行在云基础设施(比如Kubernetes)上,从而使应用具备可弹性扩展的能力,我们称之为云原生应用。简而言之:云原生就是以容器技术为载体、基于微服务架构思想的一套技术体系和方法论
    • 官方定义:云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。

Kubernetes 是 CNCF 托管的第一个开源项目。因此现在提到云原生,往往我们都把它与kubernetes联系起来。

云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。

Kubernetes架构

基础概念

  • 节点(Node):Kubernetes中工作的机器叫做节点,会运行容器化应用程序,运行实际的应用和工作负载。
  • Pod:Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。Pod表示你的集群上—组正在运行的容器。这些容器共享存储、网络、以及怎样运行这些容器的声明。
  • 集群:Kubernetes集群至少包含一个控制平面(control plane),以及一个或多个工作节点(worker node)。
  • 控制平面**(Control Plane) 😗* 控制平面负责管理工作节点和维护集群状态。所有任务分配都来自于控制平面。

Kubernetes架构

一个Kubernetes集群至少包含一个控制平面组件(control plane),以及一个或多个工作节点组件(worker node)。

控制平面组件

控制平面组件会为集群做出全局决策,比如资源的调度、检测和响应集群事件。

在这里插入图片描述

  1. kube-apiserver

    如果需要与Kubernetes 集群进行交互,就要通过 API

    apiserver是 Kubernetes 控制平面的前端,用于处理内部和外部请求。

  2. kube-scheduler

    负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。集群状况是否良好?如果需要创建新的容器,要将它们放在哪里?这些是调度程序需要关注的问题。scheduler调度程序会考虑容器集的资源需求(例如 CPU 或内存)以及集群的运行状况。随后,它会将容器集安排到适当的计算节点。

  3. etcd

    一致且高可用的键值存储,用于存储配置数据和集群状态信息, 用作 Kubernetes 所有集群数据的后台数据库。

  4. kube-controller-manager

    控制器负责实际运行集群,controller-manager控制器管理器则是将多个控制器功能合而为一,降低了程序的复杂性。

    controller-manager包含了这些控制器:

    • 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
    • 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
    • 端点控制器(Endpoints Controller):填充端点(Endpoints)对象(即加入 Service 与 Pod)
    • 服务帐户和令牌控制器(Service Account & Token Controllers):为新的命名空间创建默认帐户和 API 访问令牌
  5. cloud-controller-manager

    控制平面还包含一个可选组件cloud-controller-manager

    云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。

Node组件

节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。

在这里插入图片描述

  1. kubelet

    kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
    当控制平面需要在节点中执行某个操作时,kubelet 就会执行该操作。

  2. kube-proxy

    kube-proxy 是集群中每个节点(node)上运行的网络代理,是实现 Kubernetes 服务(Service) 概念的一部分。
    kube-proxy 维护节点网络规则和转发流量,实现从集群内部或外部的网络与 Pod 进行网络通信。

  3. 容器运行时(Container Runtime)

    这个基础组件使 Kubernetes 能够有效运行容器。 它负责管理 Kubernetes 环境中容器的执行和生命周期。负责运行容器的软件。Kubernetes 支持许多容器运行环境,例如 containerd、docker或者其他实现了 Kubernetes CRI (容器运行环境接口)的容器。

组件关系

在这里插入图片描述

安装Kubernetes

参考这篇即可K8s安装部署–超级详细(无坑,v1.23)_虚拟机部署k8s_我不当正经人了z的博客-CSDN博客

容器镜像加速详见阿里云镜像加速

个人觉得这教程更好https://blog.csdn.net/IOT_AI/article/details/131975562

基本对象和操作

Pod(容器集)

  1. 概述

    Pod 是包含一个或多个容器的容器组,是 Kubernetes 中创建和管理的最小对象。

    Pod 有以下特点:

    • Pod是kubernetes中最小的调度单位(原子单元),Kubernetes直接管理Pod而不是容器。

    • 同一个Pod中的容器总是会被自动安排到集群中的同一节点(物理机或虚拟机)上,并且一起调度

    • Pod可以理解为运行特定应用的“逻辑主机”,这些容器共享存储、网络和配置声明(如资源限制)。

    • 每个 Pod 有唯一的 IP 地址。 IP地址分配给Pod,在同一个 Pod 内,所有容器共享一个 IP 地址和端口空间,Pod 内的容器可以使用localhost互相通信。

  2. 举例

    一个Pod中你可能有一个容器,为共享卷中的文件提供 Web 服务器支持,以及一个单独的 “边车 (sidercar)” 容器负责从远端更新这些文件,如下图所示:在这里插入图片描述

  3. 操作Pod

# 拉取并且运行Pod
# --image 指定镜像
kubectl run mynginx --image=nginx
# 查看Pod
kubectl get pod
# 描述
kubectl describe pod mynginx
# 查看Pod的运行日志
kubectl logs mynginx

# 显示pod的IP和运行节点信息
kubectl get pod -owide
# 使用Pod的ip+pod里面运行容器的端口
curl 10.42.1.3

#在容器中执行
# 命令放在--后
kubectl exec mynginx -it -- /bin/bash

# --watch 隔一段时间执行一次命令用于观察
kubectl get pod --watch
# -it 交互模式 
# --rm 退出后删除容器,多用于执行一次性任务或使用客户端
kubectl run mynginx --image=nginx -it --rm -- /bin/bash 

# 删除
kubectl delete pod mynginx
# 强制删除
kubectl delete pod mynginx --force

Deployment(部署)与ReplicaSet(副本集)

  1. 介绍

    1. Deployment:Deployment是对ReplicaSetPod更高级的抽象。

      它使Pod拥有多副本,自愈,扩缩容、滚动升级等能力。一个 Deployment 为 PodReplicaSet 提供声明式的更新能力

    2. ReplicaSet:ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。通常我们不直接使用ReplicaSet,而是在Deployment中声明。

  2. 操作

    基本操作:创建、查看、删除

    #创建deployment,部署3个运行nginx的Pod
    kubectl create deployment nginx-deployment --image=nginx:1.22 --replicas=3
    #查看deployment
    kubectl get deploy
    #查看replicaSet
    kubectl get rs 
    #删除deployment
    kubectl delete deploy nginx-deployment
    

    缩放

    • 手动缩放

      #将副本数量调整为5
      kubectl scale deployment/nginx-deployment --replicas=5
      kubectl get deploy
      
    • 自动缩放

      自动缩放通过增加和减少副本的数量,以保持所有 Pod 的平均 CPU 利用率不超过 75%。

      自动伸缩需要声明Pod的资源限制,同时使用 Metrics Server 服务

      #自动缩放
      kubectl autoscale deployment/nginx-auto --min=3 --max=10 --cpu-percent=75 
      #查看自动缩放
      kubectl get hpa
      #删除自动缩放
      kubectl delete hpa nginx-deployment
      

    滚动更新

    #查看版本和Pod
    kubectl get deployment/nginx-deployment -owide
    kubectl get pods
    
    #更新容器镜像
    kubectl set image deployment/nginx-deployment nginx=nginx:1.23
    #滚动更新
    kubectl rollout status deployment/nginx-deployment
    #查看过程
    kubectl get rs --watch
    

    版本回滚

    #查看历史版本
    kubectl rollout history deployment/nginx-deployment
    #查看指定版本的信息
    kubectl rollout history deployment/nginx-deployment --revision=2
    #回滚到历史版本
    kubectl rollout undo deployment/nginx-deployment --to-revision=2
    

Service(服务)

  1. 概述

    Kubernetes 中 Service 是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法。

    Service为一组 Pod 提供相同的 DNS 名(域名),并且在它们之间进行负载均衡。

    Kubernetes 为 Pod 提供分配了IP 地址,但IP地址可能会发生变化。

    集群内的容器可以通过service名称访问服务,而不需要担心Pod的IP发生变化。

    Kubernetes Service 定义了这样一种抽象:

    逻辑上的一组可以互相替换的 Pod,通常称为微服务。

    Service 对应的 Pod 集合通常是通过选择算符来确定的。

    举个例子,在一个Service中运行了3个nginx的副本。这些副本是可互换的,我们不需要关心它们调用了哪个nginx,也不需要关注 Pod的运行状态,只需要调用这个服务就可以了。

  2. 操作

    # 将已有的部署创建为服务
    # --name:指定服务名
    # --type:指定servicetype
    # --port:指定服务公开端口
    # --target-port:指定容器内部端口
    kubectl expose deployment/nginx-deployment \
    --name=nginx-service --type=ClusterIP --port=80 --target-port=80
    # 查看服务
    kubectl get svc
    
  3. ServiceTypePort解析

    • ServiceType 取值

      • ClusterIP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的 IP,集群内的所有主机都可以通过这个Cluster-IP访问服务集群内部的Pod可以通过service名称访问服务
      • NodePort:通过每个节点的主机IP 和静态端口(NodePort)暴露服务。 集群的外部主机可以使用节点IP和NodePort访问服务kubectl get svc xxx得到的端口格式port : NodePort
      • ExternalName:将集群外部的网络引入集群内部。
      • LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。
    • Port

      在这里插入图片描述

namespace(命名空间)

  1. 概述

    **命名空间(Namespace)**是一种资源隔离机制,将同一集群中的资源划分为相互隔离的组

    命名空间可以在多个用户之间划分集群资源(通过资源配额)。

    • 例如我们可以设置开发、测试、生产等多个命名空间。

    同一命名空间内的资源名称要唯一,但跨命名空间时没有这个要求。

    命名空间作用域仅针对带有名字空间的对象,例如 Deployment、Service 等。

    这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等。

  2. Kubernetes 会创建四个初始命名空间:

    • default 默认的命名空间,不可删除,未指定命名空间的对象都会被分配到default中。
    • kube-system Kubernetes 系统对象(控制平面和Node组件)所使用的命名空间。
    • kube-public 自动创建的公共命名空间,所有用户(包括未经过身份验证的用户)都可以读取它。通常我们约定,将整个集群中公用的可见和可读的资源放在这个空间中。
    • kube-node-lease 租约(Lease)对象使用的命名空间。每个节点都有一个关联的 lease 对象,lease 是一种轻量级资源。lease对象通过发送心跳,检测集群中的每个节点是否发生故障。

    使用kubectl get lease -A查看lease对象

  3. 操作

    管理命名空间

    kubectl get pod -A
    #创建命名空间
    kubectl create namespace dev
    #查看命名空间
    kubectl get ns
    
    #在命名空间内运行Pod
    kubectl run nginx --image=nginx --namespace=dev
    kubectl run my-nginx --image=nginx -n=dev
    
    #查看命名空间内的Pod
    kubectl get pods -n=dev
    
    #查看命名空间内所有对象
    kubectl get all
    # 删除命名空间会删除命名空间下的所有内容
    kubectl delete ns dev
    

    切换当前命名空间

    #查看当前上下文
    kubectl config current-context
    
    #将dev设为当前命名空间,后续所有操作都在此命名空间下执行。
    kubectl config set-context $(kubectl config current-context) --namespace=dev
    

声明式对象配置

  1. 云原生的代表技术包括:

    • 容器

    • 服务网格

    • 微服务

    • 不可变基础设施

    • 声明式API

  2. 管理对象:命令行指令 vs 声明式配置

    • 命令行指令

      例如,使用kubectl命令来创建和管理 Kubernetes 对象。

      命令行就好比口头传达,简单、快速、高效。

      但它功能有限,不适合复杂场景,操作不容易追溯,多用于开发和调试。

    • 声明式配置

      kubernetes使用yaml文件来描述 Kubernetes 对象。

      声明式配置就好比申请表,学习难度大且配置麻烦。

      好处是操作留痕,适合操作复杂的对象,多用于生产。

  3. 常用命令缩写

    名称缩写Kind
    namespacesnsNamespace
    nodesnoNode
    podspoPod
    servicessvcService
    deploymentsdeployDeployment
    replicasetsrsReplicaSet
    statefulsetsstsStatefulSet
  4. 配置对象

    在创建的 Kubernetes 对象所对应的 yaml文件中,需要配置的字段如下:

    • apiVersion - Kubernetes API 的版本
    • kind - 对象类别,例如PodDeploymentServiceReplicaSet
    • metadata - 描述对象的元数据,包括一个 name 字符串、UID 、标签和可选的 namespace
    • spec - 对象的配置

    举例:

    # my-pod.yaml
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
        ports:
        - containerPort: 80
    

    使用yaml文件管理对象

    #创建对象
    kubectl apply -f my-pod.yaml
    #编辑对象,这里有点问题
    kubectl edit nginx
    #删除对象
    kubectl delete -f my-pod.yaml
    
  5. 标签

    标签(Labels) 是附加到对象(比如 Pod)上的键值对,用于补充对象的描述信息。

    标签使用户能够以松散的方式管理对象映射,而无需客户端存储这些映射。

    由于一个集群中可能管理成千上万个容器,我们可以使用标签高效的进行选择和操作容器集合。


    • 键的格式:
      • 前缀(可选)/名称(必须)。
    • 有效名称和值:
      • 必须为 63 个字符或更少(可以为空)
      • 如果不为空,必须以字母数字字符([a-z0-9A-Z])开头和结尾
      • 包含破折号**-**、下划线**_**、点**.**和字母或数字

    label配置模版

    apiVersion: v1
    kind: Pod
    metadata:
      name: label-demo
      labels: #定义Pod标签
        environment: test
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
        ports:
        - containerPort: 80
    
    # 查看Pod的同时展示标签
    kubectl get pod --show-labels
    # 根据标签查看Pod
    kubectl get pod -l environment=test,app=nginx
    
  6. 选择器

    标签选择器 可以识别一组对象。标签不支持唯一性。

    标签选择器最常见的用法是为Service选择一组Pod作为后端。


    Service配置模版

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      type: NodePort
      selector: #与Pod的标签一致
        environment: test
        app: nginx
      ports:
          # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
        - port: 80
          targetPort: 80
          # 可选字段
          # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
          nodePort: 30007
    

    目前支持两种类型的选择运算:基于等值的基于集合的

    多个选择条件使用逗号分隔,相当于**And(&&)**运算。

    • 等值选择:键值对

      selector:
        matchLabels: # component=redis && version=7.0
          component: redis
          version: 7.0
      
    • 集合选择

      selector:
        matchExpressions: # tier in (cache, backend) && environment not in (dev, prod)
          - {key: tier, operator: In, values: [cache, backend]}
          - {key: environment, operator: NotIn, values: [dev, prod]}
      

容器与镜像

容器运行时接口(CRI)

Kubelet运行在每个节点(Node)上,用于管理和维护Pod和容器的状态。

容器运行时接口(CRI)是kubelet 和容器运行时之间通信的主要协议。它将 Kubelet 与容器运行时解耦,理论上,实现了CRI接口的容器引擎,都可以作为kubernetes的容器运行时。

Docker没有实现(CRI)接口,Kubernetes使用dockershim来兼容docker。

自V1.24版本起,Dockershim 已从 Kubernetes 项目中移除。


crictl是一个兼容CRI的容器运行时命令,他的用法跟docker命令一样,可以用来检查和调试底层的运行时容器。

crictl pull mysql:5.7-debian
crictl images

在一些局域网环境下,我们没法通过互联网拉取镜像,可以手动的导出、导入镜像。

crictl命令没有导出、导入镜像的功能。

需要使用ctr命令导出、导入镜像,它是containerd的命令行接口。

containerd导出、导入镜像

#导出镜像,kubernetes中所有镜像都在k8s.io命名
ctr -n k8s.io images export mysql.tar docker.io/library/mysql:5.7-debian --platform linux/amd64
#导入镜像
ctr -n k8s.io images import mysql.tar

金丝雀发布

  1. 概述

    金丝雀部署(canary deployment) 也被称为灰度发布

    早期,工人下矿井之前会放入一只金丝雀检测井下是否存在有毒气体。

    采用金丝雀部署,你可以在生产环境的基础设施中小范围的部署新的应用代码。

    一旦应用签署发布,只有少数用户被路由到它,最大限度的降低影响。

    如果没有错误发生,则将新版本逐渐推广到整个基础设施在这里插入图片描述

  2. 部署过程

    在这里插入图片描述

    第一个版本

    发布v1版本的应用,镜像使用nginx:1.22,数量为 3

    • 创建Namespace

    Namespace配置模版

    • 创建Deployment

    Deployment配置模版

    • 创建外部访问的Service

    Service配置模版

    # deploy-v1.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: dev
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-v1
      namespace: dev
      labels:
        app: nginx-deployment-v1
    spec:
      replicas: 3
      selector:
        matchLabels: # 跟template.metadata.labels一致
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.22
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: canary-demo
      namespace: dev
    spec:
      type: NodePort
      selector: # 跟Deployment中的selector一致
        app: nginx
      ports:
          # By default and for convenience, the `targetPort` is set to the same value as the `port` field.
        - port: 80
          targetPort: 80
          # Optional field
          # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
          nodePort: 30008
    

    创建Canary Deployment

    # deploy-cannary.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-canary
      namespace: dev
      labels:
        app: nginx-deployment-canary
    spec:
      replicas: 1
      selector:
        matchLabels: # 跟template.metadata.labels一致
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
            track: canary
        spec:
          containers:
            - name: new-nginx
              image: docker/getting-started
              ports:
                - containerPort: 80
    

    image-20231128224122881

    分配流量

    查看服务kubectl describe svc canary-demo --namespace=dev

    • 调整比例

      待稳定运行一段时间后,扩大试用范围,将部署的v2版本数量调整为3,v1和v2的数量都是3个。

      kubectl scale deployment/nginx-deployment-canary --replicas=3 -n=dev
      

      image-20231128224029908

    • 下线旧版本

      kubectl scale deployment/nginx-deployment-v1 --replicas=0 -n=dev
      

      image-20231128224152534

    清空环境

    kubectl delete all --all -n=dev
    
  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值