Kubernetes--服务发布(Service、Ingress)
前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除
出自B站博主教程笔记:
完整版Kubernetes(K8S)全套入门+微服务实战项目,带你一站式深入掌握K8S核心能力_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1MT411x7GH/?spm_id_from=333.337.search-card.all.click
服务发布
service与ingress的关系图:
一、Service
负责东西流量(同层级/内部服务网络通信)的通信 ,Service如何把我们的容器在网络内部打通如下:
所有的请求其实都在请求api-server,而api-server会根据我们的IP找到对应的service,service就会找到自己的Endpoint,然后通过endpoint的iptables的转发找到对应的目标服务器,然后通过目标服务器找到对应的容器。
1、Service的定义
apiVersion: v1
kind: Service # 资源类型为 Service
metadata:
name: nginx-svc # Service 名称
labels:
app: nginx-svc # Service 自己本身的标签
spec:
ports: # 端口映射
- name: http # service 端口配置的名称
protocol: TCP # 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
port: 80 # service 自己的端口,在使用内网时使用
targetPort: 9527 # 目标 pod 的端口
- name: https
port: 443
protocol: TCP
targetPort: 443
selector: # 选中当前 service 匹配哪些 pod,对哪些 pod 的东西流量进行代理
app: nginx
type: NodePort # 随机启动一个端口(30000-32767),映射到ports中的端口,该端口是直接绑定在node上的,且集群中的每一个node都会绑定这个端口;也可用于将服务暴露给外部访问,不推荐,一般只在测试中使用
1.1、命令操作
# 创建service
[root@k8s ~]# kubectl create -f nginx-svc.yaml
# 查看service信息,通过service的cluster ip进行访问
[root@k8s ~]# kubectl get svc
# 查看 pod 信息,通过pod的ip进行访问
[root@k8s ~]# kubectl get po -o wide
# 创建其他pod通过service name进行访问(推荐)
[root@k8s ~]# kubectl exec -it busybox -- sh
[root@k8s ~]# curl http://nginx-svc
# 默认在当前 namespace 中访问,如果需要跨 namespace 访问 pod,则在 service name 后面加上 .<namespace> 即可
[root@k8s ~]# curl http://nginx-svc.default
1.2、Endpoint
2、代理k8s外部服务
实现方式: (1)编写 service 配置文件时,不指定 selector 属性 (2)自己创建 endpoint
示例:第一步:编写nginx-svc-external.yaml文件和nginx-ep-external.yaml
# nginx-svc-external.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-svc-external
labels:
app: nginx
spec:
ports:
- port: 80
targetPort: 80
name: web
type: ClusterIP
# nginx-ep-external.yaml:
apiVersion: v1
kind: Endpoints
metadata:
labels:
app: nginx # 与service一致
name: nginx-svc-external # 与service一致
namespace: default # 与service一致
subsets:
- addresses:
- ip: 202.108.22.5 # 目标ip地址,比如要请求到百度202.108.22.5
ports: # 与service一致
- name: web
port: 80
protocol: TCP
第二步:创建Service和Endpoint:
[root@k8s ~]# kubectl create -f nginx-svc-external.yaml
[root@k8s ~]# kubectl create -f nginx-ep-external.yaml
第三步:检查:
[root@k8s ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc-external ClusterIP 10.102.101.161 <none> 80/TCP 8s
[root@k8s ~]# kubectl get ep
NAME ENDPOINTS AGE
nginx-svc-external 202.108.22.5:80 7s
[root@k8s ~]# kubectl describe ep nginx-svc-external
Name: nginx-svc-external
Namespace: default
Labels: app=nginx
Annotations: <none>
Subsets:
Addresses: 202.108.22.5
NotReadyAddress: <none>
Ports:
Name Port Protocol
---- ---- --------
web 80 TCP
Events: <none>
第四步:测试:
# 进入一个容器中
[root@k8s ~]# kubectl exec -it dns-test -- sh
/ # wegt http://nginx-svc-exterl
Connecting to nginx-svc-external (10.102.101.161:80)
Connecting to www.baidu.com (202.108.22.5:80)
总的来说:代理K8s外部服务:
- 各环境访问名称统一
- 访问k8s集群外的其他服务
-
项目迁移
3、反向代理外部域名
编写nginx-svc-externalname.yaml文件:
apiVersion: v1
kind: Service
metadata:
labels:
app: baidu-external-domain
name: baidu-external-domain
spec:
type: ExternalName
externalName: www.baidu.cn
创建与测试:
[root@k8s ~]# kubectl create -f nginx-svc-externalname.yaml
[root@k8s ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
baidu-external-domain ExternalName www.baidu.cn <none> <none> 8s
# 进入容器测试:
[root@k8s ~]# kubectl exec -it dns-test -- sh
/ # wegt http://wolfcode-external-domain
Connecting to nginx-svc-external (120.78.159.117:80)
Connecting to www.baidu.com (202.108.22.5:80)
4、常用类型
4.1、ClusterIP
只能在集群内部使用,不配置类型的话默认就是 ClusterIP
4.2、ExternalName
返回定义的 CNAME 别名,可以配置为域名
4.3、NodePort
会在所有安装了 kube-proxy 的节点都绑定一个端口,此端口可以代理至对应的 Pod,集群外部可以使用任意节点 ip + NodePort 的端口号访问到集群中对应 Pod 中的服务。
当类型设置为 NodePort 后,可以在 ports 配置中增加 nodePort 配置指定端口,需要在下方的端口范围内,如果不指定会随机指定端口
端口范围:30000~32767
端口范围配置在 /usr/lib/systemd/system/kube-apiserver.service 文件中
4.4、LoadBalancer
使用云服务商(阿里云、腾讯云等)提供的负载均衡器服务
二、Ingress
1、安装Ingress-nginx
(1)添加helm仓库
# 添加仓库
[root@master ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# 查看仓库列表
[root@master ~]# helm repo list
NAME URL
ingress-nginx https://kubernetes.github.io/ingress-nginx
# 搜索 ingress-nginx
[root@master ~]# helm search repo ingress-nginx
NAME CHART VERSION APP VERSION DESCRIPTION
ingress-nginx/ingress-nginx 4.4.2 1.5.1 Ingress controller for..
(2)下载包
# 下载安装包
[root@master ~]# helm pull ingress-nginx/ingress-nginx --version=4.4.2
[root@master ~]# mv ingress-nginx-4.4.2.tgz /opt/k8s/helm
[root@master ~]# cd /opt/k8s/helm
(3)配置参数
# 将下载好的安装包解压
[root@master helm]# tar xf ingress-nginx-4.4.2.tgz
# 解压后,进入解压完成的目录
[root@master helm]# cd ingress-nginx
# 修改 values.yaml
# 镜像地址:修改为国内镜像/科学上网
[root@master ingress-nginx]# vim values.yaml
registry: registry.cn-hangzhou.aliyuncs.com
image: google_containers/nginx-ingress-controller
image: google_containers/kube-webhook-certgen
tag: v1.3.0
#digest: sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629
#digestChroot: sha256:c1c091b88a6c936a83bd7b098662760a87868d12452529bad0d178fb36147345
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
修改部署配置的 kind: DaemonSet
nodeSelector:
ingress: "true" # 增加选择器,如果 node 上有 ingress=true 就部署
将 admissionWebhooks.enabled 修改为 false
将 service 中的 type 由 LoadBalancer 修改为 ClusterIP,如果服务器是云平台才用 LoadBalancer
(4)创建Namespace
# 为 ingress 专门创建一个 namespace
[root@master ingress-nginx]# kubectl create ns ingress-nginx
(5)安装Ingress
# 为需要部署 ingress 的节点上加标签,由于目前k8s-master中存在污点,因此将ingress创建在node1中
[root@master ingress-nginx]# kubectl label node k8s-node1 ingress=true
# 安装 ingress-nginx
[root@master ingress-nginx]# helm install ingress-nginx -n ingress-nginx .
[root@master ingress-nginx]# helm delete ingress-nginx -n ingress-nginx # 失败重装执行
# 检查
[root@master ingress-nginx]# kubectl get po -n ingress-nginx -o wide
NAME READY TATUS RESTARTS AGE IP NODE NOMINATED NODE READINEDD GATES
ingress.. 1/1 Running 0 33s 192.168.1.11 k8s-node1 <none> <none>
2、基本使用
2.1、创建一个Ingress
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.wolfcode.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 的路径前缀匹配
2.2、多域名配置
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.wolfcode.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.wolfcode.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: /