程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • 容器部署 - Docker

  • 持续集成 - Jenkins

  • 容器管理 - kubernetes

    • Kubernetes - 介绍
    • Kubernetes - 集群架构与组件
    • Kubernetes - 核心概念与专业术语
    • Kubernetes - 安装
    • Kubernetes - 深入 Pod
    • Kubernetes - 资源调度
    • Kubernetes - 服务发布
      • Service
        • 常用类型
        • Service 的定义
        • 代理 k8s 外部服务(IP)
        • 代理 k8s 外部服务(域名)
      • Ingress
        • 安装 ingress-nginx
        • 基本使用
    • Kubernetes - 配置与存储
    • Kubernetes - 高级调度
    • Kubernetes - 认证与权限
    • Kubernetes - Helm
    • Kubernetes - 集群监控
    • Kubernetes - ELK 日志管理
    • Kubernetes - 可视化界面
    • Kubernetes - DevOps
  • 运维工具
  • 容器管理 - kubernetes
scholar
2023-06-20
目录

Kubernetes - 服务发布

  • Service
    • 常用类型
    • Service 的定义
    • 代理 k8s 外部服务(IP)
    • 代理 k8s 外部服务(域名)
  • Ingress
    • 安装 ingress-nginx
    • 基本使用

# Service

负责东西流量(同层级/内部服务网络通信)的通信。

image-20230618225953699

Service 工作远程如下:

我们访问一个容器,首先经过 master 的 api-server,然后 api-service 找到容器所在的 Pod 对应的 Service,这个 Service 在创建的时候以及通过选择器 Selector 找到对应的 Pod。Service 找到 Endpoint,Endpoint 找到目标 Pod 的 kube-proxy,然后 kube-proxy 找到容器。

一个 Endpoint 随着一个 Service 创建而创建(前提是 Service 创建的时候添加了选择器 Selector),Serivce 创建后通过选择器 Selector 找到 Pod,然后把 Pod 的 IP、Port 告诉 Endpoint。

如下图,k8s-node1 的一个容器 IP 是 10.244.36.107,Port 是 80;k8s-node2 的一个容器 IP 是 10.244.36.107,Port 是 80,且 app 都是 nginx-deploy,被 Service 的选择器匹配,所以 IP 和 Port 都交给 Endpoint 管理,外界请求的时候,Service 就去找 Endpoint,Endpoint 根据 IP + Prot 找 kube-proxy,从而找到容器。

image-20230620235954118

# 常用类型

Serivce 有如下类型可以选择配置:

  • ClusterIP:只能在集群内部使用,不配置类型的话默认就是 ClusterIP

  • ExternalName:返回定义的 CNAME 别名,可以配置为域名

  • NodePort:会在所有安装了 kube-proxy 的节点都绑定一个端口,此端口可以代理至对应的 Pod,集群外部可以使用任意节点 IP + NodePort 的端口号访问到集群中对应 Pod 中的服务

    当类型设置为 NodePort 后,可以在 ports 配置中增加 nodePort 配置指定端口,需要在下方的端口范围内,如果不指定会随机指定端口,端口范围:30000 ~ 32767。端口范围配置在 /usr/lib/systemd/system/kube-apiserver.service 文件中

  • LoadBalancer:使用云服务商(阿里云、腾讯云等)提供的负载均衡器服务

# Service 的定义

yaml Demo 文件:

apiVersion: v1
kind: Service # 资源类型为 Service
metadata:
  name: nginx-svc # Service 名字
  labels:
    app: nginx-svc # Service 本身标签
spec:
  selector: # 选中当前 Service 匹配哪些 pod,对哪些 pod 的东西流量进行代理
    app: nginx # 所有匹配到这些标签的 pod 都可以通过该 Service 进行访问
  ports:
  - name: http # Service 端口配置的名称
    protocol: TCP # 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
    port: 80 # Service 自己的端口,在使用内网 ip 访问时使用
    targetPort: 9527 # 目标 pod 的端口
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
  type: NodePort # 随机启动一个端口 (3000-32767),陕射到 ports 中的端口,该端口是直接绑定在 node 上的,且集群中的每一个 node 都会绑定这个端,也可以用于将服务暴露给外部访问,但是这种方式实际生产环境不推荐,效率较低,而且 Service 是四层负载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

