12-K8S Basic-Ingress资源介绍及实战
PS :ingress官方文档:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
一、什么是Ingress
- Ingress 公开了从集群外部到集群内 services 的HTTP和HTTPS路由。 流量路由由 Ingress 资源上定义的规则控制。
internet
|
[ Ingress ]
--|-----|--
[ Services ]
- 可以将 Ingress 配置为提供服务外部可访问的 URL、负载均衡流量、终止 SSL / TLS 并提供基于名称的虚拟主机。Ingress 控制器通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
- Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或者 Service.Type=LoadBalancer 类型的服务。
- 可以将Ingress配置为提供服务外部可访问的URL,负载均衡流量,终止 SSL / TLS 并提供基于名称的虚拟主机。 Ingress 控制器通常负责通过负载平衡器来实现入口,尽管它也可以配置边缘路由器或其他前端以帮助处理流量。
- Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开给 Internet 时,通常使用以下类型的服务 Service.Type=NodePort 或者 Service.Type=LoadBalancer.
二、Ingress资源介绍
- Ingress资源时基于HTTP虚拟主机或URL的转发规则,需要强调的是,这是一条转发规则。它在资源配置清单中的spec字段中嵌套了rules、backend和tls等字段进行定义。如下示例中定义了一个Ingress资源,其包含了一个转发规则:将发往myapp.magedu.com的请求,代理给一个名字为myapp的Service资源。
- 注意:ingress自身步支持使用标签选择器挑选真正提供服务的Pod对象,因此,他需要由Service对象的辅助完成此类功能。
- (所以还是要先为后端的一组提供服务的Pod定义一个Service,然后Ingress变相借助Service的标签选择器实现对后端Pod的过滤,Service在此仅作为一个辅助的角色实现Pod根据标签选择器发现机制及挑选机制)
apiVersion : extensions/v1beta1
kind : Ingress
metadata :
name : test-ingress
annotations : #资源注解
nginx.ingress.kubernetes.io/rewrite-target : /
spec :
rules : #rules是一个对象列表,每一个列表是一个虚拟代理形式
- http : myapp.magedu.com #指定虚拟主机名称,如果没指定代表Ingress Controller 所在的虚拟主机的名称
paths :
- path : /testpath #Server中的Url访问的路径映射到backend后端主机的upstream (-path 指明,提供客户端访问的url路径)
backend : #backend相当于后端的虚拟主机,真正提供服务的upstream
#关联到的后端Service资源,它的标签选择器匹配到的Pod对象将成为反代服务的"后端"
serviceName : test
servicePort : 80
Ingress七层代理中的Service 作用,以为一个辅助工具:
- Service的作用一 :标签过滤器
- 因为Ingress并不支持标签选择器来选择代理后端哪些pod,所以只能借助Service来完成,所以此处Service的资源仅仅是帮助Ingress提供一个选择后端Pod的标签选择器,并不是我们要代理的后端。
- 所以在定义backend是要使用serviceName资源,所以在定义之前必须实现为一组Pod来创建一个Service。切记Service并不是作为用户的访问一端,仅用于帮助七层代理提供标签选择器。
- 如果七层代理一旦开始代理,所有的请求到达Ingress Controllers,代理后是直达pod,不会经过Service。所以Service在这里仅作为标签选择器使用。
- Service的作用二 :变相将Pod变动让Ingress Controller捕获
- Ingress Controller 是无法识别到被Service标签选择的Pod的数量的,所以Service的第二个作用就是通过标签过滤器检查后端Pod的数量。
- 与所有其他 Kubernetes 资源一样,Ingress 需要使用 apiVersion、kind 和 metadata 字段。 有关使用配置文件的一般信息,请参见部署应用、 配置容器、管理资源。 Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress 控制器,例如 rewrite-target annotation。 不同的 Ingress 控制器支持不同的注解(annotations)。查看文档以供您选择 Ingress 控制器,以了解支持哪些注解(annotations)。
- Ingress 规范 具有配置负载均衡器或者代理服务器所需的所有信息。最重要的是,它包含与所有传入请求匹配的规则列表。Ingress 资源仅支持用于定向 HTTP 流量的规则。
2.1、Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段
- Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段:
rules
:用于定义当前Ingress资源的转发规则列表;由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端。backend
:默认的后端用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端。tls
:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNI TLS扩展机制来支持该功能。backend对象的定义由2个必要的字段组成:serviceName和servicePort,分别用于指定流量转发的后端目标Service资源名称和端口。rules对象由一系列的配置的Ingress资源的host规则组成,这些host规则用于将一个主机上的某个URL映射到相关后端Service对象。default backend
: 如果rules规则中的请求转发给backend的主机都宕机,则由default backend 提供sorry Server- 没有规则的 Ingress 将所有流量发送到单个默认后端。默认后端通常是 Ingress 控制器的配置选项,并且未在 Ingress 资源中指定。
- 如果没有主机或路径与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到您的默认后端。
spec:
rules:
- hosts: <string>
http:
paths:
- path:
backend:
serviceName: <string>
servicePort: <string>
- 需要注意的是,.spec.rules.host属性值,目前暂不支持使用IP地址定义,也不支持IP:Port的格式,该字段留空,代表着通配所有主机名。
- tls对象由2个内嵌的字段组成,仅在定义TLS主机的转发规则上使用。
- hosts: 包含 于 使用 的 TLS 证书 之内 的 主机 名称 字符串 列表, 因此, 此处 使用 的 主机 名 必须 匹配 tlsSecret 中的 名称。
- secretName: 用于 引用 SSL 会话 的 secret 对象 名称, 在 基于 SNI 实现 多 主机 路 由 的 场景 中, 此 字段 为 可选。
2.2、Ingress资源的类型
- ingress的资源类型有以下四种:
- 1、单Server资源型ingress
- 2、基于URL路径进行流量转发
- 3、基于主机名称的虚拟主机
- 4、TLS类型的Ingress资源
2.2.1、单Server资源型ingress
- 暴露单个服务的方法有多种,如NodePort、LoadBanlancer等等,当然也可以使用Ingress来进行暴露单个服务,只需要为Ingress指定default backend即可,如下示例:
#官方示例
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: my-svc
servicePort: 80
#-path: 省略相当于 / ,可以不用写,Ingress控制器会为其分配一个IP地址接入请求流量,并将其转发至后端my-svc
如果使用 kubectl apply -f 创建它,则应该能够查看刚刚添加的 Ingress 的状态:
kubectl get ingress test-ingress
NAME HOSTS ADDRESS PORTS AGE
test-ingress * 107.178.254.228 80 59s
其中 107.178.254.228 是由 Ingress 控制器分配以满足该 Ingress 的 IP。
注意:Ingress 控制器和负载均衡器可能需要一两分钟才能分配 IP 地址。 在此之前,您通常会看到地址为 <pending>。
注意:入口控制器和负载平衡器可能需要一两分钟才能分配IP地址。 在此之前,您通常会看到地址字段的值被设定为 <pending>。
2.2.2、基于URL路径进行流量转发(简单分列)
- 一个分列配置根据请求的 HTTP URI 将流量从单个 IP 地址路由到多个服务。 Ingress 允许您将负载均衡器的数量降至最低。例如,这样的设置
foo.bar.com -> 178.91.123.132 -> / foo service1:4200
/ bar service2:8080
- 例如创建一个ingress
#官方示例
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
当您使用 kubectl apply -f 创建 Ingress 时:
kubectl describe ingress simple-fanout-example
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
Ingress 控制器将提供实现特定的负载均衡器来满足 Ingress,只要 Service (s1,s2) 存在。 当它这样做了,你会在地址栏看到负载均衡器的地址。
注意:根据您使用的 Ingress 控制器,您可能需要创建默认 HTTP 后端 Service。
2.2.3、基于主机名称的虚拟主机(基于名称的虚拟托管)
- 基于名称的虚拟主机支持将 HTTP 流量路由到同一 IP 地址上的多个主机名。
foo.bar.com --| |-> foo.bar.com service1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com service2:80
- 以下 Ingress 让后台负载均衡器基于主机 header 路由请求
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
如果您创建的 Ingress 资源没有规则中定义的任何主机,则可以匹配到您 Ingress 控制器 IP 地址的任何网络流量,而无需基于名称的虚拟主机。
- 例如,以下 Ingress 资源会将 first.bar.com 请求的流量路由到 service1,将 second.foo.com 请求的流量路由到 service2,而没有在请求中定义主机名的 IP 地址的流量路由(即,不提供请求标头)到 service3
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: first.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: second.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
- http:
paths:
- backend:
serviceName: service3
servicePort: 80
2.2.4、TLS类型的Ingress资源
- 您可以通过指定包含 TLS 私钥和证书的 secret Secret 来加密 Ingress。 目前,Ingress 只支持单个 TLS 端口 443,并假定 TLS 终止。
- 如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过 SNI TLS 扩展指定的主机名(如果 Ingress 控制器支持 SNI)在同一端口上进行复用。 TLS Secret 必须包含名为 tls.crt 和 tls.key 的密钥,这些密钥包含用于 TLS 的证书和私钥
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
- 在 Ingress 中引用此 Secret 将会告诉 Ingress 控制器使用 TLS 加密从客户端到负载均衡器的通道。您需要确保创建的 TLS secret 来自包含 sslexample.foo.com 的 CN 的证书。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
注意:各种 Ingress 控制器所支持的 TLS 功能之间存在差异。请参阅有关文件 nginx、 GCE 或者任何其他平台特定的 Ingress 控制器,以了解 TLS 如何在您的环境中工作
2.3、高级:Ingress → annotations 注解(annotations)来配置一些选项
- Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress 控制器,例如 rewrite-target annotation。 不同的 Ingress 控制器支持不同的注解(annotations)。查看文档以供您选择 Ingress 控制器,以了解支持哪些注解(annotations)。
- Ingress - nginx 专用的资源注解很多,Github托管地址文档 : https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md
三、Ingress实战部署(单Server资源型ingress /TLS类型的Ingress资源 )
3.1、ingress资源创建清单
ingress]# kubectl explain ingress
KIND: Ingress
VERSION: extensions/v1beta1 # 所属的资源群组
DESCRIPTION:
Ingress is a collection of rules that allow inbound connections to reach
the endpoints defined by a backend. An Ingress can be configured to give
services externally-reachable urls, load balance traffic, terminate SSL,
offer name based virtual hosting etc. DEPRECATED - This group version of
Ingress is deprecated by networking.k8s.io/v1beta1 Ingress. See the release
notes for more information.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Spec is the desired state of the Ingress. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
status <Object>
Status is the current state of the Ingress. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
3.2、实战创建流程
- ingress-controller(ingress-nginx)也是个pod(ns:ingress-nginx), → 所以需要pod控制器deployment(ns:ingress-nginx) → 也需要NodePort类型service(ns:ingress-nginx) → 创建deployment类型的控制器(ns:myns)管理/创建真实被调度访问的pod → 创建 ClusterIP 类型 Service 使用标签选择器匹配被访问的pod → 创建ingress资源(七层代理) → 访问
3.3、创建实战 → 单Server资源型ingress
1、实现前要手动创建ingress-controller
ingress]# cat mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
--- #标准资源界定符
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "<election-id>-<ingress-class>"
# Here: "<ingress-controller-leader>-<nginx>"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 101
runAsUser: 101
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
---
apiVersion: v1
kind: LimitRange
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
limits:
- min:
memory: 90Mi
cpu: 100m
type: Container
2、所有的资源都会被创建在ingress-nginx名称空间中
#查看名称空间
~]# kubectl get ns
NAME STATUS AGE
ingress-nginx Active 3m46s
#查看此名称空间下的Pod 其实就是nginx的 ingress controller ( basic]# kubectl describe pods nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx查看启动步骤状态)
~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-948ffd8cc-gdxrz 1/1 Running 0 44m #nginx-ingress-controller还不能接入集群外部流量
#查看标签,此Pod标签可作为下面创建的Service使用的标签选择器的标签
~]# kubectl get pods -n ingress-nginx --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-ingress-controller-948ffd8cc-gdxrz 1/1 Running 0 50m app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=948ffd8cc
3、手动编辑一个对应NodePort类型的Service资源,并关联到nginx-ingress-controller
#定义NodePort类型的Service资源
~]# mkdir mainfests/ingress
ingress]# cat ingress-nginx-svc.yaml
#service所属的标准资源api版本定义群组
apiVersion: v1
#定义资源的类型为Service
kind: Service
#定义元数据
metadata:
#Service名称
name: ingress
#定义service所属的名称空间需要和nginx-ingress-controller————Pod在同一名称空间
namespace: ingress-nginx
#定义service规格
spec:
#定义Service的标签选择器,仅用于定义选择匹配nginx-ingress-controller的标签
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
#ports字段
ports:
#此端口的名称
- name: http
#Service地址的哪个端口于后端Pods端口映射
port: 80
#nodePort: 30080
- name: https
port: 443
#nodePort: 30443
#定义Server类型为NodePort类型
type: NodePort
4、使用声明式接口创建此Service资源
ingress]# kubectl apply -f ingress-nginx-svc.yaml
service/ingress created
5、查看定义的Service信息
ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress NodePort 10.2.100.124 <none> 80:48420/TCP,443:49572/TCP 51s #30080 30443
6、测试访问此集群中其中一台node地址+映射提供用户访问的端口
ingress]# curl 192.168.20.177:48420 #可以访问任何的node节点的IP + Port,可以访问到nginx-ingress-controller
nginx
--------------------------------------------------------以上已经再上一章定义过,这里为了回顾--------------------------------------------
1、为了方便验证创建一个单独的名称空间
~]# kubectl create ns myns
namespace/myns created
~]# kubectl get ns
NAME STATUS AGE
default Active 21d
myns Active 13s
2、(控制器+Service+pods)创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用) ,以及为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)
# 1、非自主式Pod,由Deployment控制器管理的提供后端服务的Pod(创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用))
# 2、为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)
ingress]# cat myns-deployment-pods-example.yaml
## ----> 定义控制器
# 定义deployment群组名称以及版本
apiVersion: apps/v1
# 定义资源类型
kind: Deployment
# 元数据
metadata:
# 控制器名称
name: myapp
# 控制器所属的名称空间
namespace: myns
# 定义deployment控制器资源规格(标签选择器、pod数量、pod模板)
spec:
# 定义pods数量
replicas: 2
# 匹配的pods的标签选择器
selector:
matchLabels:
app: myapp
rel: beta
# 定义pod创建依据的模板
template:
# 定义后端pod的元数据
metadata:
# 定义pod的名称
name: myapp-pod
# 定义pod所属的名称空间应该和deployment控制器保持一致
namespace: myns
# 定义pod的标签,应该和deployment控制器匹配后端pod的标签选择器保持一致
labels:
app: myapp
rel: beta
# 定义pos的资源的规格
spec:
# pod内部运行的容器信息
containers:
# pod中容器运行名称
- name: myapp-test-con
# pod内部容器运行的镜像
image: ikubernetes/myapp:v1
# 资源界定符
---
## ----> 定义Service资源
# 定义Service资源的群组名称及版本
apiVersion: v1
# 定义资源类型
kind: Service
# 定义Service资源元数据
metadata:
# 定义service资源的名称(不同资源的名称可以一致)
name: myapp
# 定义所属的名称空间
namespace: myns
# 定义service资源规格(标签选择器匹配pod标签、pod数量、pod模板)
spec:
# 定义Service匹配的后端pod的标签的标签选择器
selector:
app: myapp
rel: beta
# 定义service类型默认为cluster
type: ClusterIP
# clusterIP: 10.97.97.97
# ports字段
ports:
# 此端口的名称
- name: http
# Service地址的哪个端口于后端Pods端口映射
port: 80
# 后端Pods的哪个端口于Service做映射
targetPort: 80
# 使用apply声明式接口创建资源
ingress]# kubectl apply -f myns-deployment-pods-example.yaml
deployment.apps/myapp created
service/myapp created
3、查看创建的资源
# deployment控制器
ingress]# kubectl get deploy -n myns -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
myapp 2/2 2 2 9m44s myapp-test-con ikubernetes/myapp:v1 app=myapp,rel=beta
# server
ingress]# kubectl get svc -n myns -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
myapp ClusterIP 10.104.87.25 <none> 80/TCP 10m app=myapp,rel=beta
# pod
ingress]# kubectl get pods -n myns -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
myapp-89484f5d-qsbx7 1/1 Running 0 10m 10.244.1.38 k8s.node1 <none> <none> app=myapp,pod-template-hash=89484f5d,rel=beta
myapp-89484f5d-zqc57 1/1 Running 0 10m 10.244.1.39 k8s.node1 <none> <none> app=myapp,pod-template-hash=89484f5d,rel=beta
# 显示执行的名称空间下的所有资源
[root@k8s ingress]# kubectl get all -n myns
NAME READY STATUS RESTARTS AGE
pod/myapp-89484f5d-qsbx7 1/1 Running 0 12m
pod/myapp-89484f5d-zqc57 1/1 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/myapp ClusterIP 10.104.87.25 <none> 80/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myapp 2/2 2 2 12m
NAME DESIRED CURRENT READY AGE
replicaset.apps/myapp-89484f5d 2 2 2 12m
4、资源访问测试
# 访问pod
[root@k8s ingress]# curl 10.244.1.38
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s ingress]# curl 10.244.1.39
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
# service
ingress]# curl 10.104.87.25
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
5、通过ingress-controller七层代理进行调度
# 创建ingress资源清单
ingress]# cat myns-ingress-example.yaml
# 定义ingress资源所属群组名称以及版本
apiVersion: extensions/v1beta1
# 定义资源类型
kind: Ingress
# 元数据
metadata:
# 定义Ingress名称
name: myapp
# 定义名称空间
namespace: myns
# 定义资源注解
annotations:
# url重定向--> 非主要无需关注
nginx.ingress.kubernetes.io/rewrite-target: /
# ingress类型为nginx
kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
# 定义代理规则
rules:
# 定义虚拟主机名称,不写默认为localhost
- host: www.daizhe.net.cn
http:
paths:
# Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
- path: /
# backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port)
backend:
# ingress代理的server名称,之前创建的service为myapp
serviceName: myapp
# service和pods映射的端口(service-->sepc.ports.port)
servicePort: 80
# 使用声明式接口创建资源清单
ingress]# kubectl apply -f myns-ingress-example.yaml
ingress.extensions/myapp created
6、查看已经创建的ingress资源
ingress]# kubectl get ingress -n myns
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp <none> www.daizhe.net.cn 80 2m10s
# 显示ingress yaml格式
ingress]# kubectl get ingress -n myns -o yaml
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx","nginx.ingress.kubernetes.io/rewrite-target":"/"},"name":"myapp","namespace":"myns"},"spec":{"rules":[{"host":"www.daizhe.net.cn","http":{"paths":[{"backend":{"serviceName":"myapp","servicePort":80},"path":"/"}]}}]}}
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
creationTimestamp: "2020-05-13T10:23:47Z"
generation: 1
managedFields:
- apiVersion: extensions/v1beta1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:kubectl.kubernetes.io/last-applied-configuration: {}
f:kubernetes.io/ingress.class: {}
f:nginx.ingress.kubernetes.io/rewrite-target: {}
f:spec:
f:rules: {}
manager: kubectl
operation: Update
time: "2020-05-13T10:23:47Z"
name: myapp
namespace: myns
resourceVersion: "3868216"
selfLink: /apis/extensions/v1beta1/namespaces/myns/ingresses/myapp
uid: 0b39e70e-f19e-4c48-8031-e5ee6ebb2bbf
spec:
rules:
- host: www.daizhe.net.cn
http:
paths:
- backend:
serviceName: myapp
servicePort: 80
path: /
pathType: ImplementationSpecific
status:
loadBalancer: {}
kind: List
metadata:
resourceVersion: ""
selfLink: ""
# 使用describe查看当前状态
ingress]# kubectl describe ingress -n myns
Name: myapp
Namespace: myns
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
www.daizhe.net.cn # 可以查看到对 www.daizhe.net.cn 地址的访问都会被映射到后端myapp的service的80端口响应
# 可以查看到service四层代理的后端 pod有10.244.1.38:80,10.244.1.39:80
/ myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 4m1s nginx-ingress-controller Ingress myns/myapp
7、连接ingress-controller验证
# 手动连入ingress-controller查看配置文件
ingress]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-5bb8fb4bb6-q5lpg 1/1 Running 0 4h50m
[root@k8s ingress]# kubectl exec -it nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx -- /bin/sh
/etc/nginx $ ls
fastcgi.conf geoip mime.types nginx.conf scgi_params uwsgi_params.default
fastcgi.conf.default koi-utf mime.types.default nginx.conf.default scgi_params.default win-utf
fastcgi_params koi-win modsecurity opentracing.json template
fastcgi_params.default lua modules owasp-modsecurity-crs uwsgi_params
/etc/nginx $ more nginx.conf
.....
server {
server_name www.daizhe.net.cn ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
location / {
set $namespace "myns";
set $ingress_name "myapp";
set $service_name "myapp";
set $service_port "80";
set $location_path "/";
rewrite_by_lua_block {
lua_ingress.rewrite({
force_ssl_redirect = false,
ssl_redirect = true,
force_no_ssl_redirect = false,
use_port_in_redirects = false,
})
balancer.rewrite()
plugins.run()
}
......
8、访问验证。由于上面ingress定义的- host: www.daizhe.net.cn,需要再(本机电脑)宿主机上添加解析测试
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 daizhe.com
192.168.20.236 192.168.20.212 192.168.20.214 www.daizhe.net.cn
# 访问: http://{ingress.host}:{ingress-controller.控制器-Port.service}
# 查看ingress-controller.控制器-Port.service
~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress NodePort 10.98.225.170 <none> 80:32145/TCP,443:31430/TCP 4h23m
# windows客户端访问 --> 轮询效果 (后端pod副本数量为2,默认调度算法为随机)
daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 21 100 21 0 0 269 0 --:--:-- --:--:-- --:--:-- 269my app-89484f5d-zqc57
daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 21 100 21 0 0 269 0 --:--:-- --:--:-- --:--:-- 269my app-89484f5d-zqc57
daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 21 100 21 0 0 223 0 --:--:-- --:--:-- --:--:-- 223my app-89484f5d-qsbx7
daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 21 100 21 0 0 269 0 --:--:-- --:--:-- --:--:-- 269my
- 下面访问出错由于ingress未配置TLS
3.4、创建实战 → TLS类型的Ingress资源
1、生成自签名证书
[root@k8s ingress]# mkdir ssl
[root@k8s ingress]# cd ssl/
# 私钥
ssl]# openssl genrsa -out myapp.key 2048
Generating RSA private key, 2048 bit long modulus
.................+++
..................................+++
e is 65537 (0x10001)
You have new mail in /var/spool/mail/root
# 证书
ssl]# openssl req -new -x509 -key myapp.key -out myapp.crt -subj /C=CN/ST/Beijing/L=Beijing/O=Ops/CN=www.toptops.top -days 3650
ssl]# ls
myapp.crt myapp.key
2、创建tls 类型 secret(将自签名证书转为secret资源才能使得k8s所引用)
ssl]# kubectl create secret -h
Create a secret using specified subcommand.
Available Commands: # secret 类型
docker-registry Create a secret for use with a Docker registry
generic Create a secret from a local file, directory or literal value
tls Create a TLS secret
Usage:
kubectl create secret [flags] [options]
Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
ssl]# kubectl create secret tls -h
Usage:
kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run=server|client|none] [options]
# -n 指定名称空间,必须和ingress在同一名称空间下
# --dry-run 干跑模式
# toptops 创建的secret 名称
ssl]# kubectl create secret tls toptops -n myns --cert=myapp.crt --key=myapp.key --dry-run
ssl]# kubectl create secret tls toptops -n myns --cert=myapp.crt --key=myapp.key
secret/toptops created
3、根据创建secret名称查看证书详细信息
ssl]# kubectl describe secret toptops -n myns
Name: toptops
Namespace: myns
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 1184 bytes
tls.key: 1679 bytes
4、创建TLS类型的ingress --> 继续调度前面示例的 pod
# 官方文档 : https://kubernetes.io/zh/docs/concepts/services-networking/ingress/#ingress-%E7%B1%BB%E5%9E%8B
ssl]# cat myns-ingress-tls-example.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
# 定义ingress名称
name: myapp-tls
# 定义所属的名称空间
namespace: myns
# 定义资源注解
annotations:
# ingress类型为nginx
kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
tls:
# 定义虚拟主机名称,这里需要和上面创建tls证书中域名保持一致,不写默认为localhost
- hosts:
- www.toptops.top
# 创建tls 类型 secret名称
secretName: toptops
# 定义代理规则
rules:
# 定义虚拟主机名称,这里需要和上面创建tls证书中域名保持一致,不写默认为localhost
- host: www.toptops.top
http:
paths:
# Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
- path: /
# backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port)
backend:
# ingress代理的server名称,之前创建的service为myapp
serviceName: myapp
# service和pods映射的端口(service-->sepc.ports.port)
servicePort: 80
# 使用声明式接口创建资源
ssl]# kubectl apply -f myns-ingress-tls-example.yaml
ingress.extensions/myapp-tls created
5、查看已经创建的ingress资源
ssl]# kubectl get ingress -n myns -o wide
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp <none> www.daizhe.net.cn 80 29h
myapp-tls <none> www.toptops.top 80, 443 45s
# 使用describe查看当前状态
ssl]# kubectl describe ingress -n myns
Name: myapp
Namespace: myns
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
www.daizhe.net.cn
/ myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
Events: <none>
Name: myapp-tls
Namespace: myns
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
toptops terminates www.toptops.top
Rules:
Host Path Backends
---- ---- --------
www.toptops.top
/ myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations: kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 93s nginx-ingress-controller Ingress myns/myapp-tls
ssl]# kubectl describe ingress myapp-tls -n myns
Name: myapp-tls
Namespace: myns
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
toptops terminates www.toptops.top
Rules:
Host Path Backends
---- ---- --------
www.toptops.top
/ myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations: kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 2m22s nginx-ingress-controller Ingress myns/myapp-tls
6、连接ingress-controller验证
# 手动连入ingress-controller查看配置文件
ingress]# kubectl exec -it nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx -- /bin/sh
/etc/nginx $ more nginx.conf
...
server {
server_name www.toptops.top ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
location / {
set $namespace "myns";
set $ingress_name "myapp-tls";
set $service_name "myapp";
set $service_port "80";
set $location_path "/";
rewrite_by_lua_block {
lua_ingress.rewrite({
force_ssl_redirect = false,
ssl_redirect = true,
force_no_ssl_redirect = false,
use_port_in_redirects = false,
})
balancer.rewrite()
plugins.run()
}
...
8、访问验证。由于上面ingress定义的- host: www.toptops.top,需要再(本机电脑)宿主机上添加解析测试
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 daizhe.com
192.168.20.236 192.168.20.212 192.168.20.214 www.daizhe.net.cn
# 访问: http://{ingress.host}:{ingress-controller.控制器-Port.service}
# 查看ingress-controller.控制器-Port.service
~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress NodePort 10.98.225.170 <none> 80:32145/TCP,443:31430/TCP 4h23m
# # windows客户端访问 --> 轮询效果 (后端pod副本数量为2,默认调度算法为随机)
四、(NT)实际项目(ingress-controller(ingress-nginx)代理→ ingress → Tomcat应用
4.1、创建ingress-controller(ingress-nginx-pod)
1、实现前要手动创建ingress-controller
ingress]# cat mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
--- #标准资源界定符
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "<election-id>-<ingress-class>"
# Here: "<ingress-controller-leader>-<nginx>"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 101
runAsUser: 101
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
---
apiVersion: v1
kind: LimitRange
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
limits:
- min:
memory: 90Mi
cpu: 100m
type: Container
2、所有的资源都会被创建在ingress-nginx名称空间中
#查看名称空间
~]# kubectl get ns
NAME STATUS AGE
ingress-nginx Active 3m46s
#查看此名称空间下的Pod 其实就是nginx的 ingress controller ( basic]# kubectl describe pods nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx查看启动步骤状态)
~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-948ffd8cc-gdxrz 1/1 Running 0 44m #nginx-ingress-controller还不能接入集群外部流量
#查看标签,此Pod标签可作为下面创建的Service使用的标签选择器的标签
~]# kubectl get pods -n ingress-nginx --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-ingress-controller-948ffd8cc-gdxrz 1/1 Running 0 50m app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=948ffd8cc
3、手动编辑一个对应NodePort类型的Service资源,并关联到nginx-ingress-controller
#定义NodePort类型的Service资源
~]# mkdir mainfests/ingress
ingress]# cat ingress-nginx-svc.yaml
#service所属的标准资源api版本定义群组
apiVersion: v1
#定义资源的类型为Service
kind: Service
#定义元数据
metadata:
#Service名称
name: ingress
#定义service所属的名称空间需要和nginx-ingress-controller————Pod在同一名称空间
namespace: ingress-nginx
#定义service规格
spec:
#定义Service的标签选择器,仅用于定义选择匹配nginx-ingress-controller的标签
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
#ports字段
ports:
#此端口的名称
- name: http
#Service地址的哪个端口于后端Pods端口映射
port: 80
#nodePort: 30080
- name: https
port: 443
#nodePort: 30443
#定义Server类型为NodePort类型
type: NodePort
4、使用声明式接口创建此Service资源
ingress]# kubectl apply -f ingress-nginx-svc.yaml
service/ingress created
5、查看定义的Service信息
ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress NodePort 10.2.100.124 <none> 80:48420/TCP,443:49572/TCP 51s #30080 30443
6、测试访问此集群中其中一台node地址+映射提供用户访问的端口
ingress]# curl 192.168.20.177:48420 #可以访问任何的node节点的IP + Port,可以访问到nginx-ingress-controller
4.2、ns-Pod控制器+Service+Tomcat-pod
1、(控制器+Service+pods)创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用) ,以及为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)
# 1、非自主式Pod,由Deployment控制器管理的提供后端服务的Pod(创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用))
# 2、为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)
ingress]# cat myns-deployment-tomcatpods-example.yaml
## ---->(名称空间创建)定义tomcat-pod + service + deployment所属的名称空间
# 定义namespace群组及版本
apiVersion: v1
# 定义资源类型
kind: Namespace
# 元数据
metadata:
# 名称空间名称
name: eshop
---
## ----> 定义控制器
# 定义deployment群组名称以及版本
apiVersion: apps/v1
# 定义资源类型
kind: Deployment
# 元数据
metadata:
# 控制器名称
name: tomcat-dep
# 控制器所属的名称空间
namespace: eshop
# 定义deployment控制器资源规格(标签选择器、pod数量、pod模板)
spec:
# 定义pods数量
replicas: 2
# 匹配的pods的标签选择器
selector:
matchLabels:
app: tomcat
rel: beta
# 定义pod创建依据的模板
template:
# 定义后端pod的元数据
metadata:
# 定义pod的名称
name: tomcat-pod
# 定义pod所属的名称空间应该和deployment控制器保持一致
namespace: eshop
# 定义pod的标签,应该和deployment控制器匹配后端pod的标签选择器保持一致
labels:
app: tomcat
rel: beta
# 定义pos的资源的规格
spec:
# pod内部运行的容器信息
containers:
# pod中容器运行名称
- name: tomcat-test-con
# pod内部容器运行的镜像
image: tomcat:alpine
# 资源界定符
---
## ----> 定义Service资源
# 定义Service资源的群组名称及版本
apiVersion: v1
# 定义资源类型
kind: Service
# 定义Service资源元数据
metadata:
# 定义service资源的名称(不同资源的名称可以一致)
name: tomcat-svc
# 定义所属的名称空间
namespace: eshop
# 定义service资源规格(标签选择器匹配pod标签、pod数量、pod模板)
spec:
# 定义Service匹配的后端pod的标签的标签选择器
selector:
app: tomcat
rel: beta
# 定义service类型默认为cluster
type: ClusterIP
# clusterIP: 10.97.97.97
# ports字段
ports:
# 此端口的名称
- name: http
# Service地址的哪个端口于后端Pods端口映射
port: 8080
# 后端Pods的哪个端口于Service做映射
targetPort: 8080
- name: ajp
port: 8009
targetPort: 8009
2、使用声明式接口创建资源
ingress]# kubectl apply -f myns-deployment-tomcatpods-example.yaml
namespace/eshop created
deployment.apps/tomcat-dep created
service/tomcat-svc created
3、资源创建验证
# 名称空间
ingress]# kubectl get ns
eshop Active 40s
# pod控制器资源
ingress]# kubectl get deploy -n eshop -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
tomcat-dep 2/2 2 2 2m28s tomcat-test-con tomcat:alpine app=tomcat,rel=beta
# service资源
ingress]# kubectl get service -n eshop -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
tomcat-svc ClusterIP 10.102.124.114 <none> 8080/TCP,8009/TCP 3m14s app=tomcat,rel=beta
ingress]# kubectl describe service -n eshop
Name: tomcat-svc
Namespace: eshop
Labels: <none>
Annotations: Selector: app=tomcat,rel=beta
Type: ClusterIP
IP: 10.102.124.114
Port: http 8080/TCP
TargetPort: 8080/TCP
Endpoints: 10.244.1.40:8080,10.244.2.24:8080 # pod地址
Port: ajp 8009/TCP
TargetPort: 8009/TCP
Endpoints: 10.244.1.40:8009,10.244.2.24:8009
Session Affinity: None
Events: <none>
# pods资源
ingress]# kubectl get pods -n eshop -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
tomcat-dep-5bdc54686b-9w75x 1/1 Running 0 6m55s 10.244.2.24 k8s.node2 <none> <none> app=tomcat,pod-template-hash=5bdc54686b,rel=beta
tomcat-dep-5bdc54686b-cm5kq 1/1 Running 0 6m55s 10.244.1.40 k8s.node1 <none> <none> app=tomcat,pod-template-hash=5bdc54686b,rel=beta
4.3、ingress资源创建(通过ingress-controller七层代理进行调度)
1、创建ingress资源清单
ingress]# cat eshop-ingress-tomcat-pod.yaml
# 定义ingress资源所属群组名称以及版本
apiVersion: extensions/v1beta1
# 定义资源类型
kind: Ingress
# 元数据
metadata:
# 定义Ingress名称
name: tomcat-ingress
# 定义名称空间
namespace: eshop
# 定义资源注解
annotations:
# url重定向--> 非主要无需关注
nginx.ingress.kubernetes.io/rewrite-target: /
# ingress类型为nginx
kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
# 定义代理规则
rules:
# 定义虚拟主机名称,不写默认为localhost
- host: www.daizhe.net.cn
http:
paths:
# Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
- path: /eshop
# backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port)
backend:
# ingress代理的server名称,之前创建的service为myapp
serviceName: tomcat-svc
# service和pods映射的端口(service-->sepc.ports.port)--> 虽然tomcat-svc的service与pod映射了两个端口但是nginx是不支持ajp协议所以仅暴漏一个
servicePort: 8080
2、使用声明式接口创建资源
ingress]# kubectl apply -f eshop-ingress-tomcat-pod.yaml
ingress.extensions/tomcat-ingress created
3、查看已经创建的ingress资源
[root@k8s ingress]# kubectl get ingress -n eshop
NAME CLASS HOSTS ADDRESS PORTS AGE
tomcat-ingress <none> www.daizhe.net.cn 80 40s
[root@k8s ingress]# kubectl get ingress -n eshop -o wide
NAME CLASS HOSTS ADDRESS PORTS AGE
tomcat-ingress <none> www.daizhe.net.cn 80 46s
[root@k8s ingress]# kubectl describe ingress tomcat-ingress
Error from server (NotFound): ingresses.extensions "tomcat-ingress" not found
[root@k8s ingress]# kubectl describe ingress tomcat-ingress -n eshop
Name: tomcat-ingress
Namespace: eshop
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
www.daizhe.net.cn
/eshop tomcat-svc:8080 (10.244.1.40:8080,10.244.2.24:8080)#可以查看到对 www.daizhe.net.cn/eshop 地址的访问都会被映射到后端tomcat-svc的service的8080端口响应
# 可以查看到service四层代理的后端 pod有10.244.1.40:8080,10.244.2.24:8080
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 99s nginx-ingress-controller Ingress eshop/tomcat-ingress
4、连接ingress-controller验证
# 手动连入ingress-controller查看配置文件
ingress]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-5bb8fb4bb6-q5lpg 1/1 Running 0 4h50m
[root@k8s ingress]# kubectl exec -it nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx -- /bin/sh
...
## start server www.daizhe.net.cn
server {
server_name www.daizhe.net.cn ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
location ~* "^/eshop" {
set $namespace "eshop";
set $ingress_name "tomcat-ingress";
set $service_name "tomcat-svc";
set $service_port "8080";
set $location_path "/eshop";
rewrite_by_lua_block {
lua_ingress.rewrite({
force_ssl_redirect = false,
ssl_redirect = true,
force_no_ssl_redirect = false,
use_port_in_redirects = false,
})
balancer.rewrite()
plugins.run()
}
...
5、访问验证。由于上面ingress定义的- host: www.daizhe.net.cn/eshop:32145,需要再(本机电脑)宿主机上添加解析测试
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 daizhe.com
192.168.20.236 192.168.20.212 192.168.20.214 www.daizhe.net.cn
# 访问: http://{ingress.host}:{ingress-controller.控制器-Port.service}
# 查看ingress-controller.控制器-Port.service
~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress NodePort 10.98.225.170 <none> 80:32145/TCP,443:31430/TCP 4h23m
- tomcat中很多资源路径无法找到(问题是修改了location)
# 最好不修改location
ingress]# kubectl delete -f eshop-ingress-tomcat-pod.yaml
ingress.extensions "tomcat-ingress" deleted
ingress]# cat eshop-ingress-tomcat-pod.yaml
# 定义ingress资源所属群组名称以及版本
apiVersion: extensions/v1beta1
# 定义资源类型
kind: Ingress
# 元数据
metadata:
# 定义Ingress名称
name: tomcat-ingress
# 定义名称空间
namespace: eshop
# 定义资源注解
annotations:
# url重定向--> 非主要无需关注
nginx.ingress.kubernetes.io/rewrite-target: /
# ingress类型为nginx
kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
# 定义代理规则
rules:
# 定义虚拟主机名称,不写默认为localhost
- host: www.daizhe.com
http:
paths:
# Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
- path: /
# backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port)
backend:
# ingress代理的server名称,之前创建的service为myapp
serviceName: tomcat-svc
# service和pods映射的端口(service-->sepc.ports.port)--> 虽然tomcat-svc的service与pod映射了两个端口但是nginx是不支持ajp协议所以仅暴漏一个
servicePort: 8080
向往的地方很远,喜欢的东西很贵,这就是我努力的目标。