ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ(一个人的真正伟大之处就在于他能够认识到自己的渺小 —— 保罗)
ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

学习完本教程能给你带来什么

  • k8s的基本概念和核心知识点
  • k8s基本命令操作
  • k8s集群的搭建

本次教程搭建环境

  • VMware Workstation 虚拟机 16.2.0
  • windows系统
  • linux虚拟机 本教程使用ubuntu系统 20.04.1 内核5.11.0-38-generic
    • master节点 调度整个集群 192.168.5.138
    • node节点 负责运行应用 192.168.5.139
  • docker 20.10.10
  • kubectl 1.22.3
  • kubelet 1.22.3
  • kubeadm 1.22.3
  • 机器配置
    • 至少2个cpu
    • 2g可用内存
    • 20g磁盘空间
    • 可访问外网

什么是kubernetes

kubernetes,简称K8s,是用8代替8个字符“ubernete”而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制
它是Google开源的一个容器编排引擎,支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。
在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理

为什么需要kubernetest

先看一下目前的部署时代变革

部署时代变革
  • 传统部署时代

早期,各个组织机构在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界,这会导致资源分配问题。 例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况, 结果可能导致其他应用程序的性能下降。 一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展, 并且维护许多物理服务器的成本很高

  • 虚拟化部署时代

作为解决方案,引入了虚拟化。虚拟化技术允许你在单个物理服务器的 CPU 上运行多个虚拟机(VM)。 虚拟化允许应用程序在 VM 之间隔离,并提供一定程度的安全,因为一个应用程序的信息 不能被另一应用程序随意访问。
虚拟化技术能够更好地利用物理服务器上的资源,并且因为可轻松地添加或更新应用程序 而可以实现更好的可伸缩性,降低硬件成本等等。
每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

  • 容器部署时代

容器类似于 VM,但是它们具有被放宽的隔离属性,可以在应用程序之间共享操作系统(OS)。 因此,容器被认为是轻量级的。容器与 VM 类似,具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。

容器部署的优点
  1. 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率
  2. 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
  3. 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像, 从而将应用程序与基础架构分离。
  4. 可观察性:不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  5. 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
    跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  6. 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  7. 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  8. 资源隔离:可预测的应用程序性能。
  9. 资源利用:高效率和高密度

虚拟机和容器对比:

特性虚拟机容器
隔离级别操作系统进程
隔离策略HypervisorCGroups
系统资源5~15%0~5%
启动时间分钟级秒级
镜像存储GB-TBKB-MB
集群规模上百上万
高可用策略备份,容灾,迁移弹性,负载,动态
容器部署的缺点
  1. 随着容器的增加,容器的协调和调度步骤主键繁琐
  2. 服务升级如何保证不中断
  3. 服务运行状态的监控
  4. 容器的管理
如何解决上述问题

拥有了Kubernetes,你所需要做的事就是将镜像推送到Registry,然后等待Kubernetes来完成剩余的工作。所有部署环节的任务都由Kubernetes来管理,我们根本无需去担心基础设施

k8s的特征
  • 服务发现和负载均衡

Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定

  • 存储编排

Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。

  • 自动部署和回滚

你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器

  • 自动完成装箱计算

Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源

  • 自我修复

Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。

  • 密钥与配置管理

Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

k8s改变了什么

对于开发人员

由于公司业务多,开发环境、测试环境、预生产环境和生产环境都是隔离的,而且除了生产环境,为了节省成本,其他环境是没有日志收集的,在没有用k8s的时候,查看线下测试的日志,需要开发或者测试人员,找到对应的机器,在找到对应的容器,然后才能查看日志,在用了k8s之后,开发和测试可以直接在k8s的dashboard到对应的namespace,即可定位到业务的容器,然后可以直接通过控制台查看到对应的日志,大大降低了操作时间。

把应用部署到k8s之后,代码的发布、回滚,以及蓝绿发布、金丝雀发布等都变得特别简单,不仅加快了业务代码迭代的速度,而且全程无需人工干预。目前我们使用jenkins、gitrunner进行发版或者回滚等,从开发环境到测试环境,到最后的生产环境,完全遵守一次构建,多集群、多环境部署,通过不同的启动参数、不同的环境变量、不同的配置文件实现区分不同的环境。目前已经实现Python、Java、PHP、NodeJS、Go、.NET Core等多种语言的一键式发版、一键式回滚,大大提高了开发人员的开发效率。

