Kubernetes基础操作

K8S基础操作

✨✨✨✨✨✨✨✨✨这个基础操作一切都基于各位把k8s搭建好哦,搭建的时候请一定一定一定(很重要),选定一个版本,能避免很多错,然后本章节就给大家介绍了k8s最基础的操作,有一些复杂的我有空再仔细介绍,最起码的看完这篇,你可以将你的应用部署到k8s上给k8s管理啦!!!🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉

在本章节开始前,先安装kubectl自动代码补全功能

sudo apt-get install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
kubectl completion bash >/etc/bash_completion.d/kubectl

请检查你的集群是否可用,正常情况下kube-system下的所有pod都应该是在启动中的,如果出现有没启动的说明集群并没有完全搭建成功,请检查集群是否可用,若不肯定集群是否可用,可以跟着部署第一个应用程序的章节在集群上部署一个nginx,看看nginx是否可以进行正常访问

kubectl get pods -n kube-system

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AOyd7w6V-1684922699083)(p1.png)]

报错指南

如果你发现你的flannel插件报错了一直处于error或者一直在等待启动(CrashLoopBackOff),这里提供一个解决报错的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbAGJ2XN-1684922699085)(before.png)]

  • 解决方法一:如果你不嫌弃麻烦,直接reset ,重新init的时候加上参数--pod-network-cidr 10.244.0.0/16

  • 解决方法二:

    编辑 master 机器上的 /etc/kubernetes/manifests/kube-controller-manager.yaml
    启动文件加上下面两句话,下面这个cluster-cidr要和kube-flannel.yml里面的地址一致,要和kube-proxy.config.yaml里面的clusterCIDR一致

    –allocate-node-cidrs=true
    –cluster-cidr=10.244.0.0/16

如果你发现你的k8s集群报错是因为kube-system中的coredns这几个pod没启动成功,那么相信我,先别找别的教程,直接重启你的虚拟机,所有虚拟机,能大概率解决这个问题(这是我总结出来最容易的解决方法了!)

kubectl命令介绍

使用以下语法从终端窗口运行 kubectl 命令:

kubectl [command] [TYPE] [NAME] [flags]

其中 commandTYPENAMEflags 分别是:

  • command:指定要对一个或多个资源执行的操作,例如 creategetdescribedelete

  • TYPE:指定资源类型。资源类型不区分大小写, 可以指定单数、复数或缩写形式。例如,以下命令输出相同的结果:

    kubectl get pod pod1
    kubectl get pods pod1
    kubectl get po pod1
    
  • NAME:指定资源的名称。名称区分大小写。 如果省略名称,则显示所有资源的详细信息。例如:kubectl get pods

    在对多个资源执行操作时,你可以按类型和名称指定每个资源,或指定一个或多个文件:

  • 要按类型和名称指定资源:

  • 要对所有类型相同的资源进行分组,请执行以下操作:TYPE1 name1 name2 name<#>
    例子:kubectl get pod example-pod1 example-pod2

  • 分别指定多个资源类型:TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>
    例子:kubectl get pod/example-pod1 replicationcontroller/example-rc1

  • 用一个或多个文件指定资源:-f file1 -f file2 -f file<#>

  • 使用 YAML 而不是 JSON, 因为 YAML 对用户更友好, 特别是对于配置文件。
    例子:kubectl get -f ./pod.yaml

  • flags: 指定可选的参数。例如,可以使用 -s--server 参数指定 Kubernetes API 服务器的地址和端口。

# 查看所有pod
kubectl get pod 

# 查看某个pod
kubectl get pod pod_name

# 查看某个pod,以yaml格式展示结果
kubectl get pod pod_name -o yaml

注意:

从命令行指定的参数会覆盖默认值和任何相应的环境变量。

如果你需要帮助,在终端窗口中运行 kubectl help

 kubectl help

经常使用的操作有下面这些:

命令分类命令翻译命令作用
基本命令create创建创建一个资源
edit编辑编辑一个资源
get获取获取一个资源
patch更新更新一个资源
delete删除删除一个资源
explain解释展示资源文档
运行和调试run运行在集群中运行一个指定的镜像
expose暴露暴露资源为Service
describe描述显示资源内部信息
logs日志输出容器在 pod 中的日志输出容器在 pod 中的日志
attach缠绕进入运行中的容器进入运行中的容器
exec执行容器中的一个命令执行容器中的一个命令
cp复制在Pod内外复制文件
rollout首次展示管理资源的发布
scale规模扩(缩)容Pod的数量
autoscale自动调整自动调整Pod的数量
高级命令appy应用通过文件对资源进行配置
label标签更新资源上的标签
其他命令cluster-info集群信息显示集群信息
version版本显示当前Server和Client的版本

资源类型

kubernetes中所有的内容都抽象为资源,可以通过下面的命令进行查看:

kubectl api-resources
资源名缩写名API 版本按命名空间资源类型
bindingsv1trueBinding
componentstatusescsv1falseComponentStatus
configmapscmv1trueConfigMap
endpointsepv1trueEndpoints
eventsevv1trueEvent
limitrangeslimitsv1trueLimitRange
namespacesnsv1falseNamespace
nodesnov1falseNode
persistentvolumeclaimspvcv1truePersistentVolumeClaim
persistentvolumespvv1falsePersistentVolume
podspov1truePod
podtemplatesv1truePodTemplate
replicationcontrollersrcv1trueReplicationController
resourcequotasquotav1trueResourceQuota
secretsv1trueSecret
serviceaccountssav1trueServiceAccount
servicessvcv1trueService
mutatingwebhookconfigurationsadmissionregistration.k8s.io/v1falseMutatingWebhookConfiguration
validatingwebhookconfigurationsadmissionregistration.k8s.io/v1falseValidatingWebhookConfiguration
customresourcedefinitionscrd,crdsapiextensions.k8s.io/v1falseCustomResourceDefinition
apiservicesapiregistration.k8s.io/v1falseAPIService
controllerrevisionsapps/v1trueControllerRevision
daemonsetsdsapps/v1trueDaemonSet
deploymentsdeployapps/v1trueDeployment
replicasetsrsapps/v1trueReplicaSet
statefulsetsstsapps/v1trueStatefulSet
tokenreviewsauthentication.k8s.io/v1falseTokenReview
localsubjectaccessreviewsauthorization.k8s.io/v1trueLocalSubjectAccessReview
selfsubjectaccessreviewsauthorization.k8s.io/v1falseSelfSubjectAccessReview
selfsubjectrulesreviewsauthorization.k8s.io/v1falseSelfSubjectRulesReview
subjectaccessreviewsauthorization.k8s.io/v1falseSubjectAccessReview
horizontalpodautoscalershpaautoscaling/v2trueHorizontalPodAutoscaler
cronjobscjbatch/v1trueCronJob
jobsbatch/v1trueJob
certificatesigningrequestscsrcertificates.k8s.io/v1falseCertificateSigningRequest
leasescoordination.k8s.io/v1trueLease
endpointslicesdiscovery.k8s.io/v1trueEndpointSlice
eventsevevents.k8s.io/v1trueEvent
flowschemasflowcontrol.apiserver.k8s.io/v1beta2falseFlowSchema
prioritylevelconfigurationsflowcontrol.apiserver.k8s.io/v1beta2falsePriorityLevelConfiguration
ingressclassesnetworking.k8s.io/v1falseIngressClass
ingressesingnetworking.k8s.io/v1trueIngress
networkpoliciesnetpolnetworking.k8s.io/v1trueNetworkPolicy
runtimeclassesnode.k8s.io/v1falseRuntimeClass
poddisruptionbudgetspdbpolicy/v1truePodDisruptionBudget
podsecuritypoliciespsppolicy/v1beta1falsePodSecurityPolicy
clusterrolebindingsrbac.authorization.k8s.io/v1falseClusterRoleBinding
clusterrolesrbac.authorization.k8s.io/v1falseClusterRole
rolebindingsrbac.authorization.k8s.io/v1trueRoleBinding
rolesrbac.authorization.k8s.io/v1trueRole
priorityclassespcscheduling.k8s.io/v1falsePriorityClass
csidriversstorage.k8s.io/v1falseCSIDriver
csinodesstorage.k8s.io/v1falseCSINode
csistoragecapacitiesstorage.k8s.io/v1trueCSIStorageCapacity
storageclassesscstorage.k8s.io/v1falseStorageClass
volumeattachmentsstorage.k8s.io/v1falseVolumeAttachment

部署你在 Kubernetes上的第一个应用程序

创建一个nginx服务

kubectl create deployment nginx  --image=nginx:1.14-alpine

暴露端口

kubectl expose deploy nginx  --port=80 --target-port=80  --type=NodePort

查看服务

kubectl get pod,svc

查看pod

在这里插入图片描述

浏览器测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-USUAX1pi-1684922699086)(01.png)]

如果你出来了这个页面,恭喜你,你已经能使用k8s部署一个最简单的nginx应用,接下来将借着这个小小的demo深入学习k8s每一个工作负载资源并学会使用他

概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JtYTJnbw-1684922699087)(total.png)]

一些名词Kubernetes

Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控

Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行

Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等

Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod

Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签

NameSpace:命名空间,用来隔离pod的运行环境

Kubernetes 对象

在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 具体而言,它们描述了如下信息:

  • 哪些容器化应用正在运行(以及在哪些节点上运行)
  • 可以被应用使用的资源
  • 关于应用运行时行为的策略,比如重启策略、升级策略以及容错策略

Kubernetes 对象是一种“意向表达(Record of Intent)”。一旦创建该对象, Kubernetes 系统将不断工作以确保该对象存在。通过创建对象,你本质上是在告知 Kubernetes 系统,你想要的集群工作负载状态看起来应是什么样子的, 这就是 Kubernetes 集群所谓的期望状态(Desired State)

操作 Kubernetes 对象 —— 无论是创建、修改或者删除 —— 需要使用 Kubernetes API。 比如,当使用 kubectl 命令行接口(CLI)时,CLI 会调用必要的 Kubernetes API; 也可以在程序中使用客户端库, 来直接调用 Kubernetes API。

大多数情况下,你需要提供 .yaml 文件为 kubectl 提供这些信息。我们可以通过官网的yaml示例文件进行一个初步理解:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

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

  • apiVersion 版本,由kubernetes内部定义,版本号必须可以用 kubectl api-versions 查询到
  • kind 类型,由kubernetes内部定义,版本号必须可以用 kubectl api-resources 查询到
  • metadata 元数据,主要是资源标识和说明,常用的有name、namespace、labels等
  • spec 描述,这是配置中最重要的一部分,里面是对各种资源配置的详细描述
  • status 状态信息,里面的内容不需要定义,由kubernetes自动生成

我们可以使用这类似的yaml文件创建Kubernetes对象,

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

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 帮助唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 你所期望的该对象的状态

Kubernetes 对象管理

此处存在三种Kubernetes 对象管理的方式,应该只使用一种技术来管理 Kubernetes 对象。混合和匹配技术作用在同一对象上将导致未定义行为。

管理技术作用于建议的环境支持的写者学习难度
指令式命令活跃对象开发项目1+最低
指令式对象配置单个文件生产项目1中等
声明式对象配置文件目录生产项目1+最高

