欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

企业级容器技术 k8s service

程序员文章站 2024-03-11 18:43:31
...

首先部署pod
使用原先的deployment的资源清单进行部署。

[[email protected] ~]$ 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
[[email protected] ~]$ kubectl create -f svc-nginx.yaml 
service/svc-nginx created
[[email protected] ~]$ 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。

[[email protected] ~]$ 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完成后策略即可刷新

[[email protected] 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
创建完成后将会给你暴露出一个端口。

[[email protected] ~]$ 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

端口暴露后,使用命令进行访问

[[email protected] ~]# curl 192.168.122.4:30360
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[[email protected] ~]# curl 192.168.122.4:30360
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[[email protected] ~]# curl 192.168.122.4:30360
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

可以访问到,而且在查看的时候可以看到已经实现了负载均衡。

[[email protected] 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

[[email protected] ~]$ 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

[[email protected] ~]$ 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记录来查看。

[[email protected] ~]$ 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
[[email protected] ~]$ kubectl apply -f service.yaml 
service/svc-2 configured
[[email protected] ~]$ 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中。

[[email protected] ~]# curl 192.168.122.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[[email protected] ~]# curl 192.168.122.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[[email protected] ~]# curl 192.168.122.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>