# 简介

这里目的是理解 k8s 中的一些概念和部署一个 nginx 服务,并将其映射出去。

# 什么是 pod?

pod (豆荚)。 pod 的概念其实和 docker 中的容器非常相似。他是 k8s 中的最小工作单位。你可以把 pod 理解成一个一个的小机器人,而 k8s 抽象出来的大资源池就是他们的工厂。

# pod 和 docker 容器的关系?

pod 将一个或多个 docker 容器封装成一个统一的整体进行管理并对外提供服务。
不仅我们自己的服务是要包装成 pod 的,就连 k8s 自己也是运行在一堆 pod 上。

# 什么是命名空间?

命名空间 namespace,是 k8s 中” 组 “的概念,提供同一服务的 pod 就应该被放置同一命名空间下,而不是混杂在一起。k8s 可以用命名空间来做权限控制。如果不指定的话, pod 将被放置在默认的命名空间 default 下。

# Service

pod 每次动态创建后,自动分配的 ip 会不同,所以引入了 service (即服务的注册与发现),这里它的作用相当于 nginx,把应用暴露或者负载均衡

# 怎么创建资源

k8s 中的所有东西都可以通过 kubectl create 命令创建,无论你是想创建一个 pod 还是一个大型的滚动升级服务 deployment,create 命令都可以做到。使用 create 生成一个资源主要有两种常用方法,从 yaml 配置文件创建 和 简易创建

# yaml 配置文件创建

其实就类似 docker 中的 dockerfile
如果你想让 k8s 生成一个和你想象中一模一样的资源,那你就要充分而详细的描述这个资源,k8s 就提供了这么一个方法,你可以使用 yaml 格式创建一个文件,按照 k8s 指定好的结构定义一个对象,然后使用如下方法将该文件传递给 k8s。它就可以按照你的描述进行生成了:

kubectl create -f <配置文件名.yaml>
apiVersion: v1 #类型为Namespace
kind: Namespace  #类型为Namespace
metadata:
  name: ns-test  #命名空间名称
  labels:
    name: label-test  #pod标签

# 简易创建

k8s 为一些常用的资源提供了简易创建的方法,比如说 service、namespace、deployment 等,这些方法可以使用 kubectl create <资源类型> < 资源名 > 的方式创建。例如我想创建一个名叫 hello-world 的命名空间,直接使用下面命令即可:

kubectl create namespace hello-world

# 部署一个 nginx 项目

# 创建命名空间

kubectl create namespace -f  xxx.yaml

image-20220303153300704

image-20220303153304845

# 创建 pod

一般不直接 create pod, 而是通过 controller 来创建 pod。deployment 为其中一种 controller

  • Kind:类型,有 Deployment、Service、Pod、Ingress 等,非常丰富;

  • metadata:用于定义一些组件信息,如名字、标签等;

  • labels:标签功能,非常有用,用于选择关联;但 label 不提供唯一性,可以使用组合来选择;

  • nodePort:对于需要给外部暴露的服务,有三种方式:NodePorts、LoadBalancer、Ingress,这里使用 NodePorts;需要注意的是,默认它的端口范围是 [3000-32767],需要其它范围则需要修改相关参数

  • replicas:数量

image-20220303153313141

kubectl create  -f  xxx.yaml

创建实例,可以看到有两个 pod,因为在上面配置文件中设定了创建两个副本。这两个副本是独立的。

image-20220303153322468

image-20220303153327219

此时,pod 的部署节点是由负载均衡控制器选择的,在部署的 work 节点中,我们可以看到节点会去 pull 我们的镜像。当 pull 完成后状态也就 readay 了。

image-20220303153336422

# 访问实例

到上面为止,已经成功部署应用了。

kubectl get pod -n php -o wide #查看 pod 的部署节点和 ip

image-20220303153448454

之后,即可通过集群中任意节点的 ip,加配置文件中 nodePort 指定的端口(80),访问集群中的 应用服务。

image-20220303153452740

# 创建 SERVER

