k8s的基础知识
Posted 王佐的运维笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s的基础知识相关的知识,希望对你有一定的参考价值。
上一章,说了k8s的搭建,。搭建的流程在这---> 。
下边来说下大家最关心的应用部署以及如何访问。
部署第一个应用程序之前我们先要一下deployment的基本概念。
Deployment 译名为 部署。在k8s中,通过发布 Deployment,可以创建应用程序 (docker image) 的实例 (docker container),这个实例会被包含在称为 Pod 的概念中,Pod 是 k8s 中最小可管理单元。
在 k8s 集群中发布 Deployment 后,Deployment 将给 k8s指令,让其如何创建和更新或者回滚应用程序的实例,master 节点将应用程序实例调度到集群中的具体的节点上。
创建应用程序实例后,Kubernetes Deployment Controller 会持续监控这些实例。如果运行实例的 worker 节点关机或被删除,则 Kubernetes Deployment Controller 将在群集中资源最优的另一个 worker 节点上重新创建一个新的实例。这提供了一种自我修复机制来解决机器故障或维护问题。
下边进入正文,开始部署第一个应用程序
Deployment 处于 master 节点上,通过发布 Deployment,master 节点会选择合适的 worker 节点创建 Container,Container 会被包含在 Pod里,一个pod理论上可以包容无限的Container,但是不建议这么做。
部署nginx的deployment:
我们使用kubectl来进行部署。
首先创建 yaml文件:
apiVersion: apps/v1 #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment #该配置的类型,我们使用的是 Deployment
metadata: #译名为元数据,即 Deployment 的一些基本属性和信息
nginx-deployment #Deployment 的名称 :
labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
app: nginx #为该Deployment设置key为app,value为nginx的标签
spec: #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
replicas: 1 #使用该Deployment创建一个应用程序实例
selector: #标签选择器,与上面的标签共同作用,目前不需要理解
matchLabels: #选择包含标签app:nginx的资源
app: nginx
template: #这是选择或创建的Pod的模板
metadata: #Pod的元数据
labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
app: nginx
spec: #期望Pod实现的功能(即在pod中部署)
containers: #生成container,与docker中的container是同一种
name: nginx #container的名称
nginx:1.18.1 #使用镜像nginx:1.18.1创建container,该container默认80端口可访问 :
应用 YAML 文件
两种方式都可以使用。
kubectl apply -f nginx-deployment.yaml
kubctl creat -f nginx-deployment.yaml
查看部署结果:# 查看 Deployment
kubectl get deployments
# 查看 Pod
kubectl get pods
# 如果想查看x详细信息 加个参数 -o wide
kubectl get deployments -o wide
# pod查看同理
kubectl get pods -o wide
可分别查看到一个名为 nginx-deployment 的 Deployment 和一个名为 nginx-deployment-xxxxxxx 的 Pod
至此你已经成功在k8s上部署了一个实例的nginx应用程序。
那Deployment(部署)、Pod(容器组) 和 Node(节点) 他们之间是什么关系呢?
什么是POD呢?
Pod 容器组 是一个k8s中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器,即图上正方体),以及这些 container (容器)的一些共享资源。这些资源包括:
共享存储,称为卷(Volumes),即图上紫色圆柱
container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等
TIP
重要:
如果多个容器紧密耦合并且需要共享磁盘等资源,则他们应该被部署在同一个Pod(容器组)中。
那什么是node节点呢
一个node节点上4个pod
Pod(容器组)总是在 Node(节点) 上运行。Node(节点)是 kubernetes 集群中的计算机,可以是虚拟机或物理机。每个 Node(节点)都由 master 管理。一个 Node(节点)可以有多个Pod(容器组),kubernetes master 会根据每个 Node(节点)上可用资源的情况,自动调度 Pod(容器组)到最佳的 Node(节点)上。
每个 Kubernetes Node(节点)至少运行:
Kubelet,负责 master 节点和 worker 节点之间通信的进程;管理 Pod(容器组)和 Pod(容器组)内运行的 Container(容器)。
容器运行环境(如Docker)负责下载镜像、创建和运行容器等。
我们使用了 kubectl 命令行界面部署了 nginx 并且查看了 Deployment 和 Pod。kubectl 还有如下四个常用命令,在我们排查问题时可以提供帮助:
kubectl get deployments
kubectl get pods
kubectl get nodes
名称空间(namespace)
在命令后增加 -A 或 --all-namespaces 可查看所有 名称空间中 的对象,使用参数 -n 可查看指定名称空间的对象,例如
kubectl get deployments -A
kubectl get deployments --all-namespaces
kubectl get deployments -n kube-system
kubectl describe - 显示有关资源的详细信息
# kubectl describe 资源类型 资源名称
#查看名称为nginx-XXXXXX的Pod的信息
kubectl describe pod nginx-XXXXXX
#查看名称为nginx的Deployment的信息
kubectl describe deployment nginx
kubectl logs - 查看pod中的容器的打印日志(和命令docker logs 类似)
# kubectl logs Pod名称
#查看名称为nginx-pod-XXXXXXX的Pod内的容器打印的日志
#本案例中的 nginx-pod 没有输出日志,所以您看到的结果是空的
kubectl logs -f nginx-pod-XXXXXXX
kubectl exec - 在pod中的容器环境内执行命令(和命令docker exec 类似)
# kubectl exec Pod名称 操作命令
# 在名称为nginx-pod-xxxxxx的Pod中运行bash
kubectl exec -it nginx-pod-xxxxxx /bin/bash
TIP:
Worker节点是k8s中的工作计算机,可能是VM或物理计算机,具体取决于群集。多个Pod可以在一个节点上运行。
那么该如何访问我们部署的应用呢?
k8s提供了Service(服务)来暴露应用服务程序,使我们能否进行访问。
那什么是kubernetes Service呢?
事实上,Pod(容器组)有自己的 生命周期 (opens new window)。当 worker node(节点)故障时,节点上运行的 Pod(容器组)也会消失。然后,Deployment (opens new window)可以通过创建新的 Pod(容器组)来动态地将群集调整回原来的状态,以使应用程序保持运行。
在创建Service的时候,通过设置配置文件中的 spec.type 字段的值,可以以不同方式向外部暴露应用程序:
ClusterIP(默认)
在群集中的内部IP上公布服务,这种方式的 Service(服务)只在集群内部可以访问到
NodePort
使用 NAT 在集群中每个的同一端口上公布服务。这种方式下,可以通过访问集群中任意节点+端口号的方式访问服务 <NodeIP>:<NodePort>。此时 ClusterIP 的访问方式仍然可用。
LoadBalancer
TIP
Service是一个抽象层,它通过 LabelSelector 选择了一组 Pod(容器组),把这些 Pod 的指定端口公布到到集群外部,并支持负载均衡和服务发现。
公布 Pod 的端口以使其可访问
在多个 Pod 间实现负载均衡
使用 Label 和 LabelSelector
下图中有两个服务Service A(黄色虚线)和Service B(蓝色虚线) Service A 将请求转发到 IP 为 10.10.10.1 的Pod上, Service B 将请求转发到 IP 为 10.10.10.2、10.10.10.3、10.10.10.4 的Pod上。
Service 将外部请求路由到一组 Pod 中,它提供了一个抽象层,使得 Kubernetes 可以在不影响服务调用者的情况下,动态调度容器组(在容器组失效后重新创建容器组,增加或者减少同一个 Deployment 对应容器组的数量等)。
Service使用 Labels、LabelSelector(标签和选择器) (opens new window)匹配一组 Pod。Labels(标签)是附加到 Kubernetes 对象的键/值对,其用途有多种:
将 Kubernetes 对象(Node、Deployment、Pod、Service等)指派用于开发环境、测试环境或生产环境
嵌入版本标签,使用标签区别不同应用软件版本
使用标签对 Kubernetes 对象进行分类
下图体现了 Labels(标签)和 LabelSelector(标签选择器)之间的关联关系
Deployment B 含有 LabelSelector 为 app=B 通过此方式声明含有 app=B 标签的 Pod 与之关联
通过 Deployment B 创建的 Pod 包含标签为 app=B
Service B 通过标签选择器 app=B 选择可以路由的 Pod
Labels(标签)可以在创建 Kubernetes 对象时附加上去,也可以在创建之后再附加上去。任何时候都可以修改一个 Kubernetes 对象的 Labels(标签)
下边为我们的nginx Deployment 创建一个Service
创建nginx的Deployment中定义了Labels,如下:
metadata: #译名为元数据,即Deployment的一些基本属性和信息
name: nginx-deployment #Deployment的名称
labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组
app: nginx #为该Deployment设置key为app,value为nginx的标签
创建文件 nginx-service.yaml
cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service #Service 的名称
labels: #Service 自己的标签
app: nginx #为该 Service 设置 key 为 app,value 为 nginx 的标签
spec: #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
selector: #标签选择器
app: nginx #选择包含标签 app:nginx 的 Pod
ports:
- name: nginx-port #端口的名字
protocol: TCP #协议类型 TCP/UDP
port: 80 #集群内的其他容器组可通过 80 端口访问 Service
nodePort: 32600 #通过任意节点的 32600 端口访问 Service
targetPort: 80 #将请求转发到匹配 Pod 的 80 端口
type: NodePort #Serive的类型,ClusterIP/NodePort/LoaderBalancer
执行命令:
kubectl apply -f nginx-service.yaml
检查执行结果
kubectl get services -o wide
可查看到名称为 nginx-service 的服务。
访问服务
curl <任意节点的 IP>:32600
或者直接在浏览器中打开,可以查看到nginx的界面
到目前为止,我们已经成功部署好项目,并能够对其进行访问,
以上是关于k8s的基础知识的主要内容,如果未能解决你的问题,请参考以下文章