将服务裸露给内部客户端 P136
有以下三种形式能够在内部拜访服务:
- 将服务的类型设置成
NodePort
- 将服务的类型设置为
LoadBalance
- 创立一个
Ingress
资源
应用 NodePort
类型的服务 P137
通过创立一个 NodePort
服务,能够让 Kubernetes 在其所有节点上保留一个端口(所有节点上都应用雷同端口号),并将传入的连贯转发给作为服务局部的 pod。P137
创立 NodePort
类型的服务 P137
能够应用如下形容文件 kubia-svc-nodeport.yaml
创立一个 NodePort
类型的服务。
# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
# Service 的名称
name: kubia-nodeport
spec:
# 指定服务类型为 NodePort
type: NodePort
# 该服务可用的端口
ports:
# 第一个可用端口的名字
- name: http
# 可用端口为 80
port: 80
# 服务将连贯转发到容器的 8080 端口
targetPort: 8080
# 通过集群节点的 30000 端口能够拜访该服务
nodePort: 30000
# 第二个可用端口的名字
- name: https
# 可用端口为 443
port: 443
# 服务将连贯转发到容器的 8443 端口
targetPort: 8443
# 通过集群节点的 32767 端口能够拜访该服务
nodePort: 32767
# 具备 app=kubia 标签的 pod 都属于该服务
selector:
app: kubia
nodePort
属性不是强制的,如果疏忽就会随机抉择一个端口。P137
kubectl get services kubia-nodeport
: 查看该服务的根底信息
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubia-nodeport NodePort 10.111.59.156 <none> 80:30000/TCP,443:32767/TCP 2s
PORT(S)
列显示集群 IP 外部端口 (80, 443) 和节点端口 (30000, 32767),可通过 10.111.59.156:80
和 <any-node-ip>:30000
等拜访服务。P138
应用 JSONPath 输入须要的信息 :通过指定 kubectl 的 JSONPath,咱们能够只输入须要的信息。例如:kubectl get nodes -o jsonpath='{.items[*].status.addresses[0].address}'
将输入所有节点的 IP 地址。
通过负载均衡器将服务裸露进去 P140
负载均衡器领有本人举世无双的可公开拜访的 IP 地址,并将所有连贯重定向到服务。P140
创立 LoadBalance
服务 P140
能够应用如下形容文件 kubia-svc-loadbalancer.yaml
创立一个 LoadBalancer
类型的服务。
# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
# Service 的名称
name: kubia-loadbalancer
spec:
type: LoadBalancer
# 该服务可用的端口
ports:
# 第一个可用端口的名字
- name: http
# 可用端口为 80
port: 80
# 服务将连贯转发到容器的 8080 端口
targetPort: 8080
# 第二个可用端口的名字
- name: https
# 可用端口为 443
port: 443
# 服务将连贯转发到容器的 8443 端口
targetPort: 8443
# 具备 app=kubia 标签的 pod 都属于该服务
selector:
app: kubia
应用 minikube 会发现服务的 EXTERNAL-IP
始终为 <pending>
,咱们能够应用 minikube 自带的 minikube tunnel
命令能够实现裸露(02. 开始应用 Kubernetes 和 Docker 介绍过相干解决及踩过的坑)。
LoadBalancer
类型的服务是一个具备额定的基础设施提供的负载均衡器 NodePort
服务。应用 kubectl describe service kubia-loadbalancer
命令能够发现该服务抉择了一个节点端口。P141
理解内部连贯的个性 P142
理解并避免不必要的网络跳数 :当内部客户端通过节点端口连贯到服务时,随机抉择的 pod 并不一定在接管连贯的同一节点上。可能须要额定的网络跳转能力达到 pod。可配置 Service.spec.externalTrafficPolicy
的值为 Local
指定仅将内部通信重定向到接管连贯的节点上运行的 pod。
- 如果接管连贯的节点上没有运行对应的 pod,那么连贯将挂起,所以须要确保负载均衡器将连贯转发给至多具备一个 pod 的节点
- 假如有一个两节点三个 pod 的集群(节点 A 运行一个 pod,节点 B 运行两个 pod),如果负载均衡器在两个节点间均匀分布连贯,那么 pod 的负载散布不平衡
客户端 IP 是不记录的 :当通过节点端口接管到连贯时,因为对数据包执行了源网络地址转换 (SNAT),因而数据包对源 IP 将产生更改。如果配置 Service.spec.externalTrafficPolicy
的值为 Local
,那么将会保留客户端 IP,因为在接管连贯的节点和托管指标 pod 的节点之间没有额定的跳跃(不执行 SNAT)。P143
通过 Ingress
裸露服务 P143
为什么须要 Ingress
P144
每个 LoadBalancer
服务都须要本人的负载均衡器,以及独有的私有 IP 地址,而 Ingress
只须要一个公网 IP 就能为许多服务提供拜访。当客户端向 Ingress
发送 HTTP 申请时,Ingress
会依据申请的主机名和门路决定申请转发到的服务。P144
Ingress
在网络栈 (HTTP) 的应用层操作,并且能够提供一些服务不能实现的性能,例如基于 cookie 的会话亲和性 (session affinity) 等性能。P144
Ingress 控制器是必不可少的 P144
只有 Ingress
控制器在集群中运行,Ingress
资源能力失常工作。P144
在 minikube 上启动 Ingress
的扩大性能 P145
minikube addons list
: 能够列出所有的插件及其启用状态
minikube addons enable ingress
: 启用 ingress
插件
kubectl get pods -n kube-system
: 查看 kube-system
命名空间下的 pod,能够发现 Ingress
控制器 pod
创立 Ingress
资源 P145
能够应用如下形容文件 kubia-ingress.yaml
创立一个 Ingress
资源。
# 遵循 extensions/v1beta1 版本的 Kubernetes API
apiVersion: extensions/v1beta1
# 资源类型为 Ingress
kind: Ingress
metadata:
# Ingress 的名称
name: kubia
spec:
# Ingress 的规定列表
rules:
# 第一条规定匹配的域名为 kubia.example.com
- host: kubia.example.com
# 匹配 http
http:
# 匹配的门路列表
paths:
# 第一条门路为 /
- path: /
# 该门路将被转发到的后端服务
backend:
# 将被转发到 kubia-nodeport 服务
serviceName: kubia-nodeport
# 对应服务的端口为 80
servicePort: 80
minikube 下创立 Ingress
资源时报错了,提醒超时。起初找到一种解决方案:应用 kubectl edit ValidatingWebhookConfiguration/ingress-nginx-admission
进行编辑,找到 failurePolicy: Fail
这行,并将 Fail
改为 Ignore
,而后就能胜利创立 Ingress
资源了,等一段时间后就能够看见其调配了一个 IP 地址 (192.168.64.70
)。
为了能将指定的域名 kubia.example.com
指向调配的 IP 地址 (192.168.64.70
),能够应用 SwitchHosts 这个软件进行疾速切换。
此时咱们在主机上就能够通过 curl kubia.example.com
拜访 kubia-nodeport
服务了。
理解 Ingress
的工作原理 P147
- 客户端对
kubia.example.com
执行 DNS 查找,本地操作系统返回了Ingress
控制器的 IP - 客户端向
Ingress
控制器发送 HTTP 申请,并在 Host 头中指定kubia.example.com
- 控制器从头部确定客户端尝试拜访哪个服务,通过与该服务关联的
Endpoint
对象查看 pod IP,并将客户端的申请转发给其中一个 pod
Ingress
控制器不会将申请转发给服务,只用它来抉择一个 pod。大多数控制器都是这样工作的。P147
通过雷同的 Ingress
裸露多个服务 P147
Ingerss
的 rules
和 paths
都是数组,所以它们能够蕴含多个条目,因而一个 Ingress
能够将多个域名和门路映射到多个服务。P147
配置 Ingress
解决 TLS 传输 P149
为 Ingress
创立 TLS 认证 P149
当客户端创立到 Ingress
控制器到 TLS 连贯时,控制器将终止 TLS 连贯。客户端和控制器之间到通信是加密的,而控制器和后端 pod 之间的通信则未加密。运行在 pod 上的应用程序不须要反对 TLS。P149
为了让 Ingress
控制器负责解决与 TLS 相干的所有内容,须要将证书和私钥附加到 Ingress
。这两个必须资源存储在称为 Secret
的 Kubernetes 资源中(将在第 7 章中具体介绍 Secret
),而后在 Ingress
的形容文件中援用它。P149
openssl genrsa -out tls.key 2048
: 创立私钥
openssl req -new -x509 -key tls.key -out tls.cert -days 365 -subj /CN=kubia.example.com
: 创立证书
kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key
: 创立 Secret
资源
而后咱们就能够改写 kubia-ingress.yaml
失去 kubia-ingress-tls.yaml
形容文件:
...
spec:
# 配置 TLS
tls:
# 第一条配置的域名列表
- hosts:
- kubia.example.com
# 这些域名应用 tls-secret 取得私钥和证书
secretName: tls-secret
...
而后咱们就能够应用 curl -k -v https://kubia.example.com
通过 HTTPS 拜访服务了。(minikube 下未进行上述操作前也能够拜访,不过能够发现是 Ingress
控制器应用了假证书)P150
pod 就绪后发出信号 P150
与存活探测器(04. 正本机制和其余控制器:部署托管的 pod 中介绍过)相似,Kubernetes 还容许为容器定义就绪探测器。就绪探测器会定期调用,并确保特定的 pod 是否接管客户端申请。当容器的就绪探测器返回胜利时,示意容器已筹备好接管申请。P151
就绪探测器的类型 :P151
Exec
探测器:在容器内执行任意命令,并查看命令的退出状态码。如果状态码是 0,则探测胜利,认为容器曾经就绪,所有其余状态码都被认为失败HTTP GET
探测器:对容器的 IP 地址(指定的端口和门路)执行HTTP GET
申请。如果探测器收到响应,并且响应状态码不代表谬误(状态码为 2xx 或 3xx),则认为探测胜利,认为容器曾经就绪。如果服务器返回谬误响应状态码或者没有响应,那么探测就被认为是失败的TCP Socket
探测器:尝试与容器指定端口建设 TCP 连贯。如果连贯胜利建设,则探测胜利,认为容器曾经就绪
理解就绪探测器的操作 P151
启动容器时,能够为 Kubernetes 配置一个等待时间,通过等待时间后才能够执行第一次准备就绪查看。之后,它会周期性地调用探测器,并依据就绪探测器的后果采取行动。如果某个 pod 报告它尚未准备就绪,那么就会从服务中删除该 pod;如果这个 pod 再次准备就绪,那么就会将给 pod 从新增加到服务中。P151
就绪探测器和存活探测器的区别 P151
存活探测器通过杀死异样的容器并用新的失常容器代替它们来放弃 pod 失常工作,而就绪探测器确保只有筹备好解决申请的 pod 才能够接管申请,并不会终止或重新启动容器。P151
就绪探测器的重要性 :确保客户端只与失常的 pod 交互,并且永远不会晓得零碎存在的问题。P152
理解就绪探测器的理论作用 P154
务必定义就绪探测器 P155
应该始终定义一个就绪探测器,即便它只是向基准 URL 发送 HTTP 申请一样简略。如果没有将就绪探测器增加到 pod 中,那么它们启动后简直立刻成为服务端点。P155
不要将进行 pod 的逻辑纳入到就绪探测器中 P155
当一个容器敞开时,运行在其中的应用程序通常会在收到终止信号后立刻进行接管连贯。但在启动关机程序后,没有必要让就绪探测器返回失败以达到从所有服务中移除 pod 目标,因为在该容器删除后,Kubernetes 就会主动从所有服务中移除该容器。P155
应用 headless 服务来发现独立的 pod P155
要让客户端连贯到所有 pod,须要找出每个 pod 的 IP。Kubernetes 容许客户通过 DNS 查找发现 pod IP。通常,当执行服务的 DNS 查找时,DNS 服务器会返回单个 IP —— 服务的集群 IP。然而,如果通知 Kubernetes,不须要为服务提供集群 IP(通过在服务 spec
中将 clusterIP
字段设置为 None
来实现此操作),则 DNS 服务器将会返回 pod IP 而不是单个服务 IP。P155
DNS 服务器不会返回单个 DNS A 记录,而是会为该服务返回多个 A 记录,每个记录指向过后反对该服务的单个 pod 的 IP。客户端因而能够做一个简略的 DNS A 记录查问并获取属于该服务的所有 pod 的 IP。客户端能够应用该信息连贯到其中的一个、多个或全副。P155
创立 headless 服务 P156
能够应用如下形容文件 kubia-svc-headless.yaml
创立一个 headless 的 Service
资源。
# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
# Service 的名称
name: kubia-headless
spec:
# 该服务的集群 IP 为 None,使其变为 headless 的
clusterIP: None
# 该服务可用的端口
ports:
# 第一个可用端口的名字
- name: http
# 可用端口为 80
port: 80
# 服务将连贯转发到容器的 8080 端口
targetPort: 8080
# 第二个可用端口的名字
- name: https
# 可用端口为 443
port: 443
# 服务将连贯转发到容器的 8443 端口
targetPort: 8443
# 具备 app=kubia 标签的 pod 都属于该服务
selector:
app: kubia
通过 DNS 发现 pod P156
kubia 容器镜像不蕴含 nslookup
二进制文件,所以须要用一个新的容器镜像来执行相应的命令。P156
kubectl run dnsutils --image=tutum/dnsutils --generator=run-pod/v1 --command -- sleep infinity
: 创立一个能够执行 nslookup
命令的 pod
kubectl exec dnsutils nslookup kubia-headless
: 在 dnsutils
pod 内执行 nslookup kubia-headless
命令,能够发现 DNS 服务器为 kubia-headless.default.svc.cluster.local
FQDN 返回了多个 IP,且它们都是 pod 的 IP,能够通过 kubectl get pods -o wide
进行确认
kubectl exec dnsutils nslookup kubia
: 在 dnsutils
pod 内执行 nslookup kubia
命令,能够发现 DNS 服务器为 kubia.default.svc.cluster.local
FQDN 返回了一个 IP,该 IP 是服务的集群 IP
只管 headless 服务看起来可能与惯例服务不同,然而在客户的视角上它们并无不同。对于 headless 服务,因为 DNS 返回了 pod 的 IP,客户端间接连贯到该 pod,而不是通过服务代理(留神这里是间接拜访的 pod,所以对应的端口要改成 pod 的端口)。P157
留神 :headless 服务依然提供跨 pod 的负载平衡,然而通过 DNS 轮循机制不是通过服务代理 P157
发现所有的 pod —— 包含未就绪的 pod P157
能够通过在 Service.metadata.annotations
上面减少一条 service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
通知 Kubernetes 无论 pod 的筹备状态如何,心愿将所有 pod 增加到服务中 P158
排除服务故障 P158
如果无奈通过服务拜访 pod,应依据上面的列表进行排查:P158
- 确保从集群内连贯到服务的集群 IP
- 不要通过
ping
服务 IP 来判断服务是否可拜访(服务的集群 IP 是虚构 IP,是无奈 ping 通的) - 如果曾经定义了就绪探测器,请确保它返回胜利;否则该 pod 不会成为服务的一部分
- 要确认某个容器是服务的一部分,请应用
kubectl get endpoints
来查看相应的端点对象 - 如果尝试通过 FQDN 或其中一部分来拜访服务,但并不起作用,请查看是否能够应用其集群 IP 而不是 FQDN 来拜访服务
- 查看是否连贯到服务公开的端口,而不是指标端口
- 尝试间接连贯到 pod IP 以确认 pod 正在接管正确端口上的连贯
- 如果甚至无奈通过 pod 的 IP 拜访利用,请确保利用不是仅绑定到
localhost (127.0.0.1)
本文首发于公众号:满赋诸机(点击查看原文)开源在 GitHub:reading-notes/kubernetes-in-action