本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.2 和使用 Ingress 简化高级网络

编者按:这是关于 Kubernetes 1.2 新功能的系列深度文章的第六篇
Ingress 目前处于 Beta 阶段,并正在积极开发中。

默认情况下,在 Kubernetes 中,Service 和 Pod 的 IP 只能由集群网络路由。所有到达边缘路由器的流量都会被丢弃或转发到其他地方。在 Kubernetes 1.2 中,我们对 Ingress 对象进行了改进,以简化允许入站连接到达集群服务。它可以配置为提供可从外部访问的 URL、负载均衡流量、终止 SSL、提供基于名称的虚拟主机等。

Ingress 控制器

如今,使用容器或虚拟机,配置 Web 服务器或负载均衡器比应有的更困难。大多数 Web 服务器配置文件都非常相似。有些应用程序有一些奇怪的小怪癖,这往往会使事情变得复杂,但在大多数情况下,您可以对它们应用相同的逻辑并实现所需的结果。在 Kubernetes 1.2 中,Ingress 资源体现了这一思想,Ingress 控制器旨在处理与特定 Ingress“类”相关的所有怪癖(无论是单个负载均衡器实例,还是更复杂的前端设置,提供 GSLB、CDN、DDoS 保护等)。Ingress 控制器是一个守护进程,作为 Kubernetes Pod 部署,它监视 ApiServer 的 /ingresses 端点,以获取 Ingress 资源的更新。它的工作是满足入站请求。

您的 Kubernetes 集群必须有一个且只有一个支持 TLS 的 Ingress 控制器,才能使以下示例正常工作。如果您使用的是云提供商,请首先检查“kube-system”命名空间中是否存在 Ingress 控制器 RC。如果没有,您可以部署 nginx 控制器,或在不到 100 行代码内编写您自己的控制器

请花一点时间查看现有控制器(gce、nginx)的已知限制。

TLS 终止和 HTTP 负载均衡

由于 Ingress 跨越 Service,因此它特别适合负载均衡和集中式安全配置。如果您熟悉 Go 编程语言,Ingress 就像您整个集群的 net/http 的“Server”。以下示例向您展示了如何配置 TLS 终止。当处理入站流量时,负载均衡不是可选的,因此简单地创建对象将配置一个负载均衡器。

首先创建一个测试 Service。我们将在此示例中运行一个简单的 echo 服务器,以便您确切了解发生了什么。源代码在此处

$ kubectl run echoheaders   
--image=gcr.io/google\_containers/echoserver:1.3 --port=8080  
$ kubectl expose deployment echoheaders --target-port=8080   
--type=NodePort  

如果您是云提供商,请确保您可以通过其节点端口从集群外部访问该 Service。

$ NODE_IP=$(kubectl get node `kubectl get po -l run=echoheaders 
--template '{{range .items}}{{.spec.nodeName}}{{end}}'` --template
'{{range $i, $n := .status.addresses}}{{if eq $n.type 
"ExternalIP"}}{{$n.address}}{{end}}{{end}}')
$ NODE_PORT=$(kubectl get svc echoheaders --template '{{range $i, $e 
:= .spec.ports}}{{$e.nodePort}}{{end}}')
$ curl $NODE_IP:$NODE_PORT

这是一个健全性检查,以确保一切按预期工作。如果最后一步挂起,您可能需要一个防火墙规则

现在让我们创建 TLS 密钥

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout   

/tmp/tls.key -out /tmp/tls.crt -subj "/CN=echoheaders/O=echoheaders"

$ echo "  
apiVersion: v1  
kind: Secret  
metadata:
  name: tls  
data:  
  tls.crt: `base64 -w 0 /tmp/tls.crt`  
  tls.key: `base64 -w 0 /tmp/tls.key`  
" | kubectl create -f   

以及 Ingress

$ echo "

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: test

spec:

  tls:

  - secretName: tls
  backend:  
    serviceName: echoheaders  
    servicePort: 8080  
" | kubectl create -f -  

您很快就会获得一个负载均衡的 IP

$ kubectl get ing   
NAME      RULE      BACKEND            ADDRESS         AGE  
test      -         echoheaders:8080   130.X.X.X     4m  

如果您等到 Ingress 控制器将您的后端标记为健康,您应该会看到发送到该 IP 地址上 :80 端口的请求被重定向到 :443 端口,并使用给定的 TLS 证书进行终止。

$ curl 130.X.X.X  
\<html\>  
\<head\>\<title\>301 Moved Permanently\</title\>\</head\>\<body bgcolor="white"\>\<center\>\<h1\>301 Moved Permanently\</h1\>\</center\>  
$ curl https://130.X.X.X -kCLIENT VALUES:client\_address=10.48.0.1command=GETreal path=/  


$ curl 130.X.X.X -Lk

CLIENT VALUES:client\_address=10.48.0.1command=GETreal path=/

未来的工作

您可以通过以下链接阅读有关 Ingress API 或控制器的更多信息。Ingress 仍处于 Beta 阶段,我们非常希望您的意见来使其发展。您可以通过编写控制器或改进 API 来做出贡献。所有与“ingress”一词含义相关的事物都在讨论范围之内,这包括 DNS、不同的 TLS 模式、SNI、第 4 层负载均衡、内容缓存、更多算法、更好的健康检查;清单还在继续。

有许多参与方式。如果您对 Kubernetes 和网络特别感兴趣,您会对以下内容感兴趣

当然,有关该项目的更多信息,请访问www.kubernetes.io