指令式命令

使用指令式命令时,用户可以在集群中的活动对象上进行操作。用户将操作传给 kubectl 命令作为参数或标志。

这是开始或者在集群中运行一次性任务的推荐方法。因为这个技术直接在活跃对象 上操作,所以它不提供以前配置的历史记录。

例子

  • 通过指令式命令来运行 nginx 容器的实例:

    # 创建一个namespace
    root@k8smaster:/home/yurrize# kubectl create namespace wick
    namespace/wick created
    # 查看namespace
    root@k8smaster:/home/yurrize# kubectl get ns
    NAME              STATUS   AGE
    default           Active   89m
    kube-flannel      Active   84m
    kube-node-lease   Active   89m
    kube-public       Active   89m
    kube-system       Active   89m
    wick              Active   12s
    # 在这个namespace中创建一个nginx的pod
    root@k8smaster:/home/yurrize# kubectl run pod --image=nginx:latest -n wick
    pod/pod created
    # 获取Pod状态
    root@k8smaster:/home/yurrize# kubectl get pod -n wick
    NAME   READY   STATUS              RESTARTS   AGE
    pod    0/1     ContainerCreating   0          10s
    # 删除该命名空间下的Pod
    root@k8smaster:/home/yurrize# kubectl delete pod -n wick pod
    pod "pod" deleted
    # 查看删除状态
    root@k8smaster:/home/yurrize# kubectl get pod -n wick
    No resources found in wick namespace.
    # 删除命名空间
    root@k8smaster:/home/yurrize# kubectl delete ns wick
    namespace "wick" deleted
    

权衡

与对象配置相比的优点:

  • 命令用单个动词表示。
  • 命令仅需一步即可对集群进行更改。

与对象配置相比的缺点:

  • 命令不与变更审查流程集成。
  • 命令不提供与更改关联的审核跟踪。
  • 除了实时内容外,命令不提供记录源。
  • 命令不提供用于创建新对象的模板。

指令式对象配置

在指令式对象配置中,kubectl 命令指定操作(创建,替换等),可选标志和 至少一个文件名。指定的文件必须包含 YAML 或 JSON 格式的对象的完整定义。

警告:

replace 指令式命令将现有规范替换为新提供的规范,并放弃对配置文件中 缺少的对象的所有更改。此方法不应与对象规约被独立于配置文件进行更新的 资源类型一起使用。比如类型为 LoadBalancer 的服务,它的 externalIPs 字段就是独立于集群配置进行更新。

例子

  • 在当前目录下创建命名为nginxpod.yaml的配置文件

    # 配置ns和pod为nginx的container
    apiVersion: v1
    kind: Namespace
    metadata:
      name: wick
    
    ---
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginxpod
      namespace: wick
    spec:
      containers:
      - name: nginx-containers
        image: nginx:latest
    
  • 执行create命令,创建资源

    kubectl create -f nginxpod.yaml
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hu9Lg9BA-1684922699088)(02.png)]

    创建了两个对象,一个是namespace,一个是pod

  • 执行get命令,查看资源:

    kubectl get -f nginxpod.yaml
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CYngey60-1684922699089)(03.png)]

    查看yaml文件创建的两个对象

  • 执行delete命令,删除资源

    kubectl delete -f nginxpod.yaml 
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w7A9ZTCn-1684922699090)(04.png)]

  • 通过覆盖活动配置来更新配置文件中定义的对象:

    kubectl replace -f nginx.yaml
    

权衡

与指令式命令相比的优点:

  • 对象配置可以存储在源控制系统中,比如 Git。
  • 对象配置可以与流程集成,例如在推送和审计之前检查更新。
  • 对象配置提供了用于创建新对象的模板。

与指令式命令相比的缺点:

  • 对象配置需要对对象架构有基本的了解。
  • 对象配置需要额外的步骤来编写 YAML 文件。

与声明式对象配置相比的优点:

  • 指令式对象配置行为更加简单易懂。
  • 从 Kubernetes 1.5 版本开始,指令对象配置更加成熟。

与声明式对象配置相比的缺点:

  • 指令式对象配置更适合文件,而非目录。
  • 对活动对象的更新必须反映在配置文件中,否则会在下一次替换时丢失。

声明式对象配置

使用声明式对象配置时,用户对本地存储的对象配置文件进行操作,但是用户 未定义要对该文件执行的操作。 kubectl 会自动检测每个文件的创建、更新和删除操作。 这使得配置可以在目录上工作,根据目录中配置文件对不同的对象执行不同的操作。

说明:

声明式对象配置保留其他编写者所做的修改,即使这些更改并未合并到对象配置文件中。 可以通过使用 patch API 操作仅写入观察到的差异,而不是使用 replace API 操作来替换整个对象配置来实现。

例子

  • 使用apply指定并创建对象

    kubectl apply -f nginxpod.yaml
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oPFrtgzd-1684922699090)(05.png)]

  • 处理 configs 目录中的所有对象配置文件,创建并更新活跃对象。 可以首先使用 diff 子命令查看将要进行的更改,然后在进行应用:

    kubectl diff -f configs/
    kubectl apply -f configs/
    
  • 递归处理目录:

    kubectl diff -R -f configs/
    kubectl apply -R -f configs/
    

权衡

与指令式对象配置相比的优点:

  • 对活动对象所做的更改即使未合并到配置文件中,也会被保留下来。
  • 声明性对象配置更好地支持对目录进行操作并自动检测每个文件的操作类型(创建,修补,删除)。

与指令式对象配置相比的缺点:

  • 声明式对象配置难于调试并且出现异常时结果难以理解。
  • 使用 diff 产生的部分更新会创建复杂的合并和补丁操作。

