k8s创建service

k8s创建service

  • 一、创建service示例
    • 1.1、已有的deployment
    • 1.2、使用expose创建
    • 1.3、使用yaml创建
    • 1.4、从集群外部访问service
    • 1.5、创建无头服务Headless Service
  • 二、Service的yaml文件定义详解

一、创建service示例

1.1、已有的deployment

在之前已经创建了一个有两个nginx副本数的deployment,如下所示:

[root@k8s-node1 mytestyaml]# kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           45m
[root@k8s-node1 mytestyaml]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
nginx-deployment-85ff79dd56-42mh9   1/1     Running   0          38m   10.244.2.62   k8s-node3   <none>           <none>
nginx-deployment-85ff79dd56-gx2dl   1/1     Running   0          44m   10.244.1.68   k8s-node2   <none>           <none>

并且直接访问其IP地址也能够正常的访问到nginx,但是这些Pod的IP地址并不是固定的,如果这个Pod被重新部署的话,他的IP地址是跟着一起变的。如果只是为了对外提供服务,外界不应去关注这个IP地址的变化,最好是能够访问一个固定的IP。

而在k8s中,service就是专门来做这个事情的。

1.2、使用expose创建

我们可以直接expose这个deployment来实现,如下所示:

[root@k8s-node1 mytestyaml]# kubectl expose deployment nginx-deployment
service/nginx-deployment exposed
[root@k8s-node1 mytestyaml]# kubectl get svc
NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes         ClusterIP   10.96.0.1      <none>        443/TCP   28d
nginx-deployment   ClusterIP   10.96.112.83   <none>        80/TCP    26s

这里已经分配给了nginx-deployment 一个 CLUSTER-IP 为 10.96.112.83 ,端口号依旧是80。
那么我们直接访问这个CLUSTER-IP和端口号就能够访问到nginx了,因为service会自动的帮我们把访问到10.96.112.83:80的请求进行负载均衡,转发到10.244.2.62:80和10.244.1.68:80上去。

无论pod被重新部署或者所扩容与否,即使是IP地址变了,我们依然是可以访问CLUSTER-IP:PORT进行访问的。
如下所示,访问10.96.112.83:80:

[root@k8s-node1 mytestyaml]# curl 10.96.112.83:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

1.3、使用yaml创建

还有一种使用yaml文件的方式来声明service。
如下nginx-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service       # service的名称,全局唯一
spec:
  ports:
    - port: 80             # service暴露的端口号
      targetPort: 80       # 目标端口号
  selector:
    app: nginx
[root@k8s-node1 mytestyaml]# kubectl apply -f nginx-service.yaml
service/nginx-service created
[root@k8s-node1 mytestyaml]# kubectl get svc
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP   28d
nginx-service   ClusterIP   10.96.164.32   <none>        80/TCP    10s

1.4、从集群外部访问service

上面的yaml文件部署是ClusterIP类型的service,由于这些IP或者端口号都是k8s集群内部的虚拟出来的,因此他只能够用来在k8s集群内部访问,如果需要从集群的外部访问这些service或者Pod,就需要将service部署成为NodePort类型,将集群内部的端口号映射到这台物理机的端口上去,这样就能够直接通过物理机的IP地址+映射的端口号来访问了。

使用NodePort方式的yaml文件如下:
nginx-service2.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service       # service的名称,全局唯一
spec:
  type: NodePort            
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080       # 映射到物理机的端口号
  selector:
    app: nginx

创建该service

[root@k8s-node1 mytestyaml]# kubectl apply -f nginx-service2.yaml
service/nginx-service created
[root@k8s-node1 mytestyaml]# kubectl get svc -o wide
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        40d   <none>
nginx-service   NodePort    10.96.162.144   <none>        80:30080/TCP   28s   app=nginx

从web页面上访问,因为我开的这个 虚拟机的ip是192.168.56.100,而映射的端口号为30080,所以就访问这地址,如下所示:
k8s创建service_第1张图片
显示Welcome to nginx! 访问成功

1.5、创建无头服务Headless Service

Headless Service即无头服务,就是没有ClusterIP的Service,他的作用也不同于普通的Service,不能直接通过ClusterIP访问路由到后端的Pod上去。
而他的作用就是,当客户端通过k8s api访问这个无头服务的时候,会将其通过Label Selector匹配上的Pod列表信息返回给客户端,客户端就能够通过获得的信息,自义定去作出某些操作。

如下为无头服务的yaml文件:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service       # service的名称,全局唯一
spec:
  clusterIP: None           # 设置clusterIP为None,就表示它是一个无头服务
  ports:
    - port: 80             # service暴露的端口号
      targetPort: 80
  selector:
    app: nginx

创建无头服务

[root@k8s-node1 mytestyaml]# kubectl apply -f nginx-headless-service.yaml
service/nginx-service created
[root@k8s-node1 mytestyaml]# kubectl get svc -o wide
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE     SELECTOR
kubernetes      ClusterIP   10.96.0.1    <none>        443/TCP   41d     <none>
nginx-service   ClusterIP   None         <none>        80/TCP    2m24s   app=nginx

查看这个nginx-service的详细信息,可以看到Endpoints已经匹配到了两个后端的Pod地址

[root@k8s-node1 mytestyaml]# kubectl describe svc nginx-service
Name:              nginx-service
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"nginx-service","namespace":"default"},"spec":{"clusterIP":"None",...
Selector:          app=nginx
Type:              ClusterIP
IP:                None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.82:80,10.244.2.77:80
Session Affinity:  None
Events:            <none>

再通过postman对 k8s 的restful api进行访问:
https://192.168.56.100:6443/api/v1/namespaces/default/endpoints/nginx-service
可以看到,访问无头服务,返回的出现了这两个Pod的详细信息
k8s创建service_第2张图片
我们也可以通过java程序去使用restful api来访问k8s获取这些信息,这样就能够在应用程序中去定义自己想要的功能了。

二、Service的yaml文件定义详解

apiVersion: v1
kind: Service
metadata:            # 元数据
  name: string       # service的名称,全局唯一
  namespace: string  #命名空间,不指定时,默认为default
  labels:            #自定义标签属性列表
    - name: string
  annotations:       #自定义注解属性列表
    - name: string
spec:                #详细信息
  selector: []       #Label Selector配置,将选择具有指定label 标签的Pod作为管理范围
  type: string       #类型,指定Service的访问方式,默认为Cluster IP,还有NodePort、LoadBalancer
  clusterIP: string  #当type为clusterIP时,可以手动指定,不指定则自动分配
  sessionAffinity: string  # 支持session则同一个客户端访问则会转发到同一个Pod
  ports:                    #Service需要暴露的端口列表
    - name: string          # 端口名称
      protocol: string      # 端口协议,默认TCP,还可选UDP
      port: int             # 服务监听的的端口号
      targetPort: int       # 需要转发到后端的Pod端口号
      nodePort: int         # 当type为NodePort时,这里指定映射到物理机的端口号
  status:                   # 当spec.type=LoadBalancer时,设置外部负载均衡器的地区
    loadBalancer:
      ingress:
        ip: string          # 外部负载均衡器的ip地址
        hostname: string    # 外部负载均衡器的主机名

你可能感兴趣的:(Kubernates,nginx,linux,服务器)