注:yaml文件严格要求缩进,默认不一样层次等级是两个空格的缩进
一、使用httpd镜像建立一个Deployment资源对象node
[root@docker-k8s01 ~]# mkdir yaml [root@docker-k8s01 ~]# cd yaml/ [root@docker-k8s01 yaml]# vim test01.yaml kind: Deployment # 指定要建立的资源对象类型 apiVersion: extensions/v1beta1 # 指定deployment所对应的API版本 metadata: name: test01-deploy # 定义deployment的名称 spec: replicas: 4 # 定义须要建立pod副本的数量 template: metadata: labels: user: zyz # 指定pod的标签 spec: containers: - name: httpd # 指定容器的名称 image: httpd # 指定建立容器基于的镜像 [root@docker-k8s01 yaml]# kubectl apply -f test01.yaml # 执行编写的文件 deployment.extensions/test01-deploy created # 返回信息显示已经建立 #注:若是不知道某个资源对象所对应的API版本,能够经过此命令查看 [root@docker-k8s01 yaml]# kubectl explain deployment KIND: Deployment VERSION: extensions/v1beta1 # 这就是Deployment资源所对应的API版本 #肯定所执行的yaml文件生成了咱们所需数量的pod [root@docker-k8s01 ~]# kubectl get deployments test01-deploy NAME READY UP-TO-DATE AVAILABLE AGE test01-deploy 4/4 4 4 2m19s
查看其pod标签,是不是咱们定义的label算法
#查看这个资源对象的详细信息 [root@docker-k8s01 ~]# kubectl describe deployments test01-deploy Name: test01-deploy Namespace: default CreationTimestamp: Wed, 26 Aug 2020 11:26:28 +0800 Labels: user=zyz # 这里就是该资源对象的标签
二、建立一个svc资源对象与上述Deployment资源对象关联。且可以对外网提供服务。映射节点端口为:32123docker
[root@docker-k8s01 yaml]# vim httpd-service.yaml kind: Service apiVersion: v1 metadata: name: httpd-service spec: type: NodePort # 这里须要指定类型为“NodePort”,不然默认是cluster IP selector: user: zyz # 与deployment资源对象的这个标签进行关联 ports: - protocol: TCP # 指定协议 port: 79 # 这里指定要映射到的Cluster IP的端口 targetPort: 80 # 这里指定的是要映射pod中的端口 nodePort: 32123 # 这里指定的是映射到宿主机的端口 #执行刚刚编辑的文件 [root@docker-k8s01 yaml]# kubectl apply -f httpd-service.yaml service/httpd-service created [root@docker-k8s01 yaml]# kubectl get svc httpd-service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-service NodePort 10.102.10.20 <none> 79:32123/TCP 48s #能够看到将指定的群集端口映射到了本地的32123
如今就可使用client访问k8s群集中任意一个节点的32123端口,便可看到pod所提供的服务vim
#查看该service的详细信息 [root@docker-k8s01 yaml]# kubectl get svc httpd-service
返回的信息以下(只能显示少许IP,剩下的只是被省略了,而不是未指定)
既然上面说到了,endpoint指定的都是后端pod的IP地址,那么就来查看验证一下,是否正确后端
#输出后端pod的IP地址 #能够确认查看的IP能对应上上面service的endpoint指定的IP [root@docker-k8s01 yaml]# kubectl get pod -o wide | awk '{print$6}' IP 10.244.1.3 10.244.2.3 10.244.2.2 10.244.1.2
查看svc映射endpoint的详细状况,并详细说明负载均衡的底层原理api
三、当咱们作完上述操做后,client是能够访问咱们pod提供的服务的(而且是负载均衡的效果),那么这是一个什么样的实现过程呢?依赖什么实现的?
其实,背后的原理并无那么高大上,kube-proxy经过iptables的转发机制来实现负载均衡的效果的,先定义目标IP是service提供的群集IP,而后使用“-j”选项转发到其余iptables规则app
[root@docker-k8s01 yaml]# kubectl get svc httpd-service | awk '{print$3}' CLUSTER-IP 10.102.10.20 # 查看到service的群集IP [root@docker-k8s01 yaml]# iptables-save > a.txt # 将iptables规则输出到文件中,方便咱们查找 [root@docker-k8s01 yaml]# vim a.txt # 打开导出的规则进行查看
搜索咱们的群集IP,能够看到,当目标地址是群集IP地址时,就会转发到另外一个规则“KUBE-SVC-X2P42VLQEZCHLPKZ”,以下
那么,如今继续搜索它转发到的规则上
上面的图中,就是与他实现负载均衡相关的策略的,咱们一共四个pod,因此上图中的第一个规则使用了random的算法,只有0.25(1/4)的概率采用这个规则,当到达第二条规则后,则有0.33的概率,由于去除前一个pod,还剩下三个pod,10/3=0.33,这就是这个概率的由来,依次类推,当到达最后一个规则后,那么就不用指定概率了,确定是它来处理这条请求。负载均衡
附:为node节点打标签,以便使pod运行在指定的节点dom
#给节点node01打标签“disktype=ssd”(自定义的标签) [root@docker-k8s01 yaml]# kubectl label nodes node01 disktype=ssd #相应的yaml文件以下: kind: Deployment apiVersion: extensions/v1beta1 metadata: name: httpd spec: revisionHistoryLimit: 10 replicas: 3 template: metadata: labels: app: httpd-server spec: containers: - name: httpd image: 192.168.171.151:5000/httpd:v1 ports: - containerPort: 80 nodeSelector: //指定标签选择器 disktype: ssd