在使用服务网格后,开发人员在开发应用的过程中,不用再关心代码的网络部分,这些功能都被服务网格实现,让开发人员可以只关心代码逻辑部分,即可实现网络部分的功能,比如:断流、分流、路由、负载均衡、限速和触发故障等功能。

测试过程中,可能同时多套环境,当然也会需要再创建一套测试环境,之前测试环境的创建,需要找运维或者自行手工搭建。在迁移至k8s集群后,只需要在jenkins上点点鼠标即可在k8s集群上创建一套新的测试环境。

对于运维人员

如果你是一名运维人员,可能经常因为一些重复、繁琐的工作感觉厌倦。比如:这个需要一套新的测试环境,那个需要一套新的测试环境,之前可能需要装系统、装依赖环境、开通权限等等。而如今,可以直接用镜像直接部署一套新的测试环境,甚至全程无需自己干预,开发人员通过jenkins或者自动化运维平台即可一键式创建,大大降低了运维成本。

一开始,公司业务故障,可能是因为基础环境不一致、依赖不一致、端口冲突等等问题,现在实现镜像部署,所有的依赖、基础都是一样的,大大减少了因为这类基础问题引发的故障。也有可能公司业务是由于服务器宕机、网络等问题,造成服务不可用,此类情况均需要运维人员及时去修复,而如今,可能在你收到告警信息的时候,k8s已经帮你恢复了。

在没有使用k8s时,业务应用的扩容和缩容,都需要人工去处理,从采购服务器、上架、到部署依赖环境,不仅需要大量的人力物力,而且非常容易在中间过程出现问题,又要花费大量的时间去查找问题。成功上架后,还需要在前端反代端添加或该服务器,而如今,可以利用k8s的弹性计算,一键式进行扩容和缩容,不仅大大提高了运维效率,而且还节省了不少的服务器资源,提高了资源利用率。

对于反代配置方面,比如可能你并不会,或者对nginx的配置规则并不熟悉,一些高级的功能你也不会实现,而如今,利用k8s的ingress即可简单的实现那些负责的逻辑。并且也不会在遇到nginx少加一个斜杠和多加一个斜杠的问题。

对于负载均衡方面,之前负载均衡可能是Nginx、LVS、HAProxy、F5等,云上可能是云服务商提供的不在均衡机制。每次添加删除节点时,都需要手动去配置前端负载均衡,手动去匹配后端节点,而如今,使用k8s内部的service可以动态发现实现自动管理节点,并且支持自动扩容缩容。之前遇到高峰流量时,经常服务器性能不够,需要临时加服务器面对高峰流量,而如今对于高性能k8s集群,无需管理,自动扩容。

对于高可用方面,k8s天生的高可用功能,彻底释放了双手,无需再去创建各类高可用工具、检测检查脚本。k8s支持进程级别的健康检查,如发现接口超时或者返回值不正确,会自动处理该问题。

对于中间件搭建方面,根据定义好的deploy文件,可以实现秒级搭建各类中间件高可用集群,如Redis、RabbitMQ、Zookeeper等,并且大大减少了出错的概率。

对于应用端口方面,传统行业中,一个服务器可能跑了很多进程,每个进程都有一个端口,需要人为的去配置端口,并且还需要考虑端口冲突的问题,如果有防火墙的话,还需要配置防火墙,在k8s中,端口统一管理,统一配置,每个应用的端口都可设置成一样的,之后通过service进行负载均衡。

无论是对于开发人员、测试人员还是运维人员,k8s的诞生,不仅减少了工作的复杂性,还减少了各种成本。上述带来的变革只是其中比较小的一部分,更多优点只有用了才能体会到。

k8s带来的挑战

首先是对于k8s的学习本身就是很难的,概念太多,无从入手,可能学习了一个月也无法入门,甚至连集群也搭建不出来,使人望而却步。并且k8s对运维的技术能力要求比较高,已经不仅仅局限于传统运维,有时候你可能要修改业务代码等。并且需要掌握的知识也需要很多,你可能需要掌握公司所有使用到的代码,比如代码是如何进行编译的、如何正确发布、如何修改代码配置文件等,这对于运维人员,也是一种挑战。Kubernetes之所以被叫做k8s,业界有两种说法,通俗的说法是k和s之间有8个字母,另一种比较说法是k8s集群至少需要搭建8遍才能搭建成功。当然,在实际使用时,可能不止8遍。k8s的诞生,把运维从传统转变到了DevOps方向,需要面临的问题会更多,需要面临的新技术也有很多,但是当你掌握到了k8s的核心使用,就会受益终身。

