1 什么是微服务
用控制器来完成集群的工作负载,那么应用如何暴漏出去?需要通过微服务暴漏出去后才能被访问
- Service是一组提供相同服务的Pod对外开放的接口。
- 借助Service,应用可以实现服务发现和负载均衡。
- service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)

1.1 理解标签与service中的endpoint
建立一个service
bash
[root@k8s-master ~]# mkdir services
[root@k8s-master ~]# cd services/
[root@k8s-master services]# kubectl create service clusterip --tcp 80:80 testservice --dry-run=client -o yaml >> testservice.yaml
[root@k8s-master services]# vim testservice.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: testservice
name: testservice
spec:
ports:
- name: webport
port: 80
protocol: TCP
targetPort: 80
selector:
app: webserver
type: ClusterIP
[root@k8s-master services]# kubectl apply -f testservice.yaml
service/testservice created
#检查
[root@k8s-master ~]# watch -n 1 "kubectl describe svc testservice ; kubectl get pods --show-labels "

1.2 建立pod并测试pod是否可以被testservice暴漏
当标签与service选择器上的标签不同,pod不会被暴漏
bash
[root@k8s-master services]# kubectl run webserver --image myapp:v1 --dry-run=client -o yaml > webserver.yml
[root@k8s-master services]# vim webserver.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: webserver
name: webserver
spec:
containers:
- image: myapp:v1
name: webserver
[root@k8s-master services]# kubectl apply -f webserver.yml
pod/webserver created
#监控
watch -n 1 "kubectl describe svc testservice ; kubectl get pods --show-labels "

因为标签没有匹配上,所有端口无暴露,需要看清你的service上的标签名字,再添加上对应的标签
更改标签后看监控
bash
[root@k8s-master services]# kubectl label pods webserver app=webserver
pod/webserver labeled
#监控上的IP
[root@k8s-master services]# curl 10.103.22.193
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

2 利用service暴漏控制器
2.1 生成控制器和service的组合
bash
#监控
[root@k8s-master ~]# watch -n 1 "kubectl describe svc webservice ; kubectl get deploy --show-labels;kubectl get pods -o wide --show-labels "
[root@k8s-master services]# kubectl create service clusterip --tcp 80:80 webservice --dry-run=client -o yaml >> webservice.yaml
[root@k8s-master services]# kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml >>webservice.yaml
[root@k8s-master services]# vim webservice.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webservice
name: webservice
spec:
ports:
- name: webport
port: 80
protocol: TCP
targetPort: 80
selector:
app: webcluster
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
#生成控制器和service
[root@k8s-master services]# kubectl apply -f webservice.yaml
service/webservice created
deployment.apps/webcluster created

3 service的ipvs模式
Kubernetes Service 的 IPVS 模式,简单来说,就是kube-proxy 组件用来实现 Service 负载均衡的一种高性能模式。它用 Linux 内核中专门为负载均衡设计的 IPVS 功能,替代了默认的 iptables 模式。
3.1 在所有节点中安装ipvsadm工具
bash
[root@k8s-master ~]# for name in 100 10 20 200
> do
> ssh -l root 172.25.254.$name "dnf install ipvsadm -y"
> done
3.2 配置集群中的kube-proxy
bash
[root@k8s-master ~]# kubectl -n kube-system edit cm kube-proxy
59 mode: "ipvs"
configmap/kube-proxy edited
#查看启动的关于kube-proxy的pods
[root@k8s-master ~]# kubectl -n kube-system get pods
kube-proxy-fwmn4 1/1 Running 0 2m7s
kube-proxy-sxsx2 1/1 Running 0 2m7s
kube-proxy-x2wgb 1/1 Running 0 2m7s
#将kube-proxy的pods都删掉强制重启它们,以便让新配置生效
[root@k8s-master ~]# kubectl -n kube-system delete pods kube-proxy-6kp78 kube-proxy-hvk7k kube-proxy-p7fdf kube-proxy-tb29j
#效果
[root@k8s-master ~]# ipvsadm -Ln