指令式对象配置和声明式对象配置对比

如果使用指令式对象配置,yaml文件进行了更新,再次执行create命令会报错

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kVotu6KE-1684922699091)(06.png)]

如果使用声明式对象配置,会先进行一次检查,检查yaml文件的最终状态,可以检查一整个文件夹

  • 如果资源不存在,就创建,相当于 kubectl create
  • 如果资源已存在,就更新,相当于 kubectl patch

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VTOFsT8w-1684922699092)(07.png)]

Kubernetes 组件

当你部署完 Kubernetes,便拥有了一个完整的集群。

一组工作机器,称为节点,会运行容器化应用程序。每个集群至少有一个工作节点。

工作节点会托管 Pod,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pod。 在生产环境中,控制平面通常跨多台计算机运行, 一个集群通常运行多个节点,提供容错性和高可用性。

一个kubernetes集群主要是由控制节点(master)、**工作节点(node)**构成,每个节点上都会安装不同的组件。

master:集群的控制平面,负责集群的决策 ( 管理 )

ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制

Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上

ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等

Etcd :负责存储集群中各种资源对象的信息

node:集群的数据平面,负责为容器提供运行环境 ( 干活 )

Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器

KubeProxy : 负责提供集群内部的服务发现和负载均衡

Docker or Container : 负责节点上容器的各种操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7YsNG3YJ-1684922699092)(components-of-kubernetes.svg)]

下面,以开始时第一个demo部署nginx服务来说明kubernetes系统各个组件调用关系:

  1. 首先要明确,一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中

  2. 一个nginx服务的安装请求会首先被发送到master节点的apiServer组件

  3. apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上

    在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer

  4. apiServer调用controller-manager去调度Node节点安装nginx服务

  5. kubelet接收到指令后,会通知docker,然后由docker或container running来启动一个nginx的pod

    pod是kubernetes的最小操作单元,容器必须跑在pod中至此,

  6. 一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理

这样,外界用户就可以访问集群中的nginx服务了

Namespace

在上述对象管理中,多次提到了关键词namespace,在 Kubernetes 中,**名字空间(Namespace)**提供一种机制,将同一集群中的资源划分为相互隔离的组。

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

可以通过kubernetes的授权机制,将不同的namespace交给不同租户进行管理,这样就实现了多租户的资源隔离。此时还能结合kubernetes的资源配额机制,限定不同租户能占用的资源,例如CPU使用量、内存使用量等等,来实现租户可用资源的管理

初始名字空间

Kubernetes 启动时会创建四个初始名字空间:

root@k8smaster:/home/yurrize# kubectl  get namespace
NAME              STATUS   AGE
default           Active   8h     #  所有未指定Namespace的对象都会被分配在default命名空间
kube-flannel      Active   8h     #  集群节点之间的心跳维护,v1.13开始引入
kube-node-lease   Active   8h     #  此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-public       Active   8h     #  此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system       Active   8h     #  所有由Kubernetes系统创建的资源都处于这个命名空间
  • default

    Kubernetes 包含这个名字空间,以便于你无需创建新的名字空间即可开始使用新集群。

  • kube-node-lease

    该名字空间包含用于与各个节点关联的 Lease(租约对象。 节点租约允许 kubelet 发送心跳), 由此控制面能够检测到节点故障。

  • kube-public

    所有的客户端(包括未经身份验证的客户端)都可以读取该名字空间。 该名字空间主要预留为集群使用,以便某些资源需要在整个集群中可见可读。 该名字空间的公共属性只是一种约定而非要求。

  • kube-system

    该名字空间用于 Kubernetes 系统创建的对象。

ns基础操作

  • 查询操作

    # 查看所有的ns  命令:kubectl get ns
    kubectl get ns
     
    # 查看指定的ns   命令:kubectl get ns namespace名称
    kubectl get ns default
    
    # 指定输出格式  命令:kubectl get ns ns名称  -o 格式参数
    # kubernetes支持的格式有很多,比较常见的是wide、json、yaml
    kubectl get ns default -o yaml
      
    # 查看ns详情  命令:kubectl describe ns namespace名称
    kubectl describe ns default
    
  • 创建操作

    # 创建namespace
    kubectl create ns wick
    
  • 删除操作

    # 删除namespace
    kubectl delete ns wick
    
  • yaml配置方式

    通过yaml文件,进行命名空间的配置,此处新建文件为ns-dev.yaml

    apiVersion: v1
    kind: Namespace
    metadata:
      name: wick
    

    然后就可以执行对应的创建和删除命令了:

    # 创建
    kubectl apply -f ns-dev.yaml
    # 删除
    kubectl delete -f ns-dev.yaml
    

Pod

可以通过 kubectl explain pod 查看pod可配置项

sudo kubectl explain pod
KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Pod is a collection of containers that can run on a host. This resource is
    created by clients and scheduled onto hosts.
    
FIELDS:
  apiVersion	<string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind	<string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata	<ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec	<PodSpec>
    Specification of the desired behavior of the pod. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

  status	<PodStatus>
    Most recently observed status of the pod. This data may not be up to date.
    Populated by the system. Read-only. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status


touch一个文件,文件名为ns-test.yaml文件,用于创建ns

touch ns-test.yaml
vim ns-test.yaml 

# ns-test.yaml 内容
apiVersion: v1
kind: Namespace
metadata:
  name: test      

执行create命令通过使用yaml文件创建ns

root@k8smaster:/home/yurrize# kubectl create -f ns-test.yaml 
namespace/test created

使用deployment控制器创建Pod

