Service是k8s的核心,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并将请求进行负载分发到各个容器应用上。
目录:
Service定义详解
Service基本用法
集群外部访问Pod和Service
一、Service定义详解
Service的定义比Pod简单。
apiVersion: v1 kind: Service metadata: name: string labels: name: string annotations: name: string spec: type: string selector: name: string clusterIP: string #虚拟服务ip,缺省默认分配 sessionAffinity: string #是否支持session,可选值为ClientIP,表示同一个客户端 ports: - name: string protocol: string #端口协议,支持TCP、UDP,默认是TCP port: int #宿主机端口 targetPort: int #目标Pod的端口 nodePort: int #k8s内部端口 status: loadBalancer: ingress: ip: string hostname: string
上述定义中的spec.type有两个选项:
当为NodePort时,需要配置nodePort映射到指定端口
当为LoadBalancer,需要在status中设置外部负载均衡器
二、Service基本用法
(1)通过yaml文件创建:
apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort selector: name: nginx-pod ports: - name: nginx-service port: 80 targetPort: 80 nodePort: 30080
比如上述,定义了一个Service,对应的是具有key=name,value=nginx-pod这个标签的Pod,type定义为NodePort,宿主机端口为80,对应Pod端口为80,而nodePort为30080
通过如下命令创建Service
kubectl create -f service-name.yaml
创建之后查看:
可看到Service被分配的ip,对应的port以及选择的标签信息
(2)负载均衡
目前k8s提供了两种负载均衡策略:RoundRobin和SessionAffinity
1、RoundRobin:轮询模式
2、SessionAffinity:基于客户端IP地址进行会话保持模式,请求第一次到哪个Pod,则后续还会继续转发到那个Pod。
默认情况下,采用轮询模式,但也可以 通过设置spec.sessionAffinity设置为ClientIP启用SessionAffinity策略
接下来验证一下默认的轮询模式:
创建两个具有key=name,value=nginx-pod标签的Pod,容器内运行nginx。
nginx-one:
apiVersion: v1 kind: Pod metadata: name: nginx-pod1 labels: name: nginx-pod spec: containers: - name: nginx-pod1 image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80
nginx-two:
apiVersion: v1 kind: Pod metadata: name: nginx-pod2 labels: name: nginx-pod spec: containers: - name: nginx-pod2 image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80
创建完两个容器之后,分别进入两个容器修改nginx首页的字样。
进入容器:
kubectl exec -it nginx-pod1 /bin/bash
找到文件并进行修改,此处需要注意的是,由nginx镜像创建的容器并不具有vim和vi这两个编辑工具,所以这边使用sed或echo都行
sed命令替换字符串格式是:
sed -i 's/需要被替换字符串/替换后字符串/g' file-name sed -i 's/Welcome to nginx!/Welcome to nginx-pod two!/g' /usr/share/nginx/html/index.html
修改好后在浏览器访问:使用ip:nodePort访问
可以看到,service进行了负载均衡处理。
三、集群外部访问Pod和Service
(1)将Pod的端口号映射到宿主机
比如将上述的nginx-pod1映射到主机的20080端口:
apiVersion: v1 kind: Pod metadata: name: nginx-pod1 labels: name: nginx-pod spec: containers: - name: nginx-pod1 image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 hostPort: 20080
然后查看此Pod在哪个节点上运行
然后在浏览器中访问此节点的20080端口:
(2)通过设置Pod级别的hostNetwork=true
该Pod的所有容器的端口号都将被直接映射到宿主机上,需要注意的是,如果不指定hostPort,则默认与containerPort一样,如果指定 ,则hostPort必须等于containerPort。
例如将上述的nginx-pod2设置hostNetwork=true
apiVersion: v1 kind: Pod metadata: name: nginx-pod2 labels: name: nginx-pod spec: hostNetwork: true containers: - name: nginx-pod2 image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80
查看pod创建后在哪个节点上
在浏览器上访问:
(3)将Service的端口号映射到宿主机上
通过设置spec.type为NodePort,同时设置spec.ports.nodePort设置宿主机上的端口号。
例如在Service基本用法那一小节的Service定义,相应的使用也在那一节有
apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort selector: name: nginx-pod ports: - name: nginx-service port: 80 targetPort: 80 nodePort: 30080
===============================
我是Liusy,一个喜欢健身的程序员。
欢迎关注微信公众号【Liusy01】,一起交流Java技术及健身,获取更多干货,领取Java进阶干货,领取最新大厂面试资料,一起成为Java大神。
来都来了,关注一波再溜呗。