linuxea:kubernetes Headless Service无头服务 (14)

在之前的NodeporthostNetwork中,大致了解了暴露的用法,此后有Ingress Controller的用法。之前不管那种方式,对于调用前端而言是不清楚后端pod的ip地址的。但是,有一些有状态的应用程序就需要清楚的联系到每个容器的ip地址,直接与容器通信。那就是Service的No ClusterIP无头服务。

None

  • 无头服务(No ClusterIP):此前,每一个service都会有一个service名称,解析的结果都是cluster ip,请求由cluster ip DNAT到后端的pod上。因此cluster ip的解析结果只会有一个ip。但是,现在可以去掉中间这层cluster ip(既不会动态分配也不会手动指定),而后的解析将会解析到pod ip上,而pod的ip是取决于集群大小。这类的service就是无头service。直达后端pod。如下图:

    准备测试的yaml文件,其中使用DaemonSetpod控制器,也就意味着每个node上面会创建一个容器,而后配置标签管理,分别是app: nginxrelease: www,容器使用marksugar/nginx:1.14.a
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-linuxea
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
      release: www
  template:
    metadata:
      labels:
        app: nginx
        release: www
    spec:
      containers:
      - name: linuxea
        image: "marksugar/nginx:1.14.a"
        ports:
        - name: http
          containerPort: 80

编写service的yaml文件,标签和上述pod一致,clusterIPNone。而后apply

apiVersion: v1
kind: Service
metadata:
  name: none-linuxea
  namespace: default
spec:
  selector:
    app: nginx
    release: www
  clusterIP: None
  ports:
  - port: 80
    targetPort: 80
[root@linuxea linuxea]# kubectl apply -f none-linuxea.yaml 
service/none-linuxea created

启动之后kubectl get svc查看CLUSTER-IP这列为None

[root@linuxea linuxea]# kubectl get svc
NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
kubernetes     ClusterIP   10.96.0.1     <none>        443/TCP    18d
none-linuxea   ClusterIP   None          <none>        80/TCP     4s
redis          ClusterIP   10.96.65.65   <none>        6379/TCP   5d

此刻kubectl get pods -o wide查看到获取的pod IP,这里的pod ip会被直接解析到命名空间

  • 如果不适用无头服务,那么解析的是一个Cluster IP地址,由这个IP DNAT到后端每个容器上
[root@linuxea linuxea]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP            NODE                 NOMINATED NODE
nginx-linuxea-2qkmf      1/1       Running   0          2m        172.16.2.44   linuxea.node-2.com   <none>
nginx-linuxea-8hvk6      1/1       Running   0          2m        172.16.3.46   linuxea.node-3.com   <none>
nginx-linuxea-dk5hg      1/1       Running   0          2m        172.16.1.42   linuxea.node-1.com   <none>

使用dig none-linuxea.default.svc.cluster.local命名空间得到的ip便是三个pod的真是ip。如果此时需要在内部调用可直接使用none-linuxea.default.svc.cluster.local进行调用即可

[root@linuxea linuxea]# dig -t A none-linuxea.default.svc.cluster.local. @10.96.0.10

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> -t A none-linuxea.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32900
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
none-linuxea.default.svc.cluster.local. 5 IN A  172.16.1.42
none-linuxea.default.svc.cluster.local. 5 IN A  172.16.2.44
none-linuxea.default.svc.cluster.local. 5 IN A  172.16.3.46

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Mon Sep 10 14:10:34 BST 2018
;; MSG SIZE  rcvd: 229

[root@linuxea linuxea]# 

如果此时解析有头的(有ClusterIP的)就会解析到ClusterIP上,在前面提到过,请求到service的ClusterIP,而后DNAT到pod IP的

其中,service定义后,尤其在nodePort中需要做两级代理,甚至两级转换或者调度,无论是iptables还是ipvs都是四层调度。倘若运行https服务的话,那意味着每台nodePort service都需要配置成https主机。在四层调度中本身是无法卸载https会话。kubeneres的ingress可以引入进群外部流量的七层调度(7层pod),将流量引入到内部来,引入方式如:nginx,haproxy等等!

ExternalName

当pod内的客户端去访问kubernes集群外的服务,(外部名称)ExternalName便用于实现于此。

  • 外部名称:外部的服务的名称,通过服务名称来访问外部服务。从而使得集群内部的pod像使用集群内部的服务一样使用集群外部的服务。并且pod client访问的是一个名称(通过coredns解析)

    pod client想要访问kubernetes外部服务,需要通过service层级转换到(SNAT),请求到外部服务中,外部服务响应与node ip,再由node ip转交给service,service转交给pod client,从而使得pod client访问外部服务。
0 分享

您可以选择一种方式赞助本站

支付宝扫码赞助

支付宝扫码赞助

日期: 2018-09-27分类: kubernetes

标签: kubernetes

发表评论