k8ssvc
svc是什么
创建svc
服务发现,clusterip/变量/dns方式
服务的发布,nodeport,loadbalance/ingress
一、svc
1、svc基础
1、svc介绍
svc定义了pod的逻辑集合和访问该集合的策略,是真实服务的抽象,service提供了一个统一的服务访问入口以及服务代理和发现机制,用户不需要了解pod是如何运行的,service是通过标签来找到pod组
service在整个集群中负责网络服务的,因为pod是不可靠的,可能会被停止或者重启,一但发生重启,ip地址就会发生变化,service就是通过kube-proxy进行网络的控制,pod的ip发生变化上层的业务并不会中断,因为是通过标签进行控制的,kube-proxy是采用负载均衡实现网络服务的

2、创建一个nginx容器
[root@k-master svc]# kubectl run n1 --image nginx --image-pull-policy IfNotPresent --dry-run=client -o yaml > n1.yaml
[root@k-master svc]# ls
n1.yaml
[root@k-master svc]# kubectl apply -f n1.yaml
pod/n1 created
[root@k-master svc]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
n1 1/1 Running 0 9s 10.244.82.165 k-node1 <none> <none>
# 创建一个pod,会获取到一个地址,这个pod地址就是创建k8s集群的时候定义的
# pod用这个ip与其他的pod的ip进行访问
# 集群内部服务的ip地址
[root@k-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
# ClusterIP 集群内部可用,,所有组件和pod都通过这个svc与api-server进行通信
- nginx创建出来后,没有创建svc的话,外面的主机是访问不到的,但是k8s集群可以访问到
[root@k-master svc]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
n1 1/1 Running 0 6m45s 10.244.82.165 k-node1 <none> <none>
[root@k-master svc]# curl 10.244.82.165
<!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>
# k8s节点可以访问到pod
# 但是外面的其他主机访问不到的
# 就需要创建nodeport暴露宿主机的端口,访问宿主机ip和宿主机的端口,从而访问内部的pod服务
3、容器做个端口映射(hostPort)
[root@k-master svc]# cat n1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: n1
name: n1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: n1
ports:
- containerPort: 80 # 容器的监听的端口是80
hostPort: 5000 # 映射到主机的5000端口,会自动的修改iptables规则
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@k-master svc]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
n1 1/1 Running 0 4s 10.244.82.161 k-node1 <none> <none>
# 浏览器访问
http://192.168.50.101:5000/
# 在node1上面查看端口映射
[root@k-node1 ~]# iptables -S -t nat|grep '5000 -j'
-A CNI-HOSTPORT-DNAT -p tcp -m comment --comment "dnat name: \"k8s-pod-network\" id: \"f649f99e0c48438052497ccc9de48bf524bf0d52c217ffc464c9b13d45d98d3f\"" -m multiport --dports 5000 -j CNI-DN-410cd4f2b8823751dd68e
-A CNI-DN-410cd4f2b8823751dd68e -s 10.244.82.161/32 -p tcp -m tcp --dport 5000 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-410cd4f2b8823751dd68e -s 127.0.0.1/32 -p tcp -m tcp --dport 5000 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-410cd4f2b8823751dd68e -p tcp -m tcp --dport 5000 -j DNAT --to-destination 10.244.82.161:80
- 但是了这种很麻烦
# 但是了这种很麻烦
# 如果节点是2个,创建一个deployment,副本数为3个
# 这样的话,就会有一个处于pending的状态了,就是端口被占用了
# 并且没有负载均衡,因为访问模式是主机ip+端口,因此访问一个主机,另外一个主机是空闲的
# 就麻烦
2、svc的访问流程
创建svc的访问流程
外部用户请求访问主机+端口
service接收流量,通过pod所在物理主机上的kube-proxy将请求转发到后端pod(具有标签的)
- kube-proxy有2种模式,ipvs和iptables模式
pod处理请求,流量到达容器的80端口
也能实现负载均衡(最外层的)
是通过标签关联的pod
# 每个节点有一个
[root@k-master svc]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5bbd96d687-rsnp6 1/1 Running 15 (112m ago) 16d
coredns-5bbd96d687-svq2d 1/1 Running 15 (112m ago) 16d
etcd-k-master 1/1 Running 15 (112m ago) 16d
kube-apiserver-k-master 1/1 Running 15 (112m ago) 16d
kube-controller-manager-k-master 1/1 Running 15 (112m ago) 16d
kube-proxy-fgct4 1/1 Running 16 (112m ago) 16d
kube-proxy-lfsvb 1/1 Running 15 (112m ago) 16d
kube-proxy-mk56p 1/1 Running 15 (112m ago) 16d
kube-scheduler-k-master 1/1 Running 15 (112m ago) 16d
metrics-server-7b8674ccdc-fdp29 1/1 Running 13 (112m ago) 15d
[root@k-master svc]#
3、创建一个简单的svc
1、创建deployment个svc
- 创建deployment,副本数为3个
[root@k-master svc]# kubectl get deploy,pod
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/d-nginx 3/3 3 3 16s
NAME READY STATUS RESTARTS AGE
pod/d-nginx-59f7778498-2fzkf 1/1 Running 0 16s
pod/d-nginx-59f7778498-9d2v7 1/1 Running 0 16s
pod/d-nginx-59f7778498-fhzgn 1/1 Running 0 16s
# 修改nginx网页目录,后续访问的时候可以区分开来
[root@k-master svc]# kubectl get pod
NAME READY STATUS RESTARTS AGE
d-nginx-59f7778498-2fzkf 1/1 Running 0 5m
d-nginx-59f7778498-9d2v7 1/1 Running 0 5m
d-nginx-59f7778498-fhzgn 1/1 Running 0 5m
[root@k-master svc]# kubectl exec -ti d-nginx-59f7778498-2fzkf -- /bin/bash
root@d-nginx-59f7778498-2fzkf:/# cd /usr/share/nginx/html/
root@d-nginx-59f7778498-2fzkf:/usr/share/nginx/html# ls
50x.html index.html
root@d-nginx-59f7778498-2fzkf:/usr/share/nginx/html# echo 1 > index.html
root@d-nginx-59f7778498-2fzkf:/usr/share/nginx/html# exit
exit
[root@k-master svc]# kubectl exec -ti d-nginx-59f7778498-9d2v7 -- /bin/bash
root@d-nginx-59f7778498-9d2v7:/# echo 2 > /usr/share/nginx/html/index.html
root@d-nginx-59f7778498-9d2v7:/# exit
exit
[root@k-master svc]# kubectl exec -ti d-nginx-59f7778498-fhzgn -- /bin/bash
root@d-nginx-59f7778498-fhzgn:/# echo 3 > /usr/share/nginx/html/index.html
root@d-nginx-59f7778498-fhzgn:/# exit
exit
创建svc,没有指定svc的名字,默认使用就是deploy的名字
svc自己有一个端口,targetport是pod开放的端口
[root@k-master svc]# kubectl expose --name svc1 deployment d-nginx --port 5500 --target-port 80 --dry-run=client -o yaml > svc1.yaml
[root@k-master svc]# cat svc1.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: d-nginx
name: svc1
spec:
ports:
- port: 5500
protocol: TCP
targetPort: 80
selector: # 标签选择器
app: d-nginx
status:
loadBalancer: {}
# 集群内部的svc都会分配一个ip和端口,都是虚拟出来的,clusterip类型,这个就是内部访问的
[root@k-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
svc1 ClusterIP 10.104.191.252 <none> 5500/TCP 2s
# matser访问
[root@k-master svc]# curl 10.104.191.252:5500
2
[root@k-master svc]# curl 10.104.191.252:5500
3
[root@k-master svc]# curl 10.104.191.252:5500
1
# 不能ping 这个svc,因为没有开放icmp,但是可以wget或者curl访问
- 但是了,上面的svc是ClusterIP类型的,外面的主机访问不到的
2、svc标签选择
自动的识别具有相同标签的pod并且关联
通过标签来定位pod
[root@k-master svc]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d <none>
svc1 ClusterIP 10.104.191.252 <none> 5500/TCP 7m45s app=d-nginx
[root@k-master svc]# kubectl describe endpoints svc1
Name: svc1
Namespace: default
Labels: app=d-nginx
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2025-08-05T09:52:48Z
Subsets:
Addresses: 10.244.108.18,10.244.82.163,10.244.82.169
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 80 TCP
Events: <none>
[root@k-master svc]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
d-nginx-59f7778498-2fzkf 1/1 Running 0 18m app=d-nginx,pod-template-hash=59f7778498
d-nginx-59f7778498-9d2v7 1/1 Running 0 18m app=d-nginx,pod-template-hash=59f7778498
d-nginx-59f7778498-fhzgn 1/1 Running 0 18m app=d-nginx,pod-template-hash=59f7778498
4、服务发现
- pod与pod之间是怎么通信的
1、ClusterIP
是直接通过这个ClusterIP的ip地址实现的
默认情况下,创建的svc是不能ping通的,因为这是一个虚拟的网络接口,没有真正的mac地址,没有开放icmp协议,kube-proxy开放tcp和udp协议
1、wordpress与mysql
wordpress与mysql,之前是直接连接的
现在的话对于mysql创建一个svc-mysql,因此,wordpress连接svc-mysql就能连接到mysql,不需要知道mysql地址
有个问题wordpress的pod怎么发现的mysql-svc的ip的地址, 是通过ClusterIP发现的,通过这个可以访问到mysql
wordpress也是内网的,创建一个wordpress-svc,暴露出来
从而外部就能访问到了
有三种模式,clusterip,变量方式,dns方式
客户端
|
|
wordpress-svc
|
|
wordpress
|
|
mysql-svc
|
|
mysql
2、创建一个mysql
# 创建mysql个svc
kubectl run db --image mysql --image-pull-policy IfNotPresent --env="MYSQL_ROOT_PASSWORD=abc123" --env="MYSQL_DATABASE=wordpress" --dry-run=client -o yaml > db.yaml
# expose暴露pod的端口,port是svc的端口,target-port是容器暴露的端口
[root@k-master svc]# kubectl expose pod db --name db --port 3306 --target-port 3306
service/db exposed
# 创建出来的默认是ClusterIP类型
[root@k-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.98.174.106 <none> 3306/TCP 3s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
[root@k-master svc]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
db ClusterIP 10.98.174.106 <none> 3306/TCP 7m56s run=db
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d <none>
# 就可以通过svc来登录mysql了,集群内部访问
[root@k-master svc]# mysql -uroot -pabc123 -h 10.98.174.106
3、创建一个wordpress
# 连接数据库的地址为mysql-svc
[root@k-master svc]# kubectl run blog --image wordpress --image-pull-policy IfNotPresent --env="WORDPRESS_DB_HOST=10.98.174.106" --env="WORDPRESS_DB_USER=root" --env="WORDPRESS_DB_PASSWORD=abc123" --env="WORDPRESS_DB_NAME=wordpress" --dry-run=client -o yaml > blog.yaml
[root@k-master svc]# kubectl get pod
NAME READY STATUS RESTARTS AGE
blog 1/1 Running 0 30s
db 1/1 Running 0 18m
上面的wordpress创建成功了,但是了客户端是访问不到的,因为都是内网的,因此需要暴露wordpress的端口,NodePort类型svc
mysql-svc是ClusterIP的,但是wordpress是NodePort类型的,客户端就能访问了
[root@k-master svc]# kubectl expose pod blog --name blog --port 80 --target-port 80 --type NodePort
service/blog exposed
[root@k-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
blog NodePort 10.99.53.20 <none> 80:32254/TCP 3s
db ClusterIP 10.98.174.106 <none> 3306/TCP 15m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
# 这样客户端就能通过访问任意一个主机的ip+32254端口就能实现访问了
因此的话,客户端只要能与k8s节点能够互相通信的话,就能实现访问wordpress了
浏览器访问
192.168.50.100:32254
2、变量的方式
一个时间轴的方式
先创建一个svc1,再创建一个pod1,这样的话,pod1里面的环境变量会包含这个svc1,然后在创建svc2,pod1不包含,因为是后创建的
再次创建pod2的时候,就会包含之前的svc1,svc2了
加载的是同一个名称空间下面的svc,不同名称空间是隔离的,不会加载其他名称空间的svc
# 创建一个临时容器就能查看到之前创建的svc了
[root@k-master svc]# kubectl run pod1 --image nginx --image-pull-policy IfNotPresent --rm -ti -- bash
If you don't see a command prompt, try pressing enter.
root@pod1:/# env | grep -i blog
BLOG_PORT=tcp://10.99.53.20:80
BLOG_PORT_80_TCP_PROTO=tcp
BLOG_SERVICE_HOST=10.99.53.20
BLOG_SERVICE_PORT=80
BLOG_PORT_80_TCP_ADDR=10.99.53.20
BLOG_PORT_80_TCP=tcp://10.99.53.20:80
BLOG_PORT_80_TCP_PORT=80
之前创建wordpress的时候需要指定mysql-svc的ip地址,因此现在使用环境变量的方式来指定mysql-svc的ip地址
这样的话,mysql-svc的ip地址的变化就不影响了
DB_SERVICE_HOST 是记录svc-mysql的ip地址
[root@k-master svc]# cat blog.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: blog
name: blog
spec:
containers:
- env:
- name: WORDPRESS_DB_HOST
value: $(DB_SERVICE_HOST) # 引用环境变量
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: abc123
- name: WORDPRESS_DB_NAME
value: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
name: blog
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
- 这种就是通过变量的方式来实现服务发现
3、DNS方式(非常的好用)
在kube-system名称空间下面,有dns的pod
在创建svc的时候,svc会在dns上自动注册,对于dns而言就知道了svc的ip地址了
创建svc,创建pod,pod可以直接通过svc的服务名来访问,就不需要知道svc的ClusterIP地址了
一个pod的完整的域名是 pod-hostname.service-name.namespace.svc.cluster.local
# 创建一个nginxpod和svc
[root@k-master svc]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/blog 1/1 Running 0 21m
pod/db 1/1 Running 0 72m
pod/pod1 1/1 Running 0 37s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/blog NodePort 10.99.53.20 <none> 80:32254/TCP 50m
service/db ClusterIP 10.98.174.106 <none> 3306/TCP 66m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
service/nginx-svc ClusterIP 10.101.32.16 <none> 80/TCP 4s
# 创建一个临时容器,访问nginx-svc就能下载对应的文件了
# 访问nginx-svc就能访问后端的pod了
# 直接通过服务名来实现的访问,因为有dns的记录,不需要知道nginx-svc的地址
# 在访问nginx-svc的时候给dns服务器,解析ip地址,从而实现了访问
[root@k-master svc]# kubectl run busybox1 --image busybox --image-pull-policy IfNotPresent --rm -ti -- sh
If you don't see a command prompt, try pressing enter.
/ # wget nginx-svc
Connecting to nginx-svc (10.101.32.16:80)
saving to 'index.html'
index.html 100% |**********************| 615 0:00:00 ETA
'index.html' saved
/ #
# 访问nginx-svc就能转发到10.96.0.10对应的dnsPod,上面有记录nginx-svc的ip地址,从而实现了解析nginx-svc的ip地址,实现了访问
/ # cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
但是了a空间的pod不能解析b空间的svc,有名称空间的隔离性
但是了也是可以访问的,需要带上完整的域名
# 在test空间下创建pod和svc
[root@k-master svc]# kubectl expose pod pod1 --name t1 --port 80 --target-port 80 -n test
service/t1 exposed
[root@k-master svc]# kubectl get pod,svc -n test
NAME READY STATUS RESTARTS AGE
pod/pod1 1/1 Running 0 35s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/t1 ClusterIP 10.105.212.6 <none> 80/TCP 7s
# 在default空间访问,默认是访问到的
/ # wget t1
wget: bad address 't1'
# 可以通过svc.名称空间来实现不同空间下的方式
/ # wget t1.test
Connecting to t1.test (10.105.212.6:80)
saving to 'index.html'
index.html 100% |************************************************************************************************************************************| 615 0:00:00 ETA
'index.html' saved
/ #
- 回到上面的wordpress实验
# 删除wordpress的pod
# 可以直接输出svc名称来实现访问
[root@k-master svc]# cat blog.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: blog
name: blog
spec:
containers:
- env:
- name: WORDPRESS_DB_HOST
value: db # 直接使用mysql-svc的名称,就能实现解析成ip地址,实现访问
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: abc123
- name: WORDPRESS_DB_NAME
value: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
name: blog
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
- pod之间使用svc来进行访问
# 创建2个nginx pod 和2个svc
[root@k-master svc]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/n1 1/1 Running 0 3m21s
pod/n2 1/1 Running 0 2m46s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d
service/n1-svc ClusterIP 10.101.93.97 <none> 80/TCP 2m21s
service/n2-svc ClusterIP 10.105.67.195 <none> 80/TCP 2m11s
[root@k-master svc]# kubectl exec -ti n1 -- /bin/bash
# 在同一个名称空间下面,可以直接访问服务名称来实现通信
root@n1:/# curl n2-svc
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
# 因为n1的dns是集群内部的dns服务器,创建svc会在这个dns服务器上面进行注册,因此n1去dns服务器找到了这个域名对应的ip地址,从而实现了访问
root@n1:/# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
4、服务发现总结
上面的wordpress与mysql的连接有多种方式,也就是服务发
通过dns发现,在同一个名称空间下面可以直接访问svc的名称就能实现访问了svc对应的pod
第二个通过变量,后创建的pod会加载同一个空间下的svc,因此就有一个环境变量记录了svc的ip地址,通过这个svc的变量名称来实现了访问
第三个使用ClusterIP,来实现了访问了pod
都是集群内部之间互相通信的,pod与pod之间进行访问的方式
但是了,客户端是不能进行访问到的,因为都是集群内网的
pod之间的访问,可以通过svc来进行访问,因为svc后台关联的就是pod,不需要访问pod,即可
5、服务发布
1、NodePort
之前的ClusterIP是集群内部进行访问的,因此web客户端不能进行访问集群内部的服务
NodePort就是做一个端口映射,访问物理主机+端口就能访问到集群内部的服务了
创建出来后,每个物理主机都有这个端口,并不是只有这一个主机
生成一个3w以上的端口
[root@k-master svc]# kubectl get deployments.apps,pod
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 3/3 3 3 2m23s
NAME READY STATUS RESTARTS AGE
pod/nginx-57cc89bc77-dqrjr 1/1 Running 0 2m23s
pod/nginx-57cc89bc77-lxq2h 1/1 Running 0 2m23s
pod/nginx-57cc89bc77-p7tst 1/1 Running 0 2m23s
[root@k-master svc]# kubectl expose deployment nginx --name nginx-svc --port 80 --target-port 80 --type NodePort
service/nginx-svc exposed
# 启用了30081端口,这个端口可以修改的NodePort指定的
[root@k-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d
nginx-svc NodePort 10.100.250.171 <none> 80:30081/TCP 82s
# 每个主机都开放了这个端口
[root@k-master svc]# iptables -S -t nat | grep 30081
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/nginx-svc" -m tcp --dport 30081 -j KUBE-EXT-HL5LMXD5JFHQZ6LN
# 浏览器访问
http://192.168.50.100:30081/
http://192.168.50.101:30081/
http://192.168.50.102:30081/
访问的流程
先访问主机ip+端口
会转发到svc的ip+端口(充当一个负载均衡器)
然后转发到后端关联的pod,从而实现了访问
2、LoadBalance
默认的情况下,集群内部的主机是不会暴露在互联网上的,前面还有负载均衡器,防火墙等等,可以把防火墙或者LB的端口80暴露出去,然后80端口转发到指定端口上面去,通过DNS指定到防火墙或者LB上
loadbanlance 有一个公网的ip地址,创建svc类型为LB,会从公网地址池中分配一个公网ip地址
[root@k-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d
nginx-svc NodePort 10.100.250.171 <none> 80:30081/TCP 46m
# external-ip就是公网ip
1、使用第三方插件来模拟LB
- 下载文件
[root@k-master svc]# wget https://raw.githubusercontent.com/metallb/metallb/v0.13.9/config/manifests/metallb-native.yaml
kubectl apply -f metallb-native.yaml
[root@k-master svc]# kubectl get pod -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-68bf958bf9-5pzb5 1/1 Running 0 7m35s
speaker-2l6nf 1/1 Running 0 7m35s
speaker-m5cqg 1/1 Running 0 7m35s
speaker-pvxm4 1/1 Running 0 7m35s
2、创建地址池和绑定
# 安装一个网络计算工具
yum -y install sipcalc
[root@k-master svc]# sipcalc 192.168.50.100/24
-[ipv4 : 192.168.50.100/24] - 0
[CIDR]
Host address - 192.168.50.100
Host address (decimal) - 3232248420
Host address (hex) - C0A83264
Network address - 192.168.50.0
Network mask - 255.255.255.0
Network mask (bits) - 24
Network mask (hex) - FFFFFF00
Broadcast address - 192.168.50.255
Cisco wildcard - 0.0.0.255
Addresses in network - 256
Network range - 192.168.50.0 - 192.168.50.255
Usable range - 192.168.50.1 - 192.168.50.254
# 创建地址池
[root@k-master svc]# cat pools.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 192.168.50.200-192.168.50.220
# 创建实例绑定地址池
[root@k-master svc]# cat l2.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
spec:
ipAddressPools:
- first-pool
[root@k-master svc]# kubectl get ipaddresspools.metallb.io -n metallb-system
NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
first-pool true false ["192.168.50.200-192.168.50.220"]
3、创建svc
- 自动分配地址
# 因为是LoadBalancer,所以会自动的分配外部ip地址,从之前创建的地址池中分配一个地址
# 如果是对外提供的,就需要使用公网ip
[root@k-master svc]# kubectl expose deployment nginx --name svc666 --port 80 --target-port 80 --type LoadBalancer
service/svc666 exposed
[root@k-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d
svc666 LoadBalancer 10.99.233.85 192.168.50.200 80:31439/TCP 3s
4、访问
# 直接访问这个模拟出来的公网ip地址就能访问到后端关联的pod
# 不需要添加端口
# 如果购买了域名的话,可以使用域名访问
[root@k-master svc]# curl 192.168.50.200
<!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>
3、Ingress
上面的NodePort的创建,如果需要创建很多的话,就需要占用很多的端口,安全风险就很大
是一个管理从集群外部到集群内部服务的http和https路由
只需要一个公网ip,所有的外部流量从这个入口进入
智能路由的功能,请求的主机名和路径将流量分发到后端不同的service
1、正向代理
- pc电脑访问华为云的过程中,有一个代理,一般用于出去
2、反向代理
- 用户访问百度的时候,反向代理关联的是服务器,而不是自己的pc电脑
3、ingress定义
可以定义规则
访问不同的域名转向不同的后台
访问1.com指向server1
访问2.com指向server2
4、创建三个pod和三个svc
使用的nginx镜像是
创建三个nginx的pod
[root@k-master ~]# kubectl run n1 --image nginx --image-pull-policy IfNotPresent
pod/n1 created
[root@k-master ~]# kubectl run n2 --image nginx --image-pull-policy IfNotPresent
pod/n2 created
[root@k-master ~]# kubectl run n3 --image nginx --image-pull-policy IfNotPresent
pod/n3 created
[root@k-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
n1 1/1 Running 0 9s
n2 1/1 Running 0 6s
n3 1/1 Running 0 3s
# 修改访问页面
[root@k-master ~]# kubectl exec -ti n1 -- /bin/bash
root@n1:/# cd /usr/share/nginx/html/
root@n1:/usr/share/nginx/html# ls
50x.html index.html
root@n1:/usr/share/nginx/html# echo n1 > index.html
root@n1:/usr/share/nginx/html# exit
exit
[root@k-master ~]# kubectl exec -ti n2 -- /bin/bash
root@n2:/# cd /usr/share/nginx/html/
root@n2:/usr/share/nginx/html# ls
50x.html index.html
root@n2:/usr/share/nginx/html# echo n2 > index.html
[root@k-master ~]# kubectl exec -ti n3 -- /bin/bash
root@n3:/# ls
bin docker-entrypoint.d home media proc sbin tmp
boot docker-entrypoint.sh lib mnt root srv usr
dev etc lib64 opt run sys var
root@n3:/# cd /usr/share/nginx/html/
root@n3:/usr/share/nginx/html# ls
50x.html index.html
# 在html下面创建一个abc目录,并且创建一个index.html,模拟不同的页面
root@n3:/usr/share/nginx/html# mkdir abc
root@n3:/usr/share/nginx/html# ls
50x.html abc index.html
root@n3:/usr/share/nginx/html# cd abc/
root@n3:/usr/share/nginx/html/abc# ls
root@n3:/usr/share/nginx/html/abc# echo n3-abc > index.html
root@n3:/usr/share/nginx/html/abc# ls
index.html
root@n3:/usr/share/nginx/html/abc# exit
exit
[root@k-master ~]# kubectl expose pod n1 --name svcn1 --port 80 --target-port 80
service/svcn1 exposed
[root@k-master ~]# kubectl expose pod n2 --name svcn2 --port 80 --target-port 80
service/svcn2 exposed
[root@k-master ~]# kubectl expose pod n3 --name svcn3 --port 80 --target-port 80
service/svcn3 exposed
[root@k-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 35d
svc666 LoadBalancer 10.99.233.85 192.168.50.200 80:31439/TCP 17d
svcn1 ClusterIP 10.106.109.188 <none> 80/TCP 20s
svcn2 ClusterIP 10.99.5.184 <none> 80/TCP 9s
svcn3 ClusterIP 10.101.42.143 <none> 80/TCP 3s
5、使用ingress-nginx镜像
使用下面这个deploy.yaml文件,注意版本
[root@k-master ingress]# kubectl apply -f ingress-deploy.yaml namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
# 会有一个名称空间,pod
[root@k-master ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-gj9cg 0/1 Completed 0 110s
ingress-nginx-admission-patch-txm4g 0/1 Completed 0 110s
ingress-nginx-controller-6465b759fb-fsc4s 1/1 Running 0 110s
[root@k-master ingress]# kubectl get deployments.apps -n ingress-nginx
NAME READY UP-TO-DATE AVAILABLE AGE
ingress-nginx-controller 1/1 1 1 2m58s
# 有这些svc的服务
[root@k-master ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.101.96.191 192.168.50.201 80:31626/TCP,443:31346/TCP 119s
ingress-nginx-controller-admission ClusterIP 10.98.162.172 <none> 443/TCP 119s
[root@k-master ingress]#
- 使用的是LB这个svc,就能实现访问了ingress-nginx-controller了

6、定义ingress规则
- 访问哪一个域名指向哪一个svc,从而实现哪一个网站
[root@k-master ingress]# cat in.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
rules:
- host: www.meme1.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svcn1
port:
number: 80
- host: www.meme2.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svcn2
port:
number: 80
- path: /abc
pathType: Prefix
backend:
service:
name: svcn3
port:
number: 80
# 访问 meme1.com 指向的是svcn1
# 访问meme2.com 指向的是svcn2
# 访问meme2.com/abc 只想的是svcn3
- 创建class类,使用默认的ingress,否则会报错
[root@k-master ingress]# kubectl edit ingressclasses.networking.k8s.io
ingressclass.networking.k8s.io/nginx edited
8 annotations:
9 ingressclasses.kubernetes.io/is-default-class: "true"
- 运行ingress规则
[root@k-master ingress]# kubectl apply -f in.yaml
ingress.networking.k8s.io/my-app-ingress created
[root@k-master ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-app-ingress <none> www.meme1.com,www.meme2.com 80 36s
[root@k-master ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-app-ingress <none> www.meme1.com,www.meme2.com 80 36s
[root@k-master ingress]# kubectl describe ingress
Name: my-app-ingress
Labels: <none>
Namespace: default
Address:
Ingress Class: <none>
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
www.meme1.com
/ svcn1:80 (10.244.82.155:80)
www.meme2.com
/ svcn2:80 (10.244.82.148:80)
/abc svcn3:80 (10.244.108.41:80)
Annotations: <none>
Events: <none>
# 记录ingress-nginx-controller中的node1的ip地址为192.168.50.101
[root@k-master ingress]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-gj9cg 0/1 Completed 0 30m 10.244.108.42 k-node2 <none> <none>
ingress-nginx-admission-patch-txm4g 0/1 Completed 0 30m 10.244.82.149 k-node1 <none> <none>
ingress-nginx-controller-6465b759fb-fsc4s 1/1 Running 0 30m 10.244.82.146 k-node1 <none> <none>
7、浏览器访问
需要的就是这个LB的svc的ip地址与域名进行绑定
通过这个地址就能实现访问了ingress-nginx-controller了
http://www.meme2.com/abc/
http://www.meme1.com/
k8ssvc的更多相关文章
- k8s-svc
1. 简介 kubernets service 是将运行一组pods上的应用程序公开为网络服务的抽象方法. 有了 kubernets service,你就无需修改应用程序即可使用服务发现机制,kube ...
随机推荐
- 玩转AI新声态 | 玩转TTS/ASR/YuanQI 打造自己的AI助手
前言 halo, 各位佬友这是我24年写的整理一下发出来, 可能有点老了, ai发展这么快...... 本次带来的是腾讯云玩转AI新声态语音产品应用实践,利用 TTS / ASR / 元器智能体 打造 ...
- Hoic对网站的测试使用
禁止使用该项技术攻击一切未经允许的公网网站,违者将受到法律制裁. 下载地址:https://wwl.lanzout.com/iiJa11zsqljg 下载完成后解压,并打开. 打开 \(hoic2.1 ...
- [原创]《C#高级GDI+实战:从零开发一个流程图》第01章:有什么用、有什么效果?
一.有什么用? 问:现在这个年代哪些场景还需要GDI+? 答:很少,主要是在上位机,复杂一点的自定义控件几乎全由GDI+绘制而成.而且很多工业设备的电脑性能差,WPF等带不起来,只能是Winform. ...
- Socket实战与应用
1: Socket之序列化; 让对象能够通过socket进行传输 服务端: 1 package com.lv.study.am.first; 2 3 import java.io.ObjectOutp ...
- 线程池中execute和submit的区别?
简要回答 execute只能提交Runnable类型的任务,无返回值.submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任 ...
- AI大模型应用开发入门-LangChain开发Agent
基于 LangChain 和 GPT-4o-mini 的大模型智能体开发实战 近年来,大模型能力的持续突破,使得构建智能代理(Agent)系统成为开发者追逐的热点. 本文将以 LangChain 框架 ...
- 绘画应用当中的Midjourney和Diffusion有何区别?
本文由 ChatMoney团队出品 Midjourney与Stable Diffusion:对比分析 1. 易用性与部署 Midjourney: 在线操作:Midjourney的最大优势在于其无需下载 ...
- SenseVoice部署,并调用api接口
目录 安装Python 代码下载 虚拟环境 安装依赖 下载模型 修改启用webui.py 启用api.py 安装Python 这个网上找下教程安装下就可以,版本应该没有什么要求,我装的是3.10.7 ...
- 基于Casbin的ABAC授权模型设计与开发踩坑实录
本文分享自天翼云开发者社区<基于Casbin的ABAC授权模型设计与开发踩坑实录>,作者:upclose 最近因项⽬需求,需要寻求⼀个好⽤强⼤的权限管理⽅案.天翼云安全实验室经过仔细调研, ...
- SQL Server数据库巡检
查询所有表名 select name from sysobjects where xtype='u' select * from sys.tables 查询所有表名及对应架构 select t.[na ...