目录

一、部署nginx容器

二、部署tomcat服务

三、使用nginx代理tomcat服务

四、测试


服务发现简介:

1、service是用于K8S的服务发现的重要组件,pod作为运行业务的承载方式,要想被客户端访问或者集群内部其它服务访问,就需要提供一个访问入口;


 2、传统来说ip+端口是普适的访问方式,但是pod是一种动态的资源,它会因故障被重建或重启,因而pod ip会发生变化,所以使用ip作为pod的访问入口并不合适;而K8S是通过service来充当pod与访问端的中间代理,要访问pod首先访问pod对应的service,再由service代理到对应的pod


3、而pod采用了标签来代替ip作为唯一标识,以供service筛选。service对应的也有标签选择器用来筛选pod标签


4、 而service本身是ipvs规则,是由kube-porxy组件生成的,这个规则只要不删除就会一直存在,但是删除了service ip也会发生变化,这样一来客户端仍有无法访问到service ip的风险


 5、因此K8S使用了DNS来记录service ip和service域名的记录,客户端使用域名就可以通过DNS中拿到对应的service ip了,而当service ip发生变化时,DNS也会动态的即使跟新到记录表中,这样即使service ip发生改变,仍然可以通过service的域名拿到对应的service ip,有了service ip就可以访问到Service 而后service代理到对应的pod上

service类型:(主要用两种)

    1、clusterIP:

        2、NodePort:  可以接入集群外部流量,在每个node节点监听一个和service定义的相同的端口,用于客户端的访问,把请求转发到对应的service,然后service再转发给pod; 用于将K8S服务暴露给K8S以外的客户端访问

注:serviceIP=clusterIP

NodePort 访问流程如下:

cluster_IP+端口-------->pod_IP+端口

上面的访问流程可以看出NodePort类型还是需要借助clusterIP才能把集群外的访问引入到集群内

3、何为无头服务?

service的不同模式都是在上一种模式的基础上增强版,nodePort就是在clusterIP的基础上新增了功能,并不是一种新的功能模式,因为nodePort模式下客户端访问过程中还是要经过clusterIP的,这意味着clusterIP是service最基本要件,但也可以把这个clusterIP移除掉,而一旦No cluster,就称为无头服务了,无头服务的主要作用在于可以把服务名称(service_name)直接解析到后端的podIP;而本来只能解析到serviceIP
 

NodePort 示例:

部署nginx和tomcat这两个前后端服务pod,通过NodePort类型service 相互调用

一、部署nginx容器

1、编写yaml文件

root@k8s-deploy:~# vim nginx.yaml
kind: Deployment
apiVersion: apps/v1       #可查询它的api版本 kubectl explain deployment.apiVersion
metadata:               #定义pod元数据信息,可查询它的下级子字段kubectl explain deployment.metadata
  labels:               #定义deployment控制器标签
    app: nginx-deployment-label  #标签名称以键值形式定义,可以定义多个,这里标签是app值为nginx-deployment-label
  name: nginx-deployment   #deployment资源的名字
  namespace: myserver          #deployment所属的namespace,默认是defaule
spec:                   #定义Deployment中容器的详细信息,可通过kubectl explain deployment.spec查询
  replicas: 1           #定义创建出pod的副本数,默认值是1个pod
  selector:             #定义标签选择器,它跟上面的Deployment标签不是一回事,它是找下面template中定义的labels标签
    matchLabels:        #定义匹配的标签,必须要设置
      app: nginx-selector       #匹配的目标标签,控制器会拿这个标签匹配下面的pod
  template:             #定义模板,用来描述需要创建的pod作用
    metadata:           #定义模板元数据
      labels:             #这个labels会继承给这个yaml文件Deployment控制器创建的所有pod
        app: nginx-selector   #这个labels的key是app,值是nginx-selector,它会继承给下面的pod,和上面matchLabels.app: nginx-selector一样
    spec:                  #定义pod的详细信息
      containers:          #定义pod中容器列表,可以定义多个pod
      - name: nginx-container     #容器名称
        image: nginx:1.20       #容器镜像
        imagePullPolicy: Always                       #镜像拉取策略
        ports:                    #定义容器端口列表
        - containerPort: 80     #定义一个端口
          protocol: TCP           #定义协议
          name: http              #端口名称
        - containerPort: 443
          protocol: TCP
          name: https
        env:                      #给容器传递环境变量
        - name: "password"        #变量名称,必须引号引起来
          value: "123"            #上面变量的值
        - name: "age"
          value: "18"
---

kind: Service
apiVersion: v1
metadata:
  name: nginx-service
  labels:
    app: nginx-service-label   #service资源的标签
  namespace: myserver          #所在的命名空间,与上面控制器必须在同一个命名空间
spec:
  type: NodePort          #service类型是NodePort  
  ports:                  #定义访问端口,一个service可以定义多个端口的映射关系
  - name: http            #定义协议名称
    port: 80              #定义service端口,它可以和pod,node端口都不同,它是K8S中一个独立子网
    protocol: TCP         #定义类型
    targetPort: 80        #目标pod端口,当访问宿主机30004端口时就会转达到pod的80端口
    nodePort: 30004       #手动指定node节点暴露的端口,如果没有指定端口,那service会随机分配一个端口
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
    nodePort: 30443
  selector:
    app: nginx-selector   #这个标签就是上面pod的标签,service通过这个标签来匹配对应的pod

2、创建资源

创建资源
# kubectl apply -f nginx.yaml

查看nginx pod已经启动
root@k8s-deploy:~# kubectl get pod -A | grep nginx
myserver               nginx-deployment-766fc9dfdd-f488k            1/1     Running   0               8m11s