对于开发人员来说,对开发方式也有一些变化。从k8s的诞生到如火如荼,慢慢的k8s变成了一种标准,开发再进行代码开发时需要遵循Docker和k8s规范,严格遵守一次构建,多次部署原则,所有的配置都通过参数、变量或者k8s配置管理注入。并且对应用,要求是无状态的,因为Docker每次重启都会以最干净的基础启动。无论公司有没有进行业务容器化,遵循Docker和k8s规范都将成为未来的趋势,2019年7月

k8s基本组件

在这里插入图片描述
一个 Kubernetes 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群具有至少一个工作节点。

工作节点托管作为应用负载的组件的 Pod 。控制平面管理集群中的工作节点和 Pod 。 为集群提供故障转移和高可用性,这些控制平面一般跨多主机运行,集群跨多个节点运行

控制平面组件

控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。

控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器

kube-apiserver

Kubernetes API 服务器验证并配置 API 对象的数据, 这些对象包括 pods、services、replicationcontrollers 等。 API 服务器为 REST 操作提供服务,并为集群的共享状态提供前端, 所有其他组件都通过该前端进行交互

etcd

etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。

kube-scheduler

控制平面组件,负责监视新创建的、未指定运行节点(node)的 Pods,选择节点让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限

kube-controller-manager

运行控制器进程的控制平面组件。
从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。
这些控制器包括:

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

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

kubelet

Kubelet组件运行在Node节点上,维持运行中的Pods以及提供kuberntes运行时环境,主要完成以下使命:
1.监视分配给该Node节点的pods
2.挂载pod所需要的volumes
3.下载pod的secret
4.通过docker/rkt来运行pod中的容器
5.周期的执行pod中为容器定义的liveness探针
6.上报pod的状态给系统的其他组件
7.上报Node的状态

kube-proxy

kubernetes 工作节点上的一个网络代理组件,运行在每个节点上
它维护节点上的网络规则,实现了Kubernetes Service 概念的一部分 。它的作用是使发往 Service 的流量(通过ClusterIP和端口)负载均衡到正确的后端Pod。

docker

容器运行环境是负责运行容器的软件。

Kubernetes 支持多个容器运行环境: Docker、 containerd、CRI-O 以及任何实现 Kubernetes CRI (容器运行环境接口)。

k8s核心概念

deployment

一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力
你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
总结:deployment是用来管理pod的,比如控制pod的伸缩和更新,以及pod的更新策略等

service

将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
主要实现集群内部通信,以及基于四层的内外通信(如端口)
为pod提供一个固定,统一的访问接口及负载均衡的能力,并借助新一代DNS的服务发现功能,解决客户端发现并访问容器化应用的难题
service的地址是不会发生改变的,它通过标签选择器和后端的pod关联
总结:因为客户端通常通过k8s service的方式来访问集群内的服务,但集群内的pod每次变更都会导致ip发生变动,所以就需要一种访问来固定访问pod的模式,所以就抽象出了service的概念

k8s的四种service

我们先了解k8s的四种类型的service

  • ClusterIp

通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType

  • NodePort

通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer

使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上

  • ExternalName

通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理

或者使用ingress进行转发操作,但ingress不在本教程范围内,有兴趣的可以去了解ingress的网络策略配置

所以本教程采用较为直观的NodePort形式进行演示

service和pod之间的关系?

参考文章
官方:k8s服务代理
官方:使用service连接到应用
CSDN:十分钟了解k8s service到pod转发机制
CSDN:kubernetes endpoints是什么
总结:service和pod并没有直接的关系。pod通过endpoints暴露出来,只要pod发生变更,便会同步至endpoints中。有了service和endpoints后,kube-proxy会实时监听它们的更新和删除操作,然后更新iptables代理规则,重新生成该service访问pod的ip和端口映射规则

下图红框中endpoints中的ip是该service下所有的pod

相关命令

kubectl describe svc vue-pod-service -n vue
kubectl get service -n vue
kubectl get pods -n vue -o wide

在这里插入图片描述
将endpoints配置以yaml文件形式输出

kubectl get endpoints -n vue -o yaml

红框中的是该service和po关系的映射列表。记录了每个pod的信息,这里面的三个 Pod 信息就是我们刚才创建的三个 Pod 。addresses 里面记录了 Pod 的 ip、所在的主机名称、以及具体的 Resource Object 的引用
在这里插入图片描述
查看pod在iptables下的转发策略

# -S 打印链或所有链中的规则
# -t 要操作的表
# nat 网络地址
# 关键字匹配
# vue-pod-service k8s的service名称
iptables -S -t nat | grep "vue-pod-service"