NodePort 建议只在测试用,因为这个模式实际就是在 node 节点上随机开启一个端口,然后直接给外界通过该 node 的 IP 进行访问,而不是走 master 的 Service 和 Endpoint。

上面的图也有 NodePort 的位置,就在 Node 的上面,然后和 kube-proxy 绑定。类似于 Endpoint 了。

NodePort 默认去随机,如果想指定端口,如下:













 




apiVersion: v1
kind: Service # 资源类型为 Service
metadata:
  name: nginx-svc # Service 名字
  labels:
    app: nginx-svc # Service 本身标签
spec:
  selector: # 选中当前 Service 匹配哪些 pod,对哪些 pod 的东西流量进行代理
    app: nginx # 所有匹配到这些标签的 pod 都可以通过该 Service 进行访问
  ports:
  - name: https
    port: 443
    nodePort: 32000 # 指定端口
    protocol: TCP
    targetPort: 443
  type: NodePort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

命令操作:

# 创建 service
kubectl create -f nginx-svc.yaml

# 查看 service 信息,通过 service 的 cluster ip 进行访问
kubectl get svc 

# 查看 pod 信息,通过 pod 的 ip 进行访问
kubectl get po -o wide

# 创建其他 pod 通过 service name 进行访问(推荐)
kubectl exec -it busybox -- sh
curl http://nginx-svc

# 默认在当前 namespace 中访问,如果需要跨 namespace 访问 pod,则在 service name 后面加上 .<namespace> 即可
curl http://nginx-svc.default
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 代理 k8s 外部服务(IP)

使用场景:

  • 各环境访问名称统一
  • 访问 k8s 集群外的其他服务
  • 项目迁移

Service 创建的时候不指定选择器 Selector,则不会创建 Endpoint,因为 Endpoint 绑定的 IP、Port 等信息是 Service 告诉的,而 Service 没有选择任意一个 Pod,则 Endpoint 就先不创建。

实现方式:

  1. 编写 Service 配置文件时,不指定 Selector 属性
  2. 自己创建 Endpoint

Endpoint 配置:

apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: wolfcode-svc-external # 与 Service 一致
  name: wolfcode-svc-external # 与 Service 一致
  namespace: default # 与 Service 一致
subsets:
- addresses:
  - ip: 192.168.199.27 # 访问的目标 IP 地址,原本是 Service 选择后自动填入,但是 Service 没有加选择器,所以手动填
  ports: # 与 Service 一致
  - name: http # 与 Service 一致
    port: 80
    protocol: TCP
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Endpoint 因为手动填写了外部的 IP,所以访问 Service 时,Service 找到 Endpoint,Endpoint 就去访问外部的 IP 地址,而不是容器的 IP。

如果 Service 填写了选择器,那么选择到了 Pod,就把 Pod 的 IP、Port 给自己 Endpoint,这样 Endpoint 就去找 Pod,但是如果手动改了 Endpoint 保存的 IP、Port,则去修改后的 IP、Port 请求。

image-20230621010111592

# 代理 k8s 外部服务(域名)

配置文件

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-external-domain
  name: nginx-external-domain
spec:
  type: ExternalName
  externalName: www.youngkbt.cn # 代理的外部域名
1
2
3
4
5
6
7
8
9

# Ingress

Ingress 大家可以理解为也是一种 LB 的抽象,它的实现也是支持 nginx、haproxy 等负载均衡服务的。

如下图,左边是传统的 Nginx 代理,右边是 Ingr ess 代理。

image-20230621204628242

# 安装 ingress-nginx

官方文档:https://kubernetes.github.io/ingress-nginx/deploy/#using-helm。

中文官方文件介绍:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/。

安装 Helm(包管理器)

后面会介绍 Helm。

下载 Helm:

cd /opt/k8s

wget https://get.helm.sh/helm-v3.2.3-linux-amd64.tar.gz
1
2
3

解压

tar -zxvf helm-v3.2.3-linux-amd64.tar.gz
1

将解压目录下的 helm 程序移动到 usr/local/bin/helm

