k8s之Service服务类型

Service服务类型

Service代理模式

k8s之Service服务类型_第1张图片

Service存在的意义

service引入主要是解决Pod的动态变化,提供统一访问入口:

  • 防止Pod失联,准备找到提供同一个服务的Pod(服务发现)
  • 定义一组Pod的访问策略(负载均衡)

k8s之Service服务类型_第2张图片

Pod与Service的关系:

  • Service通过标签关联一组Pod
  • Service使用iptables或者ipvs为一组Pod提供负载均衡能力

k8s之Service服务类型_第3张图片

Kubernetes 中Service有如下4中类型:

ClusterIP:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟IP
NodePort:在 ClusterIP 基础上为Service在每台机器上绑定一个端口,这样可以通过 NodeIP:NodePort来访问服务
LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到 NodeIP:NodePort
ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用,没有任何类型代理被创建,这只有Kubernetes 1.7或更高版本的kube-dns才支持

ClusterIP

默认类型,自动分配一个仅Cluster内部能够访问的虚拟IP

编写xx.yaml文件

[root@master manifest]# cat network.yaml 
---
apiVersion: apps/v1 
kind: Deployment
metadata: 
  name: notwork  
  namespace: default 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: web 
      release: v1
  template:
    metadata: 
      labels: 
        app: web
        release: v1 
    spec: 
      containers: 
      - name: web
        image: nginx
        imagePullPolicy: IfNotPresent

--- 
apiVersion: v1 
kind: Service 
metadata: 
  name: web
spec:   
  type: ClusterIP   # 指定ClusterIP类型
  selector: 
    app: web
  ports: 
  - name: web
    port: 80
    targetPort: 80


[root@master manifest]# kubectl create -f network.yaml deployment.apps/notwork created
service/web created


#查看ip地址
[root@master ~]# kubectl get pods,svc
NAME                           READY   STATUS    RESTARTS   AGE
pod/notwork-6cb9497c86-hz8jm   1/1     Running   0          6s
pod/notwork-6cb9497c86-sfjbk   1/1     Running   0          6s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1               443/TCP   7d23h
service/web          ClusterIP   10.107.190.89           80/TCP    6s


#访问
[root@master ~]# curl 10.107.190.89



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

NodePort:对外暴露应用(集群外)

在每个节点上启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定内部集群Ip地址。

访问地址:<任意NodeIP>:

端口范围: 30000-32767

[root@master manifest]# cat network.yaml 
---
apiVersion: apps/v1 
kind: Deployment
metadata: 
  name: notwork  
  namespace: default 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: web 
      release: v1
  template:
    metadata: 
      labels: 
        app: web
        release: v1 
    spec: 
      containers: 
      - name: web
        image: nginx
        imagePullPolicy: IfNotPresent

--- 
apiVersion: v1 
kind: Service 
metadata: 
  name: web
spec: 
  type: NodePort
  namespace: default 
  selector: 
    app: web
  ports: 
  - name: web
    port: 80
    targetPort: 80
    nodePort: 30008


[root@master manifest]# kubectl create -f network.yaml 
deployment.apps/notwork created
service/web created

[root@master ~]# kubectl get pods,svc
NAME                           READY   STATUS    RESTARTS   AGE
pod/notwork-6cb9497c86-5ljbx   1/1     Running   0          40s
pod/notwork-6cb9497c86-6pvkq   1/1     Running   0          40s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1               443/TCP        7d23h
service/web          NodePort    10.109.242.11           80:30008/TCP   40s
[root@master ~]# 



[root@master ~]# iptables -t nat -nvL | grep 'web'
    0     0 KUBE-MARK-MASQ  tcp  --  *      *      !10.244.0.0/16        10.109.242.11        /* default/web:web cluster IP */ tcp dpt:80
    0     0 KUBE-SVC-FZQ4YMPBOOYJKQMV  tcp  --  *      *       0.0.0.0/0            10.109.242.11        /* default/web:web cluster IP */ tcp dpt:80
    0     0 KUBE-MARK-MASQ  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/web:web */ tcp dpt:30008
    0     0 KUBE-SVC-FZQ4YMPBOOYJKQMV  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/web:web */ tcp dpt:30008
    0     0 KUBE-SEP-FS5AJG4JGP4NFZBK  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/web:web */ statistic mode random probability 0.50000000000
    0     0 KUBE-SEP-DF4DTEZSYVN2RXLA  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/web:web */
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.2.143         0.0.0.0/0            /* default/web:web */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/web:web */ tcp to:10.244.2.143:80
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.2.144         0.0.0.0/0            /* default/web:web */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/web:web */ tcp to:10.244.2.144:80
[root@master ~]# 

#宿主机ip+<自定义端口号>
[root@master ~]# curl 192.168.244.146:30008



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

ExternalName类型示例

