• k8s快速入门教程-----5 Service


    上一篇: 4 工作负载控制器之deployment

    5.1 概述

    我们不应该期望Kubernetes Pod是健壮的,而是要假设Pod 中的容器很可能因为各种原因发生故障而死掉。Deployment 等Controller 会通过动态创建和销毁Pod来保证应用整体的健壮性。换句话说,Pod是脆弱的,但应用是健壮的。每个Pod都有自己的IP地址。当Controller 用新Pod 替代发生故障的Pod 时,新Pod会分配到新的IP地址。这样就产生了一个问题:如果一组Pod对外提供服务(比如HTTP),它们的IP很有可能发生变化,那么客户
    端如何找到并访问这个服务呢?
    Kubernetes给出的解决方案是Service。Service服务也是Kubernetes里的核心资源对象之一。

    5.2 创建service

    下面动手创建一个Service来加深对它的理解。创建一 个名为http0822-svc.yaml的定义文件,内容如下:

    kind: Service     #  ②
    apiVersion: v1    # ①
    metadata:
      name: httpd0822-svc
    spec:
      ports:  # ⑤
        - name: http-80
          protocol: TCP
          port: 80
          targetPort: 80
      selector:  # ④
        app: httpd0822
      type: ClusterIP
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ①v1是Service 的apiVersion。
    ②指明当前资源的类型为Service。
    ③Service 的名字为httpd-svc.
    ④selector 指明挑选那些label 为run: httpd的Pod作为Service 的后端。
    ⑤将Service 的80 端口映射到Pod的80端口,使用TCP协议。
    应用执行并显示:

    kubectl apply -f http0822-svc.yaml
    
    # kubectl get ep
    NAME            ENDPOINTS           AGE
    httpd0822-svc   >              2s
    kubernetes      192.168.3.81:6443   215d
    # kubectl get svc
    NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    httpd0822-svc   ClusterIP   10.254.177.175   >        80/TCP    78s
    kubernetes      ClusterIP   10.254.0.1       >        443/TCP   215d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ENDPOINTS显示none,是由于没有匹配的标签,没有对应的Pod, 而且直接访问curl 10.254.177.175无法访问。
    创建一个deployment,写service对应Pod的标签。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpd0822
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: httpd0822
      template:
        metadata:
          labels:
            app: httpd0822
        spec:
          containers:
          - image: httpd
            name: httpd0822
          restartPolicy: Always
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行:

    kubectl apply -f httpd0822.yaml
    
    • 1

    生成的pod及看到endpoint有对应的IP地址:

    # kubectl get pod    
    NAME                         READY   STATUS    RESTARTS   AGE
    httpd0822-7dc59d86f6-44qpr   1/1     Running   0          66s
    httpd0822-7dc59d86f6-lttv7   1/1     Running   0          66s
    httpd0822-7dc59d86f6-vwcxc   1/1     Running   0          66s
    
    # kubectl get ep
    NAME            ENDPOINTS                                       AGE
    httpd0822-svc   10.255.30.0:80,10.255.30.3:80,10.255.30.40:80   110m
    kubernetes      192.168.3.81:6443                               216d
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    看到可以正常访问了:

    # curl 10.254.177.175
    >>>It works!>>
    
    • 1
    • 2

    5.3 DNS 访问service

    在Cluster中,除了可以通过Cluster IP访问Service, Kubernetes 还提供了更为方便的DNS访问。kubeadm部署时会默认安装coredns 组件,如下所示:

    # kubectl get deploy -n kube-system   
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    calico-kube-controllers   1/1     1            1           33d
    coredns                   2/2     2            2           33d
    
    • 1
    • 2
    • 3
    • 4

    kube-dns是一个DNS服务器。每当有新的Service 被创建,coredns会添加该Service的 DNS。 Cluster的 Pod 可以通过 . 访问 Service,同命名空间可以省去
    同命名空间:

    # kubectl exec -it busybox0822 -- sh
    # nslookup httpd0822-svc
    Server:    10.254.0.10
    Address 1: 10.254.0.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      httpd0822-svc
    Address 1: 10.254.177.175 httpd0822-svc.default.svc.cluster.local
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    不同命名空间:(下面命名空间为default访问命令空间test的svc)

    # kubectl exec -it busybox0822 -- sh
    / # nslookup httpd0823-svc
    Server:    10.254.0.10
    Address 1: 10.254.0.10 kube-dns.kube-system.svc.cluster.local
    
    nslookup: can't resolve 'httpd0823-svc'
    / # nslookup httpd0823-svc.test
    Server:    10.254.0.10
    Address 1: 10.254.0.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      httpd0823-svc.test
    Address 1: 10.254.80.55 httpd0823-svc.test.svc.cluster.local
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    完整的DNS记录是:
    . .svc.cluster.local

    # nslookup httpd0823-svc.test.svc.cluster.local
    Server:    10.254.0.10
    Address 1: 10.254.0.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      httpd0823-svc.test.svc.cluster.local
    Address 1: 10.254.80.55 httpd0823-svc.test.svc.cluster.local
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.4 外网Service

    Kubernetes 提供了多种类型的Service, 默认是ClusterIP。
    (1) ClusterIP
    Service通过Cluster内部的IP对外提供服务,只有cluster内的节点和pod可访问,这是默认的Service 类型,前面实验中的Service 都是ClusterIP。
    (2) NodePort
    Service 通过cluster节点的静态端口对外提供服务。Cluster外部可以通过:访问service。
    通过Cluster节点的静态端口对外提供服务。Cluster外部可以通过
    : ìj [i] Service.
    修改httpd0822-svc成NodePort

    kind: Service     #  ②
    apiVersion: v1    # ①
    metadata:
      name: httpd0822-svc
    spec:
      ports:  # ⑤
        - name: http-80
          protocol: TCP
          port: 80
          targetPort: 80
      selector:  # ④
        app: httpd0822
      type: NodePort
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    重新应用:

    # kubectl apply -f http0822-svc.yaml    
    service/httpd0823-svc configured
    # kubectl get svc
    NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
    httpd0822-svc   NodePort    10.254.177.175   >        80:31188/TCP   26h
    kubernetes      ClusterIP   10.254.0.1       >        443/TCP        217d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Kubernetes依然会为httpd-svc 分配-一个ClusterIP, 不同的是:
    (1) EXTERNAL-IP为nodes, 表示可通过Cluster 每个节点自身的IP访问Service。
    (2) PORT(S)为80:31188。 80 是ClusterIP 监听的端口,31188 则是节点上监听的端口。Kubernetes 会从30000 ~ 32767中分配-一个可用的端口,每个节点都会监听此端口并将请求转发给Service, 如下所示:

    # ss -lpnt | grep 31188
    LISTEN     0      4096         *:31188                    *:*                   users:(("kube-proxy",pid=2871,fd=10))
    
    • 1
    • 2

    访问:

    ]# curl http://192.168.3.81:31188
    >>>It works!>>
    
    • 1
    • 2

    5.5 CKA题分析

    题目:请重新配置现有的部署front-end以及添加名为http的端口规范来公开现有容器nginx 的端口80/tcp。
    创建一个名为front-end-svc的新服务,以公开容器端口http。
    配置此服务,以通过在排定的节点上的NodePort来公开各个Pods

    kubectl create deployment --image=nginx --port=80 front-end
    kubectl edit deployment front-end修改port的名字
    .....
     spec:
          containers:
          - image: nginx
            imagePullPolicy: Always
            name: nginx
            ports:
            - containerPort: 80
              name: http
              protocol: TCP
    .......
    kubectl expose deployment front-end --port=80 --target-port=80 --type="NodePort" --name=front-end-svc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    Ubuntu16.04 完整版 Gym 安装及说明
    黑马瑞吉外卖项目开发笔记
    nacos集群部署
    SCM供应链具体有哪些优越性?智能供应链管理系统助力汽车服务企业数字化转型
    【Python】探索 One-Class SVM:异常检测的利器
    基于STM32两轮自平衡小车系统设计与控制
    太阳能发电与蓄电池研究(Matlab代码实现)
    BIO、NIO、AIO三者的区别及其应用场景(结合生活例子,简单易懂)
    图解kd树+Python实现
    多线程之基础篇(一)
  • 原文地址:https://blog.csdn.net/cloud_engineer/article/details/126538713