专栏首页Liusy01k8s重器之Service

k8s重器之Service

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

END

本文分享自微信公众号 - Liusy01(Liusy_01),作者:Liusy01

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-10-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 深入理解Pod(三)

    Pod只是容器的载体,通常需要通过RC、Deployment、DaemonSet、Job等对象来完成Pod的调度和自动控制功能。

    Liusy
  • 深入理解Pod(二)

    将应用所需的配置信息与程序进行分离,可以使应用程序更好的被复用,通过不同的配置实现更灵活的功能。如果将应用打包成镜像,再用环境变量或者外挂文件的方式挂载配置,在...

    Liusy
  • 使用k8s部署springboot+redis简单应用

    本文将使用k8s部署一个springboot+redis应用,由于是示例,所以功能比较简单,只有设置值和获取值两个api。

    Liusy
  • 手把手教你如何用飞桨自动生成二次元人物头像

    每次生成一组shape为[1,72]的随机数,更改其中某个数值,依次生成20组随机数,作为生成网络的输入,得到横向对比图片,观察GAN带来的神奇效果,如下所示。

    用户1386409
  • Kafka 中使用 Avro 序列化组件(三):Confluent Schema Registry

    无论是使用传统的Avro API自定义序列化类和反序列化类还是使用Twitter的Bijection类库实现Avro的序列化与反序列化,这两种方法都有一个缺点:...

    CoderJed
  • 用最简单的例子和最通俗的语言解释单进程和多进程

    采用网上的一个利用复制文件来检测多进程和单进程差异的例子。但是例子中许多关键的解释并未给出,反而给入门新手造成了很多不必要的困扰和门槛。

    一个有趣的灵魂W
  • Python学习(第二章)

    注;看见连接符了吗,就是那个“.”,我在第一章里提到过哦,这里详解一下,可以理解为{范围}append()这个方法是属于number的列表对象的。

    天钧
  • 从零搭建Kubernetes下的nignx和tomcat

    i 创建nfs持久化存储,持久化存储用于存储前端静态文件和pod产生日志文件。

    用户5166556
  • 【翻译】PHP面向对象的基本概念

    来源/https://www.startutorial.com/homes/oo_beginner

    Lemon黄
  • 设计匠艺 | 对象的角色

    若要获得良好的对象设计,就必须对职责进行合理的分配。每个对象承担的职责不能太多,也不能太少,恰如其分即可。职责分配如乐谱中对音符的组织,高明的音乐家总是能让不同...

    张逸

扫码关注云+社区

领取腾讯云代金券