k8s-Service 控制器

1,650次阅读
没有评论

共计 6520 个字符,预计需要花费 17 分钟才能阅读完成。

Service简介

service控制器定义了一组网络逻辑集合(通常由Label Selector)和一个访问入口策略,目前常用service控制器有四种

  • NodePort
  • LoadBalancer
  • ClusterIP
  • ExternalName

NodePort

对于 NodePort 类型的 Service,k8s为其分配一个节点端口(对于同一 Service,在每个节点上的节点端口都相同),该端口的范围在初始化 apiserver 时可通过参数 –service-node-port-range 指定(默认是:30000-32767)。NodePort 类型访问方式:

  • 在集群内部通过 $(ClusterIP): $(Port) 访问
  • 在集群外部通过 $(NodeIP): $(NodePort) 访问
# 创建测试deployment文件
[root@master service-test]# cat nginx2.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx2
  labels:
    app: nginx2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx2
  template:
    metadata:
      labels:
        app: nginx2
    spec:
      initContainers:
      - name: init-container
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        command: ["sh"]
        env:
#        - name: MY_POD_NAME
#          valueFrom:
#            fieldRef:
#              fieldPath: metadata.name
         - name: MY_POD_IP
           valueFrom:
             fieldRef:
               fieldPath: status.podIP
        args: 
          [
            "-c",
            "echo ${HOSTNAME} ${MY_POD_IP} > /wwwroot/index.html",
          ]
        volumeMounts:
        - name: wwwroot
          mountPath: "/wwwroot"
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html/index.html
          subPath: index.html
      volumes:
        - name: wwwroot
          emptyDir: {}

# 创建deployment
[root@master service-test]# kubectl apply -f nginx2.yaml 
deployment.apps/nginx2 created

# 查看详情
[root@master service-test]# kubectl get pods -l app=nginx2 -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
nginx2-6b7d48d445-4rr7p   1/1     Running   0          4m37s   10.100.166.137   node1   <none>           <none>
nginx2-6b7d48d445-jf7jf   1/1     Running   0          4m37s   10.100.104.9     node2   <none>           <none>
nginx2-6b7d48d445-zh598   1/1     Running   0          4m37s   10.100.104.10    node2   <none>           <none>

创建 NodePort Service类型服务

[root@master service-test]# cat >nginx2-nodeport.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx2-nodeport
spec:
  type: NodePort
  selector:
    app: nginx2
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
EOF

[root@master service-test]# kubectl apply -f nginx2-nodeport.yaml 
service/nginx2-nodeport created

[root@master service-test]# kubectl get -f nginx2-nodeport.yaml 
NAME              TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
nginx2-nodeport   NodePort   10.96.31.19   <none>        80:30985/TCP   7s

测试验证 NodePort 类型服务

# 访问任意node的30985端口
[root@master service-test]# curl 10.200.1.139:30985
nginx2-6b7d48d445-4rr7p 10.100.166.137
[root@master service-test]# curl 10.200.1.139:30985
nginx2-6b7d48d445-jf7jf 10.100.104.9
[root@master service-test]# curl 10.200.1.139:30985
nginx2-6b7d48d445-zh598 10.100.104.10

# 访问NodePort服务的clusterip
[root@master service-test]# curl 10.96.31.19
nginx2-6b7d48d445-zh598 10.100.104.10
[root@master service-test]# curl 10.96.31.19
nginx2-6b7d48d445-jf7jf 10.100.104.9
[root@master service-test]# curl 10.96.31.19
nginx2-6b7d48d445-4rr7p 10.100.166.137

ClusterIP

ClusterIP 类型的 Service 会拥有一个 clusterip(vip),仅可在集群内访问,集群外无法访问。

# 创建测试deployment文件
[root@master service-test]# cat >nginx1.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx1
  labels:
    app: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      initContainers:
      - name: init-container
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        command: ["sh"]
        env:
#        - name: MY_POD_NAME
#          valueFrom:
#            fieldRef:
#              fieldPath: metadata.name
         - name: MY_POD_IP
           valueFrom:
             fieldRef:
               fieldPath: status.podIP
        args: 
          [
            "-c",
            "echo ${HOSTNAME} ${MY_POD_IP} > /wwwroot/index.html",
          ]
        volumeMounts:
        - name: wwwroot
          mountPath: "/wwwroot"
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html/index.html
          subPath: index.html
      volumes:
        - name: wwwroot
          emptyDir: {}
EOF