下图红框中的代表k8s利用iptables中的statistic模块做概率轮询策略,百分之33的几率访问KUBE-SEP-RU2WS6VELU3XJ57F并送到10.244.1.106,百分之50的几率访问KUBE-SEP-QNVMXJN6GHH54P4U并送到10.244.1.107,否则默认走向KUBE-SEP-EIPMM2RHLXKNQK5T并送到10.244.1.108
在这里插入图片描述
但是往往我们还需要更多更灵活的算法,比如基于最少连接算法、源地址HASH算法等。而同样基于netfilter的ipvs却是专门做负载均衡的,配置简单,基于散列查找O(1)复杂度性能好,支持数十种调度算法。因此显然IPVS比iptables更适合做kube-proxy的后端

namespaces

名字空间是在多个用户之间划分集群资源的一种方法
它们在逻辑上彼此隔离。 他们可以为您和您的团队提供组织,安全甚至性能方面的帮助
总结:主要场景是区分业务,模块。利于后期的维护和管理

labels

标签(Labels) 是附加到 Kubernetes 对象(比如 Pods)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。
总结:当相同类型的资源越来越多,对资源划分管理是很有必要,此时就可以使用label为资源对象 命名,以便于配置,部署等管理工作,提升资源的管理效率

label selector

Label selector(标签选择器)是Kubernetes核心的分组机制,通过label selector客户端/用户能够识别一组有共同特征或属性的资源对象
主要作用

  1. 通过资源对象上定义的Label Selector来筛选要监控的Pod副本的数量,从而实现Pod副本的数量始终符合预期设定的全自动控制流程
  2. kupe-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立器每个Service到对应Pod的请求转发路由表,从而实现Service的智能负载均衡机制
  3. 通过对某些Node定义特定的Label,并且在Pod定义文件中使用NodeSelector这种标签调度策略,Kube-scheduler进程可以实现Pod定向调度的特性

假设我们去掉service中的selector
在这里插入图片描述
查看k8s监控平台 dashboard,发现endpoints和pods全是空
在这里插入图片描述
查看service的描述信息

kubectl describe service -n vue

在这里插入图片描述
尝试访问31066端口,发现超时
在这里插入图片描述
那么现在只有两个办法

  1. 手动配置service的endpoints的配置 官方endpoints配置文档
  2. service标签选择器关联pod的标签

现在我们重新关联service的标签选择器
在这里插入图片描述
查看监控
在这里插入图片描述
查看service的描述信息

在这里插入图片描述
访问端口
在这里插入图片描述

搭建k8s集群

第一步 配置k8s集群环境 master和node节点都要执行
关闭防火墙

简单起见 暂时放开所有端口访问,集群搭建成功后,可以自行配置自己的安全策略

## 查看防火墙状态
sudo ufw status

## 关闭防火墙
sudo ufw disable

## 开启防火墙
sudo ufw enable
关闭swap分区

swap,这个当内存不足时,linux会自动使用swap,将部分内存数据存放到磁盘中,这个这样会使性能下降,为了性能考虑推荐关掉

## 临时关闭
swapoff -a

## 永久关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab
关闭selinux

通过禁用SELinux,允许容器无障碍的访问主机文件系统 说明链接

sed -i 's/enforcing/disabled/' /etc/selinux/config 
setenforce 0
修改主机名
## 查看主机名
hostnamectl

## 修改主机名
sudo hostnamectl set-hostname k8smaster

## 修改子节点主机名
sudo hostnamectl set-hostname k8snode
修改主机名和ip对应关系
## 编辑域名ip文件
sudo vim /etc/hosts

## 添加以下内容
192.168.5.138 k8smater
192.168.5.139 k8snode
配置iptables

br_netfilter: 透明防火墙,用来启用透明伪装并促进虚拟可扩展 LAN (VxLAN) 流量,以便跨集群节点的 Kubernetes pod 之间进行通信。因此,在更改系统参数设置之前,您必须确保所有master 和所有node 节点上都安装了br_netfilter 模块

net.bridge.bridge-nf-call-ip6tables: 启用 bridge-nf-call-iptables 这个内核参数 (置为 1),表示 bridge 设备在二层转发时也去调用 iptables 配置的三层规则 (包含 conntrack),所以开启这个参数就能够解决上述 Service 同节点通信问题 说明链接

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
安装虚拟机

VMware Workstation
下载安装包傻瓜式安装即可

下载ubuntu 20虚拟机镜像

下载地址

