# 1、Cluster IP 当创建K8s Service时,Cluster IP是默认的方式。这种Service分配了一个内部的IP,使其他组件可以访问到pod。 使用一个独立的IP地址,它可以使service负载均衡到多个pod。 service通过命令部署: ``` kubectl apply -f clusterip.yaml ``` 这个定义文件可以查看: ``` cat clusterip.yaml ``` ``` cat clusterip.yaml apiVersion: v1 kind: Service metadata: name: webapp1-clusterip-svc labels: app: webapp1-clusterip spec: ports: - port: 80 selector: app: webapp1-clusterip --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: webapp1-clusterip-deployment spec: replicas: 2 template: metadata: labels: app: webapp1-clusterip spec: containers: - name: webapp1-clusterip-pod image: katacoda/docker-http-server:latest ports: - containerPort: 80 --- ``` 这将会部署一个两个副本的web app,使用service负载均衡。pod可以使用命令查看: ``` kubectl get pods ``` 同时部署了一个service: ``` kubectl get svc ``` 更多service配置和活动的端点(Pods)的详细信息查看: ``` kubectl describe svc/webapp1-clusterip-svc ``` 部署完,可以通过分配的ClusterIp进行访问: ``` export CLUSTER_IP=$(kubectl get services/webapp1-clusterip-svc -o go-template='{{(index .spec.clusterIP)}}') echo CLUSTER_IP=$CLUSTER_IP curl $CLUSTER_IP:80 ``` 多个请求将会展示service如何在基于共同的标签选择器在多个pods之间负载均衡。 ``` curl $CLUSTER_IP:80 ``` # 2、Target Port Target Port允许我们将服务可用的端口与应用程序侦听的端口分离。TargetPort是应用程序配置要监听的端口。Port是应用程序从外部访问的端口。 查看clusterip-target.yaml ``` cat clusterip-target.yaml apiVersion: v1 kind: Service metadata: name: webapp1-clusterip-targetport-svc labels: app: webapp1-clusterip-targetport spec: ports: - port: 8080 targetPort: 80 selector: app: webapp1-clusterip-targetport --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: webapp1-clusterip-targetport-deployment spec: replicas: 2 template: metadata: labels: app: webapp1-clusterip-targetport spec: containers: - name: webapp1-clusterip-targetport-pod image: katacoda/docker-http-server:latest ports: - containerPort: 80 --- ``` 像先前一样,service和另外的pod通过命令部署: ``` kubectl apply -f clusterip-target.yaml ``` 查看service ``` kubectl get svc ``` ``` kubectl describe svc/webapp-clusterip-targetport-svc ``` 当service和pod都被部署了,可以像先前一样通过cluster IP访问,但是这次定义的port是8080。 ``` export CLUSTER_IP=$(kubectl get services/webapp1-clusterip-targetport-svc -o go-template='{{(index .spec.clusterIP)}}') echo CLUSTER_IP=$CLUSTER_IP curl $CLUSTER_IP:8080 ``` 应用程序本身仍然配置的是监听80端口。Kubernetes服务管理两者之间的转换。 # 3、NodePort TargetPort和ClusterIP是在集群内是可用的,然而Nodeport通过定义一个静态的端口在每个节点IP上暴露服务。不管集群内的哪个节点是可以访问的,service在定义的端口上就是可以访问的。 注:此时ClusterIP依然可用。 ``` kubectl apply -f nodeport.yaml ``` 当查看service定义时,注意添加的类型和NodePort属性的定义。 ``` cat nodeport.yaml apiVersion: v1 kind: Service metadata: name: webapp1-nodeport-svc labels: app: webapp1-nodeport spec: type: NodePort ports: - port: 80 nodePort: 30080 selector: app: webapp1-nodeport --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: webapp1-nodeport-deployment spec: replicas: 2 template: metadata: labels: app: webapp1-nodeport spec: containers: - name: webapp1-nodeport-pod image: katacoda/docker-http-server:latest ports: - containerPort: 80 --- ``` ``` kubectl get svc ``` ``` kubectl describe svc/webapp1-nodeport-svc ``` 这个service现在可以通过定义的NodePort的节点IP地址访问。 ``` curl 172.17.0.34:30080 ``` # 4、External IPs 另一种在集群外访问service的方式时通过External IP地址。 更新定义文件的当前集群IP地址: ``` sed -i 's/HOSTIP/172.17.0.34/g' externalip.yaml ``` 查看externalip.yaml ``` cat externalip.yaml apiVersion: v1 kind: Service metadata: name: webapp1-externalip-svc labels: app: webapp1-externalip spec: ports: - port: 80 externalIPs: - 172.17.0.34 selector: app: webapp1-externalip --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: webapp1-externalip-deployment spec: replicas: 2 template: metadata: labels: app: webapp1-externalip spec: containers: - name: webapp1-externalip-pod image: katacoda/docker-http-server:latest ports: - containerPort: 80 --- ``` ``` kubectl apply -f externalip.yaml ``` ``` kubectl get svc ``` ``` kubectl describe svc/webapp1-externalip-svc ``` 这个服务绑定到主节点的IP地址的80端口。 ``` curl 172.17.0.34 ``` # 5、Load Balancer 当在云上运行时,如EC2或Azure,可以配置和分配通过云提供商发布的公共IP地址。将会通过一个负载均衡器分发,如ELB(弹性负载均衡)。这允许将额外的公共IP地址分配给Kubernetes集群,而无需直接与云提供商交互。 虽然Katacoda不是云提供商,它仍然可以动态地为LoadBalancer类型的服务分配IP地址。部署云提供商使用: ``` kubectl appky -f cloudprovider.yaml ``` 当在云提供商部署一个service,这是不必要的。 当一个service请求一个Load Balancer时,这个提供商将会从定义好的配置10.10.0.0/26范围内分配一个。 ``` kubectl get pods -n kube-system ``` ``` kubectl apply -f loadbalancer.yaml ``` 这个service通过一个Load Balancer定义,查看: ``` cat loadbalancer.yaml apiVersion: v1 kind: Service metadata: name: webapp1-loadbalancer-svc labels: app: webapp1-loadbalancer spec: type: LoadBalancer ports: - port: 80 selector: app: webapp1-loadbalancer --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: webapp1-loadbalancer-deployment spec: replicas: 2 template: metadata: labels: app: webapp1-loadbalancer spec: containers: - name: webapp1-loadbalancer-pod image: katacoda/docker-http-server:latest ports: - containerPort: 80 --- ``` 当IP地址正在被分配,service将会Pending。当分配完,将会出现在service列表中。 ``` kubectl get svc ``` ``` kubectl describe svc/webapp1-loadbalancer-svc ``` 这个service可以通过分配的IP地址访问,这个例子中来自10.10.0.0范围。 ``` export LoadBalancerIP=$(kubectl get services/webapp1-loadbalancer-svc -o go-template='{{(index .status.loadBalancer.ingress 0).ip}}') echo LoadBalancerIP=$LoadBalancerIP curl $LoadBalancerIP ```