目录
3.service的loadbalancer类型(了解即可)
4.service的externalname类型(了解即可)
三、nodeport的端口范围设置和svc的endpoint列表
一、service资源概述
每当我们企业的业务pod迭代功能的时候,都会修改pod,修改后重新启动pod,ip就会变化,那么在生产环境当中,从用户到宿主机、从宿主机到pod,这一个访问流程,都是事先写好的,一旦pod修改后,ip产生变化,就需要重新配置,因此,k8s提供了service资源用于解决这一问题;
- Service将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
- Service为一组 Pod 提供相同的 DNS 名,并且在它们之间进行负载均衡。
- Kubernetes 为 Pod 提供分配了IP 地址,但IP地址可能会发生变化。集群内的容器可以通过service名称访问服务,而不需要担心Pod的IP发生变化。
二、service资源类型
- ClusterIP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的 IP,集群内的所有主机都可以通过这个Cluster-IP访问服务。集群内部的Pod可以通过service名称访问服务。
- NodePort:通过每个节点的主机IP 和静态端口(NodePort)暴露服务。 集群的外部主机可以使用节点IP和NodePort访问服务。
- ExternalName:将集群外部的网络引入集群内部。
- LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。
1.ClusterIP类型
bash
# 编写pod资源清单
[root@k8s1 service]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: p1-svc
labels:
k8s: oslee
spec:
containers:
- name: c1
image: nginx:1.20.1-alpine
ports:
- containerPort: 80
bash
# 编写service资源清单
[root@k8s1 service]# cat 01-service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-01
spec:
#声明clusterip类型,不指定默认也是这个类型;
type: ClusterIP
#指定pod的标签
selector:
k8s: oslee
#指定service的ip地址
clusterIP: 10.200.100.100
#用户访问service时,访问哪个端口?
ports:
#指定访问协议,若不指定协议,默认也是TCP
- protocol: TCP
#service的端口
port: 80
#pod的容器端口(目标端口)
targetPort: 80
# 创建资源
[root@k8s1 service]# kubectl apply -f .
service/svc-01 created
pod/p1-svc created
bash
[root@k8s1 service]# kubectl get all -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/p1-svc 1/1 Running 0 4m1s 10.100.1.36 k8s2 <none> <none>
pod/pod1-svc 1/1 Running 0 13s 10.100.1.38 k8s2 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.200.0.1 <none> 443/TCP 2d11h <none>
service/svc-01 ClusterIP 10.200.100.100 <none> 80/TCP 4m1s k8s=oslee
[root@k8s1 service]# curl -I 10.200.100.100
HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Fri, 03 May 2024 02:55:15 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 25 May 2021 13:41:16 GMT
Connection: keep-alive
ETag: "60acfe7c-264"
Accept-Ranges: bytes
2.service的nodeport类型
nodeport类型,就是clusterip类型的升级版,它可以使用宿主机的端口,映射到service开放的端口上,从而,使得用户访问宿主机,宿主机转发到service资源,进而访问到pod资源;
bash
[root@k8s1 service]# cat 02-service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-02
spec:
#声明nodePort类型;
type: NodePort
#指定pod的标签
selector:
k8s: oslee
#指定service的ip地址(在nodeport类型中可以不设置,会随机生成)
clusterIP: 10.200.100.101
#用户访问service时,访问哪个端口?
ports:
#指定访问协议,若不指定协议,默认也是TCP
- protocol: TCP
#service的端口
port: 80
#pod的容器端口(目标端口)
targetPort: 80
#访问宿主机的哪个端口,可以转发访问到service?
#注意,默认只能使用宿主机的30000-32767区间的端口号(可以放开限制,之后再说);
nodePort: 30000
- port:port字段定义了Service暴露给集群内部和外部的端口号。当你创建一个Service时,其他应用或服务可以通过该端口与Service进行通信,将请求发送到Service上。这个端口号是Service在Kubernetes集群内部和外部可见的端口。
- targetPort:targetPort字段定义了Service将流量转发到后端Pod的容器端口号。当请求进入Service时,Service会根据其定义将请求转发到后端Pod的这个指定端口。通常,后端Pod中的应用程序在指定的容器端口上监听并处理请求。
- NodePort:NodePort是一种Service类型,它允许通过Kubernetes集群中的每个节点的IP地址和指定的端口号访问Service。NodePort是将外部流量导入到Service的一种方式。Kubernetes会在集群中的每个节点上打开一个高端口(默认30000-32767范围内),并将该端口映射到Service的port和targetPort上。这样,你可以通过任何节点的IP地址和NodePort来访问Service。
3.service的loadbalancer类型(了解即可)
我们使用云环境负载均衡器的时候,就将vip地址填写到这个类型之下,就可以实现云负载均衡访问svc访问pod;
bash
[root@k8s1 service]# cat 03-service-loadbalancer.yaml
kind: Service
apiVersion: v1
metadata:
name: svc-loadbalancer
spec:
# 指定service类型为LoadBalancer,注意,一般用于云环境
type: LoadBalancer
selector:
k8s: oslee
ports:
- protocol: TCP
port: 80
targetPort: 80
# 注意,将来这个nodeProt也对应的是云环境负载均衡的地址
nodePort: 30001
# 指定LoadBalancer云环境的负载均衡地址,要确保K8S集群能和负载均衡的IP地址进行通信!
#用户通过vip:10.0.0.88就可以访问到svc资源了;
externalIPs:
- 10.0.0.88
4.service的externalname类型(了解即可)
域名转发功能,就是做了一个跳转,将来用户访问svc就会直接访问到我们设置的地址上,写上"百度",就跳转到"百度"。
bash
[root@k8s1 service]# cat 06-svc-ex.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-externalname
spec:
# svc类型
type: ExternalName
# 指定跳转到外部的域名地址
externalName: www.baidu.com
---
apiVersion: v1
kind: Pod
metadata:
name: p1
spec:
containers:
- name: c1
image: nginx:1.20.1-alpine
bash
[root@k8s1 service]# kubectl exec p1 -it -- sh
/ # cat /etc/resolv.conf
nameserver 10.200.0.10
search default.svc.oslee.com svc.oslee.com oslee.com
options ndots:5
bash
# yum安装dig
[root@k8s1 service]# yum -y install bind-utils
# 从指定的 DNS 服务器上查询
[root@k8s1 service]# dig @10.200.0.10 svc-externalname.default.svc.oslee.com +short
www.baidu.com.
www.a.shifen.com.
183.2.172.185
183.2.172.42
三、nodeport的端口范围设置和svc的endpoint列表
还记得在svc资源nodeport类型中,宿主机端口映射的范围必须在30000-32767之间,否则会报错;
但是,这个范围是可以修改的;只需要进入到静态pod目录中,找到kube-apiserver的pod资源,进入添加一条命令【--service-node-port-range=3000-50000】;
提交这个命令后,宿主机端口映射就变成了3000-50000了;
1.修改apiservice的宿主机映射端口范围
bash
[root@k8s1 service]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
# 增加这条命令
- --service-node-port-range=3000-50000
2.创建service和pod测试端口
四、service小结(重点)
1.service资源的四种类型:
- ClusterIP:给svc资源一个固定的IP地址,默认的类型;
- NodePort:在ClusterIP基础上,映射到宿主机(物理机)的端口号,默认是30000-32767可修改;
- LoadBalancer:可以添加云环境的负载均衡VIP地址和负载均衡器的宿主机端口号,用户通过访问VIP+负载均衡器的端口访问到svc资源,进而访问到pod==容器==服务中;
- ExternalName:类似于HTTP请求的302/301跳转,可以将访问svc的请求转发到指定的地址上;主要是转发功能;
2.修改svc的NodePort类型中宿主机映射端口的范围
默认是30000-32767,可以通过静态pod目录下的kube-apiserver.yaml的pod资源清单中加上一条命令,来设置宿主机的映射端口范围;
3.svc的endpoint列表
用户通过访问SVC资源,进而将请求转发到endpoint列表中的pod中,endpoint列表,就是svc将请求转发到的目的地;
五、service资源中endpoint列表关联外部服务
1.创建一个svc资源并查看
1.1编辑资源清单
bash
[root@k8s1 service]# cat svc-out.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-out
spec:
ports:
- port: 30002
[root@k8s1 service]# kubectl apply -f svc-out.yaml
service/svc-out created
1.2.查看svc资源
可以看到endpoint列表中什么都没有,也就是说,现在访问svc资源,什么都访问不到;我们还记得上面说的,svc资源是通过"标签选择"来将pod提那家到svc的endpoint列表中的,那么我们如何将k8s集群外部的容器添加到endpoint列表中呢?
举例:在生产环境中,我们的数据库服务,都是常年运行的历史性业务服务,当企业的应用上k8s时,数据库的迁移工作非常的繁琐,所以,如果能将外部的SQL服务,提那家到svc资源的endpoint列表中,就节省了数据库迁移k8s的繁杂工作;
2.svc资源与endpoint资源关联
endpoint本质上也是一个单独的资源,只是在我们创建svc资源的时候,系统自动给我们创建的
svc资源与endpoint资源是通过元数据(metadata中的)名称,进行关联的,只要endpoint资源的名称与svc资源的名称相同,则,endpoint资源的服务IP就会出现在svc资源的endpoint列表中,即关联成功;
2.1k8s集群外部拉取一个mysql服务容器
找一个k8s集群之外的虚拟机,docker安装mysql
bash
docker run --name=oslee-mysql \
-p 13306:3306 -d \
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=admin \
-e MYSQL_PASSWORD=admin123 \
--restart always \
mysql:8.0 \
--default-authentication-plugin=mysql_native_password \
--character-set-server=utf8 \
--collation-server=utf8_bin
测试登录mysql
bash
[root@node1 data]# docker exec -it oslee-mysql mysql -u admin -padmin123
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| wordpress |
+--------------------+
2 rows in set (0.00 sec)
k8s集群中创建endpoint资源
bash
[root@k8s1 service]# cat endpoint.yaml
apiVersion: v1
kind: Endpoints
metadata:
name: svc-out
subsets:
#指定外部endpoints的宿主机ip
- addresses:
- ip: 10.128.172.46
ports:
- port: 13306
[root@k8s1 service]# kubectl apply -f endpoint.yaml
endpoints/svc-out created
六、案例:wordpress博客案例
上述内容中,我们已经有了mysql,那么接下来,我们就搭建一套简单的架构,用户通过访问宿主机,转发到wordpress服务pod容器中,wordpress通过svc资源,访问到k8s外部数据库服务实现数据存储于查询;
wordpress ---> svc-out ---> endpoint ---> k8s集群外的宿主机mysql
1.创建wordpress的pod和svc资源
bash
[root@k8s1 service]# cat wp-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: wp-pod
labels:
k8s: oslee
spec:
containers:
- name: wp-c1
image: wordpress:latest
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
#外部mysql服务的svc资源名称及端口;
value: svc-out:30002
- name: WORDPRESS_DB_USER
value: admin
- name: WORDPRESS_DB_PASSWORD
value: admin123
---
apiVersion: v1
kind: Service
metadata:
name: wp-svc
spec:
type: NodePort
selector:
k8s: oslee
ports:
- port: 80
targetPort: 80
nodePort: 30080
[root@k8s1 service]# kubectl apply -f wp-demo.yaml
pod/wp-pod created
service/wp-svc created
2.浏览器访问测试
至此,已成艺术