k8s入门:service 简单使用

系列文章目录

第一章:✨ k8s入门:裸机部署 k8s 集群
第二章:✨ k8s入门:部署应用到 k8s 集群
第三章:✨ k8s入门:service 简单使用
第四章:✨ k8s入门:StatefulSet 简单使用
第五章:✨ k8s入门:存储(storage)
第六章:✨ K8S 配置 storageclass 使用 nfs 动态申领本地磁盘空间
第七章:✨ k8s入门:配置 ConfigMap & Secret
第八章:✨ k8s入门:k8s入门:Helm 构建 MySQL
第九章:✨ k8s入门:kubernetes-dashboard 安装
第十章:✨ k8s入门:kube-prometheus-stack 全家桶搭建(Grafana + Prometheus)



一、简介

利用 Deployment 可以创建一组 Pod 来提供具有高可用性的服务。

虽然每个 Pod 都会分配一个单独的 IP,然而却存在如下两问题,可以通过 service 解决

  • Pod IP 会随着Pod的重建产生变化
  • Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问(主从结点外的机器无法访问)

在 K8s 的 yaml 配置文件中,name 属性只能包含小写字母数字字符 和 -,并且端口名称还必须以字母数字字符开头和结尾。

接上一篇 : k8s入门:部署应用到 k8s 集群,创建的 deployment/test-k8s-deployment,和其对应的 pod 如下,下面 service 会用到
在这里插入图片描述

二、Service 的类型
  • clusterIP:通过集群内部 IP 地址暴露服务,仅在集群内部可见、集群外部无法访问,Service 的默认类型

  • NodePort::暴露端口到节点,提供了集群外部访问的入口,端口范围固定 30000 ~ 32767

  • LoadBalancer: 会额外生成一个 IP 对外服务,需要公有云支持

  • ExternalName:通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理。kube-dns 1.7 及以上版本或者 CoreDNS 0.0.8 及以上版本才能使用 ExternalName 类型

你也可以使用 Ingress 来暴露自己的服务。 Ingress 不是一种服务类型,但它充当集群的入口点。 它可以将路由规则整合到一个资源中,因为它可以在同一IP地址下公开多个服务。

三、Service资源规范

参考:https://www.jianshu.com/p/1a75963b5814

apiVersion: v1
kind: Service
metadata:
  name: ..
  namespace: ...
  labels:
    key1: value1
    key2: value2
spec:
  type <string>  #Service类型,默认为ClusterIP
  selector <map[string]string> #等值类型的标签选择器,内含“与"逻辑
  ports: # Service的端口对象列表,数组类型,配置多个则必须配置 name 
  - name <string> # 端口名称
    protocol <string> # 协议,目前仅支持TCP、UDP和SCTP,默认为TCP
    port <integer> # Service的端口号
    targetPort <string> # 后端目标进程的端口号或名称,名称需由Pod规范定义
    nodePort <integer> # 节点端口号,仅适用于NodePort和LoadBalancer类型
  clusterIP <string> # Service的集群IP,建议由系统自动分配
  externalTrafficPolicy <string> # 外部流量策略处理方式,Local表示由当前节点处理,#Cluster表示向集群范围调度
  loadBalancerIP <string> # 外部负载均衡器使用的IP地址,仅适用于LoadBlancer
  externalName <string>  # 外部服务名称,该名称将作为Service的DNS CNAME值
四、ClusterIP 类型

新建 test-k8s-deployment-service.yaml 添加如下内容

apiVersion: v1
kind: Service
metadata:
  name: test-k8s-deployment-service
spec:
  selector:
    # 对应 deployment 名字
    app: test-k8s-deployment
  # 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)  
  type: ClusterIP
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口

创建 service 并查看状态,并保证 Endpoints 包含集群内部 IP

[root@master ~]# kubectl apply -f test-k8s-deployment-service.yaml 
service/test-k8s-deployment-service created
[root@master ~]# kubectl get svc
NAME                          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes                    ClusterIP   10.96.0.1      <none>        443/TCP    10h
test-k8s-deployment-service   ClusterIP   10.96.45.184   <none>        8080/TCP   10s
[root@master ~]# kubectl describe svc test-k8s-deployment-service
Name:              test-k8s-deployment-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=test-k8s-deployment
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.96.45.184
IPs:               10.96.45.184
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.1.7:8080,10.244.2.7:8080,10.244.2.8:8080
Session Affinity:  None
Events:            <none>

服务的默认类型是ClusterIP,只能在集群内部访问,kubectl exec -it pod-name -- bash 进入集群,我们可以进入到 Pod 里面访问:curl http://test-k8s-deployment-service:8080,我的容器内没有 curl 命令暂不测试

如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用),注意:一定要添加 service/,否则默认 pod