mv helm /usr/local/bin
1

添加 Helm 仓库

# 添加仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

# 查看仓库列表
helm repo list 

# 搜索 ingress-nginx
helm search repo ingress-nginx
1
2
3
4
5
6
7
8

下载包

# 下载安装包
helm pull ingress-nginx/ingress-nginx
1
2

配置参数

# 将下载好的安装包解压
tar xf ingress-nginx-xxx.tgz

# 解压后,进入解压完成的目录
cd ingress-nginx
1
2
3
4
5

修改 values.yaml 镜像地址:修改为国内镜像

# 找到
# registry: registry.k8s.io
# image: ingress-nginx/controller
# 改成如下
registry: registry.cn-hangzhou.aliyuncs.com
image: google_containers/nginx-ingress-controller
tag: v1.5.1

# 把 digest 注释掉

# 找到
# registry: registry.k8s.io
# image: ingress-nginx/kube-webhook-certgen
# 改成如下
registry: registry.cn-hangzhou.aliyuncs.com
image: google_containers/kube-webhook-certgen
tag: v1.5.1

# 找到 hostNetwork 改为 true
hostNetwork: true

# 找到 dnsPolicy 将 ClusterFirst 改为 ClusterFirstWithHostNet
dnsPolicy: ClusterFirstWithHostNet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

修改部署配置的 kind: Deployment 改成 kind: DaemonSet,然后修改 nodeSelector

kind: DaemonSet
  nodeSelector:
    kubernetes.io/os: linux
    ingress: "true" # 增加选择器,如果 node 上有 ingress=true 就部署
1
2
3
4

将 admissionWebhooks.enabled 修改为 false,禁用 https 认证。

将 service 中的 type 由 LoadBalancer 修改为 ClusterIP,如果服务器是云平台才用 LoadBalancer。

创建 Namespace

# 为 ingress 专门创建一个 namespace
kubectl create ns ingress-nginx
1
2

安装 ingress

# 为需要部署 ingress 的节点上加标签
kubectl label node k8s-node1 ingress=true

# 安装 ingress-nginx
helm install ingress-nginx -n ingress-nginx .
1
2
3
4
5

# 基本使用

创建一个 ingress

apiVersion: networking.k8s.io/v1
kind: Ingress # 资源类型为 Ingress
metadata:
  name: nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: / # 将匹配的路径重写为 /
spec:
  rules: # ingress 规则配置,可以配置多个
  - host: k8s.youngkbt.cn # 域名配置,可以使用通配符 *
    http:
      paths: # 相当于 nginx 的 location 配置,可以配置多个
      - pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
        backend:
          service: 
            name: nginx-svc # 代理到哪个 service
            port: 
              number: 80 # service 的端口
        path: /api # 等价于 nginx 中的 location 的路径前缀匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

pathType 支持三种配置:

  • ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准
  • Exact:精确匹配,URL 需要与 path 完全匹配上,且区分大小写的
  • Prefix:以 / 作为分隔符来进行前缀匹配

多域名配置

apiVersion: networking.k8s.io/v1
kind: Ingress # 资源类型为 Ingress
metadata:
  name: wolfcode-nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules: # ingress 规则配置,可以配置多个
  - host: k8s.youngkbt.cn # 域名配置,可以使用通配符 *
    http:
      paths: # 相当于 nginx 的 location 配置,可以配置多个
      - pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
        backend:
          service: 
            name: nginx-svc # 代理到哪个 service
            port: 
              number: 80 # service 的端口
        path: /api # 等价于 nginx 中的 location 的路径前缀匹配
      - pathType: Exec # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配>,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
        backend:
          service:
            name: nginx-svc # 代理到哪个 service
            port:
              number: 80 # service 的端口
        path: /
  - host: api.youngkbt.cn # 域名配置,可以使用通配符 *
    http:
      paths: # 相当于 nginx 的 location 配置,可以配置多个
      - pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配>,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
        backend:
          service:
            name: nginx-svc # 代理到哪个 service
            port:
              number: 80 # service 的端口
        path: /
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
Kubernetes - 资源调度
Kubernetes - 配置与存储

← Kubernetes - 资源调度 Kubernetes - 配置与存储→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式