# 创建deployment
[root@master service-test]# kubectl apply -f nginx1.yaml 
deployment.apps/nginx1 created

[root@master service-test]# kubectl get pods -o wide
NAME                             READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
nginx-9f5cb7f94-nbctt            1/1     Running   0          5d21h   10.100.104.2     node2    <none>           <none>
nginx1-859486d7bb-7mc4h          1/1     Running   0          11s     10.100.166.136   node1    <none>           <none>
nginx1-859486d7bb-r2sg4          1/1     Running   0          11s     10.100.166.135   node1    <none>           <none>
nginx1-859486d7bb-shzzp          1/1     Running   0          11s     10.100.104.8     node2    <none>           <none>

此时为 nginx1 创建一个 ClusterIP 类型 Service,ClusterIP 是 ServiceType 的默认值。

[root@master service-test]# cat >nginx1-clusterip.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx1-clusterip
spec:
  selector:
    app: nginx1
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
EOF

[root@master service-test]# kubectl apply -f nginx1-clusterip.yaml 
service/nginx1-clusterip created

[root@master service-test]# kubectl get -f nginx1-clusterip.yaml
NAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
[root@master service-test]# kubectl get -f nginx1-clusterip.yaml
NAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
nginx1-clusterip   ClusterIP   10.96.218.0   <none>        80/TCP    43m

# 查看该service对应的Endpoints
[root@master service-test]# kubectl describe svc nginx1-clusterip
Name:              nginx1-clusterip
Namespace:         default
Labels:            <none>
Annotations:       Selector:  app=nginx1
Type:              ClusterIP
IP:                10.96.218.0
Port:              http  80/TCP
TargetPort:        80/TCP
Endpoints:         10.100.104.8:80,10.100.166.135:80,10.100.166.136:80
Session Affinity:  None
Events:            <none>

测试访问验证clusterip

[root@master service-test]# curl 10.96.218.0
nginx1-859486d7bb-shzzp 10.100.104.8
[root@master service-test]# curl 10.96.218.0
nginx1-859486d7bb-7mc4h 10.100.166.136

[root@master service-test]# curl 10.96.218.0
nginx1-859486d7bb-r2sg4 10.100.166.135

LoadBalance

LoadBalance 类型Service 可提供外部负载均衡访问入口,由云服务商定义写法,本文不再描述

参考链接:https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer

ExternalName

ExternalName 类型 Service 可提供映射外部服务,上面那些类型 Service 是提供内部服务映射的。通常用于外部服务发生服务维护切换服务入口链接,此时便要修改应用程序链接地址,不方便。所以可以使用 ExternalName 给外部服务地址做Cname 映射。其他Service的转发发生再porxy,而这个则是再DNS Level

# 创建ExternalName demo服务,externalName字段不能填写ip地址,会被当做字符串域名。
[root@master service-test]# cat >test-externalname.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: default
spec:
  type: ExternalName
  externalName: www.xadocker.cn
EOF

[root@master service-test]# kubectl apply -f test-externalname.yaml
[root@master service-test]# kubectl get -f test-externalname.yaml 
NAME         TYPE           CLUSTER-IP   EXTERNAL-IP       PORT(S)   AGE
my-service   ExternalName   <none>       www.xadocker.cn   <none>    7m58s
[root@master service-test]# kubectl describe -f test-externalname.yaml 
Name:              my-service
Namespace:         default
Labels:            <none>
Annotations:       Selector:  <none>
Type:              ExternalName
IP:                
External Name:     www.xadocker.cn
Session Affinity:  None
Events:            <none>

测试

# 此时集群应用可以使用 my-service.default.svc.cluster.local 来调用该服务
# 创建一个busybox来测试解析域名
[root@master service-test]# cat >busybox.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
  name: test-busybox
  labels:
    app: test-busybox
spec:
  containers:
    - name: test-busybox
      image: busybox:latest
      command: ['sh','-c','echo testing! && sleep 3600']
EOF

[root@master service-test]# kubectl apply -f busybox.yaml
[root@master service-test]# kubectl exec -it test-busybox -- /bin/sh
/ # nslookup my-service.default.svc.cluster.local
Server:		10.96.0.10
Address:	10.96.0.10:53

my-service.default.svc.cluster.local	canonical name = www.xadocker.cn
Name:	www.xadocker.cn
Address: 43.13.47.25

*** Can't find my-service.default.svc.cluster.local: No answer

正文完
 21
xadocker
版权声明:本站原创文章,由 xadocker 2021-08-29发表,共计6520字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)