Kubernetes Service

  1. Kubernetes内部Service
  2. Kubernetes Ingress
  3. Kubernetes Istio
  4. 总结
  5. 附: ingress-nginx deploy&test

目录:(可以按w快捷键切换大纲视图)

本篇按顺序简单介绍 Kubernetes内部Service, Kubernetes Ingress, Kubernetes Istio。

Kubernetes内部Service

ClusterIP, NodePort, ExternalIPs 和 LoadBalancer服务是由kube-proxy或者CNI比如Cilium,Calico提供的。参考 Cilium完全替换kube-proxy

如果创建一个 NodePort 服务,它也会创建一个 ClusterIP 服务。如果创建一个 LoadBalancer,它会创建一个 NodePort,然后创建一个 ClusterIP。

为何要有 Kubernetes内部Service:

上图的情况,若pod-python被销毁并创建了一个新的。(在本文中,我们不讨论如何管理和控制 pod。)突然pod-nginx无法再到达1.1.1.3,有了Service或者说Cluster IP,情况就不一样了。

现在服务只能被集群内部访问了,为了能被外部访问,可以配置NodePort。这样内部服务 python 现在也可以从端口 30080 上的每个节点内部和外部 IP 地址访问。

Kubernetes Ingress

Kubernetes Ingress 不是 Kubernetes 服务。它是一个将请求重定向到其他内部(ClusterIP)服务的 Nginx Pod。

Ingress-nginx组成:

  • ingress-nginx-controller:根据用户编写的ingress规则(创建的ingress的yaml文件),动态的去更改nginx服务的配置文件,并且reload重载使其生效(是自动化的,通过lua脚本来实现);
  • ingress资源对象:将Nginx的配置抽象成一个Ingress对象,每添加一个新的Service资源对象只需写一个新的Ingress规则的yaml文件即可(或修改已存在的ingress规则的yaml文件)

Kubernetes Ingress 能做什么:

和 Kubernetes Service 的工作有点类似。和传统的Nginx工作内容一样,HTTP 协议接收对特定文件路径的请求 和 将 HTTP 协议的请求进行重定向转发并返回他们的响应。实现动态配置服务和减少不必要的端口映射。

例如可以配置不同的 url /folder /other转发到不同的 Kubernetes Service。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  namespace: default
  name: test-ingress
spec:
  rules:
  - http:
      paths:
      - path: /folder
        backend:
          serviceName: service-nginx
          servicePort: 3001
  - http:
      paths:
      - path: /other
        backend:
          serviceName: service-python
          servicePort: 3002 

Kubernetes Istio

Istio 是服务网格,它允许在集群中的 pod 和服务之间进行更详细、复杂和可观察的通信。它将代理容器注入所有 pod,然后控制集群中的流量。

