k8s中的微服务

一、什么是微服务

用控制器来完成集群的工作负载,那么应用如何暴漏出去?需要通过微服务暴漏出去后才能被访问

  • Service是一组提供相同服务的Pod对外开放的接口。

  • 借助Service,应用可以实现服务发现和负载均衡。

  • service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)

二 微服务的类型

微服务类型作用描述
ClusterIP默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问
NodePort将Service通过指定的Node上的端口暴露给外部,访问任意一个NodeIP:nodePort都将路由到ClusterIP
LoadBalancer在NodePort的基础上,借助cloud provider创建一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort,此模式只能在云服务器上使用
ExternalName将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定

示例:

生成控制器文件并建立控制器
kubectl create deployment timinglee --image myapp:v1  --replicas 2 --dry-run=client -o yaml > timinglee.yaml
生成微服务yaml追加到已有yaml中
kubectl expose deployment timinglee --port 80 --target-port 80 --dry-run=client -o yaml >> timinglee.yaml
​
[root@k8s-master ~]# vim timinglee.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: timingleename: timinglee
spec:replicas: 2selector:matchLabels:app: timingleetemplate:metadata:creationTimestamp: nulllabels:app: timingleespec:containers:- image: myapp:v1name: myapp
---                                     #不同资源间用---隔开
​
apiVersion: v1
kind: Service
metadata:labels:app: timingleename: timinglee
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: timinglee
​
[root@k8s-master ~]# kubectl apply  -f timinglee.yaml
deployment.apps/timinglee created
service/timinglee created
​
[root@k8s-master ~]# kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   19h
timinglee    ClusterIP   10.99.127.134   <none>        80/TCP    16s
​

微服务默认使用iptables调度

[root@k8s-master ~]# kubectl get services  -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE    SELECTOR
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   19h    <none>
timinglee    ClusterIP   10.99.127.134   <none>        80/TCP    119s   app=timinglee           #集群内部IP 134
​
#可以在火墙中查看到策略信息
[root@k8s-master ~]# iptables -t nat -nL
KUBE-SVC-I7WXYK76FWYNTTGM  6    --  0.0.0.0/0            10.99.127.134        /* default/timinglee cluster IP */ tcp dpt:80

三 ipvs模式

  • Service 是由 kube-proxy 组件,加上 iptables 来共同实现的

  • kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源

  • IPVS模式的service,可以使K8s集群支持更多量级的Pod

3.1 ipvs模式配置方式

1 在所有节点中安装ipvsadm

[root@k8s-所有节点 pod]yum install ipvsadm –y

2 修改master节点的代理配置

[root@k8s-master ~]# kubectl -n kube-system edit cm kube-proxymetricsBindAddress: ""mode: "ipvs"                            #设置kube-proxy使用ipvs模式nftables:

3 重启pod,在pod运行时配置文件中采用默认配置,当改变配置文件后已经运行的pod状态不会变化,所以要重启pod

