欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

kubernetes 基础 -- 4.1 kubernetes service

程序员文章站 2024-03-11 10:27:31
...

前言

Pod 需要一种寻找其他 pod 的方法来使用其他 pod 提供的服务,不像在没有 Kubernetes 的世界,系统管理员要在用户端配置文件中明确指出服务的精确的 IP 地址或者主机名来配置每个客户端应用,但是同样的方式在 Kubernetes 中并不适用,因为:

pod 的是短暂,随时启动或者关闭,客户端不能提前知道 pod 的 IP,多个 pod 提供相同的服务;水平伸缩意味着多个 pod 可能会提供相同的服务 – 每个 pod 都有自己的 IP 地址,客户端无须关心后端提供服务 pod 的数量,以及各自对应的 IP 地址。它们无须记录每个 pod的 IP 地址。所有的 pod 可以通过一个单一的 IP 地址进行访问。

为了解决上述问题,Kubernetes 提供了一种资源类型——服务
(service)

Service

Service: 提供单一不变的接入点的资源,服务的 IP 不会变,变的是 pod 的 IP;

创建 service

使用之前的 rs_test.yaml

labels:
        app: rs-nginx

containerPort 80

service_test.yaml

apiVersion: v1
kind: Service
metadata:
  name: service-nginx
spec:
  ports: 
  - port: 8080			//该服务的端口
    targetPort: 80		//转发到的容器端口
  selector:
    app: rs-nginx		//具有app=rs-nginx标签的 pod 都属于该 service

查看 service 描述信息,Endpoints 为所有服务管理的 pod。当然,一般就绪探针正常的才会被添加到 endpoint 中

$ kubectl apply -f service_test.yaml
$ kubectl describe   services service-nginx
Name:              service-nginx
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=rs-nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.103.127.82
IPs:               10.103.127.82
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.244.0.16:80,10.244.1.144:80,10.244.2.245:80
Session Affinity:  None
Events:            <none>

通过 service clusterIP 访问服务

$ curl 10.103.127.82:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

当然可以暴露多个端口

spec:
  ports:
    - name: http
      port: 80
      targetPort: 8080
    - name: https
      port: 443
      targetPort: 8443

通过 dns 来发现访问服务

kubernetes 内部 pod 的 dns server 都指向 kube-dns 的服务地址,所以通过访问 FQDN 连接服务,如上面创建的 service,default 为 namespace,如果同一个 namespace,也可以直接访问 service-nginx。

service-nginx.default.svc.cluster.local
$ kubectl get services -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   26d

$ kubectl exec rs-nginx-7tmjq -- cat /etc/resolv.conf 
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

$ dig service-nginx.default.svc.cluster.local @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.8 <<>> service-nginx.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32397
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;service-nginx.default.svc.cluster.local. IN A

;; ANSWER SECTION:
service-nginx.default.svc.cluster.local. 30 IN A 10.103.127.82		// clusterIP

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Mon Dec 06 23:24:30 CST 2021
;; MSG SIZE  rcvd: 123

将服务暴露给外部客户端

可以将 Service 的类型设置为 NodePort,LoadBalance 和 Ingress。可以见下章 4.2 对三种 Service 的解析。

需要注意
外部访问时,客户端的 IP 是不被记录的,因为当通过节点端口接收连接时,对数据包执行了 SNAT。

headless

也可以创建 headless 服务,headless 没有 clusterIP,通过 DNS 直接发现 pod IP。DNS 服务器会返回多个 A 记录;
可以通过设置 clusterIP 为 None 来创建;
修改之前的 services

$ kubectl edit  services service-nginx
spec:
  clusterIP: None
  clusterIPs:
  - None
$ dig service-nginx.default.svc.cluster.local @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.8 <<>> service-nginx.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54321
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;service-nginx.default.svc.cluster.local. IN A

;; ANSWER SECTION:
service-nginx.default.svc.cluster.local. 30 IN A 10.244.1.144
service-nginx.default.svc.cluster.local. 30 IN A 10.244.2.245
service-nginx.default.svc.cluster.local. 30 IN A 10.244.0.16

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Mon Dec 06 23:52:59 CST 2021
;; MSG SIZE  rcvd: 233