查看nginx-service已经创建
root@k8s-deploy:~# kubectl get svc -A | grep nginx-service
default                nginx-service               NodePort    10.100.57.113   <none>        80:30004/TCP,443:30443/TCP   2m11s

3、访问node节点的http协议的30004端口

因为service中定义了nodePort规则,因此要访问nginx容器的80端口,直接访问任意node节点的30004端口即可转发到nginx容器的80端口

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_nginx

二、部署tomcat服务

1、编写yaml文件

root@k8s-deploy:~# vim tomcat.yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: tomcat-deployment
  namespace: myserver
  labels:
    app: tomcat-deployment-label
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat-selector
  template:
    metadata:
      labels:
        app: tomcat-selector
    spec:
      containers:
      - name: tomcat-container
        image: tomcat:7.0.109-jdk8-openjdk
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123"
        - name: "age"
          value: "18"

---
kind: Service
apiVersion: v1
metadata:
  name: tomcat-serivce
  namespace: myserver
  labels:
    app: tomcat-service-label
spec:
  type: NodePort  #service有四种类型,默认是cluser ip
  ports:
  - name: http
    port: 80
    protocol: TCP
    nodePort: 30005
    targetPort: 8080
  selector:
    app: tomcat-selector

2、创建资源

root@k8s-deploy:~# kubectl apply -f tomcat.yaml

3、访问tomcat

可以访问下node节点的30005端口,报404是因为还没有页面,下面进入tomcat容器中手动创建一个页面

root@k8s-deploy:~# kubectl get pod -A | grep tomcat
myserver               tomcat-deployment-5576d59694-rv2sb           1/1     Running   0             7m16s

进入容器
root@k8s-deploy:~# kubectl exec -it nginx-deployment-7d7bd78b5c-v9mjs bash -n myserver
root@tomcat-deployment-5576d59694-rv2sb:/usr/local/tomcat# cd webapps
root@tomcat-deployment-5576d59694-rv2sb:/usr/local/tomcat/webapps# mkdir myapp
root@tomcat-deployment-5576d59694-rv2sb:/usr/local/tomcat/webapps# echo "myapp web magedu n70" > myapp/index.jsp

而后再来访问这个页面就有内容了,说明现在tomcat服务是正常的

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_tomcat_02

三、使用nginx代理tomcat服务

这个tomcat端口其实不是必须要暴露的,测试完后,我这里再把它注释掉,去掉之后就没有nodeport了,就是仅在K8S内部的一个cluser ip了 ,仅能在K8S内部访问,下面用nginx代理tomcat服务,实现在K8S内部两个服务之间通过service相互转发

 1、注释

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_kubernetes_03

2、 注释后再执行下apply,可以看见tomcat-deployment是不变的,tomcat-serivce配置了

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_容器_04

3、 查看tomcat service的名称,下面配置nginx代理tomcat文件要用

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_容器_05

4、修改nginx容器的配置文件

下面用nginx作为代理访问tomcat,进入nginx容器中进行配置

root@k8s-deploy:~# kubectl get pod -A | grep nginx
myserver               nginx-deployment-766fc9dfdd-f488k            1/1     Running   0               8m11s

进入nginx容器
root@k8s-deploy:~# kubectl exec -it nginx-deployment-766fc9dfdd-f488k bash -n myserver
root@nginx-deployment-766fc9dfdd-f488k:/etc/nginx# vim conf.d/default.conf

 修改nginx容器的配置文件/etc/nginx/conf.d/default.conf  (这是在nginx容器里配置的,配置如下图),添加完配置后nginx -s reload重置下再curl访问

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_nginx_06

 全路径访问如下:

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_运维_07

这里cluster.local是当时创建集群时候在hosts文件里定义的

可以看下当时定义的K8S集群域名

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_容器_05

四、测试

访问nginx的30004端口,就可以代理到tomcat服务了

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_nginx_09

 可以看下nginx的日志,每当请求/myapp/index.jsp文件就由nginx通过tomcat service转发给tomcat  service后面的pod了

root@k8s-deploy:~# kubectl logs -f nginx-deployment-766fc9dfdd-nq4ck -n myserver
10.200.166.128 - - [18/Nov/2022:07:50:45 +0000] "GET /myapp/ HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-"
10.200.166.128 - - [18/Nov/2022:07:50:53 +0000] "GET /myapp/index.jsp HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-"
10.200.166.128 - - [18/Nov/2022:07:52:09 +0000] "GET /myapp/index.jsp HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-"
10.200.166.128 - - [18/Nov/2022:07:52:10 +0000] "GET /myapp/index.jsp HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-"

注意:

上面使用curl访问的是tomcat-service,是因为nginx和tomcat都在同一个namesapce中,所以可以之间访问名称简写

如果不在一个namespace中需要名字全称,如果不在一个namespace就需要把nginx容器里的配置文件修改  ,其中80端口可以不写,因为这里调用的是service,而tomcat service的端口定义的就是80

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_tomcat_10

 因为在tomcat.yaml文件中定义的service 端口是80,所以在nignx配置文件中调用这个端口,这个80端口会转给pod的8080端口

总结:

客户端访问node节点的30004端口,而后转发到nginx-service, 如果nginx-pod是多副本的,再由nginx-service根据算法转发给某个nginx-pod;  然后nginx-pod把请求转发给tomcat-service,最后再由tomcat-service根据算法转发给tomcat-pod进行处理

kubernetes调用apiclient强制删除pod kubernetes pod之间调用_tomcat_11