首先部署pod
使用原先的deployment的资源清单进行部署。
[kubeadm@server1 ~]$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-7d6f48b859-5rsrm 1/1 Running 0 61s 10.244.3.17 server4 <none> <none>
nginx-deployment-7d6f48b859-f5zmh 1/1 Running 0 61s 10.244.2.17 server3 <none> <none>
nginx-deployment-7d6f48b859-n9lzd 1/1 Running 0 61s 10.244.0.23 server1 <none> <none>
这时候每个节点他会自动暴露出一个ip地址,但是这个时候外部并不能进行访问pod内部,只能在节点内部进行查看。但是使用ip访问,每个ip都是独立的,是否可以使用公共ip访问三个pod节点呢?
那就要使用service服务来创建一个vip,顺便也实现了负载均衡。
service的类型分为:
ClusterIP:系统自动分配的虚拟ip只能访问内部集群。
NodePort:将node端口主动暴露
LoadBalancer:创建一个外部的负载均衡 (收费)
ExternalName:通过DNS Cname转发
ClusterIP
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
spec:
ports:
- name: http
port: 80
targetPort: 80
selector: ##选择标签是app为nginx的
app: nginx
[kubeadm@server1 ~]$ kubectl create -f svc-nginx.yaml
service/svc-nginx created
[kubeadm@server1 ~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d1h
svc-nginx ClusterIP 10.106.48.183 <none> 80/TCP 21s
创建完成就主动将ip暴露出来了,这个ip是集群自动分配的。这样直接使用暴露出来的ip进行访问,三个集群就可以自动负载均衡。
再创建一个交互式pod,进入这个pod中也可以访问上面作负载均衡的三个pod,并且ClusterIP还自带DNS解析功能,在交互式pod的内部就可以直接使用名称进行访问。我们对集群进行查看就可以看到有两个dns。
[kubeadm@server1 ~]$ kubectl get deployments.apps -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 2/2 2 2 4d2h
service是由kube-proxy和iptables一起实现的。但是当有很多pod时,iptables会不断的刷新策略,这就消耗很多的资源,所以除了这种方法还有一种可以支持大量pod的方案,ipvs模式的service。
使用ipvs首先需要安装ipvsadm。
但是安装之后并没有使用这个ipvs,因为使用的时候需要将这个ipvs的模块进行激活操作,如何激活,一般我们是更新kube-proxy的配置文件达到激活的目的。
使用命令
kubectl -n kube-system edit cm kube-proxy
进入文件修改后定位mode,将mode模式改为ipvs
mode: "ipvs"
这时候编辑完了以后文件是不生效的,生效需要将原有的pod杀死后,因为控制器的缘故,会自动生成新的pod,这时候文件才会生效。
kubectl get pod -n kube-system -o wide | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'
重建pod完成后策略即可刷新
[root@server3 docker]# 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
-> 192.168.122.2:6443 Masq 1 0 0
TCP 10.96.0.10:53 rr
-> 10.244.0.24:53 Masq 1 0 0
-> 10.244.0.26:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 10.244.0.24:9153 Masq 1 0 0
-> 10.244.0.26:9153 Masq 1 0 0
TCP 10.106.48.183:80 rr
-> 10.244.0.25:80 Masq 1 0 0
-> 10.244.2.22:80 Masq 1 0 0
-> 10.244.3.21:80 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 10.244.0.24:53 Masq 1 0 0
-> 10.244.0.26:53 Masq 1 0 0
但是即使策略刷新了iptables也不能关闭,因为还有别的用处,不仅仅只有service使用。
nodeport
apiVersion: v1
kind: Service
metadata:
name: svc-nginx-2
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: nginx
type: NodePort
首先编写资源清单,其中最重要的是最后一行的type。type的模式设置为NodePort
创建完成后将会给你暴露出一个端口。
[kubeadm@server1 ~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx-2 NodePort 10.111.255.157 <none> 80:30360/TCP 14s
端口暴露后,使用命令进行访问
[root@localhost ~]# curl 192.168.122.4:30360
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@localhost ~]# curl 192.168.122.4:30360
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@localhost ~]# curl 192.168.122.4:30360
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
可以访问到,而且在查看的时候可以看到已经实现了负载均衡。
[root@server3 docker]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.122.4:30360 rr
-> 10.244.0.25:80 Masq 1 0 1
-> 10.244.2.22:80 Masq 1 0 2
-> 10.244.3.21:80 Masq 1 0 2
ExternalName
说白了ExternalName就是一个DNS。用来作解析功能。下来首先进行设置。
第一步编写资源清单,这个资源清单十分的少,不用指定端口什么的,要指定的只有模式再指定一个域名即可使用。
apiVersion: v1
kind: Service
metadata:
name: my-nginx
spec:
type: ExternalName
externalName: test.passyt.com
创建完成后我们查看svc
[kubeadm@server1 ~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ExternalName <none> test.passyt.com <none> 6s
他并没有和别的svc一样显示ip ,而是显示我们设置的域名。那我们应该怎么使用呢?
首先查看CLUSTER-IP
[kubeadm@server1 ~]$ kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 4d7h
再来使用A记录来查看。
[kubeadm@server1 ~]$ dig -t A test.passyt.com @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> -t A test.passyt.com @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 38011
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test.passyt.com. IN A
;; AUTHORITY SECTION:
com. 30 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1582207923 1800 900 604800 86400
;; Query time: 2699 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 四 2月 20 22:12:20 CST 2020
;; MSG SIZE rcvd: 123
service还可以设置分配一个公有的ip
第一步还是编写资源清单,但是用之前的也可以,不同点在于externalIPs
这个选项。
piVersion: v1
kind: Service
metadata:
name: svc-2
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: nginx
externalIPs:
- 192.168.122.100
[kubeadm@server1 ~]$ kubectl apply -f service.yaml
service/svc-2 configured
[kubeadm@server1 ~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d2h
svc-2 ClusterIP 10.103.181.74 192.168.122.100 80/TCP 3m14s
这样已经设置出来一个对外的ip,外部使用这个ip就可以直接访问到pod中。
[root@localhost ~]# curl 192.168.122.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@localhost ~]# curl 192.168.122.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@localhost ~]# curl 192.168.122.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>