Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

k8s通过service访问pod(五)--技术流ken

技术流ken 2019-02-17 09:44:00 阅读数:262 评论数:0 点赞数:0 收藏数:0

 

service

 

每个 Pod 都有自己的 IP 地址。当 controller 用新 Pod 替代发生故障的 Pod 时,新 Pod 会分配到新的 IP 地址。这样就产生了一个问题:

如果一组 Pod 对外提供服务(比如 HTTP),它们的 IP 很有可能发生变化,那么客户端如何找到并访问这个服务呢?

Kubernetes 给出的解决方案是 Service。

 

创建 Service

 

Kubernetes Service 从逻辑上代表了一组 Pod,具体是哪些 Pod 则是由 label 来挑选。Service 有自己 IP,而且这个 IP 是不变的。客户端只需要访问 Service 的 IP,Kubernetes 则负责建立和维护 Service 与 Pod 的映射关系。无论后端 Pod 如何变化,对客户端不会有任何影响,因为 Service 没有变。

 

第一步:创建下面的这个 Deployment:

查看支持的apiversion使用命令kubectl api-versions

 

第二步:部署并查看pod

我们启动了三个 Pod,运行 httpd镜像,label是 run: httpd,Service将会用这个 label来挑选 Pod。[root@ken ~]/# kubectl apply -f httpd.yml deployment.apps/httpd created [root@ken~]/# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES httpd-8c6c4bd9b-ljvlb 1/1 Running 0 41s 10.244.1.27 host1 httpd-8c6c4bd9b-ngxqv 1/1 Running 0 41s 10.244.1.28 host1 httpd-8c6c4bd9b-wxblj 1/1 Running 0 41s 10.244.2.18 host2

 

第三步:集群内部测试连通性

Pod 分配了各自的 IP,这些 IP 只能被 Kubernetes Cluster 中的容器和节点访问。[root@ken ~]/# curl 10.244.1.28

It works!

[root@ken~]/# curl 10.244.1.27

It works!

[root@ken~]/# curl 10.244.2.18

It works!

 

第四步:接下来创建 Service,其配置文件如下:

① v1 是 Service 的 apiVersion。

② 指明当前资源的类型为 Service。

③ Service 的名字为 httpd-svc。

④ selector 指明挑选那些 label 为 run: httpd 的 Pod 作为 Service 的后端。

⑤ 将 Service 的 8080 端口映射到 Pod 的 80 端口,使用 TCP 协议。

 

 

第五步: 执行 kubectl apply 创建 Service httpd-svc。[root@ken ~]/# kubectl apply -f service.yml service/httpd-svc created [root@ken~]/# kubectl getservice NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-svc ClusterIP 10.106.64.97 8080/TCP 17s kubernetes ClusterIP10.96.0.1 443/TCP 11h

 

httpd-svc 分配到一个 CLUSTER-IP 10.106.64.97。可以通过该 IP 访问后端的 httpd Pod。[root@ken ~]/# curl 10.106.64.97:8080

It works!

根据前面的端口映射,这里要使用 8080 端口。另外,除了我们创建的 httpd-svc,还有一个 Service kubernetes,Cluster内部通过这个 Service访问 kubernetes API Server。

 

通过 kubectl describe 可以查看 httpd-svc与 Pod的对应关系。[root@ken ~]/# kubectl describe service httpd-svc Name: httpd-svc Namespace:defaultLabels:Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"httpd-svc","namespace":"default"},"spec":{"ports":[{"port":8080,"... Selector: run=httpd Type: ClusterIP IP:10.106.64.97Port: 8080/TCP TargetPort:80/TCP Endpoints:10.244.1.27:80,10.244.1.28:80,10.244.2.18:80Session Affinity: None Events:

Endpoints 罗列了三个 Pod 的 IP 和端口。

 

DNS访问service

 

在 Cluster 中,除了可以通过 Cluster IP 访问 Service,Kubernetes 还提供了更为方便的 DNS 访问。

 

第一步:查看coredns

kubeadm 部署时会默认安装 coredns 组件。[root@ken ~]/# kubectl get deployment --namespace=kube-system NAME READY UP-TO-DATE AVAILABLE AGE coredns2/2 2 2 11h

 

coredns 是一个 DNS 服务器。每当有新的 Service 被创建,coredns 会添加该 Service 的 DNS 记录。Cluster 中的 Pod 可以通过 NAME>.NAME> 访问 Service。

 

第二步:dns访问

比如可以用 httpd-svc.default 访问 Service httpd-svc。[root@ken ~]/# kubectl run busybox --rm -it --image=busybox /bin/sh/ /# wget httpd-svc:8080Connecting to httpd-svc:8080 (10.106.64.97:8080) index.html100% |/*/*/*/*/*/*/*/*/*/*/*/*/*| 45 0:00:00ETA//# ls bin home root usr dev index.html sysvaretc proc tmp//# cat index.html