配置ubuntu虚拟机镜像
  1. 配置操作系统
    在这里插入图片描述
  2. 配置用户名和密码
    在这里插入图片描述
  3. 配置工作目录
    在这里插入图片描述
  4. 分配内存大小
    在这里插入图片描述
  5. 完成操作
    在这里插入图片描述
  6. 再克隆一台node节点虚拟机 重复前几个步骤即可
  7. 在这里插入图片描述
安装docker

docker官网

  • 卸载已安装的docker内容
 sudo apt-get remove docker docker-engine docker.io containerd runc
  • 更新ubuntu存储库
sudo apt-get update
  • 更新安装docker所属包环境
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
  • 添加docker官方GPG密钥
 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  • 设置docker存储库
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  • 安装docker
 sudo apt-get update
 sudo apt-get install docker-ce docker-ce-cli containerd.io
  • 验证docker
    在这里插入图片描述
安装kubectl,kubelet,kudeadm
  • kubectl

用来管理k8s集群的命令行工具,使用它,你可以部署应用程序、检查和管理集群资源以及查看日志等

  • kubelet

1.监视分配给该Node节点的pods
2.挂载pod所需要的volumes
3.下载pod的secret
4.通过docker/rkt来运行pod中的容器
5.周期的执行pod中为容器定义的liveness探针
6.上报pod的状态给系统的其他组件
7.上报Node的状态

  • kudeadm

Kubeadm 是一个提供了 kubeadm init 和 kubeadm join 的工具, 作为创建 Kubernetes 集群的 “快捷途径” 的最佳实践。
kubeadm 通过执行必要的操作来启动和运行最小可用集群。 按照设计,它只关注启动引导,而非配置机器。同样的, 安装各种 “锦上添花” 的扩展,例如 Kubernetes Dashboard、 监控方案、以及特定云平台的扩展,都不在讨论范围内。

设置开机启动kubelet
systemctl enable kubelet
配置k8s

说明链接
kubelet文件驱动默认cgroupfs, 而我们安装的docker使用的文件驱动是systemd, 造成不一致, 导致镜像无法启动。
现在有两种方式, 一种是修改docker, 另一种是修改kubelet。
我这里采用修改docker的方式

## 编辑docker配置文件
sudo vim /etc/docker/daemon.json

## 加入以下配置
{
"exec-opts": ["native.cgroupdriver=systemd"]
}

开始安装

## 配置镜像仓库密钥
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys  FEEA9169307EA071

## 配置国内阿里云镜像仓库
cat <<EOF > /etc/apt/sources.list.d/kubernetes.list
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main
EOF

## 更新仓库
apt-get update

## 安装
apt-get install -y kubelet kubeadm kubectl

在这里插入图片描述

第二步 初始化k8s集群

一个 Kubernetes 集群包含两种类型的资源:

  • Master 调度整个集群
  • Nodes 负责运行应用

在这里插入图片描述

使用kubeadm初始化k8s master节点

kubeadm初始化相关命令文档

kubeadm init \
--apiserver-advertise-address=192.168.5.138 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.22.3 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16
  • apiserver-advertise-address

API 服务器所公布的其正在监听的 IP 地址。如果未设置,则使用默认网络接口

  • image-repository

选择用于拉取控制平面镜像的容器仓库

  • kubernetes-version

为控制平面选择一个特定的 Kubernetes 版本

  • service-cidr

为服务的虚拟 IP 地址另外指定 IP 地址段

  • pod-network-cidr

指明 pod 网络可以使用的 IP 地址段。如果设置了这个参数,控制平面将会为每一个节点自动分配 CIDRs

运行结果

在这里插入图片描述在这里插入图片描述

图中红框的两边部分需要单独记下 用于后续操作中使用

## export 命令用于设置或显示环境变量
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

## work节点加入集群命令
kubeadm join 192.168.5.138:6443 --token ump3iw.ccbfwpuoel0jngx7 \
	--discovery-token-ca-cert-hash sha256:3bacd931ea5cb96fd51258bf5b8fd4bb2b9598875337a8bf149d874610ce980c 
设置环境变量
## 在master机器上执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
进入work节点 加入master节点集群
kubeadm join 192.168.5.138:6443 --token ump3iw.ccbfwpuoel0jngx7 \
	--discovery-token-ca-cert-hash sha256:3bacd931ea5cb96fd51258bf5b8fd4bb2b9598875337a8bf149d874610ce980c 

在这里插入图片描述
出现该错误 很可能是因为配置未生效 执行以下命令进行恢复

## 重置kubeadm
kubeadm reset

## 刷新docker配置文件
systemctl daemon-reload

## 重启docker
systemctl restart docker

## 重启kubelet
systemctl restart kubelet
加入master集群成功

在这里插入图片描述

在master机器中查看所有节点

在这里插入图片描述
至此,集群已经搭建成功了 一个master节点,一个work节点
接下来 我们尝试安装nginx 来验证k8s结群

## 创建nginx 容器
kubectl create deployment nginx --image=nginx

## 暴漏对外端口
kubectl expose deployment nginx --port=80 --type=NodePort

在这里插入图片描述

安装pod网络组件
kubectl apply -fhttps://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

但由于github访问限制 有时连接超时 所以可以使用我下载好的文件

kubectl apply -f kube-flannel.yml 

在这里插入图片描述

---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp.flannel.unprivileged
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
  privileged: false
  volumes:
  - configMap
  - secret
  - emptyDir
  - hostPath
  allowedHostPaths:
  - pathPrefix: "/etc/cni/net.d"
  - pathPrefix: "/etc/kube-flannel"
  - pathPrefix: "/run/flannel"
  readOnlyRootFilesystem: false
  # Users and groups
  runAsUser:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  # Privilege Escalation
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  # Capabilities
  allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
  defaultAddCapabilities: []
  requiredDropCapabilities: []
  # Host namespaces
  hostPID: false
  hostIPC: false
  hostNetwork: true
  hostPorts:
  - min: 0
    max: 65535
  # SELinux
  seLinux:
    # SELinux is unused in CaaSP
    rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
rules:
- apiGroups: ['extensions']
  resources: ['podsecuritypolicies']
  verbs: ['use']
  resourceNames: ['psp.flannel.unprivileged']
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
        image: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.2
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
        image: quay.io/coreos/flannel:v0.15.0
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.15.0
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-plugin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
第三步 验证集群
创建nginx容器
kubectlcreate deployment nginx --image=nginx
设置容器对外访问端口类型为NodePort
kubectl expose deployment nginx --port=80 --type=NodePort
结果

在这里插入图片描述
在这里插入图片描述

第四步 k8s可视化组件

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

Dashboard 同时展示了 Kubernetes 集群中的资源状态信息和所有报错信息
在这里插入图片描述

安装dashboard

通过官方yml配置文件安装
但由于github访问问题,我就整理成了文件 直接赋值粘贴即可
recommended.yaml

## 应用配置文件
kubectl apply -f recommended.yaml

在这里插入图片描述

# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: Namespace
metadata:
  name: kubernetes-dashboard

---

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard

---

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kubernetes-dashboard
type: Opaque

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-csrf
  namespace: kubernetes-dashboard
type: Opaque
data:
  csrf: ""

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-key-holder
  namespace: kubernetes-dashboard
type: Opaque

---

kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-settings
  namespace: kubernetes-dashboard

---

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
rules:
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
    verbs: ["get", "update", "delete"]
    # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["kubernetes-dashboard-settings"]
    verbs: ["get", "update"]
    # Allow Dashboard to get metrics.
  - apiGroups: [""]
    resources: ["services"]
    resourceNames: ["heapster", "dashboard-metrics-scraper"]
    verbs: ["proxy"]
  - apiGroups: [""]
    resources: ["services/proxy"]
    resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
    verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
