Service
将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。使用 kubernetes 你无需修改应用程序即可使用不熟悉的服务发现机制,kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名,并且可以在它们之间进行负载均衡。
发布服务(服务类型)
由于运行的 Pod IP 是 docker 网桥的 IP 地址段进行分配的通常是一个虚拟的二层网络,外部网络并没有办法直接访问且由于 Pod IP 不是固定的、随时改变的, K8s 引入 Service 概念,通过 Service 管理这些 Pod,service 创建后 Service IP 是固定的,但需要注意的是这时的 Service IP 是Cluster IP 是一个虚拟的 IP,由 kubernetes 管理和分配外部网络无法直接访问,K8s 提供三种方式暴露 Service 以供外部网络访问。
NodePort
在定义 service 时将 type 设置为 NodePort 类型,设置 type 后每一个集群节点在节点本身打开一个端口,并将在该端口上接收到的流量重定向到基础服务,该服务仅在内部集群 IP. 和端口才可以访问,但也可以通过节点上的专用端口访问。
-
创建一个 deployment
-
deployment 文件
apiVersion: apps/v1 kind: Deployment metadata: name: demo-nginx spec: selector: matchLabels: app: demo-nginx template: metadata: labels: app: demo-nginx spec: containers: - name: demo-nginx image: nginx:1.14.2 # 对 pod 资源进行限制 resources: limits: memory: "128Mi" cpu: "500m" ports: - containerPort: 80
-
使用 kubectl 创建 deploymeny
kubectl apply -f ./deploy.yml
-
-
创建类型为 NodePort 的 Service
-
service 文件
apiVersion: v1 kind: Service metadata: name: demo-nginx spec: type: NodePort selector: app: demo-nginx ports: - port: 80 targetPort: 80
-
kubectl 创建 Service
kubectl apply -f ./svc.yml
-
-
使用 kubectl describe svc <服务名称> 查看服务详情,可以看到 NodePort 端口为 30332
-
访问服务(通过 NodeIP + NodePort 访问):127.0.0.1:30232
-
总结:虽然 NodePort 这种方式暴露服务操作起来很简单但是当服务一旦多起来 NodePort 在每个节点上开启的端口将会极其庞大,而且难以维护,不建议在生产环境下使用。
LoadBalancer
LoadBalance 是通过 NodePort 暴露外部访问的一个优化,在原来 NodePort 的基础上增加一个负载均衡器,NodePort 是所有节点都开放一个端口提供给外部访问,并没有做 Node 节点负载均衡,LoadBalance 则是在上面的基础上增加一层,只提供一个公网 IP 给外部访问,外部访问这个 IP 在负载均衡分发给 Node 节点上的 Pod
注意⚠️:在云服务提供商上运行的 Kubernetes 集群通常支持云基础架构自动提供负载均衡,只需要设置服务类型为 LoadBalancer 即可,负载均衡器拥有自己独一无二的可公开访问的 IP 地址。并将所有链接重定向到对应的服务,外部可以通过负载均衡器的 IP 地址访问服务。
总结:LoadBalancer 暴露的服务都会有它自己的 IP 地址和端口,不能做到一个 IP 地址访问所有服务。
Ingress
采用 NodePort 方式暴露服务在服务多起来后 NodePort 在每个节点上开启的端口会很多难以维护,如果采用 LoadBalance 每个服务都的开放一个公网 IP,服务量大时难以维护。这个时候 Ingress 暴露服务时一种很合适的方案,可以通过一个 Ingress 暴露多个服务,可以简单理解将 Ingress 当成一个特殊的网关
本机集群搭建(ingress)
Ingress 包含两大组件:Ingress Controller 和 Ingress.
-
通常情况下 Service 和 Pod 的 IP 仅可在集群内部访问,集群外部的请求需要通过负载均衡转发到 Service 在 Node 上暴露的NodePort 上,然后再由 kube-proxy 通过边缘路由(edge router) 将其转发给相关的 Pod 或者丢弃,而Ingress 就是为进入集群的请求提供路由规则的集合。Ingress 简单理解为你需要的 nginx 配置,然后配置各种域名对应到的 Service,现在把这个动作抽象出来变成一个 Ingress 对象,你可以通过 yaml 创建。
-
Ingress Controller 是解决 Nginx 怎么才能动态处理配置 的程序,Ingress Controller 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化然后读取它,按照他自己模块生成一段 Nginx 配置,再写到 Nginx Pod 最后 reload 下工作流程如下图:
部署步骤:ingress-controller => ingress svc => deployment(应用)=> service(应用)=> ingress(相当于代理 service)
部署 ingress-controller(nginx-ingress-controller)
参考:https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx
namespace: ingress-nginx
automountServiceAccountToken: true
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
name: ingress-nginx
rules:
- apiGroups:
- ''
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ''
resources:
- nodes
verbs:
- get
- apiGroups:
- ''
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io # k8s 1.14+
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- extensions
- networking.k8s.io # k8s 1.14+
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io # k8s 1.14+
resources:
- ingressclasses
verbs:
- get
- list
- watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding