乐趣区

关于kubernetes:KubernetesService实践

Service 作用和原理

作用:Service 的作用次要是用来做负载平衡,dns 解析以及对外裸露端口。所有的 pod IP 和端口都会通过 label 匹配到,而后通过 coredns 解析实现了服务发现
原理:Service 通过 iptables 或者 ipvs 对拜访的指标地址进行批改转发数据

Service 的类型

  • Cluster
  • NodePort
  • LoadBalancer
  • ExternalName

Cluster 类型
$ cat myapp-deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1
        ports:
        - containerPort: 80
        name: http
$ cat myapp-svc.yaml 
kind: Service
apiVersion: v1
metadata:
  name: myapp-svc
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
$ kubectl apply -f myapp-deploy.yaml
deployment.apps/myapp-deploy created

$ kubectl apply -f myapp-svc.yaml
service/myapp-svc created

$ kubectl get deploy,svc,endpoints
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myapp-deploy   3/3     3            3           28s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   5d21h
service/myapp-svc    ClusterIP   10.105.225.171   <none>        80/TCP    22s

NAME                   ENDPOINTS                                   AGE
endpoints/kubernetes   172.16.56.133:8443                          5d21h
endpoints/myapp-svc    172.17.0.6:80,172.17.0.7:80,172.17.0.8:80   22s

$ kubectl run cirros-$RANDOM --rm -ti --image=cirros -- sh

/ # curl http://10.105.225.171
<h3>Hello World!</h3><b>Hostname:</b> myapp-deploy-ccc8b4bb5-f829g<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>/


NodePort 类型
$ cat myapp-svc.yaml 
kind: Service
apiVersion: v1
metadata:
  name: myapp-svc
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 32223
$ kubectl apply -f myapp-svc.yaml
service/myapp-svc configured

$ kubectl get svc               
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        5d21h
myapp-svc    NodePort    10.105.225.171   <none>        80:32223/TCP   9m46s

$ kubectl get pod -o wide        
NAME                           READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
myapp-deploy-ccc8b4bb5-dn4lb   1/1     Running   0          10m   172.17.0.6   minikube   <none>           <none>
myapp-deploy-ccc8b4bb5-ds542   1/1     Running   0          10m   172.17.0.7   minikube   <none>           <none>
myapp-deploy-ccc8b4bb5-f829g   1/1     Running   0          10m   172.17.0.8   minikube   <none>           <none>

如果你尝试刷新页面,会发现失去不同的主机名,这是正确的


ExternalName 类型
$ cat external-redis-svc.yaml 
kind: Service
apiVersion: v1
metadata:
  name: external-redis-svc
  namespace: default
spec:
  type: ExternalName
  externalName: www.baidu.com
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 0
  selector: {}
$ kubectl create -f external-redis-svc.yaml
service/external-redis-svc created

$ kubectl get svc
NAME                 TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
external-redis-svc   ExternalName   <none>           www.baidu.com   80/TCP         5s
kubernetes           ClusterIP      10.96.0.1        <none>          443/TCP        5d21h
myapp-svc            NodePort       10.105.225.171   <none>          80:32223/TCP   17m

$ kubectl run -ti --rm busybox --image=busybox -- sh
/ # nslookup external-redis-svc.default.svc.cluster.local.
Server:        10.96.0.10
Address:    10.96.0.10:53

external-redis-svc.default.svc.cluster.local    canonical name = www.baidu.com
www.baidu.com    canonical name = www.a.shifen.com
Name:    www.a.shifen.com
Address: 163.177.151.109
Name:    www.a.shifen.com
Address: 163.177.151.110

*** Can't find external-redis-svc.default.svc.cluster.local.: No answer

/ # exit

 
 
 

  • 如果内部服务没有域名,为了进步服务的兼容性能够采纳 service+ 手动 endponit,自定义一个域名
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376

【完结】

退出移动版