kubectl create deployment nginx --image=nginx:1.17.1 -n test
kubectl scale --replicas=3 deploy/nginx -n test

测试

yurrize@k8smaster:~$ kubectl get pod -n test
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6599ff7445-4n2lk   1/1     Running   0          41m
nginx-6599ff7445-hd5fv   1/1     Running   0          41m
nginx-6599ff7445-jlzxg   1/1     Running   0          41m

# -o参数是以格式化形式输出pod信息,可选JSON,Yaml,Wide
yurrize@k8smaster:~$ kubectl get pod -n test -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE                    NOMINATED NODE   READINESS GATES
nginx-6599ff7445-4n2lk   1/1     Running   0          41m   10.244.0.6   k8smaster.yurrize.net   <none>           <none>
nginx-6599ff7445-hd5fv   1/1     Running   0          41m   10.244.0.4   k8smaster.yurrize.net   <none>           <none>
nginx-6599ff7445-jlzxg   1/1     Running   0          41m   10.244.0.5   k8smaster.yurrize.net   <none>           <none>

yurrize@k8smaster:~$ curl http://10.244.0.6
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

ns能通过yaml形式创建,那么同理,pod也可以,touch一个文件pod-nginx.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: test
spec:
  containers:
  - image: nginx:latest
    name: pod
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP

然后就可以通过create指令控制pod的生成和销毁

kubectl create -f pod-nginx.yaml
kubectl delete -f pod-nginx.yaml

如果想更加详细的了解这个pod节点到底做了什么,可以使用kubectl的描述功能

kubectl describe pod 'your pod id'  -n 'your namespace'

理解Pod

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

Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的 “逻辑主机”,其中包含一个或多个应用容器, 这些容器相对紧密地耦合在一起。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用。

除了应用容器,Pod 还可以包含在 Pod 启动期间运行的 Init 容器。 你也可以在集群支持临时性容器的情况下, 为调试的目的注入临时性容器。

Pod生命周期

Pod 的 status 字段是一个 PodStatus 对象,其中包含一个 phase 字段。

生命周期可以通过get指令,配合-o格式化参数进行查看

sudo kubectl get pods -n 'yournamespace' -o wide

Pod 的阶段(Phase)是 Pod 在其生命周期中所处位置的简单宏观概述。 该阶段并不是对容器或 Pod 状态的综合汇总,也不是为了成为完整的状态机。

Pod 阶段的数量和含义是严格定义的。 除了本文档中列举的内容外,不应该再假定 Pod 有其他的 phase 值。

下面是 phase 可能的值:

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

说明:

当一个 Pod 被删除时,执行一些 kubectl 命令会展示这个 Pod 的状态为 Terminating(终止)。 这个 Terminating 状态并不是 Pod 阶段之一。 Pod 被赋予一个可以体面终止的期限,默认为 30 秒。 你可以使用 --force 参数来强制终止 Pod。

从 Kubernetes 1.27 开始,除了静态 Pod和没有 Finalizer 的强制终止 Pod之外,kubelet 会将已删除的 Pod 转换到终止阶段 (FailedSucceeded 具体取决于 Pod 容器的退出状态),然后再从 API 服务器中删除。

如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的 phase 设置为 Failed

容器探针

probe 是由 kubelet对容器执行的定期诊断。 要执行诊断,kubelet 既可以在容器内执行代码,也可以发出一个网络请求。

  • 检查机制

使用探针来检查容器有四种不同的方法。 每个探针都必须准确定义为这四种机制中的一种:

  • exec

    在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。

  • grpc

    使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC 健康检查。 如果响应的状态是 “SERVING”,则认为诊断成功。

  • httpGet

    对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。

  • tcpSocket

    对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的。

  • 探测结果

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

  • Success(成功)

    容器通过了诊断。

  • Failure(失败)

    容器未通过诊断。

  • Unknown(未知)

    诊断失败,因此不会采取任何行动。

为Pod分配资源

可以为容器和Pod分配内存资源,CPU资源,也可以对这些资源进行调整,

接下来以一个limit.yaml文件进行介绍,这个yaml文件对cpu和内存资源都进行了上下限的限制

apiVersion: v1
kind: Pod
metadata:
  name: resources-demo
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    resources: # 资源配额
      requests:  # 请求资源(下限)
      	cpu: "1"  # CPU限制,单位是core数
        memory: "100Mi" # 内存限制
      limits: # 限制资源(上限)
      	cpu: "2" # CPU限制,单位是core数
        memory: "200Mi" # 内存限制

工作负载资源

在pod基础操作中,提到了pod的创建是通过使用deployment控制器进行创建的,你可以使用工作负载资源来创建和管理多个 Pod。 资源的控制器能够处理副本的管理、上线,并在 Pod 失效时提供自愈能力。 例如,如果一个节点失败,控制器注意到该节点上的 Pod 已经停止工作, 就可以创建替换性的 Pod。调度器会将替身 Pod 调度到一个健康的节点执行。

在官网中有介绍到这么多种工作负载资源

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wIGz6uxb-1684922699093)(08.png)]

Deployments

一个 Deployment 为 Pod和 ReplicaSet提供声明式的更新能力。

你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller)以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。

Deployments 的典型用例:

  • 创建 Deployment 以将 ReplicaSet 上线。ReplicaSet 在后台创建 Pod。 检查 ReplicaSet 的上线状态,查看其是否成功。

  • 通过更新 Deployment 的 PodTemplateSpec,声明 Pod 的新状态 。 新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新 Deployment 的修订版本。

  • 如果 Deployment 的当前状态不稳定,回滚到较早的 Deployment 版本。 每次回滚都会更新 Deployment 的修订版本。

  • 扩大 Deployment 规模以承担更多负载。

  • 暂停 Deployment 的上线以应用对 PodTemplateSpec 所作的多项修改, 然后恢复其执行以启动新的上线版本。

  • 使用 Deployment 状态来判定上线过程是否出现停滞。

  • 清理较旧的不再需要的 ReplicaSet。

