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

①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   <none>              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   <none>        80/TCP    78s
kubernetes      ClusterIP   10.254.0.1       <none>        443/TCP   215d

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

运行:

kubectl apply -f httpd0822.yaml

生成的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

看到可以正常访问了:

# curl 10.254.177.175
<html><body><h1>It works!</h1></body></html>

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

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

# 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

不同命名空间:(下面命名空间为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

完整的DNS记录是:
. <NAMESPACE_ NAME>.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

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

重新应用:

# 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   <none>        80:31188/TCP   26h
kubernetes      ClusterIP   10.254.0.1       <none>        443/TCP        217d

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))

访问:

]# curl http://192.168.3.81:31188
<html><body><h1>It works!</h1></body></html>

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值