kubernetes-service
IPVS模式
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。 Service 所针对的 Pods 集合通常是通过选择算符来确定的。
Service 在 Kubernetes 中是一个 REST 对象,和 Pod 类似。 像所有的 REST 对象一样,Service 定义可以基于 POST 方式,请求 API server 创建新的实例。 Service 对象的名称必须是合法的 DNS 标签名称。
编辑ipvs模式
[root@server2 pod]# yum install -y ipvsadm.x86_64
[root@server2 pod]# kubectl -n kube-system get cm
NAME DATA AGE
calico-config 4 25h
coredns 1 4d22h
extension-apiserver-authentication 6 4d22h
kube-proxy 2 4d22h
kube-root-ca.crt 1 4d22h
kubeadm-config 2 4d22h
kubelet-config-1.21 1 4d22h
[root@server2 pod]# kubectl -n kube-system edit cm
mode: "ipvs"
[root@server2 pod]# ipvsadm -l
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
删除副本自动生成新副本
[root@server2 pod]# kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
pod "kube-proxy-czbm9" deleted
pod "kube-proxy-phhnb" deleted
pod "kube-proxy-t4mb8" deleted
[root@server2 pod]# 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.12.2:6443 Masq 1 2 0
TCP 10.96.0.10:53 rr
-> 10.244.0.4:53 Masq 1 0 0
-> 10.244.0.5:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 10.244.0.4:9153 Masq 1 0 0
-> 10.244.0.5:9153 Masq 1 0 0
TCP 10.111.193.201:80 rr
-> 10.244.5.38:80 Masq 1 0 0
-> 10.244.5.39:80 Masq 1 0 0
-> 10.244.5.40:80 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 10.244.0.4:53 Masq 1 0 0
-> 10.244.0.5:53 Masq 1 0 0
[root@server2 pod]# curl 10.244.5.40
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
Service实现外部访问
NodePort
[root@server2 pod]# kubectl edit svc mysvc
service/mysvc edited
type: NodePort
[root@server2 pod]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d23h
mysvc NodePort 10.111.193.201 <none> 80:31430/TCP 11m
[root@server2 pod]# netstat -antlp | grep 31430
tcp 0 0 0.0.0.0:31430 0.0.0.0:* LISTEN 2524/kube-proxy
[root@server2 pod]# curl 10.111.193.201
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 pod]#
sever和master都会暴露出端口
[root@server3 ~]# netstat -antlp | grep :31430
tcp 0 0 0.0.0.0:31430 0.0.0.0:* LISTEN 8739/kube-proxy
外部可以访问端口
[root@foundation12 ~]# curl 172.25.12.2:31430
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
查看解析
[root@server2 pod]# kubectl run demo -it --image=busyboxplus --restart=Never
If you don't see a command prompt, try pressing enter.
/ # nslookup mysvc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: mysvc
Address 1: 10.111.193.201 mysvc.default.svc.cluster.local
/ #
查看svc的endpoint
[root@server2 pod]kubectl -n kube-system describe svc kube-dns
Name: kube-dns
Namespace: kube-system
Labels: k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=CoreDNS
Annotations: prometheus.io/port: 9153
prometheus.io/scrape: true
Selector: k8s-app=kube-dns
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.96.0.10
IPs: 10.96.0.10
Port: dns 53/UDP
TargetPort: 53/UDP
Endpoints: 10.244.0.4:53,10.244.0.5:53
Port: dns-tcp 53/TCP
TargetPort: 53/TCP
Endpoints: 10.244.0.4:53,10.244.0.5:53
Port: metrics 9153/TCP
TargetPort: 9153/TCP
Endpoints: 10.244.0.4:9153,10.244.0.5:9153
Session Affinity: None
Events: <none>
[root@server2 pod]#
endpoint正是服务所在节点
[root@server2 pod]# kubectl -n kube-system get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-7777df944c-4ls4d 1/1 Running 1 5d 10.244.0.4 server2 <none> <none>
coredns-7777df944c-gwxzq 1/1 Running 1 5d 10.244.0.5 server2 <none> <none>
Headless无头模式
有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 “None” 来创建 Headless Service。
你可以使用无头 Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。
对这无头 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们, 而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了选择算符。
[root@server2 pod]# cat headless.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: myapp
clusterIP: None
[root@server2 pod]# kubectl apply -f headless.yaml
service/nginx-svc created
[root@server2 pod]# kubectl get svc
nginx-svc ClusterIP None <none> 80/TCP 65m
进入容器查看解析
[root@server2 pod]# kubectl run demo -it --image=busyboxplus --restart=Never
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.244.5.44 10-244-5-44.nginx-svc.default.svc.cluster.local
Address 2: 10.244.5.45 10-244-5-45.nginx-svc.default.svc.cluster.local
Address 3: 10.244.5.43 10-244-5-43.nginx-svc.default.svc.cluster.local
可以直接访问服务名
/ # curl nginx-svc
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl nginx-svc/hostname.html
myapp-deployment-59dff4cf5d-krnss
/ # curl nginx-svc/hostname.html
myapp-deployment-59dff4cf5d-6fkvg
/ # curl nginx-svc/hostname.html
myapp-deployment-59dff4cf5d-6fkvg
/ # curl nginx-svc/hostname.html
myapp-deployment-59dff4cf5d-nb2bq
/ # curl nginx-svc/hostname.html
myapp-deployment-59dff4cf5d-krnss
dig查看解析
[root@server2 pod]# yum install -y bind-utils
[root@server2 pod]# dig -t -A nginx-svc.default.svc.cluster.local. @10.96.0.10
;; Warning, ignoring invalid type -A
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> -t -A nginx-svc.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23304
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx-svc.default.svc.cluster.local. IN A
;; ANSWER SECTION:
nginx-svc.default.svc.cluster.local. 30 IN A 10.244.5.44
nginx-svc.default.svc.cluster.local. 30 IN A 10.244.5.43
nginx-svc.default.svc.cluster.local. 30 IN A 10.244.5.45
;; Query time: 1 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Fri Jul 30 01:14:08 EDT 2021
;; MSG SIZE rcvd: 217
LoadBalancer
在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 “LoadBalancer”, 将为 Service 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去。
更改kube-proxy配置
[root@server2 pod]# kubectl edit cm kube-proxy -n kube-system
configmap/kube-proxy edited
strictARP: true
[root@server2 pod]# kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
pod "kube-proxy-ftl8b" deleted
pod "kube-proxy-h2kgj" deleted
pod "kube-proxy-lbdv5" deleted
上传镜像
官网找到metallb.yaml 修改镜像路径
[root@server2 ~]# mkdir metallb
[root@server2 ~]# cd metallb/
[root@server2 metallb]# vim metallb.yaml
image: metallb/speaker:v0.10.2
image: metallb/controller:v0.10.2
编辑配置文件,给定IP
[root@server2 metallb]# vim configmap.yaml
[root@server2 metallb]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.25.12.10-172.25.12.20
[root@server2 metallb]# kubectl apply -f metallb.yaml
namespace/metallb-system unchanged
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/controller configured
podsecuritypolicy.policy/speaker configured
serviceaccount/controller unchanged
serviceaccount/speaker unchanged
clusterrole.rbac.authorization.k8s.io/metallb-system:controller unchanged
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker unchanged
role.rbac.authorization.k8s.io/config-watcher unchanged
role.rbac.authorization.k8s.io/pod-lister unchanged
role.rbac.authorization.k8s.io/controller unchanged
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller unchanged
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker unchanged
rolebinding.rbac.authorization.k8s.io/config-watcher unchanged
rolebinding.rbac.authorization.k8s.io/pod-lister unchanged
rolebinding.rbac.authorization.k8s.io/controller unchanged
daemonset.apps/speaker unchanged
deployment.apps/controller unchanged
[root@server2 metallb]# kubectl get ns
NAME STATUS AGE
default Active 5d19h
kube-node-lease Active 5d19h
kube-public Active 5d19h
kube-system Active 5d19h
metallb-system Active 2d2h
[root@server2 metallb]# kubectl -n metallb-system get all
NAME READY STATUS RESTARTS AGE
pod/controller-674f4b76b8-8w4pz 1/1 Running 1 2d2h
pod/speaker-cqr4t 1/1 Running 1 2d2h
pod/speaker-h94ql 1/1 Running 1 2d2h
pod/speaker-rww6z 1/1 Running 2 2d2h
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/speaker 3 3 3 3 3 kubernetes.io/os=linux 2d2h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 1/1 1 1 2d2h
NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-674f4b76b8 1 1 1 2d2h
[root@server2 metallb]# kubectl -n metallb-system get pod
NAME READY STATUS RESTARTS AGE
controller-674f4b76b8-8w4pz 1/1 Running 1 2d2h
speaker-cqr4t 1/1 Running 1 2d2h
speaker-h94ql 1/1 Running 1 2d2h
speaker-rww6z 1/1 Running 2 2d2h
[root@server2 metallb]# kubectl -n metallb-system get secrets
NAME TYPE DATA AGE
controller-token-4xpkw kubernetes.io/service-account-token 3 2d2h
default-token-7j2jn kubernetes.io/service-account-token 3 2d2h
memberlist Opaque 1 2d2h
speaker-token-gflz6 kubernetes.io/service-account-token 3 2d2h
[root@server2 metallb]# kubectl -n metallb-system get pod
NAME READY STATUS RESTARTS AGE
controller-674f4b76b8-8w4pz 1/1 Running 1 2d2h
speaker-cqr4t 1/1 Running 1 2d2h
speaker-h94ql 1/1 Running 1 2d2h
speaker-rww6z 1/1 Running 2 2d2h
[root@server2 metallb]# kubectl apply -f configmap.yaml
configmap/config unchanged
[root@server2 metallb]# kubectl get cm -n metallb-system
NAME DATA AGE
config 1 2d2h
kube-root-ca.crt 1 2d2h
[root@server2 metallb]# vim lb-svc.yaml
[root@server2 metallb]# cat lb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: lb-svc
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: myapp
type: LoadBalancer
[root@server2 metallb]# kubectl apply -f lb-svc.yaml
service/lb-svc created
[root@server2 metallb]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d19h
lb-svc LoadBalancer 10.102.235.137 172.25.12.10 80:30603/TCP 9s
mysvc NodePort 10.109.144.155 <none> 80:31480/TCP 52m
访问ip 负载均衡
[root@foundation12 ~]# curl 172.25.12.10
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@foundation12 ~]# curl 172.25.12.10/hostname.html
myapp-deployment-59dff4cf5d-jbtjz
[root@foundation12 ~]# curl 172.25.12.10/hostname.html
myapp-deployment-59dff4cf5d-ngxc9
[root@foundation12 ~]# curl 172.25.12.10/hostname.html
myapp-deployment-59dff4cf5d-jvh4n
[root@foundation12 ~]# curl 172.25.12.10/hostname.html
myapp-deployment-59dff4cf5d-jbtjz
[root@foundation12 ~]# curl 172.25.12.10/hostname.html
myapp-deployment-59dff4cf5d-ngxc9
[root@foundation12 ~]# curl 172.25.12.10/hostname.html
myapp-deployment-59dff4cf5d-jvh4n
[root@foundation12 ~]#
ExternalName
设定域名
[root@server2 metallb]# vim ex-svc.yaml
[root@server2 metallb]# cat ex-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ExternalName
externalName: www.westos.org
[root@server2 metallb]# kubectl apply -f ex-svc.yaml
service/my-service created
查看svc信息
[root@server2 metallb]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ExternalName <none> www.westos.org <none> 7s
dig查看详细解析信息
[root@server2 metallb]# dig -t A my-service.default.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> -t A my-service.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13749
;; 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
;; QUESTION SECTION:
;my-service.default.svc.cluster.local. IN A
;; ANSWER SECTION:
my-service.default.svc.cluster.local. 30 IN CNAME www.westos.org.
;; Query time: 2002 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Fri Jul 30 03:43:28 EDT 2021
;; MSG SIZE rcvd: 129