It works!

由于这个 Pod 与 httpd-svc同属于 default namespace,可以省略 default直接用 httpd-svc访问 Service。

 

第三步:查看namespace

如果要访问其他 namespace 中的 Service,就必须带上 namesapce了。kubectl get namespace查看已有的 namespace。[root@ken ~]/# kubectl get namespaceNAME STATUS AGEdefaultActive 11h kube-publicActive 11h kube-system Active 11h

 

第四步:在 kube-public 中部署 Service httpd2-svc

配置如下:

 

 第五步:创建资源

通过 namespace: kube-public 指定资源所属的 namespace。多个资源可以在一个 YAML文件中定义,用 ---分割。执行 kubectl apply创建资源:[root@ken ~]/# kubectl apply -f service.yml deployment.apps/httpd2 created service/httpd2-svc created

 

第六步:查看 kube-public 的 Service:[root@ken ~]/# kubectl get service --namespace=kube-publicNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd2-svc ClusterIP 10.111.175.138 8080/TCP 63s

 

第七步:在 busybox Pod 中访问 httpd2-svc:[root@ken ~]/# kubectl run busybox --rm -it --image=busybox /bin/sh/ /# wget httpd2-svc:8080wget: bad address'httpd2-svc:8080' / /# wget httpd2-svc.kube-public:8080Connecting to httpd2-svc.kube-public:8080 (10.111.175.138:8080) index.html100% |/*/*/*/*/*/*/*/*/*/*/*/*/*| 45 0:00:00 ETA

因为属于不同的 namespace,必须使用 httpd2-svc.kube-public才能访问到。

 

外网访问service

 

除了 Cluster 内部可以访问 Service,很多情况我们也希望应用的 Service能够暴露给 Cluster外部。Kubernetes提供了多种类型的 Service,默认是 ClusterIP。

 

ClusterIP

Service 通过 Cluster内部的 IP对外提供服务,只有 Cluster内的节点和 Pod可访问,这是默认的 Service类型,前面实验中的 Service都是 ClusterIP。

 

NodePort

Service 通过 Cluster节点的静态端口对外提供服务。Cluster外部可以通过 :访问 Service。

 

LoadBalancer

Service 利用 cloud provider特有的 load balancer对外提供服务,cloud provider负责将 load balancer的流量导向 Service。目前支持的 cloud provider有 GCP、AWS、Azur等。

 

第一步:实践 NodePort,Service httpd-svc的配置文件修改如下:

添加 type: NodePort,重新创建 httpd-svc。

 

第二步:创建service[root@ken ~]/# kubectl apply -f service.yml service/httpd-svc created [root@ken~]/# kubectl get service httpd-svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-svc NodePort 10.108.118.202 8080:31785/TCP 12s

Kubernetes 依然会为 httpd-svc 分配一个 ClusterIP,不同的是:

EXTERNAL-IP 为 nodes,表示可通过 Cluster 每个节点自身的 IP 访问 Service。

PORT(S) 为 8080:31785。8080 是 ClusterIP 监听的端口(每个节点都有该端口),31785 则是节点上监听的端口。Kubernetes 会从 30000-32767 中分配一个可用的端口,每个节点都会监听此端口并将请求转发给 Service。[root@ken ~]/# ss -tnl | grep 31785LISTEN0 128 :::31785 :::/*

 

第三步:测试nodeport是否正常工作[root@ken ~]/# curl 172.20.10.2:31785

It works!

[root@ken~]/# curl 172.20.10.7:31785

It works!

[root@ken~]/# curl 172.20.10.9:31785

It works!

通过三个节点 IP + 32312 端口都能够访问 httpd-svc。

 

第四步:指定特定端口

NodePort 默认是的随机选择,不过我们可以用 

nodePort 指定某个特定端口。

现在配置文件中就有三个 Port 了:

nodePort 是节点上监听的端口。

port 是 ClusterIP上监听的端口。

targetPort 是 Pod监听的端口。

 

最终,Node 和 ClusterIP在各自端口上接收到的请求都会通过 iptables转发到 Pod的 targetPort。

 

第四步:应用新的 nodePort 并验证:[root@ken ~]/# kubectl apply -f service.yml service/httpd-svc configured [root@ken~]/# kubectl get service httpd-svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-svc NodePort 10.108.118.202 8080:30000/TCP 6m8s [root@ken~]/# curl 172.20.10.2:30000

It works!

[root@ken~]/# curl 172.20.10.7:30000

It works!

[root@ken~]/# curl 172.20.10.9:30000

It works!

nodePort: 30000 已经生效了。

版权声明
本文为[技术流ken]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/kenken2018/p/10335998.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领