创建一个Deployment

创建一个nginx-deployment.yaml文件,通过apply指令创建一个deployment

# 这是一个 Deployment 示例。其中创建了一个 ReplicaSet,负责启动三个 nginx Pod:
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型  
metadata: # 元数据
  name: nginx-deployment # ReplicaSet名称 
  namespace: test
  labels: # 标签
    app: nginx
spec: # 详情描述
  replicas: 3 # 副本数量
  selector: # 选择器,通过它指定该控制器管理哪些pod
    matchLabels:  # Labels匹配规则
      app: nginx
  template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

根据这个配置文件,我们可以创建副本为三的nginxPod,同时我们可以对Deployment进行缩放

# 查看deployment
kubectl get deployment -n test

# 查看pod
kubectl get pods -n test

# 获取 Deployment 的更多信息
kubectl describe deployments -n test

# 编辑deployment的副本数量,修改spec:replicas: 数目
kubectl edit deploy nginx-deployment -n test

# 指令缩放 Deployment
kubectl scale deployment/nginx-deployment  -n test --replicas=10

# 为 Deployment 设置自动缩放器,并基于现有 Pod 的 CPU 利用率选择要运行的 Pod 个数下限和上限
kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80  -n test

# 查看rs信息
kubectl get rs

我们也可以对版本进行回滚操作

# 查看当前升级版本的状态
kubectl rollout status deploy nginx-deployment -n test

# 检查 Deployment 修订历史
kubectl rollout history deployment/nginx-deployment -n test

# 查看升级历史记录
kubectl rollout history deploy nginx-deployment -n test

# 版本回滚,回滚到版本1
kubectl rollout undo deployment nginx-deployment --to-revision=1  -n test

删除deployment,注意这会一并删除此配置文件产生的所有ns,pod

kubectl delete -f nginx-deployment.yaml

ReplicaSet

StatefulSet

DaemonSet

Job

CronJob

ReplicationController

Label标签

了解了Pod,工作负载资源,我们就可以部署一个较为完整的应用了,但是当资源多起来的时候,没有标签就会显得特别的凌乱(谁也不喜欢自己的地方特别乱对吧),k8s也提供了Label这个功能为资源进行一个简单的分类

标签(Labels) 是附加到 Kubernetes 对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。

给节点添加标签

  1. 列出你的集群中的节点, 包括这些节点上的标签:

    kubectl get nodes --show-labels
    

    输出类似如下:

    NAME      STATUS    ROLES    AGE     VERSION        LABELS
    worker0   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker0
    worker1   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker1
    worker2   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker2
    
  2. 从你的节点中选择一个,为它添加标签:

    kubectl label nodes <your-node-name> disktype=ssd
    

    <your-node-name> 是你选择的节点的名称。

  3. 验证你选择的节点确实带有 disktype=ssd 标签:

    kubectl get nodes --show-labels
    

    输出类似如下:

    NAME      STATUS    ROLES    AGE     VERSION        LABELS
    worker0   Ready     <none>   1d      v1.13.0        ...,disktype=ssd,kubernetes.io/hostname=worker0
    worker1   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker1
    worker2   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker2
    

    在前面的输出中,你可以看到 worker0 节点有 disktype=ssd 标签。

创建一个将被调度到你选择的节点的 Pod

此 Pod 配置文件描述了一个拥有节点选择器 disktype: ssd 的 Pod。这表明该 Pod 将被调度到有 disktype=ssd 标签的节点。

创建一个pod-nginx.yaml文件

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd
  1. 使用该配置文件创建一个 Pod,该 Pod 将被调度到你选择的节点上:

    kubectl create -f pod-nginx.yaml
    
  2. 验证 Pod 确实运行在你选择的节点上:

    kubectl get pods --output=wide
    

    输出类似如下:

    NAME     READY     STATUS    RESTARTS   AGE    IP           NODE
    nginx    1/1       Running   0          13s    10.200.0.4   worker0
    

创建一个会被调度到特定节点上的 Pod

你也可以通过设置 nodeName 将某个 Pod 调度到特定的节点。创建一个pod-nginx-specific-node.yaml文件

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeName: foo-node # 调度 Pod 到特定的节点
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent

使用此配置文件来创建一个 Pod,该 Pod 将只能被调度到 foo-node 节点。

删除标签

#删除Pod标签,node标签同理,注意标签名后面是一个减号!
kubectl label pod 'your pod name' 'labelName -' -n ns

Service

了解完如何在k8s内部署一个应用,如何对k8s资源进行控制,也了解了如何管理一个Pod那么就是时候对外提供服务了

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

Kubernetes 中 Service 的一个关键目标是让你无需修改现有应用程序就能使用不熟悉的服务发现机制。 你可以在 Pod 中运行代码,无需顾虑这是为云原生世界设计的代码,还是为已容器化的老应用程序设计的代码。 你可以使用 Service 让一组 Pod 在网络上可用,让客户端能够与其交互。

如果你使用 Deployment 来运行你的应用, Deployment 可以动态地创建和销毁 Pod。不管是这一刻还是下一刻, 你不知道有多少个这样的 Pod 正在工作以及健康与否;你可能甚至不知道那些健康的 Pod 是如何命名的。 Kubernetes Pod 被创建和销毁以匹配集群的预期状态。 Pod 是临时资源(你不应该期待单个 Pod 既可靠又耐用)。

