1150网站建设服务器主板,网站开发管理学什么,网站建设岗位任职资格,wordpress菜单iconService对象
为什么需要Service
每个Pod都有自己的IP地址#xff0c;但是在Deployment中#xff0c;在同一时刻运行的Pod集合可能与稍后运行该应用程序的Pod集合不同。
这就导致了一个问题#xff1a;如果一组Pod#xff08;称为后端#xff09;为集群内其他Pod#x…Service对象
为什么需要Service
每个Pod都有自己的IP地址但是在Deployment中在同一时刻运行的Pod集合可能与稍后运行该应用程序的Pod集合不同。
这就导致了一个问题如果一组Pod称为后端为集群内其他Pod称为前端提供功能那么前端如何找出并跟踪要连接的IP地址以便前端可以使用后端服务
Service定义
将运行在一组Pods上的应用程序公开为网络服务的抽象方法
使用Kubernetes服务无需修改应用程序即可使用通用的服务发现机制。Kubernetes为Pods提供自己的IP地址并为一组Pod提供相同的DNS并且可以在他们之间进行负载均衡。
定义Service
Service在Kubernetes中是一个REST对象和Pod类似。像所有的REST对象一样Service定义可以基于POST方式请求API server创建新的实例。
例如有一组Pod它们对外暴露9376端口同时还被打上appmyapp标签
apiVersion: v1
kind: Service
metadata:name: my-service
spec:selector:app: myappports:- port: 80targetPort: 9376
[rootmaster k8s]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 none 443/TCP 2d22h
my-service ClusterIP 10.104.177.192 none 80/TCP 7s
上述配置创建一个名为my-service的Service对象它会将请求代理到使用tcp端口的9376并且具有标签appmyapp的Pod上Kubernetes为该服务分配了一个IP地址或集群IP改IP地址有服务代理使用。
需要注意的是Service能够将一个接口port映射到任意的tatgetPort。默认情况下targetPort与port字段值相同。
用Service暴露Pod服务地址
在集群中暴露Pod
创建一个nginx pod声明具有一个80的容器端口
nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: my-nginx
spec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxresources:limits:memory: 128Micpu: 500mports:- containerPort: 80
Pod 的 IP 地址
[rootmaster k8s]# kubectl get pods -l runmy-nginx -o yaml | grep podIPpodIP: 10.244.2.23podIPs:podIP: 10.244.1.11podIPs:
[rootmaster k8s]#
此时能够通过 ssh 登录到集群中的任何一个节点上使用 curl 也能调通所有 IP 地址。 需要注意的是容器不会使用该节点上的 80 端口也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。 这意味着可以在同一个节点上运行多个 Pod使用相同的容器端口并且可以从集群中任何其他的 Pod 或节点上使用 IP 的方式访问到它们。
创建Service
Kubernetes Service 从逻辑上定义了运行在集群中的一组 Pod这些 Pod 提供了相同的功能。 当每个 Service 创建时会被分配一个唯一的 IP 地址也称为 clusterIP。 这个 IP 地址与一个 Service 的生命周期绑定在一起当 Service 存在的时候它也不会改变。 可以配置 Pod 使它与 Service 进行通信Pod 知道与 Service 通信将被自动地负载均衡到该 Service 中的某些 Pod 上。
示例nginx-service.yaml
apiVersion: v1
kind: Service
metadata:name: my-nginxlabels:run: my-nginx
spec:ports:- port: 80protocol: TCPselector:run: my-nginx
上述规约将创建一个 Service对应具有标签 run: my-nginx 的 Pod目标 TCP 端口 80 并且在一个抽象的 Service 端口targetPort容器接收流量的端口port抽象的 Service 端口可以使任何其它 Pod 访问该 Service 的端口上暴露。
[rootmaster k8s]# kubectl get service my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.111.78.3 none 80/TCP 57s
[rootmaster k8s]#
正如前面所提到的一个 Service 由一组 backend Pod 组成。这些 Pod 通过 endpoints 暴露出来。 Service Selector 将持续观察结果被 POST 到一个名称为 my-nginx 的 Endpoint 对象上。 当 Pod 终止后它会自动从 Endpoint 中移除新的能够匹配上 Service Selector 的 Pod 将自动地被添加到 Endpoint 中。 检查该 Endpoint注意到 IP 地址与在第一步创建的 Pod 是相同的。
[rootmaster k8s]# kubectl describe service my-nginx
Name: my-nginx
Namespace: default
Labels: none
Annotations: none
Selector: runmy-nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111.78.3
IPs: 10.111.78.3
Port: unset 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.11:80,10.244.2.23:80
Session Affinity: None
Events: none
[rootmaster k8s]#
[rootmaster k8s]# kubectl get ep my-nginx
NAME ENDPOINTS AGE
my-nginx 10.244.1.11:80,10.244.2.23:80 2m14s
[rootmaster k8s]#
现在能够从集群中任意节点上使用 curl 命令请求 Nginx Service : 。 注意 Service IP 完全是虚拟的它从来没有走过网络。
[rootmaster k8s]# curl 10.111.78.3:80
!DOCTYPE html
html
head
titleWelcome 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
h1Welcome to nginx!/h1
pIf you see this page, the nginx web server is successfully installed and
working. Further configuration is required./ppFor online documentation and support please refer to
a hrefhttp://nginx.org/nginx.org/a.br/
Commercial support is available at
a hrefhttp://nginx.com/nginx.com/a./ppemThank you for using nginx./em/p
/body
/html
[rootmaster k8s]#
集群内Pod通信机制
Kubernetes支持两种基本的服务发现模式--环境变量和DNS
环境变量
当Pod运行在Node上kubelet会为每个活跃的Service添加一组环境变量。它同时支持Dockerlinks、简单的{SVCNAME}_SERVICE_HOST和{SVCNAME}_SERVICE_PORT变量。这里Service的名称需大写横线被转换成下划线。
实例一个名为my-nginx的Service暴露了TCP端口80同时分配了Cluster IP地址10.1.180.155这个Service生成了如下的环境变量
MY_NGINX_PORT_80_TCP_PORT80
MY_NGINX_PORT_80_TCP_PROTOtcp
MY_NGINX_PORT_80_TCP_ADDR10.1.180/155
注意当具有需要访问服务的Pod时并且正在使用环境变量的方法将端口和集群IP发布到客户端Pod时必须在客户端Pod出现之前创建服务。否则这些客户端Pod将不会设定其环境变量
DNS
可以使用附加组件为Kubernetes集群设置DNS服务
支持集群的DNS服务器例如CoreDNS监视Kubernetes API中的新服务并为每个服务创建一组DNS记录。如果整个集群中都启用了DNS则所有的Pod都应该能够通过其DNS名称自动解析服务。
例如在Kubernetes命名空间my-ns中有一个名为my-service的服务则控制节点和DNS服务共同为my-service.my-ns创建DNS记录。my-ns命名空间中的Pod能够通过简单的对my-service进行名称查找来找到它。
其他命名空间中的Pod必须将名称限定为my-service.my-ns,这些名称将解析为服务分配的集群IP
Service创建DNS记录
Kubernetes DNS在集群上调度DNS Pod和服务并配置kubelet以告知各个容器使用DNS服务的IP来解析DNS名称
服务
A/AAAA记录
普通服务会以my-svc.my-namespace.svc.cluster-domain.example这种名称的形式被分配一个DNS A或AAAA记录取决于服务的IP协议族该名称会解析成对应服务的集群IP
Pods A/AAAA记录
经由Deployment或者DaemonSet所创建的所有Pods都会有如下DNS解析项与之对应
pod-ip-address.deploymnet-name.my-namespace.svc.cluster-domain.example
Pod规约中包含一个可选的hostname字段可以用来指定Pod的主机名当这个字段被设置是它将优先于Pod的名字称为该Pod的主机名、举例给定一个hostname为my-host的Pod该Pod的主机名将被设置成my-host
Pod规约中还有一个可选的subdomain字段可以用来指定Pod子域名。举例某Pod hostnamefoosubdomainbar在命名空间my-ns中对应的完全限定域名为foo.bar.my-ns.svc.cluster-domain.example
实例dns.yaml
apiVersion: v1
kind: Service
metadata:name: busybox
spec:selector:app: busyboxports:- port: 80targetPort: 80
---
apiVersion: v1
kind: Pod
metadata:name: busybox-1labels:app: busybox
spec:hostname: busybox-1subdomain: default-subdomaincontainers:- name: busyboximage: busybox:1.28command: [sh, -c, sleep 1h]resources:limits:memory: 128Micpu: 500mports:- containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:name: busybox-2labels:app: busybox
spec:hostname: busybox-2subdomain: default-subdomaincontainers:- name: myappimage: busybox:1.28command: [sh, -c, sleep 1h]resources:limits:memory: 128Micpu: 500mports:- containerPort: 80
[rootmaster k8s]# kubectl exec -it busybox-1 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # hostname -f
busybox-1.default-subdomain.default.svc.cluster.local
从集群外部访问Service
从集群外部访问Service的方法
1、Cluster IP
仅仅使用一个集群内部的Ip地址默认值。选择这个值意味着只想这个服务在集群内部才可以被访问到
2、NodePort
在集群内部IP的基础上在集群每个节点的端口上开发这个服务。可以再任意NodePort地址上访问这个服务
3、LoadBalancer
在使用一个集群内部IP地址和在NodePort上开放一个服务外像云提供商申请一个负载均衡器会让流量转发到每个在节点上移NodePort形式开放的服务上。
在使用一个集群内部IP地址和在NodePort上开放一个Service的基础上像云提供商申请一个负载均衡器会让流量转发到每个在节点上移NodePort形式开放的Service上。
示例
1、创建nginx pod
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx
spec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: registry.cn-beijing.aliyuncs.com/qingfeng666/nginxresources:limits:memory: 128Micpu: 500mports:- containerPort: 80
2、创建NodePort类型的Service
apiVersion: v1
kind: Service
metadata:name: nginx
spec:selector:app: nginxtype: NodePortports:- port: 80targetPort: 80nodePort: 30001
Ingress
Ingress是对集群中服务的外部访问进行管理的api对象典型的访问方式是http
Ingress公开了从集群外部带内部服务的http和https路由。流量路由由ingress资源上定义的规则控制
图示是一个将所有流量都发送到同一个Service的简单Ingress示例 可以将Ingress配置为服务提供外部可访问的URL、负载均衡流量、终止SSL/TLS以及提供基于名称的虚拟主机等能力。Ingress控制器通常负责通过负载均衡器来实现Ingress
环境准备
必须具有Ingress控制器才能满足Ingress的要求仅创建Ingress资源本身没有任何效果需要部署Ingress控制器例如ingress-nginx
Ingress资源
最小的Ingress资源示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: example-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target: /
spec:rules:- host: hello-world.infohttp:paths:- path: /pathType: Prefixbackend:service:name: webport:number: 8080
Ingress资源仅支持用于转发http流量的规则
Ingress规则
每个HTTP规则都包含以下信息
1、可选的host。若果未指定host则规则只适用于通过指定IP地址的所有入站http通信如果提供了host例如foo.bar.com则规则适用于该host
2、路径列表paths每个路径都有一个有serviceName和servicePod定义的关联后端。在负载均衡器将流量定向到引用的服务之前主机和路径都必须匹配传入请求的内容
3、backend是Service服务和端口组合。与规则host和path匹配的Ingress的HTTP请求将发送到列出的backend
安装Nginx Ingress控制器
https://github.com/kubernetes/ingress-nginx
版本对应 下载对应版本的ingress-nginx提取部署文件 deploy/static/provider/cloud/deploy.yaml
# 修改Service名称ingress-nginx-controller的type为NodePort
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.5.1name: ingress-nginx-controllernamespace: ingress-nginx
spec:externalTrafficPolicy: LocalipFamilies:- IPv4ipFamilyPolicy: SingleStackports:- appProtocol: httpname: httpport: 80protocol: TCPtargetPort: http- appProtocol: httpsname: httpsport: 443protocol: TCPtargetPort: httpsselector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: NodePort
替换国内镜像
registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.5.1
registry.aliyuncs.com/google_containers/kube-webhook-certgen:v20220916-gd32f8c343
查询 ingress-nginx 命名空间下的 deployment、pod、service 资源
get deployment,pods,service -n ingress-nginx -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/ingress-nginx-controller 1/1 1 1 41s controller registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.5.1 app.kubernetes.io/componentcontroller,app.kubernetes.io/instanceingress-nginx,app.kubernetes.io/nameingress-nginxNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/ingress-nginx-admission-create-czqlz 0/1 Completed 0 41s 10.244.2.25 node2 none none
pod/ingress-nginx-admission-patch-9j694 0/1 Completed 2 41s 10.244.1.13 node1 none none
pod/ingress-nginx-controller-fbd49d74b-r8cxg 1/1 Running 0 41s 10.244.1.14 node1 none noneNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/ingress-nginx-controller NodePort 10.97.172.217 none 80:19386/TCP,443:13175/TCP 41s app.kubernetes.io/componentcontroller,app.kubernetes.io/instanceingress-nginx,app.kubernetes.io/nameingress-nginx
service/ingress-nginx-controller-admission ClusterIP 10.109.60.199 none 443/TCP 41s app.kubernetes.io/componentcontroller,app.kubernetes.io/instanceingress-nginx,app.kubernetes.io/nameingress-nginx
[rootmaster k8s]#
Nginx Ingress流量验证
1、创建一个Deployment
[rootmaster k8s]# kubectl create deployment web --imageregistry.cn-beijing.aliyuncs.com/qingfeng666/hello-app:1.0
deployment.apps/web created
2、暴露Deployment
[rootmaster k8s]# kubectl expose deployment web --typeNodePort --port8080
service/web exposed[rootmaster k8s]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 none 443/TCP 5d23h
web NodePort 10.108.4.70 none 8080:18455/TCP 89s
[rootmaster k8s]#
访问
[rootmaster k8s]# curl node1:18455
Hello, world!
Version: 1.0.0
Hostname: web-5978f64c6-jk64w
3、创建Ingress资源
ingress-example.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: example-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target: /
spec:rules:- host: hello-world.infohttp:paths:- path: /pathType: Prefixbackend:service:name: webport:number: 8080
创建ingress
[rootmaster k8s]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress nginx hello-world.info 10.97.172.217 80 3m34s
修改hosts
[rootmaster k8s]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
179.220.56.230 master
179.220.56.231 node1
179.220.56.232 node2
10.97.172.217 hello-world.info
访问hello-world.info
[rootmaster k8s]# curl hello-world.info
Hello, world!
Version: 1.0.0
Hostname: web-5978f64c6-khzk6