Kubernetes 网络服务Service
文章目录
Service服务介绍
通过前面的实验我们已经掌握了使用Pod控制器来管理Pod,我们也会发现,Pod的生命周期非常短暂,每次镜像升级都会销毁以及创建,而我们知道每个Pod都拥有自己的IP地址,并且随着Pod删除和创建,这个IP是会变化的。
当我们的Pod数量非常多的时候前端的入口服务该怎么知道后面都有哪些Pod呢?
为了解决这个问题k8s提供了一个对象Service和三种IP,创建的Service资源通过标签可以动态的知道后端的Pod的IP地址,在PodIP之上设计一个固定的IP,也就是ClusterIP,然后使用NodePort来对外暴露端口提供访问。
接下来我们先认识一下K8s里的三种IP及其作用。
Service的三种资源
NodePort
节点对外提供访问的IP
ClusterIP
用来动态发现和负载均衡POD的IP
PodIP
提供POD使用的IP
创建Cluster IP
Cluster IP和它连接的后端pod必须在同一个名称空间里,我们可以使用不同的名称空间来隔离不同项目所需资源
apiVersion: v1
kind: Service
metadata:
name: php-apache # 连接的pod的标签,cluster ip是去连接pod的ip
namespace: default # 指定名称空间,不存在就要先创建
spec:
selector:
run: php-apache
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
[root@db01 php-apache]$ kubectl apply -f cluster_ip.yaml
# 查看Cluster IP
[root@db01 php-apache]$ kubectl get [svc|service]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 3d
php-apache ClusterIP 10.1.187.11 <none> 80/TCP 14s
## 查看cluster ip的详细信息
[root@db01 php-apache]$ kubectl describe svc php-apache
Name: php-apache
Namespace: default
Labels: <none>
Annotations: <none>
Selector: run=php-apache
Type: ClusterIP
IP: 10.1.187.11
Port: http 80/TCP
TargetPort: 80/TCP
Endpoints: 10.2.2.67:80 # 识别到了后端有一个pod ip(通过标签自动发现后端)
Session Affinity: None
Events: <none>
## 此时访问Cluster IP即可,它会将请求发到后端的pod,并做到负载均衡
# 创建名称空间方式
kubectl create namespace 指定名称空间的名字
配置解释
ports:
- name: http
port: 80 # Cluster IP的端口号
protocol: TCP # 协议类型
targetPort: 80 # pod暴露的端口
type: ClusterIP # service类型,默认Cluster IP
通过Cluster IP名字即可访问到POD原理
直接通过Cluster IP名称访问的活,即便Cluster IP变更也不会影响访问
kubernetes内嵌的DNS做了域名解析
# 就是这俩做的nds解析
[root@db01 ~]$ kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
coredns-6d56c8448f-7tdwj 1/1 Running 2 8d
coredns-6d56c8448f-lfvjt 1/1 Running 2 8d
# DNS配置文件
[root@db01 ~]$ cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 223.5.5.5
# 连接其他名称空间方式
## 进入容器
search default.svc.cluster.local
NodePort
apiVersion: v1
kind: Service
metadata:
name: php-nodeport
namespace: default
spec:
selector:
run: php-apache
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30000 # 与Cluster IP唯一的区别就在这,加了一个nodeport端口(端口范围30000~32767)
type: NodePort # 修改类型为nodeport
## 启动nodeport时,nodeport会自动启动一个Cluster IP,所以不需要额外配置Cluster IP启动
缺陷:
1.对外开放的端口只能30000~32767,用户访问网站不可能在网站后面加端口
2.如果使用nodeport,为了用户访问体验势必要做代理,但是这层代理不能做到容器化,因为要使用外网,所以没有任何意义
所以我们不使用nodeport,但是cluster ip可以用来给MySQL做内网连接
service 服务发现
在不同的名称空间中访问POD
servicename.namespace.svc.cluster.local
servicename.namespac
servicename
servicename:也就是cluster ip名称
# 例
curl 对端clusterip名称.对端pod所在名称空间.svc.cluster.local
ingress网络
1.没有ingress之前,pod对外提供服务只能通过NodeIP:NodePort的形式,但是这种形式有缺点,一个节点上的PORT不能重复利用。比如某个服务占用了80,那么其他服务就不能在用这个端口了。
2.NodePort是4层代理,不能解析7层的http,不能通过域名区分流量
3.为了解决这个问题,我们需要用到资源控制器叫Ingress,作用就是提供一个统一的访问入口。工作在7层
4.虽然我们可以使用nginx/haproxy来实现类似的效果,但是传统部署不能动态的发现我们新创建的资源,必须手动修改配置文件并重启。
5.适用于k8s的ingress控制器主流的有nginx-ingress和traefik
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: php-apache-ingress
spec:
rules:
- host: php.drz.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: php-apache-svc
port:
number: 80
安装部署nginx-ingress
我们可以直接使用kubernetes官方自带的nginx-ingress控制清单来部署
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml -O nginx-ingress.yaml
修改资源配置文件
这里我们主要修改三个地方
1.Deployment类型修改为Demoset类型
2.Pod网络修改为HostPort
3.镜像地址修改为阿里云
294 kind: DaemonSet
-------------------
323 image: registry.aliyuncs.com/google_containers/nginx-ingresscontroller:v0.48.1
-------------------
377 ports:
378 - name: http
379 containerPort: 80
380 protocol: TCP
381 hostPort: 80
382 - name: https
383 containerPort: 443
384 protocol: TCP
385 hostPort: 443
386 - name: webhook
387 containerPort: 8443
388 protocol: TCP
389 hostPort: 8443
应用资源配置
kubectl apply -f nginx-ingrss.yml
查看创建的资源
[root@node1 nginx-ingress]$ kubectl -n ingress-nginx get all
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-k5rfg 0/1 Completed 0 60m
pod/ingress-nginx-admission-patch-kk2qb 0/1 Completed 0 60m
pod/ingress-nginx-controller-d44bf 1/1 Running 0 114s
pod/ingress-nginx-controller-rkxlm 1/1 Running 0 114s
NAME TYPE CLUSTER-IP EXTERNAL-IP
PORT(S) AGE
service/ingress-nginx-controller NodePort 10.1.144.123 <none>
80:31053/TCP,443:30450/TCP 60m
service/ingress-nginx-controller-admission ClusterIP 10.1.195.159 <none>
443/TCP 60m
NAME DESIRED CURRENT READY UP-TO-DATE
AVAILABLE NODE SELECTOR AGE
daemonset.apps/ingress-nginx-controller 2 2 2 2 2
kubernetes.io/os=linux 114s
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 51s 60m
job.batch/ingress-nginx-admission-patch 1/1 66s 60m
创建测试的服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
app: my-nginx
spec:
ports:
- port: 80
protocol: TCP
name: http
selector:
app: my-nginx
创建Ingress规则
资源配置清单:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-nginx
spec:
rules:
- host: nginx.k8s.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service: # cluster ip名称,通过此项配置与cluster ip建立连接
name: my-nginx
port:
number: 80
规则解释:
spec: # 转发规则
rules:
- host: nginx.k8s.com # 匹配的域名
http: # 基于http协议解析
paths: # 基于路径进行匹配
- path: / # 匹配/路径
pathType: ImplementationSpecific # 路径类型
backend: # 匹配后跳转的后端服务
service: # 设置后端跳转到Service的配置
name: my-nginx # 跳转到名为my-nginx的ClusterIP
port: # 跳转到的端口
number: 80 # Service端口号
pathType路径类型支持的类型:
ImplementationSpecific 系统默认,由IngressClass控制器提供
Exact 精确匹配URL路径,区分大小写
Prefix 匹配URL路径的前缀,区分大小写
访问测试
在windows上配置hosts解析:
nginx.k8s.com