ExternalName:经过返回 CNAME 和它的值,能够将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。没有任何类型代理被建立。
须要注意的是:Service 可以将一个接收 port 映射到任意的 targetPort。默认状况下,targetPort 将被设置为与 port 字段相同的值。

[root@master manifest]# cat network.yaml 
---
apiVersion: apps/v1 
kind: Deployment
metadata: 
  name: notwork  
  namespace: default 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: web 
      release: v1
  template:
    metadata: 
      labels: 
        app: web
        release: v1 
    spec: 
      containers: 
      - name: web
        image: nginx
        imagePullPolicy: IfNotPresent

--- 
apiVersion: v1 
kind: Service 
metadata: 
  name: web
  namespace: default
spec: 
  type: ExternalName
  externalName: tom.k8s.example.com


[root@master manifest]# kubectl create -f network.yaml 
deployment.apps/notwork created
service/web created


[root@master ~]# kubectl get pods,svc
NAME                           READY   STATUS    RESTARTS   AGE
pod/notwork-6cb9497c86-76td2   1/1     Running   0          14s
pod/notwork-6cb9497c86-9cg49   1/1     Running   0          14s

NAME                 TYPE           CLUSTER-IP   EXTERNAL-IP           PORT(S)   AGE
service/kubernetes   ClusterIP      10.96.0.1                    443/TCP   7d23h
service/web          ExternalName          tom.k8s.example.com       14s
[root@master ~]# 

这种类型的Service经过返回CNAME和它的值,能够将服务映射到externalName字段的内容(例如:amu.k8s.example.com;能够实现跨namespace名称空间访问)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它经过返回该外部服务的别名这种方式提供服务。

ExternalIP示例

若是外部的 IP 路由到集群中一个或多个 Node 上,Kubernetes Service 会被暴露给这些 externalIPs。经过外部 IP(做为目的 IP 地址)进入到集群,打到 Service 端口上的流量,将会被路由到 Service 的 Endpoint 上。

externalIPs 不会被 Kubernetes 管理,它属于集群管理员的职责范畴。

[root@master manifest]# cat network.yaml 
---
apiVersion: apps/v1 
kind: Deployment
metadata: 
  name: notwork  
  namespace: default 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: web 
      release: v1
  template:
    metadata: 
      labels: 
        app: web
        release: v1 
    spec: 
      containers: 
      - name: web
        image: httpd
        imagePullPolicy: IfNotPresent

--- 
apiVersion: v1 
kind: Service 
metadata: 
  name: web
  namespace: default
spec: 
  selector:
    app: web
    release: v1
  ports:
  - name: web
    port: 80
    targetPort: 80
  externalIPs:
    - 10.0.0.230

[root@master ~]# kubectl get pods,svc
NAME                           READY   STATUS    RESTARTS   AGE
pod/notwork-7b5664dc66-w4jbq   1/1     Running   0          13m

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1              443/TCP   8d
service/web          ClusterIP   10.101.72.35   10.0.0.230    80/TCP    13m

[root@master ~]# curl 10.101.72.35

It works!

service代理模式

kubeadm方式修改ipvs模式

kubectl edit configmap kube-proxy -n kube-system

.....

  mode:"ipvs"

.....


kubectl delete pod kube-proxy-btz4p -n kube-system

注意:

  • kube-proxy配置文件以configmap方式存储
  • 如果让所有节点生效,需要重建所有节点kube-proxy pod

二进制方式修改ipvs模式

vim kube-proxy-config.yaml

mode: ipvs

ipvs:

  scheduler: "rr"

systemctl restart kube-proxy

流程包

流程:客户端 -> NodePort/ClusterIP(iptables/Ipvs负载均衡规则) -> 分布在各节点Pod

查看负载均衡规则:

  • iptables模式

iptables-save | grep

  • ipvs模式

ipvsadm -L -n

k8s之Service服务类型_第4张图片

实战

创建一个deployment 副本数3.然后滚动更新镜像版本,并记录这个更新记录,最后在回滚到上一个版本

[root@master manifest]# cat test3.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: web
  namespace: default
spec: 
  replicas: 3           
  revisionHistoryLimit: 5               
  strategy: 
    rollingUpdate: 
      maxSurge: 40
      maxUnavailable: 50%
    type: RollingUpdate
  selector: 
    matchLabels: 
      app: httpd
  template: 
    metadata:  
      labels:
        app: httpd
    spec: 
      containers: 
      - name: httpd
        image: httpd
        imagePullPolicy: IfNotPresent

[root@master manifest]# kubectl create -f test3.yaml 
deployment.apps/web created

#查看历史记录
[root@master manifest]#  kubectl rollout history deployment/web
deployment.apps/web 
REVISION  CHANGE-CAUSE
1         