每个 Pod 获取其自己的 IP 地址(Kubernetes 期待网络插件确保 IP 地址分配)。 对于集群中给定的 Deployment,这一刻运行的这组 Pod 可能不同于下一刻运行应用程序的那组 Pod。

虚拟 IP 和服务代理

Kubernetes 集群中的每个 节点会运行一个 kube-proxy ,实现虚拟 IP 机制。

使用代理转发方式实现 Service 的原因有以下几个:

  • DNS 的实现不遵守记录的 TTL 约定的历史由来已久,在记录过期后可能仍有结果缓存。
  • 有些应用只做一次 DNS 查询,然后永久缓存结果。
  • 即使应用程序和库进行了适当的重新解析,TTL 取值较低或为零的 DNS 记录可能会给 DNS 带来很大的压力, 从而变得难以管理。

代理模式

kube-proxy 会根据不同配置以不同的模式启动。

在 Linux 节点上,kube-proxy 的可用模式是:

  • iptables

    kube-proxy 在 Linux 上使用 iptables 配置数据包转发规则的一种模式。

  • ipvs

    kube-proxy 使用 ipvs 配置数据包转发规则的一种模式。

Windows 上的 kube-proxy 只有一种模式可用:

  • kernelspace

    kube-proxy 在 Windows 内核中配置数据包转发规则的一种模式。

iptables 代理模式

此代理模式仅适用于 Linux 节点。

在这种模式下,kube-proxy 监视 Kubernetes 控制平面,获知对 Service 和 EndpointSlice 对象的添加和删除操作。 对于每个 Service,kube-proxy 会添加 iptables 规则,这些规则捕获流向 Service 的 clusterIPport 的流量, 并将这些流量重定向到 Service 后端集合中的其中之一。 对于每个端点,它会添加指向一个特定后端 Pod 的 iptables 规则。

默认情况下,iptables 模式下的 kube-proxy 会随机选择一个后端。

使用 iptables 处理流量的系统开销较低,因为流量由 Linux netfilter 处理, 无需在用户空间和内核空间之间切换。这种方案也更为可靠。

如果 kube-proxy 以 iptables 模式运行,并且它选择的第一个 Pod 没有响应, 那么连接会失败。这与用户空间模式不同: 在后者这种情况下,kube-proxy 会检测到与第一个 Pod 的连接失败, 并会自动用不同的后端 Pod 重试。

你可以使用 Pod 就绪探针来验证后端 Pod 是否健康。 这样可以避免 kube-proxy 将流量发送到已知失败的 Pod 上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWmfjRf6-1684922699094)(services-iptables-overview.svg)]

IPVS 代理模式

此代理模式仅适用于 Linux 节点。

ipvs 模式下,kube-proxy 监视 Kubernetes Service 和 EndpointSlice, 然后调用 netlink 接口创建 IPVS 规则, 并定期与 Kubernetes Service 和 EndpointSlice 同步 IPVS 规则。 该控制回路确保 IPVS 状态与期望的状态保持一致。 访问 Service 时,IPVS 会将流量导向到某一个后端 Pod。

IPVS 代理模式基于 netfilter 回调函数,类似于 iptables 模式, 但它使用哈希表作为底层数据结构,在内核空间中生效。 这意味着 IPVS 模式下的 kube-proxy 比 iptables 模式下的 kube-proxy 重定向流量的延迟更低,同步代理规则时性能也更好。 与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。

IPVS 为将流量均衡到后端 Pod 提供了更多选择:

  • rr:轮询
  • lc:最少连接(打开连接数最少)
  • dh:目标地址哈希
  • sh:源地址哈希
  • sed:最短预期延迟
  • nq:最少队列

说明:

要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前确保节点上的 IPVS 可用。

当 kube-proxy 以 IPVS 代理模式启动时,它会验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则 kube-proxy 会退回到 iptables 代理模式运行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eczXFxmQ-1684922699095)(services-ipvs-overview.svg)]

定义Service

Service 在 Kubernetes 中是一个对象 (与 Pod 或 ConfigMap 类似的对象)。你可以使用 Kubernetes API 创建、查看或修改 Service 定义。 通常你使用 kubectl 这类工具来进行这些 API 调用。

Service的可选配置文件:可以通过 kubectl explain service进行查询

sudo kubectl explain service
[sudo] password for yurrize: 
KIND:       Service
VERSION:    v1

DESCRIPTION:
    Service is a named abstraction of software service (for example, mysql)
    consisting of local port (for example 3306) that the proxy listens on, and
    the selector that determines which pods will answer requests sent through
    the proxy.
    
FIELDS:
  apiVersion	<string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind	<string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata	<ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec	<ServiceSpec>
    Spec defines the behavior of a service.
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

  status	<ServiceStatus>
    Most recently observed status of the service. Populated by the system.
    Read-only. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

配置项解析

apiVersion: v1 # 资源版本
kind: Service # 资源类型
metadata: # 元数据
  name: nginx-service
  namespace: test # 命名空间
spec:
  selector:  # 标签选择器,用于确定当前service代理哪些pod
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80  # service端口
    targetPort:  5003 # pod端口
    nodePort: 31122 # 主机端口

使用Service

在使用service之前,首先利用Deployment创建出3个pod,注意要为pod设置app=nginx-pod的标签

创建deployment.yaml,内容如下:

apiVersion: apps/v1
kind: Deployment      
metadata:
  name: pc-deployment
  namespace: dev
spec: 
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - containerPort: 80

使用apply执行文件

kubectl create -f deployment.yaml

