知识点:
k8s Service是Kubernetes中的一种重要资源对象,用于定义一组Pod的访问规则。Service可以实现负载均衡、服务发现等功能,为应用程序提供稳定的入口。
Service在Kubernetes中有以下几种类型,每种类型都有其特点和适用场景:
1)ClusterIP:这是默认的Service类型,自动分配一个仅Cluster内部可以访问的虚拟IP。它主要用于内部服务通信,对外部不可见,适用于在同一集群内的不同服务之间建立通信的情况,例如数据库服务、内部API等。
2)NodePort:这种类型的Service允许将服务公开到集群节点上的某个端口上,从而可以从集群外部访问服务。它会在每个节点上监听相同的端口,并将流量转发到Service中的Pod。这种类型适用于需要从集群外部访问服务的情况,通常用于测试和开发环境。
3)LoadBalancer:这种类型的Service通过云服务提供商(如AWS、GCP、Azure)的负载均衡器来公开服务,可以将流量分布到多个节点上的Pod。它适用于需要在云环境中公开服务,并且需要负载均衡的情况,常用于生产环境。
4)ExternalName:这种类型的Service允许将Kubernetes Service映射到DNS名称而不是IP地址。它通常用于将现有的外部服务映射到Kubernetes内部服务,适用于需要将外部服务绑定到Kubernetes内部的场景,可以实现平滑迁移。
5)Headless:这种类型的Service不分配ClusterIP,而是为每个选择的Pod创建DNS记录。这意味着每个Pod都有其独立的DNS记录,通常用于服务发现或数据库复制等场景。
总的来说,选择哪种类型的Service取决于应用程序的需求和部署环境。如果服务需要从外部网络访问,那么NodePort或LoadBalancer可能是更好的选择。如果服务只在集群内部使用,那么ClusterIP就足够了。如果需要将服务指向集群外部的某个服务,那么ExternalName是合适的选择。
在Kubernetes(k8s)中,Endpoint是一种资源对象,用于表示Service所依赖的真实后端节点的Pod信息。简单来说,Endpoint将Service与其后端Pod的IP地址和端口号进行关联,用于在集群内部进行通信。
Endpoint的主要作用是将Service与后端Pod实例进行关联,以便实现负载均衡和流量路由。当一个Service被创建时,Kubernetes会自动为其关联一个Endpoint资源对象,并将该Service所选择的Pod的IP地址和端口信息填充到Endpoint中。这样,当有请求发送给Service时,Kubernetes会根据Service的配置将请求转发到对应的Endpoint上的Pod实例。
Endpoint存储了一组IP地址和端口号的列表,这些IP地址和端口号对应着提供相同服务的Pod实例。Endpoint资源对象包含以下重要字段:
1)subsets:一个或多个subset对象,每个subset中包含一组IP地址和端口号的列表。不同的subset可以根据Label Selector将后端Pod进行分类。
2)addresses:一个IP地址列表,表示属于该Endpoint的Pod的IP地址。
ports:一个端口号列表,表示属于该Endpoint的Pod所开放的端口号。
此外,Endpoint控制器是Kubernetes集群控制器的其中一个组件,负责生成和维护所有Endpoint对象。当Service或相关Pod发生变化时,Endpoint控制器会相应地更新Endpoint对象,以确保服务能够正常与其后端Pod进行通信。
总的来说,Endpoint在Kubernetes中扮演着将Service与后端Pod实例进行关联的重要角色,是实现负载均衡和流量路由的关键组件。
一、实验环境:
开master1\node1\node2三台虚拟机,都还原至单节点集群配置完成;node1,node2导入nginx:1.21.6、nginx-1.25.1
二、node1\node2容器运行时导入nginx:1.21.6、nginx-1.25.1的镜像
[root@node1 ~]# ctr -n k8s.io images import nginx-1.21.6.tar 容器运行时导入nginx:1.21.6的镜像
unpacking docker.io/library/nginx:1.21.6 (sha256:94b808e393739b5363decf631a746d0241083d40eb05f07200a6d1c0c16f54b8)...done
[root@node1 ~]# ctr -n k8s.io images import nginx-1.25.1.tar 容器运行时导入nginx-1.25.1的镜像
unpacking docker.io/library/nginx:1.25.1 (sha256:220f06adf50c8d0dbb287301993a43e4e90721b83d4ed337780b59d51cdef48e)...done
[root@node2 ~]# ls
anaconda-ks.cfg busybox-1-28.tar.gz calico.tar.gz nginx-1.21.6.tar nginx-1.2
[root@node2 ~]# ctr -n k8s.io images import nginx-1.21.6.tar 容器运行时导入nginx:1.21.6的镜像
unpacking docker.io/library/nginx:1.21.6 (sha256:94b808e393739b5363decf631a746d0241083d40eb05f07200a6d1c0c16f54b8)…done
[root@node2 ~]# ctr -n k8s.io images import nginx-1.25.1.tar 容器运行时导入nginx-1.25.1的镜像
unpacking docker.io/library/nginx:1.25.1 (sha256:220f06adf50c8d0dbb287301993a43e4e90721b83d4ed337780b59d51cdef48e)…done
[root@node2 ~]#
三、master1节点上创建一个new nginx配置文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: new-nginx
labels:
app: new-nginx
spec:
replicas: 2
selector:
matchLabels:
app: new-nginx
template:
metadata:
labels:
app: new-nginx
spec:
containers:
#--------------------------------------------------
- name: new-nginx
image: nginx:1.21.6
# image: nginx:1.25.1
env:
- name: TZ
value: Asia/Shanghai
ports:
- containerPort: 80
volumeMounts:
- name: html-files
mountPath: "/usr/share/nginx/html"
#--------------------------------------------------
- name: busybox
image: registry.cn-shanghai.aliyuncs.com/acs/busybox:v1.29.2
# image: nicolaka/netshoot
args:
- /bin/sh
- -c
- >
while :; do
if [ -f /html/index.html ];then
echo "[$(date +%F\ %T)] ${MY_POD_NAMESPACE}-${MY_POD_NAME}-${MY_POD_IP}" > /html/index.html
sleep 1
else
touch /html/index.html
fi
done
env:
- name: TZ
value: Asia/Shanghai
- name: MY_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
volumeMounts:
- name: html-files
mountPath: "/html"
- mountPath: /etc/localtime
name: tz-config
#--------------------------------------------------
volumes:
- name: html-files
emptyDir:
medium: Memory
sizeLimit: 10Mi
- name: tz-config
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
四、上传busy.tar.gz到node1、node2节点上