4 Sevice的ClusterIP 类型
4.1 clusterip
ClusterIP 会为 Service 分配一个集群内部才能访问的虚拟 IP 地址,仅供集群内的 Pod 之间互相访问。
特点:
- 仅限集群内部访问:只服务于集群内部网络的通信
- 提供一个稳定的访问入口:无论后端的 Pod 怎么重启、扩容、缩容,甚至 IP 变了,前端应用永远只需要访问那个不变的 ClusterIP
- 实现服务发现:Kubernetes 自带的 DNS,会自动将 Service 的名字解析为 ClusterIP,让微服务之间可以通过名字直接调用。
bash
[root@k8s-master services]# vim webservice.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webservice
name: webservice
spec:
ports:
- name: webport
port: 80
protocol: TCP
targetPort: 80
selector:
app: webcluster
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s-master services]# kubectl apply -f webservice.yaml
service/webservice created
deployment.apps/webcluster created
[root@k8s-master services]# kubectl describe svc webservice

4.2 在k8s集群内部解析
#集群内部通常使用service的解析名称进行通信地址的指定,因为资源的ip会变但是名字不会
bash
[root@k8s-master services]# kubectl -n kube-system get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
calico-typha ClusterIP 10.101.60.8 <none> 5473/TCP 2d
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 14d
#资源解析时输入的格式
#dig <servicename>.<namespace>.<sourcetype>.cluster.local @10.96.0.10
#以当前为例
[root@k8s-master services]# dig webservice.default.svc.cluster.local @10.96.0.10

4.3 clusterIP的headless模式
当设定此模式,那么service不会被分配一个ip而是直接把endpoints上的ip直接通过dns裸漏
clusterIP: None------表示不为这个 Service 分配虚拟 IP,客户端访问时直接拿到后端的 Pod IP 列表,而不是通过一个中间 VIP 进行负载均衡。
bash
[root@k8s-master services]# vim webservice.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webservice
name: webservice
spec:
ports:
- name: webport
port: 80
protocol: TCP
targetPort: 80
selector:
app: webcluster
type: ClusterIP
clusterIP: None #添加无头服务
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s-master services]# kubectl delete -f webservice.yaml
service "webservice" deleted from default namespace
deployment.apps "webcluster" deleted from default namespace
[root@k8s-master services]# kubectl apply -f webservice.yaml
service/webservice created
deployment.apps/webcluster created
[root@k8s-master services]# kubectl describe svc webservice

bash
#查看解析
[root@k8s-master services]# dig webservice.default.svc.cluster.local @10.96.0.10

5 service的nodeport模式
NodePort 是在 ClusterIP 的基础上,再在集群的每个节点上打开一个固定端口(默认 30000-32767),让外部流量可以通过 节点IP:NodePort 访问到 Service。
5.1 生成nodeport
bash
[root@k8s-master services]# vim nodeport.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webservice
name: webservice
spec:
ports:
- name: webport
port: 80
protocol: TCP
targetPort: 80
nodePort: 30951 #指定端口,如不写可以从30000~32767之间随机分
selector:
app: webcluster
type: NodePort #nodeport模式
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s-master services]# kubectl apply -f nodeport.yaml
service/webservice created
deployment.apps/webcluster created
5.2 查看策略和访问
bash
#查看策略
[root@k8s-master services]# ipvsadm -Ln
#访问
[root@k8s-master ~]# curl 172.25.254.100:30951/hostname.html
webcluster-77c87d9946-4tpzr
[root@k8s-master ~]# curl 172.25.254.100:30951/hostname.html
webcluster-77c87d9946-qxqpx

5.3 端口破限
bash
[root@k8s-master services]# vim nodeport.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webservice
name: webservice
spec:
ports:
- name: webport
port: 80
protocol: TCP
targetPort: 80
nodePort: 44444 #书写范围外的端口
selector:
app: webcluster
type: NodePort #nodeport模式
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
bash
#生成无法生效超出范围
[root@k8s-master services]# kubectl apply -f nodeport.yaml
deployment.apps/webcluster created
The Service "webservice" is invalid: spec.ports[0].nodePort: Invalid value: 44444: provided port is not in the valid range. The range of valid ports is 30000-32767
#进入配置文件修改
[root@k8s-master services]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
42 - --service-node-port-range=30000-50000
#重启所有pods,启用新服务生效
[root@k8s-master services]# kubectl -n kube-system delete pods all
[root@k8s-master services]# kubectl apply -f nodeport.yaml
service/webservice created
deployment.apps/webcluster created
[root@k8s-master services]# kubectl describe svc webservice