[root@master ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-8487457bf4-7zfmx   1/1     Running   0          41s
web-8487457bf4-9fx2g   1/1     Running   0          41s
web-8487457bf4-zl5kj   1/1     Running   0          41s


#修改镜像版本
......
    spec:
      containers:
      - name: web
        image: httpd   #随便改镜像
        imagePullPolicy: IfNotPresent

[root@master manifest]# kubectl apply -f test3.yaml 
deployment.apps/web unchanged


[root@master ~]# kubectl get pods
NAME                   READY   STATUS        RESTARTS   AGE
web-66dd47b7cd-4v6mr   0/1     Terminating   0          10m
web-66dd47b7cd-qnngq   0/1     Terminating   0          10m
web-66dd47b7cd-wwtpz   0/1     Terminating   0          10m
web-7bbbccf79c-fhk6g   1/1     Running       0          10s
web-7bbbccf79c-mvq9j   1/1     Running       0          10s
web-7bbbccf79c-n7z42   1/1     Running       0          10s

[root@master ~]# kubectl rollout history deployment/web
deployment.apps/web 
REVISION  CHANGE-CAUSE
1         
2         
3         

#回滚
[root@master ~]# kubectl rollout undo deployment/web --to-revision=2
deployment.apps/web rolled back
[root@master ~]# kubectl rollout history deployment/web
deployment.apps/web 
REVISION  CHANGE-CAUSE
1         
3         
4         

给一个应用扩容副本数为5

[root@master manifest]# cat test3.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: web
  namespace: default
spec: 
  replicas: 5    # 改为5        
  revisionHistoryLimit: 5    #历史记录            
  strategy: 
    rollingUpdate: 
      maxSurge: 40
      maxUnavailable: 50%
    type: RollingUpdate
  selector: 
    matchLabels: 
      app: httpd
  template: 
    metadata:  
      labels: 
        app: httpd
    spec: 
      containers: 
      - name: httpd
        image: sktystwd/apache:v0.1
        imagePullPolicy: IfNotPresent

[root@master manifest]# kubectl apply -f test3.yaml 
deployment.apps/web configured


[root@master ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-7bbbccf79c-4jd27   1/1     Running   0          39s
web-7bbbccf79c-8gncv   1/1     Running   0          39s
web-7bbbccf79c-jqbzj   1/1     Running   0          39s
web-7bbbccf79c-mj6x7   1/1     Running   0          39s
web-7bbbccf79c-rhj56   1/1     Running   0          39s


创建一个pod,其中运行着nginx、redis、memcached 3个容器

[root@master manifest]# cat test4.yaml 
---
apiVersion: v1
kind: Pod
metadata: 
  name: test
  labels: 
    app: tests
spec: 
  containers: 
  - image: nginx
    name: nginx
  - image: redis
    name: redis
  - image: memcached
    name: memcached

[root@master manifest]# kubectl create -f test4.yaml
pod/test created


[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
test   3/3     Running   0          95s

给一个pod创建service,并可以通过ClusterIP/NodePort访问

[root@master manifest]# cat test5.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: httpd
  namespace: default
spec: 
  replicas: 1
  selector: 
    matchLabels: 
      app: httpd
      release: v1
  template: 
    metadata: 
      labels: 
        app: httpd
        release: v1
    spec: 
      containers: 
      - name: httpd
        image: httpd
        imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Service
metadata: 
  name: web
  namespace: default
spec: 
  type: NodePort
  selector: 
    app: httpd
    release: v1
  ports: 
  - name: httpd
    port: 80
    targetPort: 80
    nodePort: 31888



[root@master ~]# kubectl get pods,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/httpd-66cf97c986-94bff   1/1     Running   0          10s
pod/test-66dd47b7cd-mrtl7    1/1     Running   0          2m50s
pod/web-6cb9497c86-qkkbb     1/1     Running   0          5m32s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1               443/TCP        8d
service/web          NodePort    10.110.155.23           80:31888/TCP   10s
[root@master ~]# curl 10.110.155.23

It works!

[root@master ~]# curl 192.168.244.146:31888

It works!

创建deployment和service,使用busybox容器nslookup解析service

[root@master manifest]# kubectl run max --image busybox -- sleep 1200
pod/max created

[root@master manifest]# kubectl exec -it max -- /bin/sh 
/ # nslookup kubernetes 
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can't find kubernetes.default.svc.cluster.local: NXDOMAIN

*** Can't find kubernetes.svc.cluster.local: No answer
*** Can't find kubernetes.cluster.local: No answer
*** Can't find kubernetes.example.com: No answer
*** Can't find kubernetes.default.svc.cluster.local: No answer
*** Can't find kubernetes.svc.cluster.local: No answer
*** Can't find kubernetes.cluster.local: No answer
*** Can't find kubernetes.example.com: No answer

/ # 


你可能感兴趣的:(kubernetes)