K8s集群:Pod 与 Deployment
一、k8s - Pod 介绍
创建第一个 Pod 资源
Pod 可以理解为一组容器,是 K8s 最小的调度单位。首先我们创建第一个 Pod 资源来运行我们的项目。
1 | # cat datarc-test-pod.yaml |
二、Deployment 介绍
创建第一个 Deployment
因为 Pod 是最小的调度单位,我们通常会创建 Deployment 对象,通过 Deployment 对象来进行管理 Pod。
1 | 问:为什么一般不创建 Pod 对象呢? |
我们通过创建 YAML
的描述文件,k8s
根据这个 YAML
来创建相对应的资源对象。
1 | # cat datarc-deployment-test1.yaml |
相关命令:
查看
Deployment
kubectl get deployments -n
查看
Pod
kubectl get pods -n
kubectl describe pods -n datarc
查看
logs
日志kubectl logs
-n 进入
exec
kubectl exec
– curl -s
三、Service 暴露服务
是运行 Pod Ip
是 Docker
网桥的 IP
地址段进行分配的,通常是一个虚拟的二层网络,外部网络并没有办法访问,并且,Pod Ip
是随时会变的,不是固定的,k8s
引入了 Service
的概念,通过 Service
管理这些 Pod
,Service
创建后的 Service IP
是固定的。但是 Service IP(Cluster IP)
是一个虚拟的 IP
,由 Kubernetes
管理和分配 IP
地址,外部网络无法访问。k8s
有三种方式暴露 Service
给外部网络访问。
1 | 问:为什么Pod的IP会变化? |
Service 有以下几种类型:
- ClusterIp :默认类型,自动分配一个仅
ClusterIP
内部可以访问的虚拟服务IP
,集群内部有效,适用于集群内多个service
之间互相通讯;
- NodePort:在
ClusterIP
基础上为Service
在每台机器上绑定一个端口,这样就可以通过:NodePort
来访问该服务,外层配合Nginx
对用户提供访问。
- LoadBalane:在
NodePort
的基础上,借助Cloud Provider
创建一个外部负载均衡器,并将请求转发到NodePort
- ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 Kubernetes 1.7或更高版本的kube-dns才支持。
Service 是怎么运行的:
- 客户端访问节点时通过 iptables 实现
- iptables 规则是通过 kube-proxy 写入
- apiserver 通过监控 kube-proxy 去进行对服务和端点的监控
- kube-proxy 通过 pod 的标签( lables)去判断这个断点信息是否写入到 Endpoints 里
暴露服务的三种方式:
ClusterIP
ClusterIP
主要在每个node
节点使用iptables
,将发向ClusterIP
对应端口的数据,转发到kube-proxy
中。然后kube-proxy
自己内部实现有负载均衡的方法,并可以查询到这个service
下对应pod
的地址和端口,进而把数据转发给对应的pod
的地址和端口。NodePort
将服务的类型设置成NodePort
每个集群节点都会在节点上打开一个端口, 对于NodePort
服务, 每个集群节点在节点本身(因此得名叫 NodePort )上打开一个端口,并将在该端口上接收到的流量重定向到基础服务。该服务仅在内部集群 IP 和端口上才可访间, 但也可通过所有节点上的专用端口访问。LoadBalane
将服务的类型设置成
LoadBalance
,NodePort
类型的一 种扩展,这使得服务可以通过一个专用的负载均衡器来访问, 这是由Kubernetes
中正在运行的云基础设施提供的。 负载均衡器将流量重定向到跨所有节点的节点端口。客户端通过负载均衡器的IP
连接到服务。Ingress
创建一个Ingress
资源, 这是一 个完全不同的机制, 通过一 个IP地址公开多个服务,就是一个网关入口。
loadbalance
方式的 service
有 external IP
,是对外的
ClusterIP
ClusterIP
主要在每个 node
节点使用 iptables
,将发向 ClusterIP
对应端口的数据,转发到 kube-proxy
中。然后 kube-proxy
自己内部实现有负载均衡的方法,并可以查询到这个 service
下对应 pod
的地址和端口,进而把数据转发给对应的 pod
的地址和端口。
为了实现图上的功能,主要需要以下几个组件的协同工作:
apiserver:用户通过 kubectl
命令向 apiserver
发送创建 service
的命令, apiserver
接收到请求后将数据存储到 etcd
中 kube-proxy: Kubernetes
的每个节点中都有一个叫做 kube-porxy
的进程,这个进程负责感知 service、 pod
的变化,并将变化的信息写入本地的 iptables
规则中iptables:使用 NAT
等技术将 virtualIP
的流量转至 endpoint
中创建 myapp-deploy.yaml
文件
1 | #1. 创建 Service 的 YAML 描述文件 |
NodePort
在 k8s
上可以给 Service
设置成 NodePort
类型,这样的话可以让 Kubernetes
在其所有节点上开放一个端口给外部访问(所有节点上都使用相同的端口号), 并将传入的连接转发给作为 Service
服务对象的 pod
。这样我们的 pod
就可以被外部请求访问。
- (NodePort的原理在于在 Node上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy进一步到给对应的 pod)
1 | #1. 创建 Service 的 YAML 描述文件 |
相关命令:
查看
SVC
kubectl get svc
kubectl describe svc -n
NodePort总结
简单易用,但是服务一旦多起来,NodePort
在每个节点上开启的端口会及其庞大,而且难以维护,所以生产环境不建议这么使用
Ingress
采用 NodePort
方式暴露服务面临问题是,服务一旦多起来,NodePort
在每个节点上开启的端口会及其庞大,而且难以维护;如果采用 LoadBalane
,每个服务都得开放一个公网IP,也会很庞大。这时候 Ingress
暴露服务就是一种很合适的方案。可以通过一个 Ingress
暴露多个服务。
我们可以能否使用一个Nginx直接对内进行转发呢?众所周知的是,Pod与Pod之间是可以互相通信的,而Pod是可以共享宿主机的网络名称空间的,也就是说当在共享网络名称空间时,Pod上所监听的就是Node上的端口。那么这又该如何实现呢?简单的实现就是在每个 Node 上监听 80,然后写好规则,因为 Nginx 外面绑定了宿主机 80 端口(就像 NodePort),本身又在集群内,那么向后直接转发到相应 Service IP 就行了,如下图所示:
Ingress 简单的理解就是你原来需要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yaml 创建,每次不要去改 Nginx 了,直接改 yaml 然后创建/更新就行了;那么问题来了:”Nginx 怎么才能动态处理配置?”
注:Ingress资源时基于HTTP虚拟主机或URL的转发规则,需要强调的是,这是一条转发规则,没有任何功能,创建了Ingress对象,Ingress Controller会去动态感知和更新Ingress对象的转发规则
Ingress Controller 这东西就是解决 “Nginx 怎么才能动态处理配置” 的程序(可以简单理解成Ngixn程序,实际不一定,实现方案有很多种);Ingress Controoler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下.
实际上,Ingress相当于一个7层的负载均衡器,是 kubernetes 对反向代理的一个抽象,它的工作原理类似于 Nginx,可以理解成在 Ingress 里建立诸多映射规则
Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:
ingress:
kubernetes
中的一个对象,给管理员提供一个定义请求如何转发到service
的规则的定义方法ingress controller:具体实现反向代理及负载均衡的程序,对
ingress
定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx, Contour, Haproxy
Ingress(以Nginx为例)的工作原理如下:
- 用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service
- Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
- Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
- 到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则
Ingress 安装
1 | #1. 安装 Ingress 镜像 |
创建 Service
1 | #1. ingress是代理 service 的,在使用 ingress 前要先有创建 service |
Ingress 使用
1 | #1. 创建规则 |
商务专线没有IP(联通),可换楼层,换楼的话,提前询问,是否能换 | 半年 | 网络 |
---|---|---|
50M | 2800 | 相对稳 |
100M | 4750(5000) | 相对稳 |
拨号上网 | ||
200M | 2700 | 不稳 |
300M | 3000 | 不稳 |
专线 有固定IP 50M | 2万左右 | 稳 |
访问
1 | #1. 查看 ingress |
ingress 切换宿主机 ip
1 | #1. 在ingress的yaml中搜索containers |
ingress总结ingress
是一个全局入口(80和443),为集群中所有应用转发
公网负载均衡器在其中的作用:
- 将k8s节点(内网)暴露到互联网上
- 是互联网用户统一访问入口,特别是针对
service nodeport
- 加强k8s网络安全
ingress 有两种部署方式,因为他本质上也是一个 pod
- pod创建,用service在对他进行代理( 官方默认 )。
- 直接共用宿主机网络,将端口暴露在宿主机。
1 | #1. 安装 Ingress 镜像 |
1 | 注: |
总结:
K8S Ingress = 微服务网关, 本质:七层反向代理,微服务集中出入口
1 |
|