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

二、微服务的类型
 示例:
 示例:
 
#生成控制器文件并建立控制器
[root@k8s-master ~]# kubectl create deployment timinglee --image myapp:v1 --replicas 2 --dry-run=client -o yaml > timinglee.yaml#生成微服务yaml追加到已有yaml中
[root@k8s-master ~]# kubectl expose deployment timinglee --port 80 --target-port 80 --dry-run=client -o yaml >> timinglee.yaml[root@k8s-master ~]# vim timinglee.yaml
[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
[root@k8s-master ~]# dnf install ipvsadm -y
[root@k8s-node1 ~]# dnf install ipvsadm -y
[root@k8s-node2 ~]# dnf install ipvsadm -y
2 修改master节点的代理配置

[root@k8s-master ~]# kubectl -n kube-system edit cm kube-proxy


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



[!NOTE]
切换ipvs模式后,kube-proxy会在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配所有service IP
四、微服务类型详解
4.1 clusterip
特点:
clusterip模式只能在集群内访问,并对集群内的pod提供健康检测和自动发现功能
示例:
[root@k8s-master ~]# kubectl run testpod --image myapp:v1
pod/testpod created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
testpod 1/1 Running 0 3s
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINES S GATES
testpod 1/1 Running 0 18s 10.244.1.27 k8s-node2.timinglee.org <none> <none>
[root@k8s-master ~]# kubectl get pods -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINES S GATES LABELS
testpod 1/1 Running 0 45s 10.244.1.27 k8s-node2.timinglee.org <none> <none> run=testpod
[root@k8s-master ~]# kubectl expose pod testpod --port 80 --target-port 80 --dry-run=client -o yaml > testpod-svc.yml
[root@k8s-master ~]# vim testpod-svc.yml



[root@k8s-master ~]# kubectl run busybox -it --image busyboxplus:latest
/ # curl testpod.default.svc.cluster.local.
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl testpod.default.svc.cluster.local.
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local timinglee.org
options ndots:5/ # nslookup testpod.default.svc.cluster.local.
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName: testpod.default.svc.cluster.local.
Address 1: 10.106.59.102 testpod.default.svc.cluster.local
/ # nslookup testpod
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName: testpod
Address 1: 10.106.59.102 testpod.default.svc.cluster.local
[root@k8s-master ~]# kubectl delete -f testpod-svc.yml
 service "testpod" deleted 
4.2 ClusterIP中的特殊模式headless
headless(无头服务)
对于无头 Services 并不会分配 Cluster IP,kube-proxy不会处理它们, 而且平台也不会为它们进行负载均衡和路由,集群访问通过dns解析直接指向到业务pod上的IP,所有的调度有dns单独完成
[root@k8s-master ~]# vim testpod-svc.yml
 



/ # curl testpod
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl testpod/hostname.html
testpod
/ # curl testpod/hostname.html
testpod[root@k8s-master ~]# kubectl delete -f testpod-svc.yml
service "testpod" deleted
4.3 nodeport
通过ipvs暴漏端口从而使外部主机通过master节点的对外ip:<port>来访问pod业务
其访问过程为:

示例:
[root@k8s-master ~]# vim testpod-svc.yml
[root@k8s-master ~]# kubectl apply -f testpod-svc.yml
 service/testpod created
 [root@k8s-master ~]# kubectl get svc testpod
 NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
 testpod   NodePort   10.101.130.40   <none>        80:30774/TCP   26s

[!NOTE]
nodeport默认端口
nodeport默认端口是30000-32767,超出会报错
#####直接指定端口 若超过32767
[root@k8s-master ~]# vim testpod-svc.yml


如果需要使用这个范围以外的端口就需要特殊设定
[root@k8s-master ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml

[!NOTE]
添加“--service-node-port-range=“ 参数,端口范围可以自定义
修改后api-server会自动重启,等apiserver正常启动后才能操作集群
集群重启自动完成在修改完参数后全程不需要人为干预

[root@k8s-master ~]# kubectl delete -f testpod-svc.yml
 service "testpod" deleted 
4.4 loadbalancer
云平台会为我们分配vip并实现访问,如果是裸金属主机那么需要metallb来实现ip的分配
 
示例:
[root@k8s-master ~]#  vim testpod-svc.yml 
 

LoadBalancer模式适用云平台,裸金属环境需要安装metallb提供支持
4.5 metalLB
官网:Installation :: MetalLB, bare metal load-balancer for Kubernetes

metalLB功能
为LoadBalancer分配vip
部署方式
修改文件中镜像地址,与harbor仓库路径保持一致
[root@k8s-master ~]# mkdir metalLB
[root@k8s-master ~]# cd metalLB/
[root@k8s-master metalLB]# ls
[root@k8s-master metalLB]# ls
metallb-native.yaml metalLB.tag.gz
[root@k8s-master metalLB]# vim metallb-native.yaml



###部署服务



#####配置分配地址段
[root@k8s-master metalLB]# vim configmap.yml


4.6 externalname
-  开启services后,不会被分配IP,而是用dns解析CNAME固定域名来解决ip变化问题 
-  一般应用于外部业务和pod沟通或外部业务迁移到pod内时 
-  在应用向集群迁移过程中,externalname在过度阶段就可以起作用了。 
-  集群外的资源迁移到集群时,在迁移的过程中ip可能会变化,但是域名+dns解析能完美解决此问题 
示例:
[root@k8s-master ~]# kubectl delete -f testpod-svc.yml
 service "testpod" deleted
 [root@k8s-master ~]# vim testpod-svc.yml



[root@k8s-master ~]# kubectl delete -f testpod-svc.yml
 service "testpod" deleted
五、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
实验素材
[root@k8s-master ~]# mkdir ingress
 [root@k8s-master ~]# cd ingress/
 [root@k8s-master ingress]# ls
 [root@k8s-master ingress]# mkdir app
 [root@k8s-master ingress]# cd app/
 [root@k8s-master app]# ls
 [root@k8s-master app]# kubectl create deployment myappv1 --image myapp:v1 --dry-run=client -o yaml > myapp-v1.yml
 [root@k8s-master app]# vim myapp-v1.yml
[root@k8s-master app]# cp myapp-v1.yml myapp-v2.yml
 [root@k8s-master app]# vim myapp-v2.yml

[root@k8s-master app]# kubectl apply -f myapp-v1.yml
 deployment.apps/myappv1 created
 [root@k8s-master app]# kubectl apply -f myapp-v2.yml
 deployment.apps/myappv2 created
 [root@k8s-master app]# kubectl expose deployment myappv1 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v1.yml
 [root@k8s-master app]# kubectl expose deployment myappv2 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v2.yml
 [root@k8s-master app]# vim myapp-v1.yml
[root@k8s-master app]# vim myapp-v2.yml

5.2.1 下载部署文件
[root@k8s-master app]# cd ..
 [root@k8s-master ingress]# ls
 app  deploy.yaml
 [root@k8s-master ingress]# vim deploy.yaml





5.2.2 安装ingress
[root@k8s-master ~]# vim deploy.yaml





#修改微服务为loadbalancer
[root@k8s-master ingress]# kubectl -n ingress-nginx edit svc ingress-nginx-controller

[!NOTE]
在ingress-nginx-controller中看到的对外IP就是ingress最终对外开放的ip
5.2.3 测试ingress


[root@k8s-master ingress]# vim ingress1.yml



[!NOTE]
ingress必须和输出的service资源处于同一namespace
5.3 ingress 的高级用法
5.3.1 基于路径的访问


生成ingress
[root@k8s-master ingress]#  ls
 app  deploy.yaml  ingress1.yml  ingress-nginx-1.11.2.tag.gz
 [root@k8s-master ingress]# cp ingress1.yml ingress2.yml
 [root@k8s-master ingress]# vim ingress2.yml

[root@k8s-master ingress]# vim /etc/hosts

 
 

[root@k8s-master ingress]# kubectl delete  -f ingress2.yml
 ingress.networking.k8s.io "myapp" deleted
5.3.2 基于域名的访问
[root@k8s-master ingress]# cp ingress2.yml ingress3.yml
 [root@k8s-master ingress]# vim ingress3.yml

[root@k8s-master ingress]# vim /etc/hosts

 
 
5.3.3 建立tls加密
#建立证书
[root@k8s-master ingress]# openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -subj "/CN=nginxsvc/O=nginxsvc" -out tls.crt
#建立加密资源类型secret
[root@k8s-master ingress]# kubectl create secret tls  web-tls-secret --key tls.key --cert tls.crt
 secret/web-tls-secret created

[!NOTE]
secret通常在kubernetes中存放敏感数据,他并不是一种加密方式,在后面课程中会有专门讲解
[root@k8s-master ingress]# cp ingress3.yml  ingress4.yml
 [root@k8s-master ingress]# vim ingress4.yml
  
[root@k8s-master ingress]# kubectl apply -f ingress4.yml
 ingress.networking.k8s.io/myapp configured




[root@k8s-master ingress]# kubectl delete -f ingress4.yml
 ingress.networking.k8s.io "myapp" deleted
5.3.4 建立auth认证
#建立认证文件
[root@k8s-master ingress]# dnf install httpd-tools -y
[root@k8s-master ingress]# htpasswd -cm auth lee
New password:
Re-type new password:
Adding password for user lee
[root@k8s-master ingress]# cat auth
lee:$apr1$0mCu4T3l$BFqJaLTzfAkjInTijB3Qe/
#建立认证类型资源

#建立ingress5基于用户认证的yaml文件
[root@k8s-master ingress]# cp ingress2.yml ingress5.yml
 [root@k8s-master ingress]# vim ingress5.yml




[root@k8s-master ingress]# kubectl delete -f ingress5.yml
 ingress.networking.k8s.io "myapp" deleted
5.3.5 rewrite重定向
[root@k8s-master ingress]# cp ingress5.yml ingress6.yml
 [root@k8s-master ingress]# vim ingress6.yml

 
 

[root@k8s-master ingress]# kubectl delete -f ingress6.yml
 ingress.networking.k8s.io "myapp" deleted
 [root@k8s-master ingress]# vim ingress6.yml

[root@k8s-master ingress]# kubectl delete -f ingress6.yml
 ingress.networking.k8s.io "myapp" deleted
六、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 测试新的业务体系是否有问题。 
示例:
[root@k8s-master ingress]# vim ingress1.yml

[root@k8s-master ingress]# kubectl apply  -f ingress1.yml
 ingress.networking.k8s.io/myappv1 created
 [root@k8s-master ingress]# cp ingress2.yml ingress7.yml
 [root@k8s-master ingress]# vim ingress7.yml

6.2.2 基于权重的灰度发布

-  通过Annotaion拓展 
-  创建灰度ingress,配置灰度权重以及总权重 
-  灰度流量验证完毕后,切换正式ingress到新版本 
示例:
[root@k8s-master ingress]# kubectl delete  -f ingress7.yml
 ingress.networking.k8s.io "myapp" deleted
 [root@k8s-master ingress]# vim ingress7.yml
[root@k8s-master ingress]# kubectl apply  -f ingress7.yml
 ingress.networking.k8s.io/myappv2 created
 [root@k8s-master ingress]# vim check_ingress.sh

[root@k8s-master ingress]# kubectl delete  -f ingress7.yml
 ingress.networking.k8s.io "myappv2" deleted
 [root@k8s-master ingress]# kubectl delete  -f ingress1.yml
 ingress.networking.k8s.io "myappv1" deleted











