云原生——k8s中的微服务

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]# 
相关推荐
分布式存储与RustFS1 小时前
用 RustFS 原生 CLI `rc` 管对象存储:从 alias 到 cp 的完整玩法
云原生·开源·对象存储·分布式存储·s3·rustfs·性能基准
分布式存储与RustFS1 小时前
用 RPM/DEB 包在 Linux 上安装 RustFS:生产落地第一步
云原生·开源·对象存储·分布式存储·s3·rustfs·性能基准
^酸酸2 小时前
Kubernetes 运维实战:临时容器、端口转发与资源管理详解
运维·容器·kubernetes
阿里云云原生2 小时前
阿里云微服务引擎 MSE 及 API 网关 2026 年 8 月产品动态
阿里云·微服务·云计算
奇特認2 小时前
kubernetes 微服务
微服务·容器·kubernetes
专注仿真3 小时前
Go操作Kubernetes API
贪心算法·golang·kubernetes
UseLessQQ3 小时前
云原生 kubernetes 中的service
云原生·容器·kubernetes
大大大大晴天️3 小时前
把湖仓一体放进 K8s:Iceberg、Hudi、Paimon 如何重塑云原生大数据架构
大数据·云原生·kubernetes
智购科技无人售货机工厂3 小时前
2026自动售货机云端API设计规范:从RESTful到GraphQL的接口演进~YH
android·人工智能·驱动开发·单片机·云原生·pandas·设计规范