6 service中的loadbalancer模式
LoadBalancer 是在 NodePort 的基础上,再向云厂商(如 AWS、阿里云、腾讯云等)申请一个外部负载均衡器,分配一个公网 IP,让外部用户通过这个公网 IP 直接访问服务。

6.1 建立一个service
bash
[root@k8s-master services]# vim loadbalancer.yml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webservice
name: webservice
spec:
ports:
- name: webport
port: 80
protocol: TCP
targetPort: 80
selector:
app: webcluster
type: LoadBalancer #指定模式
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s-master services]# kubectl apply -f loadbalancer.yml
service/webservice created
deployment.apps/webcluster created
[root@k8s-master services]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d19h
webservice LoadBalancer 10.96.3.32 <none> 80:46678/TCP 8s
6.2 构建metalLB
上传镜像到harbor中
bash
[root@k8s-master services]# tar zxf metallb-v0.16.1.tar.gz
[root@k8s-master services]# cd metaLLB/
[root@k8s-master metaLLB]# ls
1-metallb-native.yaml 2-metallb-confmap.yml metallb-v0.16.1.tar
[root@k8s-master metaLLB]# docker load -i metallb-v0.16.1.tar
[root@k8s-master metaLLB]# docker tag quay.io/metallb/controller:v0.16.1 reg.timinglee.org/metallb/controller:v0.16.1
[root@k8s-master metaLLB]# docker tag quay.io/metallb/speaker:v0.16.1 reg.timinglee.org/metallb/speaker:v0.16.1
[root@k8s-master metaLLB]# docker push reg.timinglee.org/metallb/controller:v0.16.1
[root@k8s-master metaLLB]# docker push reg.timinglee.org/metallb/speaker:v0.16.1
更改kube-proxy
bash
[root@k8s-master mateLLB]# kubectl edit configmap -n kube-system kube-proxy
configmap/kube-proxy edited
59 mode: "ipvs"
60 ipvs:
61 strictARP: true