[root@node1 ~]# ls
anaconda-ks.cfg busybox.tar calico.tar.gz nginx-1.21.6.tar nginx-1.25.1.tar
[root@node1 ~]#
[root@node2 ~]# ls
anaconda-ks.cfg busybox.tar calico.tar.gz nginx-1.21.6.tar nginx-1.25.1.tar
[root@node2~]#
[root@node1 ~]# ls
anaconda-ks.cfg busybox.tar calico.tar.gz nginx-1.21.6.tar nginx-1.25.1.tar
[root@node1 ~]# ctr -n k8s.io images import busybox.tar
unpacking docker.io/library/busybox:latest (sha256:40680ace50cfe34f2180f482e3e8ee0dc8f 87bb9b752da3a3a0dcc4616e78933)...done
[root@node1 ~]#
[root@node2 ~]# ls
anaconda-ks.cfg busybox.tar calico.tar.gz nginx-1.21.6.tar nginx-1.25.1.tar
[root@node2 ~]# ctr -n k8s.io images import busybox.tar
unpacking docker.io/library/busybox:latest (sha256:40680ace50cfe34f2180f482e3e8ee0dc8f 87bb9b752da3a3a0dcc4616e78933)...done
[root@node2 ~]#
五、master1上应用new-nginx的配置文件
[root@master1 ~]# kubectl apply -f new-nginx.yaml 应用new-nginx的配置文件deployment.apps/new-nginx created
[root@master1 ~]#
[root@master1 ~]# kubectl get pods 查看pod信息
NAME READY STATUS RESTARTS AGE
new-nginx-7677955946-2x5s6 2/2 Running 0 17s 有副本,自动创建2
new-nginx-7677955946-fh9n9 2/2 Running 0 17s
[root@master1 ~]#
六、master1将new-nginx无状态服务发不出去,端口80,目标端口80
[root@master1 ~]# kubectl expose deployment new-nginx --port=80 --target-port=80
service/new-nginx exposed 将new-nginx无状态服务发不出去,端口80,目标端口80
[root@master1 ~]#
七、查看服务及new-nginx末端节点信息
[root@master1 ~]# kubectl get svc 查看服务
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d21h
new-nginx ClusterIP 10.111.158.213 <none> 80/TCP 17s
[root@master1 ~]#
[root@master1 ~]# kubectl get endpoints new-nginx 查看new-nginx末端节点信息
NAME ENDPOINTS AGE
new-nginx 10.244.104.2:80,10.244.166.129:80 17m 10.244.104.1:80,10.244.166.130:80末端节点俩pod
八、访问集群IP
[root@master1 ~]# curl 10.111.158.213 访问集群IP
[2025-06-25 06:34:51] default-new-nginx-7677955946-vx7rj-10.244.166.130
[root@master1 ~]# curl 10.111.158.213 访问集群IP(轮询)
[2025-06-25 06:34:53] default-new-nginx-7677955946-fpgkd-10.244.104.1
[root@master1 ~]# curl 10.111.158.213
[2025-06-25 06:34:56] default-new-nginx-7677955946-vx7rj-10.244.166.130
[root@master1 ~]# curl 10.111.158.213
[2025-06-25 06:34:58] default-new-nginx-7677955946-fpgkd-10.244.104.1
[root@master1 ~]#
九、NodePort提供web访问:
[root@master1 ~]# kubectl patch svc new-nginx -p '{"spec":{"type":"NodePort"}}' 将new-nginx服务的类型更改为NodePort
命令行修改
service/new-nginx patched
[root@master1 ~]#
[root@master1 ~]#
[root@master1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d21h
new-nginx NodePort 10.111.158.213 <none> 80:30531/TCP 22m NodePort节点服务,从web访问集群,clusterIP 从内部访问集群
[root@master1 ~]#80:30531 80容器端口号,30531宿主机的端口号
十、浏览器测试访问集群IP,查看是否末端节点轮询


十一、编辑new-nginx服务
[root@master1 ~]# kubectl edit svc new-nginx 编辑new-nginx服务
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- nodePort: 30531
port: 80
protocol: TCP
targetPort: 80
selector:
app: new-nginx
sessionAffinity: None
type: NodePort 改为NodePort或clusterIP
status:
loadBalancer: {}
~
~
十二、查看nginx服务的详细信息
[root@master1 ~]# kubectl describe svc new-nginx 查看nginx服务的详细信息
Name: new-nginx
Namespace: default
Labels: app=new-nginx
Annotations: <none>
Selector: app=new-nginx
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111.158.213
IPs: 10.111.158.213
Port: <unset> 80/TCP 端口80,
TargetPort: 80/TCP 目标端口80
NodePort: <unset> 30531/TCP
Endpoints: 10.244.104.2:80,10.244.166.129:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
[root@master1 ~]# kubectl -n kube-system get deployment,pod
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/calico-kube-controllers 1/1 1 1 5d21h
deployment.apps/coredns 2/2 2 2 5d22h
NAME READY STATUS RESTARTS AGE
pod/calico-kube-controllers-7dc5458bc6-5jztl 1/1 Running 2 (70m ago) 5d21h
pod/calico-node-clzfg 1/1 Running 2 (70m ago) 5d21h
pod/calico-node-kbqjt 1/1 Running 2 (70m ago) 5d21h
pod/calico-node-ng6b2 1/1 Running 2 (70m ago) 5d21h
pod/coredns-7c445c467-kff9r 用于集群内部dns访问 1/1 Running 2 (70m ago) 5d22h
pod/coredns-7c445c467-mmcg7 1/1 Running 2 (70m ago) 5d22h
pod/etcd-master1 1/1 Running 2 (70m ago) 5d22h
pod/kube-apiserver-master1 1/1 Running 2 (70m ago) 5d22h
pod/kube-controller-manager-master1 1/1 Running 2 (70m ago) 5d22h
pod/kube-proxy-6kdb8 1/1 Running 2 (70m ago) 5d22h
pod/kube-proxy-gq9js 1/1 Running 2 (70m ago) 5d22h
pod/kube-proxy-vjm2p 1/1 Running 2 (70m ago) 5d22h
pod/kube-scheduler-master1 1/1 Running 2 (70m ago) 5d22h
[root@master1 ~]#
十三、运行busybox镜像生成busybox容器,退出后删除busybox的pod
[root@master1 ~]# kubectl run busybox --image docker.io/library/busybox:1.28 --image- pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh 运行busybox镜像生成busybox容器,退出后删除busybox的 pod
If you don't see a command prompt, try pressing enter.
/ # wget new-nginx.default 下载new-nginx的域名网站
Connecting to new-nginx.default (10.111.158.213:80)
index.html 100% |*************************************| 72 0:00:00 ETA
/ # cat index.html 查看首页内容
[2025-06-25 07:11:44] default-new-nginx-7677955946-fh9n9-10.244.166.129 查看busybox的信息
/ #
十四、易错点:
如何删除busybox:
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox 0/1 ErrImagePull 0 4m48s
new-nginx-7677955946-2x5s6 2/2 Running 0 54m
new-nginx-7677955946-fh9n9 2/2 Running 0 54m
[root@master1 ~]# kubectl delete pod busybox
pod "busybox" deleted
如何删除无状态服务nginx:
[root@master1 ~]# kubectl expose deployment nginx --port=80 --target-port=80 --name=ngnx
[root@master1 ~]# kubectl delete svc ngnx
service "ngnx" deleted