[root@k8s-master ~]# kubectl -n kube-system get  pods   | awk '/kube-proxy/{system("kubectl -n kube-system delete pods "$1)}'
​
[root@k8s-master ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr-> 172.25.254.100:6443          Masq    1      0          0
TCP  10.96.0.10:53 rr-> 10.244.0.2:53                Masq    1      0          0-> 10.244.0.3:53                Masq    1      0          0
TCP  10.96.0.10:9153 rr-> 10.244.0.2:9153              Masq    1      0          0-> 10.244.0.3:9153              Masq    1      0          0
TCP  10.97.59.25:80 rr-> 10.244.1.17:80               Masq    1      0          0-> 10.244.2.13:80               Masq    1      0          0
UDP  10.96.0.10:53 rr-> 10.244.0.2:53                Masq    1      0          0-> 10.244.0.3:53                Masq    1      0          0
​

[!NOTE]

切换ipvs模式后,kube-proxy会在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配所有service IP

[root@k8s-master ~]# ip a | tailinet6 fe80::c4fb:e9ff:feee:7d32/64 scope linkvalid_lft forever preferred_lft forever
8: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group defaultlink/ether fe:9f:c8:5d:a6:c8 brd ff:ff:ff:ff:ff:ffinet 10.96.0.10/32 scope global kube-ipvs0valid_lft forever preferred_lft foreverinet 10.96.0.1/32 scope global kube-ipvs0valid_lft forever preferred_lft foreverinet 10.97.59.25/32 scope global kube-ipvs0valid_lft forever preferred_lft forever

四 微服务类型详解

4.1 clusterip

特点:

clusterip模式只能在集群内访问,并对集群内的pod提供健康检测和自动发现功能

示例:

[root@k8s2 service]# vim myapp.yml
---
apiVersion: v1
kind: Service
metadata:labels:app: timingleename: timinglee
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: timingleetype: ClusterIP
​
​
service创建后集群DNS提供解析
[root@k8s-master ~]# dig  timinglee.default.svc.cluster.local @10.96.0.10
​
; <<>> DiG 9.16.23-RH <<>> timinglee.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27827
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
​
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 057d9ff344fe9a3a (echoed)
;; QUESTION SECTION:
;timinglee.default.svc.cluster.local. IN        A
​
;; ANSWER SECTION:
timinglee.default.svc.cluster.local. 30 IN A    10.97.59.25
​
;; Query time: 8 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Wed Sep 04 13:44:30 CST 2024
;; MSG SIZE  rcvd: 127

4.2 ClusterIP中的特殊模式headless

headless(无头服务)

对于无头 Services 并不会分配 Cluster IP,kube-proxy不会处理它们, 而且平台也不会为它们进行负载均衡和路由,集群访问通过dns解析直接指向到业务pod上的IP,所有的调度有dns单独完成

[root@k8s-master ~]# vim timinglee.yaml
---
apiVersion: v1
kind: Service
metadata:labels:app: timingleename: timinglee
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: timingleetype: ClusterIPclusterIP: None
​
​
[root@k8s-master ~]# kubectl delete -f timinglee.yaml
[root@k8s-master ~]# kubectl apply -f timinglee.yaml
deployment.apps/timinglee created
​
#测试
[root@k8s-master ~]# kubectl get services timinglee
NAME        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
timinglee   ClusterIP   None         <none>        80/TCP    6s
​
[root@k8s-master ~]# dig  timinglee.default.svc.cluster.local @10.96.0.10
​
; <<>> DiG 9.16.23-RH <<>> timinglee.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51527
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
​
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 81f9c97b3f28b3b9 (echoed)
;; QUESTION SECTION:
;timinglee.default.svc.cluster.local. IN        A
​
;; ANSWER SECTION:
timinglee.default.svc.cluster.local. 20 IN A    10.244.2.14     #直接解析到pod上
timinglee.default.svc.cluster.local. 20 IN A    10.244.1.18
​
;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Wed Sep 04 13:58:23 CST 2024
;; MSG SIZE  rcvd: 178
​
​
#开启一个busyboxplus的pod测试
[root@k8s-master ~]# kubectl run  test --image busyboxplus -it
If you don't see a command prompt, try pressing enter.
/ # nslookup timinglee-service
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
​
Name:      timinglee-service
Address 1: 10.244.2.16 10-244-2-16.timinglee-service.default.svc.cluster.local
Address 2: 10.244.2.17 10-244-2-17.timinglee-service.default.svc.cluster.local
Address 3: 10.244.1.22 10-244-1-22.timinglee-service.default.svc.cluster.local
Address 4: 10.244.1.21 10-244-1-21.timinglee-service.default.svc.cluster.local
/ # curl timinglee-service
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl timinglee-service/hostname.html
timinglee-c56f584cf-b8t6m
​
​

4.3 nodeport

通过ipvs暴漏端口从而使外部主机通过master节点的对外ip:<port>来访问pod业务

其访问过程为:

示例:

[root@k8s-master ~]# vim timinglee.yaml
---
​
apiVersion: v1
kind: Service
metadata:labels:app: timinglee-servicename: timinglee-service
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: timingleetype: NodePort
​
[root@k8s-master ~]# kubectl apply -f timinglee.yaml
deployment.apps/timinglee created
service/timinglee-service created
[root@k8s-master ~]# kubectl get services  timinglee-service
NAME                TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
timinglee-service   NodePort   10.98.60.22   <none>        80:31771/TCP   8
​
nodeport在集群节点上绑定端口,一个端口对应一个服务
[root@k8s-master ~]# for i in {1..5}
> do
> curl 172.25.254.100:31771/hostname.html
> done
timinglee-c56f584cf-fjxdk
timinglee-c56f584cf-5m2z5
timinglee-c56f584cf-z2w4d
timinglee-c56f584cf-tt5g6
timinglee-c56f584cf-fjxdk
​

[!NOTE]

nodeport默认端口

nodeport默认端口是30000-32767,超出会报错

[root@k8s-master ~]# vim timinglee.yaml
apiVersion: v1
kind: Service
metadata:labels:app: timinglee-servicename: timinglee-service
spec:ports:
​- port: 80protocol: TCPtargetPort: 80nodePort: 33333selector:app: timingleetype: NodePort
​
[root@k8s-master ~]# kubectl apply -f timinglee.yaml
deployment.apps/timinglee created
The Service "timinglee-service" is invalid: spec.ports[0].nodePort: Invalid value: 33333: provided port is not in the valid range. The range of valid ports is 30000-32767

如果需要使用这个范围以外的端口就需要特殊设定

[root@k8s-master ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
​
- --service-node-port-range=30000-40000

[!NOTE]

添加“--service-node-port-range=“ 参数,端口范围可以自定义

修改后api-server会自动重启,等apiserver正常启动后才能操作集群

集群重启自动完成在修改完参数后全程不需要人为干预

4.4 loadbalancer

云平台会为我们分配vip并实现访问,如果是裸金属主机那么需要metallb来实现ip的分配

[root@k8s-master ~]# vim timinglee.yaml
​
---
apiVersion: v1
kind: Service
metadata:labels:app: timinglee-servicename: timinglee-service
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: timingleetype: LoadBalancer
​
[root@k8s2 service]# kubectl apply -f myapp.yml
​
默认无法分配外部访问IP
[root@k8s2 service]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP        4d1h
myapp        LoadBalancer   10.107.23.134   <pending>     80:32537/TCP   4s
​
LoadBalancer模式适用云平台,裸金属环境需要安装metallb提供支持

4.5 metalLB

官网:Installation :: MetalLB, bare metal load-balancer for Kubernetes

metalLB功能

为LoadBalancer分配vip

部署方式

1.设置ipvs模式
[root@k8s-master ~]# kubectl edit cm -n kube-system kube-proxy
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:strictARP: true
​
[root@k8s-master ~]# kubectl -n kube-system get  pods   | awk '/kube-proxy/{system("kubectl -n kube-system delete pods "$1)}'
​
2.下载部署文件
[root@k8s2 metallb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
​
3.修改文件中镜像地址,与harbor仓库路径保持一致
[root@k8s-master ~]# vim metallb-native.yaml
...
image: metallb/controller:v0.14.8
image: metallb/speaker:v0.14.8
​
4.上传镜像到harbor
[root@k8s-master ~]# docker pull quay.io/metallb/controller:v0.14.8
[root@k8s-master ~]# docker pull quay.io/metallb/speaker:v0.14.8
​
[root@k8s-master ~]# docker tag quay.io/metallb/speaker:v0.14.8 reg.timinglee.org/metallb/speaker:v0.14.8
[root@k8s-master ~]# docker tag quay.io/metallb/controller:v0.14.8 reg.timinglee.org/metallb/controller:v0.14.8
​
[root@k8s-master ~]# docker push reg.timinglee.org/metallb/speaker:v0.14.8
[root@k8s-master ~]# docker push reg.timinglee.org/metallb/controller:v0.14.8
​
​
部署服务
[root@k8s2 metallb]# kubectl apply -f metallb-native.yaml
[root@k8s-master ~]# kubectl -n metallb-system get pods
NAME                          READY   STATUS    RESTARTS   AGE
controller-65957f77c8-25nrw   1/1     Running   0          30s
speaker-p94xq                 1/1     Running   0          29s
speaker-qmpct                 1/1     Running   0          29s
speaker-xh4zh                 1/1     Running   0          30s
​
配置分配地址段
[root@k8s-master ~]# vim configmap.yml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: first-pool                      #地址池名称namespace: metallb-system
spec:addresses:- 172.25.254.50-172.25.254.99         #修改为自己本地地址段
​
---                                     #两个不同的kind中间必须加分割
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: examplenamespace: metallb-system
spec:ipAddressPools:- first-pool                          #使用地址池 
​
[root@k8s-master ~]# kubectl apply -f configmap.yml
ipaddresspool.metallb.io/first-pool created
l2advertisement.metallb.io/example created
​
​
[root@k8s-master ~]# kubectl get services
NAME                TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
kubernetes          ClusterIP      10.96.0.1       <none>          443/TCP        21h
timinglee-service   LoadBalancer   10.109.36.123   172.25.254.50   80:31595/TCP   9m9s
​
​
#通过分配地址从集群外访问服务
[root@reg ~]# curl  172.25.254.50
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
​

4.6 externalname

  • 开启services后,不会被分配IP,而是用dns解析CNAME固定域名来解决ip变化问题

  • 一般应用于外部业务和pod沟通或外部业务迁移到pod内时

  • 在应用向集群迁移过程中,externalname在过度阶段就可以起作用了。

  • 集群外的资源迁移到集群时,在迁移的过程中ip可能会变化,但是域名+dns解析能完美解决此问题

示例:

[root@k8s-master ~]# vim timinglee.yaml
---
apiVersion: v1
kind: Service
metadata:labels:app: timinglee-servicename: timinglee-service
spec:selector:app: timingleetype: ExternalNameexternalName: www.timinglee.org
[root@k8s-master ~]# kubectl apply -f timinglee.yaml
​
[root@k8s-master ~]# kubectl get services  timinglee-service
NAME                TYPE           CLUSTER-IP   EXTERNAL-IP         PORT(S)   AGE
timinglee-service   ExternalName   <none>       www.timinglee.org   <none>    2m58s
​

五 Ingress-nginx

官网:

Installation Guide - Ingress-Nginx Controller

5.1 ingress-nginx功能

  • 一种全局的、为了代理不同后端 Service 而设置的负载均衡服务,支持7层

  • Ingress由两部分组成:Ingress controller和Ingress服务

  • Ingress Controller 会根据你定义的 Ingress 对象,提供对应的代理能力。

  • 业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller。

5.2 部署ingress

5.2.1 下载部署文件

[root@k8s-master ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/baremetal/deploy.yaml

上传ingress所需镜像到harbor

[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/controller:v1.11.2@sha256:d5f8217feeac4887cb1ed21f27c2674e58be06bd8f5184cacea2a69abaf78dce reg.timinglee.org/ingress-nginx/controller:v1.11.2
​
[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3@sha256:a320a50cc91bd15fd2d6fa6de58bd98c1bd64b9a6f926ce23a600d87043455a3 reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.4.3
​
[root@k8s-master ~]# docker push reg.timinglee.org/ingress-nginx/controller:v1.11.2
[root@k8s-master ~]# docker push reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.4.3

5.2.2 安装ingress

[root@k8s-master ~]# vim deploy.yaml
445         image: ingress-nginx/controller:v1.11.2
546         image: ingress-nginx/kube-webhook-certgen:v1.4.3
599         image: ingress-nginx/kube-webhook-certgen:v1.4.3
​
[root@k8s-master ~]# kubectl -n ingress-nginx get pods
NAME                                       READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-ggqm6       0/1     Completed   0          82s
ingress-nginx-admission-patch-q4wp2        0/1     Completed   0          82s
ingress-nginx-controller-bb7d8f97c-g2h4p   1/1     Running     0          82s
[root@k8s-master ~]# kubectl -n ingress-nginx get svc
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.103.33.148   <none>        80:34512/TCP,443:34727/TCP   108s
ingress-nginx-controller-admission   ClusterIP   10.103.183.64   <none>        443/TCP                      108s
​
​
#修改微服务为loadbalancer
[root@k8s-master ~]# kubectl -n ingress-nginx edit svc ingress-nginx-controller
49   type: LoadBalancer
​
[root@k8s-master ~]# kubectl -n ingress-nginx get services
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.103.33.148   172.25.254.50   80:34512/TCP,443:34727/TCP   4m43s
ingress-nginx-controller-admission   ClusterIP      10.103.183.64   <none>          443/TCP                      4m43s

[!NOTE]

在ingress-nginx-controller中看到的对外IP就是ingress最终对外开放的ip

5.2.3 测试ingress

#生成yaml文件
[root@k8s-master ~]# kubectl create ingress webcluster --rule '*/=timinglee-svc:80' --dry-run=client -o yaml > timinglee-ingress.yml
​
[root@k8s-master ~]# vim timinglee-ingress.yml
aapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: test-ingress
spec:ingressClassName: nginxrules:- http:paths:- backend:service:name: timinglee-svcport:number: 80path: /pathType: Prefix    #Exact(精确匹配),ImplementationSpecific(特定实现),Prefix(前缀匹配),Regular expression(正则表达式匹配)
#建立ingress控制器
[root@k8s-master ~]# kubectl apply -f timinglee-ingress.yml
ingress.networking.k8s.io/webserver created
​
[root@k8s-master ~]# kubectl get ingress
NAME           CLASS   HOSTS   ADDRESS         PORTS   AGE
test-ingress   nginx   *       172.25.254.10   80      8m30s
​
​
[root@reg ~]# for n in {1..5}; do curl 172.25.254.50/hostname.html; done
timinglee-c56f584cf-8jhn6
timinglee-c56f584cf-8cwfm
timinglee-c56f584cf-8jhn6
timinglee-c56f584cf-8cwfm
timinglee-c56f584cf-8jhn6

[!NOTE]

ingress必须和输出的service资源处于同一namespace

5.3 ingress 的高级用法

5.3.1 基于路径的访问

1.建立用于测试的控制器myapp

[root@k8s-master app]# kubectl create deployment myapp-v1 --image myapp:v1 --dry-run=client -o yaml > myapp-v1.yaml[root@k8s-master app]# kubectl create deployment myapp-v2 --image myapp:v2 --dry-run=client -o yaml > myapp-v2.yaml[root@k8s-master app]# vim myapp-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: myapp-v1name: myapp-v1
spec:replicas: 1selector:matchLabels:app: myapp-v1strategy: {}template:metadata:labels:app: myapp-v1spec:containers:- image: myapp:v1name: myapp---apiVersion: v1
kind: Service
metadata:labels:app: myapp-v1name: myapp-v1
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: myapp-v1
[root@k8s-master app]# vim myapp-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: myapp-v2name: myapp-v2
spec:replicas: 1selector:matchLabels:app: myapp-v2template:metadata:labels:app: myapp-v2spec:containers:- image: myapp:v2name: myapp
---
apiVersion: v1
kind: Service
metadata:labels:app: myapp-v2name: myapp-v2
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: myapp-v2
[root@k8s-master app]# kubectl expose deployment myapp-v1 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v1.yaml[root@k8s-master app]# kubectl expose deployment myapp-v2 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v1.yaml[root@k8s-master app]# kubectl get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   29h
myapp-v1     ClusterIP   10.104.84.65     <none>        80/TCP    13s
myapp-v2     ClusterIP   10.105.246.219   <none>        80/TCP    7s

2.建立ingress的yaml

[root@k8s-master app]# vim ingress1.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /		#访问路径后加任何内容都被定向到/name: ingress1
spec:ingressClassName: nginxrules:- host: www.timinglee.orghttp:paths:- backend:service:name: myapp-v1port:number: 80path: /v1pathType: Prefix- backend:service:name: myapp-v2port:number: 80path: /v2pathType: Prefix
#测试:
[root@reg ~]# echo 172.25.254.50 www.timinglee.org >> /etc/hosts[root@reg ~]# curl  www.timinglee.org/v1
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@reg ~]# curl  www.timinglee.org/v2
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>#nginx.ingress.kubernetes.io/rewrite-target: / 的功能实现
[root@reg ~]# curl  www.timinglee.org/v2/aaaa
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

5.3.2 基于域名的访问

#在测试主机中设定解析
[root@reg ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.250 reg.timinglee.org
172.25.254.50 www.timinglee.org myappv1.timinglee.org myappv2.timinglee.org# 建立基于域名的yml文件
[root@k8s-master app]# vim ingress2.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /name: ingress2
spec:ingressClassName: nginxrules:- host: myappv1.timinglee.orghttp:paths:- backend:service:name: myapp-v1port:number: 80path: /pathType: Prefix- host: myappv2.timinglee.orghttp:paths:- backend:service:name: myapp-v2port:number: 80path: /pathType: Prefix
        
#利用文件建立ingress
[root@k8s-master app]# kubectl apply -f ingress2.yml
ingress.networking.k8s.io/ingress2 created[root@k8s-master app]# kubectl describe ingress ingress2
Name:             ingress2
Labels:           <none>
Namespace:        default
Address:
Ingress Class:    nginx
Default backend:  <default>
Rules:Host                   Path  Backends----                   ----  --------myappv1.timinglee.org/   myapp-v1:80 (10.244.2.31:80)myappv2.timinglee.org/   myapp-v2:80 (10.244.2.32:80)
Annotations:             nginx.ingress.kubernetes.io/rewrite-target: /
Events:Type    Reason  Age   From                      Message----    ------  ----  ----                      -------Normal  Sync    21s   nginx-ingress-controller  Scheduled for sync#在测试主机中测试
[root@reg ~]# curl  www.timinglee.org/v1
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@reg ~]# curl  www.timinglee.org/v2
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

5.3.3 建立tls加密

#建立证书
[root@k8s-master app]# openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -subj "/CN=nginxsvc/O=nginxsvc" -out tls.crt
#建立加密资源类型secret
[root@k8s-master app]# kubectl create secret tls  web-tls-secret --key tls.key --cert tls.crt
secret/web-tls-secret created
[root@k8s-master app]# kubectl get secrets
NAME             TYPE                DATA   AGE
web-tls-secret   kubernetes.io/tls   2      6s

[!NOTE]

secret通常在kubernetes中存放敏感数据,他并不是一种加密方式,在后面课程中会有专门讲解

#建立ingress3基于tls认证的yml文件
[root@k8s-master app]# vim ingress3.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /name: ingress3
spec:tls:- hosts:- myapp-tls.timinglee.orgsecretName: web-tls-secretingressClassName: nginxrules:- host: myapp-tls.timinglee.orghttp:paths:- backend:service:name: myapp-v1port:number: 80path: /pathType: Prefix
        
#测试
[root@reg ~]# curl -k https://myapp-tls.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

5.3.4 建立auth认证

#建立认证文件
[root@k8s-master app]# dnf install httpd-tools -y
[root@k8s-master app]# htpasswd -cm auth lee
New password:
Re-type new password:
Adding password for user lee
[root@k8s-master app]# cat auth
lee:$apr1$BohBRkkI$hZzRDfpdtNzue98bFgcU10#建立认证类型资源
[root@k8s-master app]# kubectl create secret generic auth-web --from-file auth
root@k8s-master app]# kubectl describe secrets auth-web
Name:         auth-web
Namespace:    default
Labels:       <none>
Annotations:  <none>Type:  OpaqueData
====
auth:  42 bytes
#建立ingress4基于用户认证的yaml文件
[root@k8s-master app]# vim ingress4.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/auth-type: basicnginx.ingress.kubernetes.io/auth-secret: auth-webnginx.ingress.kubernetes.io/auth-realm: "Please input username and password"name: ingress4
spec:tls:- hosts:- myapp-tls.timinglee.orgsecretName: web-tls-secretingressClassName: nginxrules:- host: myapp-tls.timinglee.orghttp:paths:- backend:service:name: myapp-v1port:number: 80path: /pathType: Prefix
#建立ingress4
[root@k8s-master app]# kubectl apply -f ingress4.yml
ingress.networking.k8s.io/ingress4 created
[root@k8s-master app]# kubectl describe ingress ingress4
Name:             ingress4
Labels:           <none>
Namespace:        default
Address:
Ingress Class:    nginx
Default backend:  <default>
TLS:web-tls-secret terminates myapp-tls.timinglee.org
Rules:Host                     Path  Backends----                     ----  --------myapp-tls.timinglee.org/   myapp-v1:80 (10.244.2.31:80)
Annotations:               nginx.ingress.kubernetes.io/auth-realm: Please input username and passwordnginx.ingress.kubernetes.io/auth-secret: auth-webnginx.ingress.kubernetes.io/auth-type: basic
Events:Type    Reason  Age   From                      Message----    ------  ----  ----                      -------Normal  Sync    14s   nginx-ingress-controller  Scheduled for sync#测试:
[root@reg ~]# curl -k https://myapp-tls.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@reg ~]# vim /etc/hosts ^C
[root@reg ~]# curl -k https://myapp-tls.timinglee.org
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>[root@reg ~]# curl -k https://myapp-tls.timinglee.org -ulee:lee
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

5.3.5 rewrite重定向

#指定默认访问的文件到hostname.html上
[root@k8s-master app]# vim ingress5.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/app-root: /hostname.htmlnginx.ingress.kubernetes.io/auth-type: basicnginx.ingress.kubernetes.io/auth-secret: auth-webnginx.ingress.kubernetes.io/auth-realm: "Please input username and password"name: ingress5
spec:tls:- hosts:- myapp-tls.timinglee.orgsecretName: web-tls-secretingressClassName: nginxrules:- host: myapp-tls.timinglee.orghttp:paths:- backend:service:name: myapp-v1port:number: 80path: /pathType: Prefix
[root@k8s-master app]# kubectl apply -f ingress5.yml
ingress.networking.k8s.io/ingress5 created
[root@k8s-master app]# kubectl describe ingress ingress5
Name:             ingress5
Labels:           <none>
Namespace:        default
Address:          172.25.254.10
Ingress Class:    nginx
Default backend:  <default>
TLS:web-tls-secret terminates myapp-tls.timinglee.org
Rules:Host                     Path  Backends----                     ----  --------myapp-tls.timinglee.org/   myapp-v1:80 (10.244.2.31:80)
Annotations:               nginx.ingress.kubernetes.io/app-root: /hostname.htmlnginx.ingress.kubernetes.io/auth-realm: Please input username and passwordnginx.ingress.kubernetes.io/auth-secret: auth-webnginx.ingress.kubernetes.io/auth-type: basic
Events:Type    Reason  Age                    From                      Message----    ------  ----                   ----                      -------Normal  Sync    2m16s (x2 over 2m54s)  nginx-ingress-controller  Scheduled for sync#测试:
[root@reg ~]# curl -Lk https://myapp-tls.timinglee.org -ulee:lee
myapp-v1-7479d6c54d-j9xc6[root@reg ~]# curl -Lk https://myapp-tls.timinglee.org/lee/hostname.html -ulee:lee
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>#解决重定向路径问题
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /$2nginx.ingress.kubernetes.io/use-regex: "true"nginx.ingress.kubernetes.io/auth-type: basicnginx.ingress.kubernetes.io/auth-secret: auth-webnginx.ingress.kubernetes.io/auth-realm: "Please input username and password"name: ingress6
spec:tls:- hosts:- myapp-tls.timinglee.orgsecretName: web-tls-secretingressClassName: nginxrules:- host: myapp-tls.timinglee.orghttp:paths:- backend:service:name: myapp-v1port:number: 80path: /pathType: Prefix- backend:service:name: myapp-v1port:number: 80path: /lee(/|$)(.*)					#正则表达式匹配/lee/,/lee/abcpathType: ImplementationSpecific
#测试
[root@reg ~]# curl -Lk https://myapp-tls.timinglee.org/lee/hostname.html -ulee:lee
myapp-v1-7479d6c54d-j9xc6

六 Canary金丝雀发布

6.1 么是金丝雀发布

金丝雀发布(Canary Release)也称为灰度发布,是一种软件发布策略。

主要目的是在将新版本的软件全面推广到生产环境之前,先在一小部分用户或服务器上进行测试和验证,以降低因新版本引入重大问题而对整个系统造成的影响。

是一种Pod的发布方式。金丝雀发布采取先添加、再删除的方式,保证Pod的总量不低于期望值。并且在更新部分Pod后,暂停更新,当确认新Pod版本运行正常后再进行其他版本的Pod的更新。

6.2 Canary发布方式

其中header和weiht中的最多

6.2.1 基于header(http包头)灰度

  • 通过Annotaion扩展

  • 创建灰度ingress,配置灰度头部key以及value

  • 灰度流量验证完毕后,切换正式ingress到新版本

  • 之前我们在做升级时可以通过控制器做滚动更新,默认25%利用header可以使升级更为平滑,通过key 和vule 测试新的业务体系是否有问题。

示例:

#建立版本1的ingress
[root@k8s-master app]# vim ingress7.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:name: myapp-v1-ingress
spec:ingressClassName: nginxrules:- host: myapp.timinglee.orghttp:paths:- backend:service:name: myapp-v1port:number: 80path: /pathType: Prefix
        
[root@k8s-master app]# kubectl describe ingress myapp-v1-ingress
Name:             myapp-v1-ingress
Labels:           <none>
Namespace:        default
Address:          172.25.254.10
Ingress Class:    nginx
Default backend:  <default>
Rules:Host                 Path  Backends----                 ----  --------myapp.timinglee.org/   myapp-v1:80 (10.244.2.31:80)
Annotations:           <none>
Events:Type    Reason  Age                From                      Message----    ------  ----               ----                      -------Normal  Sync    44s (x2 over 73s)  nginx-ingress-controller  Scheduled for sync#建立基于header的ingress
[root@k8s-master app]# vim ingress8.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-header: versionnginx.ingress.kubernetes.io/canary-by-header-value: 2name: myapp-v2-ingress
spec:ingressClassName: nginxrules:- host: myapp.timinglee.orghttp:paths:- backend:service:name: myapp-v2port:number: 80path: /pathType: Prefix
[root@k8s-master app]# kubectl apply -f ingress8.yml
ingress.networking.k8s.io/myapp-v2-ingress created
[root@k8s-master app]# kubectl describe ingress myapp-v2-ingress
Name:             myapp-v2-ingress
Labels:           <none>
Namespace:        default
Address:
Ingress Class:    nginx
Default backend:  <default>
Rules:Host                 Path  Backends----                 ----  --------myapp.timinglee.org/   myapp-v2:80 (10.244.2.32:80)
Annotations:           nginx.ingress.kubernetes.io/canary: truenginx.ingress.kubernetes.io/canary-by-header: versionnginx.ingress.kubernetes.io/canary-by-header-value: 2
Events:Type    Reason  Age   From                      Message----    ------  ----  ----                      -------Normal  Sync    21s   nginx-ingress-controller  Scheduled for sync#测试:
[root@reg ~]# curl  myapp.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@reg ~]# curl -H "version: 2" myapp.timinglee.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

6.2.2 基于权重的灰度发布

  • 通过Annotaion拓展

  • 创建灰度ingress,配置灰度权重以及总权重

  • 灰度流量验证完毕后,切换正式ingress到新版本

示例

#基于权重的灰度发布
[root@k8s-master app]# vim ingress8.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "10"		#更改权重值nginx.ingress.kubernetes.io/canary-weight-total: "100"name: myapp-v2-ingress
spec:ingressClassName: nginxrules:- host: myapp.timinglee.orghttp:paths:- backend:service:name: myapp-v2port:number: 80path: /pathType: Prefix
[root@k8s-master app]# kubectl apply -f ingress8.yml
ingress.networking.k8s.io/myapp-v2-ingress created#测试:
[root@reg ~]# vim check_ingress.sh
#!/bin/bash
v1=0
v2=0for (( i=0; i<100; i++))
doresponse=`curl -s myapp.timinglee.org |grep -c v1`v1=`expr $v1 + $response`v2=`expr $v2 + 1 - $response`done
echo "v1:$v1, v2:$v2"
[root@reg ~]# sh check_ingress.sh
v1:90, v2:10#更改完毕权重后继续测试可观察变化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/56518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二叉树与堆讲解

目录 1.树的概念及结构 1.树的概念 2.树的相关概念 3.树的表示 2.二叉树 1.概念 2.特殊的二叉树 1.满二叉树 2.完全二叉树 3.二叉树的性质 4.二叉树的存储结构 1.顺序结构 2.链式存储 3.堆 1.堆的概念及结构 2.堆的实现 1.堆的创建 2.堆的初始化&#xff08;H…

Spring Boot知识管理:跨平台集成方案

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

STM32 407 RS485通信实现数据收发【我的创作纪念日】

1. 前言 本例中的485驱动&#xff0c;基于标准库编写&#xff0c;不是HAL库&#xff0c;请大家注意。 最近搞嵌入式程序&#xff0c;踩了不少坑&#xff0c;这里统一记录一下。 2. 收获 1.串口通信&#xff0c;数据是一个字节一个字节的发送&#xff0c;对方收到的数据是放在…

【消息队列】Kafka从入门到面试学习总结

国科大学习生活&#xff08;期末复习资料、课程大作业解析、大厂实习经验心得等&#xff09;: 文章专栏&#xff08;点击跳转&#xff09; 大数据开发学习文档&#xff08;分布式文件系统的实现&#xff0c;大数据生态圈学习文档等&#xff09;: 文章专栏&#xff08;点击跳转&…

小米电机与STM32——CAN通信

背景介绍&#xff1a;为了利用小米电机&#xff0c;搭建机械臂的关节&#xff0c;需要学习小米电机的使用方法。计划采用STM32驱动小米电机&#xff0c;实现指定运动&#xff0c;为此需要了解他们之间的通信方式&#xff0c;指令写入方法等。花了很多时间学习&#xff0c;但网络…

【Next.js 项目实战系列】05-删除 Issue

原文链接 CSDN 的排版/样式可能有问题&#xff0c;去我的博客查看原文系列吧&#xff0c;觉得有用的话&#xff0c;给我的库点个star&#xff0c;关注一下吧 上一篇【Next.js 项目实战系列】04-修改 Issue 删除 Issue 添加删除 Button​ 本节代码链接 这里我们主要关注布局…

类和对象的认识

类&#xff1a;类是用来描述一个对象的&#xff0c;在java中万物皆对象&#xff0c;通过对类的抽象&#xff0c;类有哪些属性和行为&#xff0c;将这些抽象出来就是类。比如&#xff1a;狗&#xff0c;有名字&#xff0c;年龄&#xff0c;要吃饭的行为等等&#xff0c;将这些动…

仓储管理系统原型图移动端(WMS),出入库管理、库存盘点、库存调拨等(Axure原型、Axure实战项目)

仓储管理系统原型图移动端 Warehouse Management System Prototype 仓储管理系统原型图移动端是一个以图形化方式展示系统移动端界面和功能的原型设计图。原型图展示和说明系统移动端的功能和界面布局&#xff0c;为相关利益方提供一个直观的视觉化展示&#xff0c;帮助他们更…

RAG(检索增强生成)面经(1)

1、RAG有哪几个步骤&#xff1f; 1.1、文本分块 第一个步骤是文本分块&#xff08;chunking&#xff09;&#xff0c;这是一个重要的步骤&#xff0c;尤其在构建与处理文档的大型文本的时候。分块作为一种预处理技术&#xff0c;将长文档拆分成较小的文本块&#xff0c;这些文…

Android中的内容提供者

目录 1.创建内容提供者 1--手动创建一个Android应用程序 2--创建自定义的内容提供者 2.访问其他应用程序 1. 解析URI 2. 查询数据 3. 遍历查询结果 3)案例:读取手机通信录 1.声明权限 2.activity_main.xml文件内容 3.my_phone_list.xml文件内容 4.定义PhoneInfo实体 5.定义MyPh…

线程异步和通信(promise和future)

线程异步和通信&#xff08;promise和future&#xff09; #include <thread> #include <iostream> #include <future> #include <string> using namespace std;void TestFuture(promise<string> p)//线程函数 {cout << "begin TestFu…

JAVA就业笔记7——第二阶段(4)

课程须知 A类知识&#xff1a;工作和面试常用&#xff0c;代码必须要手敲&#xff0c;需要掌握。 B类知识&#xff1a;面试会问道&#xff0c;工作不常用&#xff0c;代码不需要手敲&#xff0c;理解能正确表达即可。 C类知识&#xff1a;工作和面试不常用&#xff0c;代码不…

绘制YOLOv11模型在训练过程中,精准率,召回率,mAP_0.5,mAP_0.5:0.95,以及各种损失的变化曲线

一、本文介绍 本文用于绘制模型在训练过程中,精准率,召回率,mAP_0.5,mAP_0.5:0.95,以及各种损失的变化曲线。用以比较不同算法的收敛速度,最终精度等,并且能够在论文中直观的展示改进效果。支持多文件的数据比较。 专栏目录:YOLOv11改进目录一览 | 涉及卷积层、轻量化…

spring task的使用场景

spring task 简介 spring task 是spring自带的任务调度框架按照约定的时间执行某个方法的工具&#xff0c;类似于闹钟 应用场景 cron表达式 周和日两者必定有一个是问号 简单案例 使用步骤 demo Component注解表示这是一个Spring的组件&#xff0c;会被Spring容器扫描到&#…

全面超越Spark,Clickhouse,比 Spark 快 900%,基于云器Lakehouse构建新一代一体化数据平台

人工智能的迅速发展正在改变着我们的世界&#xff0c;对于大数据企业来说更是如此。 在大语言模型的引领下&#xff0c;数据平台领军企业 Databricks 和 Snowflake 的未来正在被重新书写。这两家企业在不久前的发布会上强调了大语言模型和 AI 能力的重要性&#xff0c;试图通过…

[单master节点k8s部署]41.部署springcloud项目

在之前的文章中我们配置了mysql和harbor&#xff0c;现在我们可以将一个springcloud部署在k8s集群中了。 项目概述 这个springcloud项目将采用maven进行打包部署。首先安装maven&#xff1a; yum install java-1.8.0-openjdk maven-3.0.5* -y 然后将该项目上传到k8s集群的m…

ANSYS 2024 R2设置中文

ANSYS 2024 R2设置中文 打开ANSYS Workbench R2软件依次点击Tools、Options 在弹出的Options选项卡中选择Regional and Language Options项&#xff0c;选择Language为Chinese然后点击OK 重启软件即可切换为中文界面

珠海自闭症寄宿学校:打造温馨家庭般的学习氛围

原文链接&#xff1a;http://www.zibizhengwang.com/page35.html 在探索自闭症儿童教育的广阔领域里&#xff0c;寄宿制学校以其独特的优势&#xff0c;为自闭症儿童提供了一个集教育、康复与生活于一体的综合性环境。而在珠海乃至全国&#xff0c;众多自闭症寄宿学校正不断努…

为什么inet_ntoa会返回错误的IP地址?

目录 1、调用inet_addr和inet_ntoa实现整型IP与点式字符串之间的转换 1.1、调用inet_addr将点式字符串IP转换成整型IP 1.2、调用inet_ntoa将整型IP转换成点式字符串IP 2、调用inet_ntoa返回错误点式字符串IP的原因分析 3、解决多线程调用inet_ntoa返回错误点式字符串IP的办…

请求第三方接口有反斜杠和双引号怎么处理,且做格式校验?

如&#xff1a;接口文档要求 直接使用转义失败&#xff0c;在postman中填值请求正常。 String para "[" "\\" "\"" "预计今天白天我市多云间晴&#xff1b;" "\\" "\"]"; System.err.println(pa…