5 Kubernetes-service
LBC:负载均衡集群
HAC:高可用集群
HPC:高性能运算集群
一、概念
1)service:负载调度器(svc)
K8S中的逻辑分组(名字空间、标签)。svc为逻辑分组的标签分组
Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector
2)迭代核心
在 kubernetes 集群中,每个节点运行一个kube-proxy 进程。负责为 service 实现了一种 VIP(虚拟ip) 的形式,而不是 ExternalName 的形式
在 Kubernetes v1.0 版本,代理完全在 userspace ,在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。
从 Kubernetes v1.2 起,默认就是 iptables 代理。
在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理
在 Kubernetes 1.14 版本开始默认使用 ipvs 代理
3)Kube-proxy 底层工作方式
Ⅰ、userspace 代理模式
userspace:基本实现了四层代理
1、kube-proxy 监听 apiserver ,将负载网络变化信息通过 netlinks 接口,写入到 iptables
2、kube-proxy 代理访问本地 pod 的 client 请求
Ⅱ、iptables 代理模式
iptables:
1、kube-proxy 仅监听 apiserver ,将负载网络变化信息,通过 netlinks 接口,写入至 iptables ,
2、本地 pod 的 client 请求,直接通过 iptables 负载
优点:Kube-proxy 压力变小
Ⅲ、ipvs 代理模式
注意:ipvs 模式需要在安装集群时启用模块,若未安装,则 kube-proxy 将回退到 iptables 代理模式
ipvs:(将 iptables 替换为更底层的内核技术)
kube-proxy 监听 apiserver 将负载网络变化信息通过 netlinks 接口写入至 ipvs
优点:kube-proxy 压力变小,由 netfilter 替换为 ipvs ,负载能力进一步加强
注意:ipvs 负载的流量
ipvs 仅负载本机节点,客户端 pod 请求的流量。每一个节点都有一个 ipvs 负载。从而压力均摊
限制:
Service能够提供负载均衡的能力,但是在使用上有以下限制:
1、只提供 4 层负载均衡能力
只提供 4 层负载均衡能力,而没有 7 层功能。但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的
2、不能实现https会话卸载层
https 会话卸载层需要7层的能力,而此处的4层负载不能实现
拓展:https 会话卸载层原理图:
用户--》代理server--》真实server,都采用https。
为了防止反复tcp握手连接,需要持久化链接
https 会话卸载层
用户---》代理server,采用https。代理server--》真实server,采用由七层卸载为4层的http
3、暴露一个接口,从而能实现7层的能力
在 Kubernetes v1.0 版本,Service 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用来表示 “7层”(HTTP)服务
4)Service 的类型
1、Clusterip 类型
集群内部的调用。默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP(重点)
原理:
nginx控制器 指向 svc调度器,svc调度器 再去管理 tomcat控制器 。若 tomcat控制器 管理的 pod 出现故障,则直接由 tomcat控制器 重建 pod ,而 svc调度器 也会做出对应的负载调整
拓展:短时间内ipvs仍保留之前调度的ip
之前调度的ip信息会隔一段时间再删除
pod ipvs RS 的信息删除的步骤:
1、将死亡的 pod 地址权重改写为 0 2、删除此 pod 地址
2、Nodeport 类型
**将内部服务暴露出去**,使用3万以上的端口。在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 `<NodeIP>: NodePort` 来访问该服务
原理:
当客户端访问节点的 <NodeIP>: NodePort ,由 ipvs 负载到集群内部的 nginx-pod ,再转发至 clusterip 调度器的负载均衡中,再转发到真实的服务器
3、LoadBalancer 类型
在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到
前提:cloud provider (云供应商)
拓展:K8S 高可用拓扑图
1、在 Kubernetes 外部也需要结合 ipvs 实现
2、在 Kubernetes 外部,结合 LAAS (负载均衡即服务) 实现(即LoadBalancer 类型)
4、ExternalName 类型
将外部不稳定的地址或域名,通过DNS做别名的方式,实现解析
service域名:创建完成svc以后默认产生
原理:
二、实验
1)Clusterip 类型
1、创建控制器
[root@k8s-master01 ~]# mkdir 5 ; cd 5
[root@k8s-master01 5]# vim 1.deployment.yaml
[root@k8s-master01 5]# cat 1.deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
template:
metadata:
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp
image: wangyanglinux/myapp:v1
ports:
- name: http
containerPort: 80
[root@k8s-master01 5]# kubectl apply -f 1.deployment.yaml
deployment.apps/myapp-deploy created
[root@k8s-master01 5]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-deploy-684d6487b6-cm2bq 1/1 Running 0 3s
myapp-deploy-684d6487b6-dzt7d 1/1 Running 0 3s
myapp-deploy-684d6487b6-vd27z 1/1 Running 0 3s
2、创建svc
[root@k8s-master01 5]# vim 2.service.yaml
[root@k8s-master01 5]# kubectl apply -f 2.service.yaml
service/myapp created
[root@k8s-master01 5]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d
myapp ClusterIP 10.110.66.4 <none> 80/TCP 2s
[root@k8s-master01 5]# cat 2.service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: ClusterIP
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
3、测试负载均衡
底层原理:ipvs
注意:当前本地的ipvs,只负载当前节点的客户端
4、模拟测试pod挂掉
若控制器管理的pod挂掉,控制器会重建pod,svc会重新调度新的pod,实现负载均衡
[root@k8s-master01 5]# kubectl delete pod myapp-deploy-684d6487b6-cm2bq
[root@k8s-master01 5]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-deploy-684d6487b6-6vrvv 1/1 Running 0 18s
myapp-deploy-684d6487b6-dzt7d 1/1 Running 0 13m
myapp-deploy-684d6487b6-vd27z 1/1 Running 0 13m
重新调度成功,之前的调度ip负载权重为0:(规则同步与控制器创建pod实时)
拓展:短时间内ipvs仍保留之前调度的ip
之前调度的ip信息会隔一段时间再删除
pod ipvs RS 的信息删除的步骤:
1、将死亡的 pod 地址权重改写为 0 2、删除此 pod 地址
5、pod内部也有负载均衡
创建一个客户端pod,进入测试负载均衡
[root@k8s-master01 5]# vim 3.pod.yaml
[root@k8s-master01 5]# cat 3.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp-1
image: wangyanglinux/myapp:v1
- name: busybox-1
image: busybox:1.36.0
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
[root@k8s-master01 5]# kubectl apply -f 3.pod.yaml
[root@k8s-master01 5]# kubectl exec -it pod-demo -c busybox-1 -- /bin/sh
/ # wget http://10.110.66.4/hostname.html && cat hostname.html && rm -rf hostname.html
验证负载均衡
6、svc域名解析
service域名:创建完成svc以后默认产生
用途:此特性可以实现通过域名指向svc。即使创建的svc地址变化,也能精准定位
即使 service 还未创建,根据规则编写,就能知道创建完成的 service 如何通过域名访问
比如:在编写配置文件 deployment-tomcat.yaml ,会提前编写 service-taomcat.yaml 和 deployment-nginx.yaml
在编写deployment-nginx.yaml 时,直接指向 svc-tomcat的域名,就能实现 nginx控制器 指向 svc-tomcat调度器
Ⅰ 查询集群的域名
[root@k8s-master01 5]# cat /usr/local/kubernetes/install/kubeadm-config.yaml |grep dnsDomain
dnsDomain: cluster.local
Ⅱ 查询集群内部的dns地址
存在两个dns地址:实现高可用
[root@k8s-master01 5]# kubectl get pod -n kube-system -o wide |grep coredns
coredns-5c98db65d4-fb8z2 1/1 Running 11 10d 172.100.1.185 k8s-node01 <none> <none>
coredns-5c98db65d4-gqtpz 1/1 Running 11 10d 172.100.1.186 k8s-node01 <none> <none>
[root@k8s-master01 5]# ipvsadm -Ln |grep :53
TCP 10.96.0.10:53 rr
-> 172.100.1.185:53 Masq 1 0 0
-> 172.100.1.186:53 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 172.100.1.185:53 Masq 1 0 0
-> 172.100.1.186:53 Masq 1 0 0
Ⅲ svc域名解析
[root@k8s-master01 5]# yum -y install bind-utils
[root@k8s-master01 5]# dig -t A myapp.default.svc.cluster.local. @10.96.0.10
Ⅳ 验证
[root@k8s-master01 5]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d
myapp ClusterIP 10.110.66.4 <none> 80/TCP 45m
7、会话保持
在固定的时间内,将 同一请求 分配至同一台机器(类似 ipvs 中的持久化连接)
K8S 集群中:
Ⅰ 查看默认未设置会话保持
Ⅱ 设置会话保持(也可设置不同的yaml文件实现)
[root@k8s-master01 5]# kubectl edit svc myapp
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3000
Ⅲ 测试
设定了 service 会话亲和性以后,先访问一次得到 pod hostname,然后等待 3小时 以后,在去访问应该会发现跳转至一个新的 pod,如果一直不间断访问下去, pod 不会改变
一直访问,则会一直保持会话
[root@k8s-master01 5]# while true;do curl 10.110.66.4/hostname.html;sleep 1;do
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
myapp-deploy-684d6487b6-dzt7d
^C
停留一段时间再访问
[root@k8s-master01 5]# curl 10.110.66.4/hostname.html;date
myapp-deploy-684d6487b6-vd27z
2023年 01月 21日 星期六 16:17:07 CST
# 停留一段时间再访问
[root@k8s-master01 5]# curl 10.110.66.4/hostname.html;date
myapp-deploy-684d6487b6-dzt7d
2023年 01月 21日 星期六 16:21:09 CST
[root@k8s-master01 5]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-deploy-684d6487b6-6vrvv 1/1 Running 0 4h12m
myapp-deploy-684d6487b6-dzt7d 1/1 Running 0 4h25m
myapp-deploy-684d6487b6-vd27z 1/1 Running 0 4h25m
pod-demo 2/2 Running 4 4h2m
8、Headless Service (statefulSet 控制器专用,后续介绍)
有时不需要或不想要负载均衡,以及单独的 Service IP 。遇到这种情况,可以通过指定 Cluster IP ( spec.clusterIP ) 的值为 “ None ” 来创建 Headless Service 。这类 Service 并不会分配 Cluster IP, kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由
# yum -y install bind-utils
[root@k8s-master mainfests]# vim myapp-svc-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-headless
namespace: default
spec:
selector:
app: myapp
clusterIP: "None"
ports:
- port: 80
targetPort: 80
[root@k8s-master mainfests]# dig -t A myapp-headless.default.svc.cluster.local. @10.96.0.10
2)Nodeport 类型
采用的是 ipvs集群 中的 nat转换,作为工作方式(端口映射)
不仅仅是负载均衡。若只有一个pod,也可用过 Nodeport 给外部提供访问
[root@k8s-master01 5]# vim 4.nodeport.yaml
[root@k8s-master01 5]# cat 4.nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
namespace: default
spec:
type: NodePort
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
# nodePort: 30005
# 设置指定端口,不建议自定义,避免冲突
[root@k8s-master01 5]# kubectl apply -f 4.nodeport.yaml
浏览器访问测试:
3)LoadBalancer
loadBalancer 和 nodePort 其实是同一种方式。区别在于 loadBalancer 比 nodePort 多了一步,就是可以调用 cloud provider 去创建 LB 来向节点导流
4)ExternalName
利用本集群的 dns插件 ,将一个固定的域名 my-service-1.default.svc.cluster.local.解析到一个不固定的域名 hub.xinxianghf.com1 上,实现每一个pod的配置文件不用单独修改,仅需改 service对象的别名 即可
kind: Service
apiVersion: v1
metadata:
name: my-service-1
namespace: default
spec:
type: ExternalName
externalName: hub.xinxianghf.com
# my-service-1.default.svc.cluster.local.
当查询主机 my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )时,集群的 DNS 服务将返回一个值 my.database.example.com 的 CNAME 记录。访问这个服务的工作方式和其他的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发
三、Endpoints
1、介绍
Endpoints是一个资源对象。一组 pod 的服务端点集合
Endpoint 分类:
自动生成:若创建 service 控制器,存在标签选择器,则会自动生成 Endpoints
手动配置:若创建的 service 控制器,不存在标签选择器(无 selector),则需要手动创建(有灵活性)
2、实验
1)Endpoints 自动创建
1.创建deployment控制器管理pod
2.创建svc负载deployemnt控制器(会自动创建和 service 同名的 Endpoints )
[root@k8s-master01 6]# mkdir 6 ;cd 6
[root@k8s-master01 6]# kubectl create deployment myapp --image=wangyanglinux/myapp:v1 --dry-run -o yaml > 1.deployment.yaml
[root@k8s-master01 6]# vim 1.deployment.yaml
[root@k8s-master01 6]# cat 1.deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myapp
name: myapp
spec:
replicas: 5
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: wangyanglinux/myapp:v1
name: myapp
[root@k8s-master01 6]# kubectl apply -f 1.deployment.yaml
deployment.apps/myapp created
[root@k8s-master01 6]# kubectl create svc clusterip myapp --tcp=80:80 --dry-run -o yaml > 2.svc.yaml
[root@k8s-master01 6]# cat 2.svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: myapp
name: myapp
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: myapp
[root@k8s-master01 6]# kubectl apply -f 2.svc.yaml
service/myapp created
[root@k8s-master01 6]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
myapp ClusterIP 10.104.33.100 <none> 80/TCP 3s
[root@k8s-master01 6]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.20.201:6443 22d
myapp 172.100.1.50:80,172.100.1.51:80,172.100.2.86:80 + 2 more... 39s
2)手动创建 Endpoints
创建的 service 不指定标签选择器。需要手动创建 Endpoints
1.根据 3.svc.yaml 文件创建 service 和 Endpoints
# 3.svc.yaml 文件详解
apiVersion: v1 #指定核心组为 v1版
kind: Service #指定创建的资源对象为 service
metadata: #指定元数据信息
name: nginx #指定service对象的名称
spec: #定义service对象的期望
ports: #定义端口信息
- protocol: TCP #tcp连接
port: 6666 #外部访问svc的端口
targetPort: 80 #svc负载后台访问的端口
# 创建没有标签选择器的service
[root@k8s-master01 6]# vim 3.svc.yaml
[root@k8s-master01 6]# cat 3.svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- protocol: TCP
port: 6666
targetPort: 80
[root@k8s-master01 6]# kubectl apply -f 3.svc.yaml
service/nginx created
# 验证:没有自动创建Endpoints
[root@k8s-master01 6]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
myapp ClusterIP 10.96.9.32 <none> 80/TCP 66m
nginx ClusterIP 10.109.102.43 <none> 6666/TCP 18s
[root@k8s-master01 6]# kubectl get Endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.20.201:6443 22d
myapp 172.100.1.52:80,172.100.1.53:80,172.100.2.89:80 + 2 more... 67m
2.在node01节点中部署服务
3.手动创建Endpoints
将刚才在node01中部署的服务,添加到自动创建的 service 中(手动创建 Endpoints 实现)
# cat 4.Endpoints.yaml 详解
apiVersion: v1
kind: Endpoints #指定创建的资源对象为 Endpoints
metadata: #定义资源对象中的元数据信息
name: nginx
subsets: #定义管理的ip地址和端口
- addresses:
- ip: 192.168.20.202
ports:
- port: 80
[root@k8s-master01 6]# vim 4.Endpoints.yaml
[root@k8s-master01 6]# cat 4.Endpoints.yaml
apiVersion: v1
kind: Endpoints
metadata:
name: nginx
subsets:
- addresses:
- ip: 192.168.20.202
ports:
- port: 80
[root@k8s-master01 6]# kubectl apply -f 4.Endpoints.yaml
endpoints/nginx created
[root@k8s-master01 6]# kubectl get Endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.20.201:6443 22d
myapp 172.100.1.52:80,172.100.1.53:80,172.100.2.89:80 + 2 more... 90m
nginx 192.168.20.202:80 105s
[root@k8s-master01 6]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
myapp ClusterIP 10.96.9.32 <none> 80/TCP 89m
nginx ClusterIP 10.109.102.43 <none> 6666/TCP 22m
4.测试访问
注意:Endpoints可跟踪多个ip
四、ingress
Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/
由于 service 的负载是4层负载,可以借助nginx、ingress-nginx实现七层负载
1、可手动创建nginx,实现七层负载
实现会话卸载层:客户端与nginx之间采用https,nginx与内部采用http
2、通过ingress自动实现七层负载
ingress-nginx是ingress实现的其中一种方式
原理:尽可能减少nginx的重启
对配置文件的修改:store协程 监听apiserver是否存在reload,syncqueue协程 再次判断是否reload
重要的:两个协程进行判断为重要的之后,直接进行重启
不重要的:store协程 为不重要的判断后,放入一级缓冲,经过主城后,放入二级缓冲,经过syncqueue协程 再次判断是否reload
3、ingress实验
拓展:Rancher Desktop 的 K3S (相当于精简版K8S,省去了一些的无用的接口)
K3S目标:边缘计算(每个独立的位置都能进行运算)
1)ingress-nginx搭建
Ⅰ 清理
[root@k8s-master01 6]# kubectl delete deployment --all
deployment.extensions "myapp" deleted
[root@k8s-master01 6]# kubectl delete svc nginx myapp
service "nginx" deleted
service "myapp" deleted
[root@k8s-master01 6]# kubectl get pod
No resources found.
Ⅱ 准备环境
[root@k8s-master01 ~]# mkdir /usr/local/kubernetes/ingress
[root@k8s-master01 ~]# cd !$
cd /usr/local/kubernetes/ingress
上传压缩包(本次采用基础本地安装)
# master01节点中
$ yum -y install unzip ;unzip Ingress-nginx.zip
[root@k8s-master01 ingress]# cd Ingress-nginx
[root@k8s-master01 Ingress-nginx]# tar -xf ingress-nginx.tar.gz
[root@k8s-master01 Ingress-nginx]# cd ingress-nginx
[root@k8s-master01 ingress-nginx]# docker load -i ingress.tar
[root@k8s-master01 ingress-nginx]# scp ingress.tar root@n1:/root/
[root@k8s-master01 ingress-nginx]# scp ingress.tar root@n2:/root/
# node01节点中
[root@k8s-node01 ~]# docker load -i ingress.tar
# node02节点中
[root@k8s-node02 ~]# docker load -i ingress.tar
Ⅲ 根据 yaml 文件创建ingress-nginx
mandatory.yaml #运行deployment控制器
service-nodeport #运行service的ingress-nginx
[root@k8s-master01 ingress-nginx]# kubectl apply -f mandatory.yaml
[root@k8s-master01 ingress-nginx]# kubectl apply -f service-nodeport.yaml
[root@k8s-master01 ingress-nginx]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.96.131.122 <none> 80:30914/TCP,443:30050/TCP 4m6s
Ⅳ 测试访问
2)ingress http代理访问---实现虚拟主机
实现:同一个ip,能用不同的域名访问,且不同域名下的资源不同
Ⅰ、创建5.http.yaml、6.http.yaml,并进行部署
[root@k8s-master01 6]# pwd
/root/6
[root@k8s-master01 6]# ls
1.deployment.yaml 2.svc.yaml 3.svc.yaml 4.Endpoints.yaml
[root@k8s-master01 6]# vim 5.http.yaml
[root@k8s-master01 6]# cat 5.http.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: www1
spec:
replicas: 2
template:
metadata:
labels:
name: www1
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: www1
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: www1
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www1
spec:
rules:
- host: www1.hongfu.com
http:
paths:
- path: /
backend:
serviceName: www1
servicePort: 80
[root@k8s-master01 6]# kubectl apply -f 5.http.yaml
[root@k8s-master01 6]# cp -a 5.http.yaml 6.http.yaml
[root@k8s-master01 6]# vim 6.http.yaml
[root@k8s-master01 6]# cat 6.http.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: www2
spec:
replicas: 2
template:
metadata:
labels:
name: www2
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: www2
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: www2
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www2
spec:
rules:
- host: www2.hongfu.com
http:
paths:
- path: /
backend:
serviceName: www2
servicePort: 80
[root@k8s-master01 6]# kubectl apply -f 6.http.yaml
Ⅱ、查看运行状态,并获取http端口号
[root@k8s-master01 6]# kubectl get pod,deployment,ingress,svc
NAME READY STATUS RESTARTS AGE
pod/www1-7cfb5dd7bf-2bs26 1/1 Running 0 6m57s
pod/www1-7cfb5dd7bf-2l8qg 1/1 Running 0 6m57s
pod/www2-68dd4464cf-9cz85 1/1 Running 0 113s
pod/www2-68dd4464cf-nhpx8 1/1 Running 0 113s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/www1 2/2 2 2 6m57s
deployment.extensions/www2 2/2 2 2 113s
NAME HOSTS ADDRESS PORTS AGE
ingress.extensions/www1 www1.hongfu.com 80 6m57s
ingress.extensions/www2 www2.hongfu.com 80 113s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
service/www1 ClusterIP 10.110.217.28 <none> 80/TCP 6m57s
service/www2 ClusterIP 10.103.47.29 <none> 80/TCP 113s
[root@k8s-master01 6]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.96.131.122 <none> 80:30914/TCP,443:30050/TCP 21m
Ⅲ Windows写入hosts文件
192.168.20.201 www1.hongfu.com
192.168.20.201 www2.hongfu.com
192.168.20.201 ssl.hongfu.com
192.168.20.201 auth.hongfu.com
192.168.20.201 rew.hongfu.com
Ⅳ 浏览器测试访问:
3)ingress https代理访问---会话卸载层
注意:会话卸载层的客户端访问,需要有路由实现地址转换
客户端访问路由地址,路由将来自80的访问转换端口为31891,经过svc-nodeport到ingress-nginx,由80跳转到443
客户端再次访问,由记录直接访问443,这个时候需要路由将来自443的访问转换为31732。若没有,则不会访问成功。
拓展:label与annotation区别
label:集群内部使用的约定
annotation:第三方开发与使用者之间的约定
Ⅰ、创建证书
[root@k8s-master01 6]# mkdir 7
[root@k8s-master01 6]# cd 7/
[root@k8s-master01 7]# openssl genrsa -des3 -out tls.key 2048
[root@k8s-master01 7]# openssl req -new -key tls.key -out tls.csr
[root@k8s-master01 7]# cp tls.key tls.key.org
[root@k8s-master01 7]# openssl rsa -in tls.key.org -out tls.key
[root@k8s-master01 7]# openssl x509 -req -days 365 -in tls.csr -signkey tls.key -out
[root@k8s-master01 7]# ls
tls.crt tls.csr tls.key tls.key.org
Ⅱ、cert存储
Ⅲ、创建deployment控制器
[root@k8s-master01 7]# vim 1.deployment.yaml
[root@k8s-master01 7]# cat 1.deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ssl
spec:
replicas: 2
template:
metadata:
labels:
name: ssl
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: ssl
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: ssl
[root@k8s-master01 7]# kubectl apply -f 1.deployment.yaml
Ⅳ、创建ingress对象
annotation中定义:与ingress-nginx官方规定好的需要开启的功能key,和对应value
[root@k8s-master01 7]# vim 2.ingress.yaml
[root@k8s-master01 7]# cat 2.ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ssl.hongfu.com
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- ssl.hongfu.com
secretName: tls-secret
rules:
- host: ssl.hongfu.com
http:
paths:
- path: /
backend:
serviceName: ssl
servicePort: 80
[root@k8s-master01 7]# kubectl apply -f 2.ingress.yaml
Ⅴ 测试访问
此处因为没有路由,所以80跳转到443失败:
4)nginx进行BasicAuth---目录保护
Ⅰ、创建登录用户、创建cert存储
[root@k8s-master01 6]# mkdir 8
[root@k8s-master01 6]# cd 8/
[root@k8s-master01 8]# pwd
/root/6/8
[root@k8s-master01 6]# yum -y install httpd-tools
[root@k8s-master01 6]# htpasswd -c auth foo
[root@k8s-master01 6]# kubectl create secret generic basic-auth --from-file=auth
Ⅱ、创建deployment、ingress
[root@k8s-master01 8]# vim 1.deployment.yaml
[root@k8s-master01 8]# cat 1.deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: auth
spec:
replicas: 2
template:
metadata:
labels:
name: auth
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v4
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: auth
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: auth
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: auth
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - wangyang'
spec:
rules:
- host: auth.hongfu.com
http:
paths:
- path: /
backend:
serviceName: auth
servicePort: 80
[root@k8s-master01 8]# kubectl apply -f 1.deployment.yaml
Ⅲ、查看svc端口
[root@k8s-master01 8]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.96.131.122 <none> 80:30914/TCP,443:30050/TCP 63m
Ⅳ、测试访问
(前提:Windows的hosts文件有定义)
5)nginx进行重写---地址跳转
Ⅰ、根据yaml文件创建ingress
注意:此处的Ingress资源对象的期望中,规则中,http的定义可以不写
[root@k8s-master01 6]# vim 9.rew.yaml
[root@k8s-master01 6]# cat 9.rew.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rew
annotations:
nginx.ingress.kubernetes.io/rewrite-target: https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9404712539650433019%22%7D&n_type=-1&p_from=-1
spec:
rules:
- host: rew.hongfu.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
[root@k8s-master01 6]# kubectl apply -f 9.rew.yaml
Ⅱ、测试访问
(前提:hosts文件存在定义)








