# 只支持本机访问
[root@master ~]# kubectl port-forward service/test-k8s-deployment-service 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Handling connection for 8080
# 支持所有地址
[root@master ~]# kubectl port-forward service/test-k8s-deployment-service --address 0.0.0.0 8080:8080
Forwarding from 0.0.0.0:8080 -> 8080

ClusterIP 适用于一个 pod 中有多个容器,容器之间可相互通信

五、NodePort 类型
1、新建 NodePort 类型 service

新建 test-k8s-deployment-service-NodePort.yaml 添加如下内容

apiVersion: v1
kind: Service
metadata:
  # 必须小写
  name: test-k8s-deployment-service-nodeport
spec:
  selector:
    # 对应 deployment 名字
    app: test-k8s-deployment
  type: NodePort
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口
      nodePort: 30001   # 节点端口,范围固定 30000 ~ 32767

创建查看详情

[root@master ~]# kubectl apply -f test-k8s-deployment-service-NodePort.yaml 
service/test-k8s-deployment-service-nodeport created
[root@master ~]# kubectl get svc
NAME                                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes                             ClusterIP   10.96.0.1       <none>        443/TCP          23h
test-k8s-deployment-service-nodeport   NodePort    10.96.227.136   <none>        8080:30001/TCP   135m
[root@master ~]# kubectl describe svc test-k8s-deployment-service-nodeport
Name:                     test-k8s-deployment-service-nodeport
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=test-k8s-deployment
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.96.227.136
IPs:                      10.96.227.136
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  30001/TCP
Endpoints:                10.244.1.9:8080,10.244.2.10:8080,10.244.2.11:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

测试,可以看到转发到了不同的 pod,和 service 中 Endpoints 的地址一致
在这里插入图片描述

2、修改 nodeport 端口范围

nodeport 默认端口范围 30000-32767,如果我指定 Nginx:80 端口会报如下错误

[root@master ant]# kubectl apply -f ant-service.yaml 
The Service "ant-deployment-service-nodeport" is invalid: spec.ports[0].nodePort: Invalid value: 80: provided port is not in the valid range. The range of valid ports is 30000-32767

解决办法,修改 /etc/kubernetes/manifests/kube-apiserver.yaml 文件,添加 - --service-node-port-range=1-65535 # 限定端口范围 1~65535

[root@master ant]# cat /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.25.100:6443
  creationTimestamp: null
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=192.168.25.100
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --service-node-port-range=1-65535 # 限定端口范围 1~65535
    - --feature-gates=RemoveSelfLink=false   # 添加这条
    - --client-ca-file=/etc/kubernetes/pki/ca.crt

使用 systemctl restart kubelet 重启服务即可生效,如下 80 端口指定成功

[root@master ant]# kubectl get svc
NAME                                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
ant-deployment-service-nodeport        NodePort    10.96.166.157   <none>        80:80/TCP        2m8s
六、暴露多个端口

多端口时必须配置 name,新增 test-k8s-deployment-service-NodePort-many.yaml 添加如下内容

apiVersion: v1
kind: Service
metadata:
  # 必须小写
  name: test-k8s-deployment-service-nodeport
spec:
  selector:
    # 对应 deployment 名字
    app: test-k8s-deployment
  type: NodePort
  ports:
    - port: 8080        # 本 Service 的端口
      name: default     # 必须配置
      targetPort: 8080  # 容器端口
      nodePort: 30001   # 节点端口,范围固定 30000 ~ 32767
    - port: 8088
      name: other
      targetPort: 8088
      nodePort: 30002

创建发现两个端口暴露成功

[root@master ~]# kubectl apply -f test-k8s-deployment-service-NodePort-many.yaml 
service/test-k8s-deployment-service-nodeport-many created
[root@master ~]# kubectl get service
NAME                                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                         AGE
kubernetes                                  ClusterIP   10.96.0.1       <none>        443/TCP                         27h
test-k8s-deployment-service-nodeport-many   NodePort    10.96.111.32    <none>        8080:30001/TCP,8088:30002/TCP   6s
七、命令行方式暴露端口

通过命令行,不能暴露多个端口,NodePort 类型不能指定 nodePort 端口号,会随机分配

[root@master ~]# kubectl expose deployment test-k8s-deployment --name=test-k8s-deployment-service2 --type=NodePort --port=8080 --target-port=8080 
service/test-k8s-deployment-service2 exposed
[root@master ~]# kubectl get deployment
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
test-k8s-deployment   3/3     3            3           22h
[root@master ~]# kubectl get service
NAME                           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes                     ClusterIP   10.96.0.1     <none>        443/TCP          27h
test-k8s-deployment-service2   NodePort    10.96.71.19   <none>        8080:32459/TCP   18s
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值