Kubernetes 中的服务由kube-proxy运行在每个节点上的组件实现。该组件创建将请求重定向到 pod 的 iptables 规则。因此,服务只不过是 iptables 规则。(还有其他不使用 iptables 的代理模式可用,但过程相同。 参考 Cilium完全替换kube-proxy

上图显示了已安装的 Istio,它与 Istio 控制平面一起提供。同样普遍的是,每个 pod 都有一个名为 的第二个容器istio-proxy,它会在创建过程中自动注入到 pod 中。具有 的 pod istio-proxy将不再使用这些kube-proxy组件。

istio-proxy每当配置或服务的 pod 发生更改时,Istio 控制平面都会对所有sidecar 进行配置。类似于 Kubernetes API 对kube-proxy进行配置。Istio 控制平面利用pod ip实现了自己的路由。Istio 会将 Kubernetes 服务声明转换为自己的路由声明。

接下来看看如何使用 Istio 发出请求:

上图中,所有istio-proxy容器都已由 Istio 控制平面进行了配置,并包含所有必要的路由信息​​。nginx 容器 from pod1-nginx向 service 发出请求service-python。

请求被istio-proxy容器拦截pod1-nginx并重定向到istio-proxy 一个python pod的容器,然后将其重定向到python容器。

可见,Istio 和 Kubernetes内部Service 和 Kubernetes内部Service 有很多重叠的功能,或者说可以是相同需求的多种实现。Istio 相对于 Kubernetes Service 和 Kubernetes Ingress的优势是什么?

所有流量都通过istio-proxy每个 pod 中的容器进行路由。每当istio-proxy接收和重定向请求时,它也会将有关它的信息提交给 Istio 控制平面。因此,Istio 控制平面确切地知道请求来自哪个 pod、存在哪些 HTTP 标头、从一个请求istio-proxy到另一个请求需要多长时间等等。在具有许多相互通信的服务的集群中,这可以提高可观察性并更好地控制所有流量。

具体点的优势有:

  • 高级路由:Kubernetes 内部服务只能将服务请求轮询或随机分发到 Pod。使用 Istio 可以实现更复杂的方法。就像根据请求标头重定向一样,如果发生错误或使用最少的服务。
  • 部署:它允许将某些百分比的流量路由到某些服务版本,因此允许绿/蓝和金丝雀部署。
  • 加密:可以加密pod 之间的集群内部流量 from istio-proxy 到 istio-proxy。
  • 监控/图表生成:Istio 连接到 Prometheus 等监控工具。它还可以与 Kiali 一起很好地显示所有服务及其流量。
  • 追踪:由于 Istio 控制平面有大量关于请求的数据,因此可以使用 Jaeger 等工具对这些数据进行跟踪和检查。
  • 多集群网格:Istio 有一个内部服务注册中心,可以使用现有的 Kubernetes 服务。也可以从集群外部添加资源,甚至可以将不同的集群连接到一个网格中。

总结

综上,ingress是k8s集群的请求入口,可以理解为对多个service的再次抽象,通常说的ingress一般包括ingress资源对象及ingress-controller两部分组成。Istio不是取代 Kubernetes内部服务 的,Istio 使用现有的 Kubernetes内部服务 来获取其所有端点/pod IP 地址。Istio 是可以取代Kubernetes Ingress的,Istio 提供了新的资源,例如 Gateway 和 VirtualService,甚至还附带了 ingress 转换器istioctl convert-ingress。

附: ingress-nginx deploy&test

# 创建集群
[root@centos7 ~]# kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.24.0) 🖼
 ✓ Preparing nodes 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Thanks for using kind! 😊
# 检查集群状态
[root@centos7 ~]# kubectl get node -o wide
NAME                 STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION               CONTAINER-RUNTIME
kind-control-plane   Ready    control-plane   32s   v1.24.0   172.18.0.2    <none>        Ubuntu 21.10   5.19.5-1.el7.elrepo.x86_64   containerd://1.6.4
[root@centos7 ~]# kubectl get po -A -o wide
NAMESPACE            NAME                                         READY   STATUS    RESTARTS   AGE   IP           NODE                 NOMINATED NODE   READINESS GATES
kube-system          coredns-6d4b75cb6d-4ck55                     1/1     Running   0          19s   10.244.0.3   kind-control-plane   <none>           <none>
kube-system          coredns-6d4b75cb6d-ps5sf                     1/1     Running   0          19s   10.244.0.2   kind-control-plane   <none>           <none>
kube-system          etcd-kind-control-plane                      1/1     Running   0          34s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kindnet-fbjj6                                1/1     Running   0          19s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-apiserver-kind-control-plane            1/1     Running   0          34s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-controller-manager-kind-control-plane   1/1     Running   0          34s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-proxy-rz9vk                             1/1     Running   0          19s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-scheduler-kind-control-plane            1/1     Running   0          34s   172.18.0.2   kind-control-plane   <none>           <none>
local-path-storage   local-path-provisioner-9cd9bd544-xddpx       1/1     Running   0          19s   10.244.0.4   kind-control-plane   <none>           <none>
# 部署 ingress-nginx
[root@centos7 ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
# 检查 ingress-nginx 状态
[root@centos7 ~]# kubectl get po -A -o wide
NAMESPACE            NAME                                         READY   STATUS      RESTARTS   AGE     IP           NODE                 NOMINATED NODE   READINESS GATES
ingress-nginx        ingress-nginx-admission-create-ddgdc         0/1     Completed   0          59s     10.244.0.5   kind-control-plane   <none>           <none>
ingress-nginx        ingress-nginx-admission-patch-6tfbk          0/1     Completed   0          59s     10.244.0.6   kind-control-plane   <none>           <none>
ingress-nginx        ingress-nginx-controller-6bf7bc7f94-k94c4    1/1     Running     0          59s     10.244.0.7   kind-control-plane   <none>           <none>
kube-system          coredns-6d4b75cb6d-4ck55                     1/1     Running     0          2m55s   10.244.0.3   kind-control-plane   <none>           <none>
kube-system          coredns-6d4b75cb6d-ps5sf                     1/1     Running     0          2m55s   10.244.0.2   kind-control-plane   <none>           <none>
kube-system          etcd-kind-control-plane                      1/1     Running     0          3m10s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kindnet-fbjj6                                1/1     Running     0          2m55s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-apiserver-kind-control-plane            1/1     Running     0          3m10s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-controller-manager-kind-control-plane   1/1     Running     0          3m10s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-proxy-rz9vk                             1/1     Running     0          2m55s   172.18.0.2   kind-control-plane   <none>           <none>
kube-system          kube-scheduler-kind-control-plane            1/1     Running     0          3m10s   172.18.0.2   kind-control-plane   <none>           <none>
local-path-storage   local-path-provisioner-9cd9bd544-xddpx       1/1     Running     0          2m55s   10.244.0.4   kind-control-plane   <none>           <none>
[root@centos7 ~]# kubectl get pods --namespace=ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-ddgdc        0/1     Completed   0          73s
ingress-nginx-admission-patch-6tfbk         0/1     Completed   0          73s
ingress-nginx-controller-6bf7bc7f94-k94c4   1/1     Running     0          73s
# 测试 ingress-nginx
[root@centos7 ~]# kubectl create deployment demo --image=httpd --port=80
deployment.apps/demo created
[root@centos7 ~]# kubectl expose deployment demo
service/demo exposed
[root@centos7 ~]# kubectl get svc -A
NAMESPACE       NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
default         demo                                 ClusterIP      10.96.179.60    <none>        80/TCP                       56s
default         kubernetes                           ClusterIP      10.96.0.1       <none>        443/TCP                      4m40s
ingress-nginx   ingress-nginx-controller             LoadBalancer   10.96.170.222   <pending>     80:32137/TCP,443:30208/TCP   2m27s
ingress-nginx   ingress-nginx-controller-admission   ClusterIP      10.96.139.192   <none>        443/TCP                      2m27s
kube-system     kube-dns                             ClusterIP      10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP       4m38s
[root@centos7 ~]# kubectl get po
NAME                    READY   STATUS    RESTARTS   AGE
demo-6486d57d96-j65cf   1/1     Running   0          94s
[root@centos7 ~]# kubectl create ingress demo-localhost --class=nginx \
>   --rule="demo.localdev.me/*=demo:80"
ingress.networking.k8s.io/demo-localhost created
[root@centos7 ~]# kubectl get ingress -A
NAMESPACE   NAME             CLASS   HOSTS              ADDRESS   PORTS   AGE
default     demo-localhost   nginx   demo.localdev.me             80      8s
[root@centos7 ~]# kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
[root@centos7 ~]# curl http://demo.localdev.me:8080/
<html><body><h1>It works!</h1></body></html>

转载请注明来源,欢迎指出任何有错误或不够清晰的表达。可以邮件至 backendcloud@gmail.com