# 查看pod详情
kubectl get pods -n dev -o wide --show-labels
NAME                            READY   STATUS             RESTARTS        AGE   IP            NODE                     NOMINATED NODE   READINESS GATES   LABELS
pc-deployment-6fdb77cb4-8hnks   0/1     CrashLoopBackOff   4 (9s ago)      13m   10.244.1.12   k8sworker1.yurrize.net   <none>           <none>            app=nginx-pod,pod-template-hash=6fdb77cb4
pc-deployment-6fdb77cb4-npljm   1/1     Running            4 (2m41s ago)   13m   10.244.1.10   k8sworker1.yurrize.net   <none>           <none>            app=nginx-pod,pod-template-hash=6fdb77cb4
pc-deployment-6fdb77cb4-xvdkz   1/1     Running            0               13m   10.244.0.18   k8smaster.yurrize.net    <none>           <none>            app=nginx-pod,pod-template-hash=6fdb77cb4

# 为了方便后面的测试,修改下三台nginx的index.html页面(三台修改的IP地址不一致)
# =============以下操作三个pod都要进行=================
# 进入容器终端,使用以下命令,或者kubectl exec -it pc-deployment-6fdb77cb4-8hnks  -n dev  -- /bin/sh
kubectl exec pc-deployment-6fdb77cb4-8hnks  -n dev --stdin --tty -- /bin/sh 
# 说明:短的命令参数 -i 和 -t 与长的命令参数 --stdin 和 --tty 作用相同。
echo "这里是10.244.1.12" > /usr/share/nginx/html/index.html
# =============以上操作三个pod都要进行=================

#修改完毕之后,访问测试,可以看见每一次访问都会负载到不同pod上
curl 10.244.2.33
这里是10.244.1.12
curl 10.244.2.33
这里是10.244.1.10

Endpoint

Endpoint是kubernetes中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址,它是根据service配置文件中selector描述产生的。

一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。换句话说,service和pod之间的联系是通过endpoints实现的。

负载分发策略

对Service的访问被分发到了后端的Pod上去,目前kubernetes提供了两种负载分发策略:

  • 如果不定义,默认使用kube-proxy的策略,比如随机、轮询

  • 基于客户端地址的会话保持模式,即来自同一个客户端发起的所有请求都会转发到固定的一个Pod上

    开启此模式,在spec中添加sessionAffinity:ClientIP选项

创建yaml文件,service-clusterip.yaml

apiVersion: v1
kind: Service
metadata:
  name: service-clusterip
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: 10.97.97.97 # service的ip地址,如果不写,默认会生成一个
  type: ClusterIP
  ports:
  - port: 80  # Service端口       
    targetPort: 80 # pod端口

使用apply执行

# 循环访问测试
while true;do curl 10.97.97.97:80; sleep 5; done;
# 可以看见是轮询访问的
这里是10.244.1.12
这里是10.244.1.10

# 修改分发策略----sessionAffinity:ClientIP
# 循环访问测试
while true;do curl 10.97.97.97; sleep 5; done;
# 可以看见一直只访问一个节点
这里是10.244.1.12
这里是10.244.1.12
这里是10.244.1.12
  
# 删除service
kubectl delete -f service-clusterip.yaml

Ingress

Ingress 是允许入站连接到达后端定义的端点的规则集合。 Ingress 可以配置为向服务提供外部可访问的 URL、负载均衡流量、终止 SSL、提供基于名称的虚拟主机等。(说白了就是在service层上再加一层,相当于域名访问,支持外部对于部署在k8s的服务进行访问)

Ingress 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。

下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hjpuEMaX-1684922699096)(ingress.svg)]

图. Ingress

Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管。 Ingress 控制器通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。

Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。

https://kubernetes.github.io/ingress-nginx/deploy/#quick-start

注意这个版本问题,如果想不开要去折腾这个的话!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DbfP0jPC-1684922699096)(10.png)]

部署和访问 Kubernetes 仪表板

Dashboard 是基于网页的 Kubernetes 用户界面。 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。 你可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源 (如 Deployment,Job,DaemonSet 等等)。 例如,你可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。

Dashboard 同时展示了 Kubernetes 集群中的资源状态信息和所有报错信息。

# 将这个网址的内容cp下来,touch文件名称叫recommended.yaml
https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

然后编辑recommended.yaml

# 修改kubernetes-dashboard的Service类型
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort  # 新增
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30009  # 新增
  selector:
    k8s-app: kubernetes-dashboard

执行部署命令

# 部署
kubectl create -f recommended.yaml

创建访问账户,并给予访问权限,这里的用户名叫admin-user可以自己更改

  • 创建service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
  • 创建cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
  • 通过kubectl apply -f命令执行,创建用户指令

查看kubernetes-dashboard用户的登录token

kubectl -n kubernetes-dashboard create token admin-user

通过浏览器访问可视化页面

https://ip:30009/

选择token方式登录,并且将你刚刚查看到的token填入点击登录,这样就能可视化操纵k8s了!!!!(他甚至可以在setting设置为中文,真的我哭死)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KKUaSRzp-1684922699097)(view.png)]

防止可视化崩溃,为可视化资源分配三个资源

kubectl get deployment -n kubernetes-dashboard
NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
dashboard-metrics-scraper   0/1     1            0           31m
kubernetes-dashboard        2/3     3            2           31m

# kubernetes-dashboard按照你自己电脑上的这个ns中的pod来加,别直接复制我这个,每个人的pod名称可能不一样
kubectl scale deployment/dashboard-metrics-scraper  -n kubernetes-dashboard --replicas=3
kubectl scale deployment/kubernetes-dashboard  -n kubernetes-dashboard --replicas=3

到这里,k8s的最基本的操作就结束啦!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值