rules:
  # Allow Metrics Scraper to get metrics from the Metrics server
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods", "nodes"]
    verbs: ["get", "list", "watch"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
        - name: kubernetes-dashboard
          image: kubernetesui/dashboard:v2.2.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8443
              protocol: TCP
          args:
            - --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            # Uncomment the following line to manually specify Kubernetes API server Host
            # If not specified, Dashboard will attempt to auto discover the API server and connect
            # to it. Uncomment only if the default does not work.
            # - --apiserver-host=http://my-address:port
          volumeMounts:
            - name: kubernetes-dashboard-certs
              mountPath: /certs
              # Create on-disk volume to store exec logs
            - mountPath: /tmp
              name: tmp-volume
          livenessProbe:
            httpGet:
              scheme: HTTPS
              path: /
              port: 8443
            initialDelaySeconds: 30
            timeoutSeconds: 30
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsUser: 1001
            runAsGroup: 2001
      volumes:
        - name: kubernetes-dashboard-certs
          secret:
            secretName: kubernetes-dashboard-certs
        - name: tmp-volume
          emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      nodeSelector:
        "kubernetes.io/os": linux
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule

---

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 8000
      targetPort: 8000
  selector:
    k8s-app: dashboard-metrics-scraper

---

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: dashboard-metrics-scraper
  template:
    metadata:
      labels:
        k8s-app: dashboard-metrics-scraper
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: 'runtime/default'
    spec:
      containers:
        - name: dashboard-metrics-scraper
          image: kubernetesui/metrics-scraper:v1.0.6
          ports:
            - containerPort: 8000
              protocol: TCP
          livenessProbe:
            httpGet:
              scheme: HTTP
              path: /
              port: 8000
            initialDelaySeconds: 30
            timeoutSeconds: 30
          volumeMounts:
          - mountPath: /tmp
            name: tmp-volume
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsUser: 1001
            runAsGroup: 2001
      serviceAccountName: kubernetes-dashboard
      nodeSelector:
        "kubernetes.io/os": linux
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      volumes:
        - name: tmp-volume
          emptyDir: {}
启动dashboard
## 启动
kubectl proxy
访问

访问地址
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login

在这里插入图片描述
默认情况下,Dashboard 会使用最少的 角色的访问控制(RBAC) 配置进行部署。 当前,Dashboard 仅支持使用 Bearer 令牌登录
原因是Kubernetes API server需要配置授权方式ABAC并–basic-auth-file提供flag。如果没有该 API 服务器自动回退到匿名用户,则无法检查提供的凭据是否有效

创建service account并绑定默认cluster-admin管理员集群角色并获取令牌
## 创建账户和角色
kubectl create serviceaccount dashboard-admin -n kube-system

## 绑定账户角色
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin

## 获取登录密钥
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
结果

在这里插入图片描述
复制token 登录k8s dashboard
在这里插入图片描述

配置dashboard跳过登录认证 (正式环境不推荐使用 仅用于学习)

dashboard启动参数文档

  • enable-skip-login

启用后,将显示登录页面上的跳过按钮

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

dashboard集群外访问

编辑yml文件 将CluserIP改成NodePort

## 编辑dashboard yml文件
kubectl -n kubernetes-dashboard edit service kubernetes-dashboard

在这里插入图片描述
查看dashboard暴露的端口

## 查看dashboard暴露的端口
kubectl -n kubernetes-dashboard get service kubernetes-dashboard

在这里插入图片描述
集群外访问
在这里插入图片描述

操作k8s集群

通过以上教程 我们完成了k8s的集群和可视化组件的搭建 接下来我们将完成k8s的基本操作,发布和部署等

应用基本环境

  • 镜像仓库 DockerHub docker.io
  • 编程语言 JavaScript
  • 语言框架 Vue
  • 代理 Nginx
发布应用

使用vue项目进行演示或者使用vue-cli快速生成

编写Dockerfile
# 安装node 阶段别名builder docker 17版本新增多阶段构建
FROM node:12 as builder

# 镜像的维护者
MAINTAINER zhangzw

# 创建工作目录
RUN mkdir app

# 指定工作目录
WORKDIR /app

# 拷贝目录
COPY . /app

# 安装npm包
RUN npm --registry https://registry.npm.taobao.org i

# 编译
RUN npm run build

# 安装nginx
FROM nginx

# 从阶段builder中将编译好的dist文件夹复制到nginx下
COPY --from=builder /app/dist /usr/share/nginx/html

# 从阶段builder中将本地nginx.conf替换容器内nginx.conf
COPY --from=builder /app/nginx.conf /etc/nginx/nginx.conf

# 设置时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone

# 指定容器端口为80
EXPOSE 80
##### 打包,推送docker镜像
将本地项目打包生成docker镜像
docker build -t vue-master-2919c3e2acd37a1d69cfd2fe1b943d03eb02ac68 .

先登录docker 用于后续推送镜像

docker login

镜像发布
比如 docker push vue-master-2919c3e2acd37a1d69cfd2fe1b943d03eb02ac68

docker push ${仓库名字}:镜像标签
创建镜像命名空间
kubectl create namespace vue

获取k8s集群命名空间

kubectl get namespace

在这里插入图片描述

创建docker仓库的密钥文件secret

kubectl create secret说明文档
创建密钥 以dockerhub私有仓库为例

kubectl create secret docker-registry docker-secret \
--docker-server=https://index.docker.io/v1/ \
--docker-username=dockerhub用户名 \
--docker-password=dockerhub用户密码 \
--docker-email=注册dockerhub用的邮箱

查看密钥

kubectl get secret

在这里插入图片描述
查看密钥配置文件json

cat ~/.docker/config.json

在这里插入图片描述

查看密钥的yaml格式信息

kubectl get secret docker-secret -o yaml

在这里插入图片描述

编写k8s应用发布yaml文件 test-deploy.yaml

yaml配置文件说明

apiVersion: v1 # kubernetesAPI版本
kind: Service # 想要创建的资源对象类别
metadata: # 帮助唯一性标识对象的一些数据
  name: vue-service # 对象名称
  namespace: vue # 命名空间
  labels: # pod标签
    app: vue-service-lable # pod标签
spec: # 资源内容
  type: NodePort # 服务暴露类型,一般有ClusterIp,Nodeport,loadBlannce
  ports: # 需要暴露的端口库号列表
  - port: 31065 # service 暴露在 cluster ip上的端口
    targetPort: 80 # targetPort 是 pod 上的端口
    nodePort: 31066 # 暴露在集群物理节点上 node 的端口
    protocol: TCP # 端口协议,支持TCP和UDP,默认TCP
    name: http # 端口号名称
  selector: # 标签选择器
    app: vue-pod # 标签名称

apiVersion: apps/v1 # kubernetesAPI版本
kind: Deployment # 想要创建的资源对象类别
metadata:# 帮助唯一性标识对象的一些数据
  name: vue-deployment # 对象名称
  namespace: vue # 命名空间
spec: # 资源内容
  selector: # 标签选择器
    matchLabels: # 定义一组标签
      app: vue-pod # 标签名字
  replicas: 3 # 副本数
  strategy: # 更新策略
    type: RollingUpdate # 滚动发布 
    rollingUpdate: # 滚动升级配置
      maxSurge: 1 # 同时最大有多少个pod启动
      maxUnavailable: 1 # 同时最大有多少个pod不可用
  template: # Pod的定义
    metadata: # 帮助唯一性标识对象的一些数据
      labels: # pod标签
        app: vue-pod # 标签名字
    spec: # 资源内容定义
      containers: # 容器定义
      - name: vue-container # 容器名称
        image: 你的镜像 # 容器镜像
        ports: # 端口配置
        - containerPort: 80 # 容器对外端口
      imagePullSecrets: # 镜像拉取密钥
      - name: docker-secret # 密钥名称

k8s使用yaml配置文件发布应用

kubect apply -f test-deploy.yaml

查看该命名空间下的发布的应用内容并携带标签信息

kubectl get pods,service,deployment,endpoints --show-labels -n vue -o wide

在这里插入图片描述

通过service的NodePort访问
192.168.5.138是宿主机ip
在这里插入图片描述
通过service的ClusterIp访问
10.1.245.201是该service的cluster ip
在这里插入图片描述

在dashboard下查看应用状态

在这里插入图片描述
在这里插入图片描述

操作应用
pod基本操作

接下来我们将学习如何重启,更新,删除pod,如何查看pod的日志和详细信息,以及进入pod,在pod环境内进行操作

replicaset相关官方文档

  • 重启应用
    通过删除某个命名空间下的所有pod达到重启的目的
kubectl delete --all pods --namespace=vue

在这里插入图片描述
因为删除了所有的pod 且应用中的副本数是2 所以自动重启了两个pod
在这里插入图片描述
在这里插入图片描述

  • pod扩容
    更改yaml配置文件中的replicas字段 将pod扩容为2个
    在这里插入图片描述
    更新应用
kubectl apply -f test-deploy.yaml

在这里插入图片描述
在这里插入图片描述

  • pod缩减
    将配置文件中的replicas改为要降低的数字 k8s将随机删除一个pod
  • 删除命名空间下的指定pod
kubectl delete pod vue-deployment-5dbd7dc568-zphgb -n vue

在这里插入图片描述

因为此时应用中的副本集是2 删除掉一个之后 k8s会自动一个新的副本
在这里插入图片描述
在这里插入图片描述

  • 查看pod运行日志
    查看某个命名空间下的pod日志
kubectl logs vue-deployment-5dbd7dc568-b87zj -n vue

在这里插入图片描述
实时查看某个命名空间下的pod日志

kubectl logs -f vue-deployment-5dbd7dc568-b87zj -n vue

在这里插入图片描述

  • 查看某命名空间下的pod详细信息
kubectl describe pods/vue-deployment-5dbd7dc568-b87zj -n vue
  • 进入pod容器
kubectl exec -it vue-deployment-5dbd7dc568-b87zj -n vue -- /bin/bash

在这里插入图片描述

  • pod升级
    变更yaml配置中文件中的image镜像即可
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