如何通过其他POD访问StatefulSet

时间:2020-06-09 12:00:07

标签: elasticsearch kubernetes

我有一个正在运行的Elasticsearch STS,并为其分配了无头服务:

svc.yaml:

kind: Service
apiVersion: v1
metadata:
  name: elasticsearch
  namespace: elasticsearch-namespace
  labels:
    app: elasticsearch
spec:
  selector:
    app: elasticsearch
  clusterIP: None
  ports:
    - port: 9200
      name: rest
    - port: 9300
      name: inter-node

stateful.yaml:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: es-cluster
  namespace: elasticsearch-namespace
spec:
  serviceName: elasticsearch
  replicas: 3
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
        resources:
            limits:
              cpu: 1000m
            requests:
              cpu: 100m
        ports:
        - containerPort: 9200
          name: rest
          protocol: TCP
        - containerPort: 9300
          name: inter-node
          protocol: TCP
        volumeMounts:
          - name: elasticsearch-persistent-storage
            mountPath: /usr/share/elasticsearch/data
        env:
          - name: cluster.name
            value: k8s-logs
          - name: node.name
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: discovery.seed_hosts
            value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
          - name: cluster.initial_master_nodes
            value: "es-cluster-0,es-cluster-1,es-cluster-2"
          - name: ES_JAVA_OPTS
            value: "-Xms512m -Xmx512m"
      initContainers:
      - name: fix-permissions
        image: busybox
        command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
        securityContext:
          privileged: true
        volumeMounts:
        - name: elasticsearch-persistent-storage
          mountPath: /usr/share/elasticsearch/data
      - name: increase-vm-max-map
        image: busybox
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
      - name: increase-fd-ulimit
        image: busybox
        command: ["sh", "-c", "ulimit -n 65536"]
        securityContext:
          privileged: true
  volumeClaimTemplates:
    - metadata:
        name: elasticsearch-persistent-storage
        labels:
          app: elasticsearch
      spec:
        accessModes: [ "ReadWriteOnce" ]
        storageClassName: elasticsearch-storageclass
        resources:
          requests:
            storage: 20Gi

问题是:如何使用Deployment Kind的POD访问此STS?假设使用此Redis POD:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-ws-app
  labels:
    app: redis-ws-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis-ws-app
  template:
    metadata:
      labels:
        app: redis-ws-app
    spec:
      containers:
      - name: redis-ws-app
        image: redis:latest
        command: [ "redis-server"]
        ports:
        - containerPort: 6379

我一直在尝试创建另一个服务,这将使我能够从外部访问它,但是没有运气:

kind: Service
apiVersion: v1
metadata:
  name: elasticsearch-tcp
  namespace: elasticsearch-namespace
  labels:
    app: elasticsearch
spec:
  selector:
    app: elasticsearch
  ports:
  - protocol: TCP
    port: 9200
    targetPort: 9200

2 个答案:

答案 0 :(得分:1)

您将直接到达无头服务。例如,这个StatefulSet和这个Service

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 4
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web

---

kind: Service
apiVersion: v1
metadata:
  name: nginx-headless
spec:
  selector:
    app: nginx
  clusterIP: None
  ports:
    - port: 80
      name: http

我可以通过集群中任何吊舱的无头服务到达有状态集的吊舱:

/ # curl -I nginx-headless
HTTP/1.1 200 OK
Server: nginx/1.19.0
Date: Tue, 09 Jun 2020 12:36:47 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 26 May 2020 15:00:20 GMT
Connection: keep-alive
ETag: "5ecd2f04-264"
Accept-Ranges: bytes

无头服务的奇异之处在于,它没有为该服务创建iptable规则。因此,当您查询该服务时,它将转到kube-dns(或CoreDNS),并返回后端,而不是IP地址就是服务本身。因此,例如,如果您执行nslookup,它将返回该服务的所有后端(荚):

/ # nslookup nginx-headless

Name:      nginx-headless
Address 1: 10.56.1.44
Address 2: 10.56.1.45
Address 3: 10.56.1.46
Address 4: 10.56.1.47

并且不会为其分配任何iptable规则:

$ sudo iptables-save | grep -i nginx-headless
$

与普通服务不同,它将返回服务本身的IP地址:

/ # nslookup nginx

Name:      nginx
Address 1: 10.60.15.30 nginx.default.svc.cluster.local

它将为其分配iptable条规则:

$ sudo iptables-save | grep -i nginx
-A KUBE-SERVICES ! -s 10.56.0.0/14 -d 10.60.15.30/32 -p tcp -m comment --comment "default/nginx: cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.60.15.30/32 -p tcp -m comment --comment "default/nginx: cluster IP" -m tcp --dport 80 -j KUBE-SVC-4N57TFCL4MD7ZTDA

答案 1 :(得分:0)

@suren用户对无头服务是正确的。就我而言,我只是使用了错误的引用。

The Kube-DNS naming convention is 
service.namespace.svc.cluster-domain.tld 
and the default cluster domain is cluster.local

在我的情况下,要到达豆荚,必须使用:

curl -I elasticsearch.elasticsearch-namespace