让它们能被内部访问(只能被内部节点访问)
这里其实只是起了一个在集群内才能访问的虚拟 ip
上面,我们创建了两个 pod,现在如果需要让它们被外部访问的话,就需要使用 Svc 来完成。
(通过 SVC 只能实现这两个副本的负载均衡,不能让它们独立被外界访问)
这里下面的是应用的端口(docker),上面的是暴露出去的端口(容器)。

kubectl create -f  xxx.yaml

image-20220303153459060

kubectl get svc -n php

image-20220303153504642

后续如果想要修改只需修改配置文件,然后

kubectl apply -f <yaml>

image-20220303153544579

# 客户如何从外部访问集群中的服务(重点)

前面的 Server 中配置用了默认的一些配置,所以只是起了一个在集群内才能访问的虚拟 ip,

# 简介

Service 的类型 (ServiceType) 决定了 Service 如何对外提供服务,根据类型不同,服务可以只在 Kubernetes cluster 中可见,也可以暴露到 Cluster 外部。Service 有三种类型,ClusterIP,NodePort 和 LoadBalancer。其中 ClusterIP 是 Service 的缺省类型,这种类型的服务会提供一个只能在 Cluster 内才能访问的虚拟 IP。

# K8s 集群中的三种 IP

  • Node IP

    是物理机的 IP(或虚拟机 IP)。每个 Service 都会在 Node 节点上开通一个端口,外部可以通过 http://NodeIP:NodePort 即可访问 Service 里的 Pod 提供的服务。

  • Pod IP

    是每个 Pod 的 IP 地址,Docker Engine 根据 docker 网桥的 IP 地址段进行分配的,通常是一个虚拟的二层网络。

    • 同 Service 下的 pod 可以直接根据 Pod IP 相互通信

    • 不同 Service 下的 pod 在集群间 pod 通信要借助于 cluster ip

    • pod 和集群外通信,要借助于 node ip

  • Cluster IP

    是 Service 的 IP 地址,此为虚拟 IP 地址,外部网络无法 ping 通,只有 kubernetes 集群内 部访 问使用。

    • Cluster IP 仅仅作用于 Kubernetes Service 这个对象,并由 Kubernetes 管理和分配 P 地址 Cluster
    • IP 无法被 ping,他没有一个 “实体网络对象” 来响应 Cluster IP 只能结合 Service
    • Port 组成一个具体的通信端口,单独的 Cluster IP 不具备通信的基础,并且他们属于 Kubernetes 集群这样一个封闭的空间。
    • 在不同 Service 下的 pod 节点在集群间相互访问可以通过 Cluster IP

image-20220303154116150

①:代表外部通过公有云的 LoadBalancer 负载均衡服务访问集群内部服务流程

②:代表外部用户直接访问集群内部 Service 的 ClusterIP 访问集群内部服务流程

③:代表集群内部不同 Service 之间的 Pod 服务访问流程

④:代表集群内部同一个 Service 中 Pod 服务之间访问流程

# 如何暴露端口给外部

# nodePort

nodePort 方式在服务变多的情况下会导致节点要开的端口越来越多,不好管理
通常将 Pod 或 Service 的端口号映射到宿主机,以使客户端应用能够通过物理机访问容器应用。
Pod(不推荐,不太安全而且没负载均衡)

将 Service 的端口映射到物理机(可用,存在负载均衡)

image-20220303154200945

在上图配置中,80 端口即 pod 内应用的端口(相当于我们平时 docker 的 expose 端口),而 7777 则是 Cluster 虚拟地址的端口,而 8888 则是在宿主机上监听的端口。如果不指定宿主机的端口的话,会随机分配 30000-32767 之间的端口(可修改配置文件进行更改)。

image-20220303154211603

image-20220303154216039

# LoadBalancer 服务负载

通过公有云的 LoadBalancer 服务负载均衡,以使客户端从外部访问集群内部容器应用。
需要云厂商支持才可以。

# Ingress 负载均衡

仍需部署 server
其实它就类似于一个 nginx
使用 k8s 自带的 Ingress 负载均衡服务,以使客户端从外部访问集群内部容器应用。
https://www.jianshu.com/p/dfb1d07db644
https://segmentfault.com/a/1190000023153444