bash
#查看pod
[root@k8s-master mateLLB]# kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
coredns-697886855d-5whcs 1/1 Running 0 24m
coredns-697886855d-wcrt5 1/1 Running 0 24m
etcd-k8s-master 1/1 Running 1 (3d23h ago) 24m
kube-apiserver-k8s-master 1/1 Running 0 24m
kube-controller-manager-k8s-master 1/1 Running 2 (27m ago) 24m
kube-proxy-57bhn 1/1 Running 0 24m
kube-proxy-854kz 1/1 Running 0 24m
kube-proxy-cnq7t 1/1 Running 0 24m
kube-proxy-s9plr 1/1 Running 0 24m
kube-scheduler-k8s-master 1/1 Running 2 (27m ago) 24m
#删掉旧的pod,重启pod,生效服务
[root@k8s-master mateLLB]# kubectl -n kube-system delete pods kube-proxy-57bhn kube-proxy-854kz kube-proxy-cnq7t kube-proxy-s9plr
pod "kube-proxy-57bhn" deleted from kube-system namespace
pod "kube-proxy-854kz" deleted from kube-system namespace
pod "kube-proxy-cnq7t" deleted from kube-system namespace
pod "kube-proxy-s9plr" deleted from kube-system namespace
[root@k8s-master mateLLB]# kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
coredns-697886855d-5whcs 1/1 Running 0 25m
coredns-697886855d-wcrt5 1/1 Running 0 25m
etcd-k8s-master 1/1 Running 1 (3d23h ago) 25m
kube-apiserver-k8s-master 1/1 Running 0 25m
kube-controller-manager-k8s-master 1/1 Running 2 (27m ago) 25m
kube-proxy-c6snt 1/1 Running 0 2s
kube-proxy-m7wdg 1/1 Running 0 2s
kube-proxy-p94tw 1/1 Running 0 2s
kube-proxy-pdbxw 1/1 Running 0 2s
kube-scheduler-k8s-master 1/1 Running 2 (27m ago) 25m
更改metallb的配置文件
bash
[root@k8s-master metaLLB]# vim 1-metallb-native.yaml
2136: image: metallb/controller:v0.16.1
2233: image: metallb/speaker:v0.16.1
[root@k8s-master metaLLB]# vim 2-metallb-confmap.yml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 172.25.254.50-172.25.254.99
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
spec:
ipAddressPools:
- first-pool
[root@k8s-master metaLLB]# kubectl apply -f 2-metallb-confmap.yml -f 1-metallb-native.yaml
验证
bash
[root@k8s-master metaLLB]# kubectl get namespaces
NAME STATUS AGE
cephfs Active 4d
cephrdb Active 3d21h
default Active 14d
ingress-nginx Active 8d
kube-node-lease Active 14d
kube-public Active 14d
kube-system Active 14d
metallb-system Active 9d
nfs-storage Active 4d19h
[root@k8s-master metaLLB]# kubectl -n metallb-system get pods
NAME READY STATUS RESTARTS AGE
controller-b7cdf5787-gxsj9 1/1 Running 4 (2d1h ago) 9d
speaker-ntd2c 1/1 Running 3 (2d1h ago) 9d
speaker-wrc2b 1/1 Running 4 (2d1h ago) 9d
speaker-x72qg 1/1 Running 2 (7d2h ago) 9d
[root@k8s-master metaLLB]# kubectl -n metallb-system get cm
NAME DATA AGE
kube-root-ca.crt 1 9d
metallb-excludel2 1 9d
[root@k8s-master services]# kubectl delete -f loadbalancer.yml
service "webservice" deleted from default namespace
deployment.apps "webcluster" deleted from default namespace
[root@k8s-master services]# kubectl apply -f loadbalancer.yml
service/webservice created
deployment.apps/webcluster created
[root@k8s-master services]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d19h
webservice LoadBalancer 10.111.118.75 172.25.254.50 80:49082/TCP 11s
7 service的extrnalname模式
ExternalName 是一种特殊的 Service 类型,它不代理集群内的 Pod,而是将 Service 直接映射到集群外部的某个域名(CNAME 记录),让集群内的 Pod 可以通过 Service 名称访问外部服务。
bash
[root@k8s-master services]# vim extrnalname.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: extrnalname
name: extrnalname
spec:
selector:
app: extrnalname
type: ExternalName
externalName: www.timinglee.org
[root@k8s-master services]# kubectl apply -f extrnalname.yaml
service/extrnalname created
[root@k8s-master services]# kubectl get svc extrnalname
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
extrnalname ExternalName <none> www.timinglee.org <none> 5s
8 ingress七层代理
Ingress 是 Kubernetes 中专门管理集群内服务对外访问的 API 对象,工作在 OSI 模型的第七层(应用层),基于域名和 URL 路径将外部 HTTP/HTTPS 请求路由到不同的 Service。
8.1 igress的部署
下载deploy文件
bash
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/baremetal/deploy.yaml
准备ingress所需镜像
bash
[root@k8s-master ingress-v1.5.1]# docker load -i ingress-v1.15.1.tar
[root@k8s-master ingress-v1.5.1]# docker tag registry.k8s.io/ingress-nginx/controller:v1.15.1 reg.timinglee.org/ingress-nginx/controller:v1.15.1
[root@k8s-master ingress-v1.5.1]# docker push reg.timinglee.org/ingress-nginx/controller:v1.15.1
[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9 reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.6.9
[root@k8s-master ~]# docker push reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.6.9
更改deploy.yaml
可以在vim中用/image查找,按n往下查询
bash
[root@k8s-master ingress-v1.5.1]# vim deploy.yaml
444: image: ingress-nginx/controller:v1.15.1
547: image: ingress-nginx/kube-webhook-certgen:v1.6.9
603: image: ingress-nginx/kube-webhook-certgen:v1.6.9
365 type: LoadBalancer
通过deplay.yaml部署ingress
bash
[root@k8s-master ingress-v1.5.1]# kubectl apply -f deploy.yaml
[root@k8s-master ingress-v1.5.1]# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.110.84.218 172.25.254.52 80:32823/TCP,443:38605/TCP 8d
ingress-nginx-controller-admission ClusterIP 10.103.190.180 <none> 443/TCP 8d
8.2 ingress功能的基本实现
ingress必须和输出的service资源处于同一namespace
建立ingress代理的微服务
bash
#业务1
[root@k8s-master services]# kubectl create deployment myappv1 --image myapp:v1 --replicas 2 --dry-run=client -o yaml > myappv1.yaml
[root@k8s-master services]# kubectl create service clusterip servicev1 --tcp 80:80 --dry-run=client -o yaml >> myappv1.yaml
[root@k8s-master services]# vim myappv1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myappv1
name: myappv1
spec:
replicas: 2
selector:
matchLabels:
app: myappv1
template:
metadata:
labels:
app: myappv1
spec:
containers:
- image: myapp:v1
name: myapp
---
apiVersion: v1
kind: Service
metadata:
labels:
app: servicev1
name: servicev1
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: myappv1
type: ClusterIP
#业务2
[root@k8s-master services]# vim myappv2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myappv2
name: myappv2
spec:
replicas: 2
selector:
matchLabels:
app: myappv2
template:
metadata:
labels:
app: myappv2
spec:
containers:
- image: myapp:v2
name: myapp
---
apiVersion: v1
kind: Service
metadata:
labels:
app: servicev2
name: servicev2
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: myappv2
type: ClusterIP
[root@k8s-master ingress-v1.5.1]# kubectl apply -f myappv1.yaml
deployment.apps/myappv1 created
service/servicev1 created
[root@k8s-master ingress-v1.5.1]# kubectl apply -f myappv2.yaml
deployment.apps/myappv2 created
service/servicev2 created
[root@k8s-master ingress-v1.5.1]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d19h
servicev1 ClusterIP 10.110.41.119 <none> 80/TCP 25s
servicev2 ClusterIP 10.98.160.186 <none> 80/TCP 19s
#保证都能够访问到
[root@k8s-master ingress-v1.5.1]# curl 10.110.41.119
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl 10.98.160.186
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myappv1-8676894bf8-ck6j8 1/1 Running 0 43m
myappv1-8676894bf8-tqnws 1/1 Running 0 43m
myappv2-688fc4d776-xsbk6 1/1 Running 0 43m
myappv2-688fc4d776-zggc2 1/1 Running 0 43m
建立ingress
bash
[root@k8s-master services]# kubectl create ingress ingress1 --class nginx --rule "*/=servicev1:80" --dry-run=client -o yaml > 1-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: 'www.timinglee.org'
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /v1
pathType: Prefix
- backend:
service:
name: servicev2
port:
number: 80
path: /v2
pathType: Prefix
[root@k8s-master services]# kubectl apply -f 1-ingress.yml
[root@k8s-master services]# kubectl describe ingress ingress1

测试
bash
#需要在hosts上面添加上域名解析
[root@k8s-master ingress-v1.5.1]# vim /etc/hosts
172.25.254.52 www.timinglee.org myapp1.timinglee.org myapp2.timinglee.org myapp-tls.timinglee.org
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/v1
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/v2
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
8.3 基于域名的访问
bash
[root@k8s-master services]# vim 2-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
# nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp1.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /
pathType: Prefix
- host: myapp2.timinglee.org
http:
paths:
- backend:
service:
name: servicev2
port:
number: 80
path: /
pathType: Prefix
[root@k8s-master services]# kubectl apply -f 2-ingress.yaml
ingress.networking.k8s.io/ingress1 created
[root@k8s-master services]# kubectl describe ingress ingress1

bash
#需要在hosts上面添加上域名解析
[root@k8s-master ingress-v1.5.1]# vim /etc/hosts
172.25.254.52 www.timinglee.org myapp1.timinglee.org myapp2.timinglee.org myapp-tls.timinglee.org
#验证
[root@k8s-master ingress-v1.5.1]# curl myapp1.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl myapp2.timinglee.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
88.4 基于动静分离
bash
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /index.html
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /php
pathType: ImplementationSpecific
- backend:
service:
name: servicev2
port:
number: 80
path: /static
pathType: ImplementationSpecific
[root@k8s-master ingress-v1.5.1]# kubectl apply -f 3-ingress.yaml
ingress.networking.k8s.io/ingress1 created
#验证访问不同的目录,以实现分离
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/php/
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/static/
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
8.5 tls加密访问
bash
[root@k8s-master ~]# openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -subj "/CN=nginxsvc/O=nginxsvc" -out tls.crt
kubectl create secret tls web-tls-secret --key tls.key --cert tls.crt
secret/web-tls-secret created
[root@k8s-master services]# vim 4-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- myapp-tls.timinglee.org
secretName: web-tls-secret
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /
pathType: Prefix
[root@k8s-master ingress-v1.5.1]# kubectl apply -f 4-ingress.yml
ingress.networking.k8s.io/ingress1 created
[root@k8s-master ingress-v1.5.1]# curl -k https://www.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
8.6 auth认证
生成认证文件并将认证文件注入k8s中
bash
#安装生成认证文件模板工具
[root@k8s-master ~]# dnf install httpd-tools -y
#生成认证文件
[root@k8s-master ~]# htpasswd -cm auth admin #这里的密码是验证是所需要的密码
[root@k8s-master ~]# cat auth
admin:$apr1$k8PiN9hR$TWLIGse6Y9oGgGFZr96P00
#将认证文件注入k8s中
[root@k8s-master ~]# kubectl create secret generic web-auth --from-file auth
在ingress中配置auth认证
bash
[root@k8s-master services]# vim 5-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: web-auth
nginx.ingress.kubernetes.io/auth-realm: "Please input username and password"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /v1
pathType: Prefix
[root@k8s-master services]# kubectl apply -f 5-ingress.yaml
验证auth
bash
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/v1
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/v1 -uadmin:123
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
8.7 ingress中的网页重写
利用网页从写定义默认发布文件
bash
[root@k8s-master ingress-v1.5.1]# kubectl apply -f 6-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
nginx.ingress.kubernetes.io/app-root: /hostname.html
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /
pathType: Prefix
ingress.networking.k8s.io/ingress1 created
[root@k8s-master ingress-v1.5.1]# curl -I www.timinglee.org
HTTP/1.1 302 Moved Temporarily
Date: Thu, 03 Sep 2026 05:58:44 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
Location: http://www.timinglee.org/hostname.html
[root@k8s-master ingress-v1.5.1]# curl -L www.timinglee.org
myappv1-8676894bf8-tqnws
[root@k8s-master ingress-v1.5.1]#
利用正侧表达式从定向网页
bash
[root@k8s-master ingress-v1.5.1]# vim 6-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /
pathType: Prefix
- backend:
service:
name: servicev2
port:
number: 80
path: /lee(/*.*/*|$)(.*)
pathType: ImplementationSpecific
[root@k8s-master ingress-v1.5.1]# kubectl apply -f 6-ingress.yaml
ingress.networking.k8s.io/ingress1 configured
[root@k8s-master ingress-v1.5.1]# curl -L www.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl -L www.timinglee.org/lee
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl -L www.timinglee.org/lee/a
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl -L www.timinglee.org/lee/a/a
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
9 金丝雀发布(cannary)
9.1 基于headr的灰度发布
bash
[root@k8s-master services]# vim cannary.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress2
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "version" #基于head发布
nginx.ingress.kubernetes.io/canary-by-header-value: "2" #访问的值为2
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev2
port:
number: 80
path: /
pathType: Prefix
[root@k8s-master services]# kubectl apply -f cannary.yaml
ingress.networking.k8s.io/ingress1 configured
ingress.networking.k8s.io/ingress2 created
[root@k8s-master services]# curl www.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master services]# curl -H "version:2" www.timinglee.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
9.2 基于权重的灰度发布
bash
[root@k8s-master services]# vim cannary.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
annotations:
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev1
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress2
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" #占总量100的10%
nginx.ingress.kubernetes.io/canary-weight-total: "100"
spec:
ingressClassName: nginx
rules:
- host: www.timinglee.org
http:
paths:
- backend:
service:
name: servicev2
port:
number: 80
path: /
pathType: Prefix
[root@k8s-master services]# kubectl apply -f cannary.yaml
ingress.networking.k8s.io/ingress1 unchanged
ingress.networking.k8s.io/ingress2 configured
验证
bash
#创建一个脚本来进行验证流量打上去多少
[root@k8s-master services]# vim check_cannary.sh
#!/bin/bash
v1=0
v2=0
for (( i=0; i<100; i++))
do
response=`curl -s www.timinglee.org |grep -c v1`
v1=`expr $v1 + $response`
v2=`expr $v2 + 1 - $response`
done
echo "v1:$v1, v2:$v2"
[root@k8s-master services]# sh check_cannary.sh
v1:86, v2:14
[root@k8s-master services]#