Kubernetes 权威指南 - 深入掌握Service

1. Service 定义详情

YAML 格式的Service 定义文件的完整内容如下:

apiVersion: v1			// Required
kind: Service			// Required
metadata:
	name: string		// Required
	namespace: string	// Required
	labels:
		- name: string
	annotations:
		- name: string
spec:					// Required
	selector: []		// Required
	type: string		// Required
	clusterIP: string
	sessionAffinity: string
	ports:
		- name: string
		  protocol: string
		  port: int
		  targetPort: int
		  nodePort: int
    status:
    	loadBalancer:
    		ingress:
    			ip: string
    			hostname: string

下表对Service的定义文件模板的各属性的说明:

属性名称 取值类型 是否必选 取值说明
apiVersion string Required v1
kind string Required Service
metadata object Required 元数据
metadata.name string Required Service名称,需符合RFC1035规范
metadata.namespace string Required 命名空间,不指定系统时将使用名为default的命名空间
metadata.labels[] list - 自定义标签属性列表
metadata.annotations[] list - 自定义注解属性列表
spec object Required 详细描述
spec.selector[] list Required Label Selector配置,将选择具有指定Label标签的Pod作为管理范围
spec.type string Required Service的类型,指定Service的访问方式,默认值为ClusterIP
1. ClusterIP:虚拟的服务IP地址,该地址用于Kubernetes集群内部的Pod访问,在Node上kube-proxy通过设置的iptables规则进行转发。
2. NodePort:使用宿主机的端口,使能够访问各Node的外部客户端通过Node的IP地址和端口号就能访问服务。
3. LoadBalancer:使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer字段指定外部负载均衡器的IP地址,并同时定义nodePortclusterIP,用于公有云环境。
spec.clusterIP string - 虚拟服务IP地址,当type=ClusterIP时,如果不指定,则系统进行自动分配,也可以手工指定;当type=LoadBalancer时,则需要指定
spec.sessionAffinity string - 是否支持Session,可选值为ClusterIP,默认值为空。
ClientIP:表示将同一个客户端的访问请求都转发到同一个后端Pod
spec.ports[] list - Service 需要暴露的端口列表
spec.ports[].name string - 端口名称
spec.ports[].protocol string - 端口协议,支持TCP和UDP,默认值为TCP
spec.ports[].port int - 服务监听的端口号
spec.ports[].targetPort int - 需要转发到后端 Pod 的端口号
spec.ports[].nodePort int - spec.type=NodePort时,需要指定映射到物理机的端口号
Status object - spec.type=LoadBalancer时,设置外部服负载均衡器的地址,用于公有云环境
staus.loadBalancer object - 外部负载均衡器
status.loadBalancer.ingress object - 外部负载均衡器
status.loadBalancer.ingress.ip string - 外部负载均衡器
status.loadBalancer.ingress.hostname string - 外部负载均衡器

2. Service 的基本用法

一般来说,容器应用都是通过TCP/IP机制及监听IP和端口号来实现。

# cat > webapp-rc.yaml << EOF
---
apiVersion: v1
kind: ReplicationController
metadata:
	name: webapp
spec:
	replicas: 2
	template:
		metadata:
			name: webapp
			labels:
				app: webapp
		spec:
			containers:
				- name: webapp
				  image: tomcat
				  ports:
				  	- containerPort: 8080
EOF

创建该 RC:

# kubectl create -f webapp-rc.yaml

获取 Pod 的 IP 地址:

# kubectl get pods -l app=webapp -o yaml | grep podIP

那么就可以直接通过这两个Pod的IP地址和端口号访问Tomcat服务。

直接通过Pod的IP地址和端口号可以访问到容器应用内的服务,但是Pod的IP地址是不可靠的,例如当Pod所在的Node发生故障时,Pod将被Kubernetes重新调度到另一台Node,Pod的IP地址将发生变化。

如果容器应用本身是分布式的部署,通过多个实例共同提供服务,就需要在这些实例的前端设置一个负载均衡器来实现请求分发。 Kubernetes中的Service就是用于解决这个问题的核心组件。

方式一:Kubernetes提供了一种快速的方法,即通过kubectl expose命令来创建Service

# kubectl expose rc webapp
service "webapp" exposed

# kubectl get svc

那么,接下来就可以通过Service的IP地址和Service的端口号访问该Service了。

方式二:除了使用kubectl expose命令创建service,我们也可以通过配置文件定义Service,再通过kubectl create命令进行创建:

# cat > webapp_service.yaml << EOF
---
apiVersion:v1
kind: Service
metadata:
    name: webapp
spec:
    ports:
        - port: 8081
          targetPort: 8080
    selector:
        app: webapp
EOF

其中,Service定义中的关键字段是protsselectorselector定义部分设置的是后端Pod所拥有的label: app=webapp


目前 Kubernetes 提供了两种负载分发策略:RoundRobinSessionAffinity,具体说明如下:

  • RoundRobin:轮询模式,即轮询将请求转发到后端的各个Pod上。 默认策略
  • SessionAffinity:基于客户端IP地址进行会话保持的模式,相同的客户端发起的请求都将被转发到后端相同的Pod上。

默认采用RoundRobin轮询模式进行负载分发,但是也可以通过设置service.spec.sessionAffinity=ClientIP来启用SessionAffinity策略。


2.1 多端口 Service

在Service的定义中也可以设置多个端口。

....
    ports:
        - port: 8081
          targetPort: 8080
          name: web
        - port: 8005
          targetPort: 8005
          name: management
....

2.2 外部服务 Service

我们可以将 Service 的标签选择器设置为空,再手动创建一个EndPoints资源与之绑定。

kind: Service
apiVersion: v1
metadata:
	name: my-service
spec:
	ports:
		- protocol: TCP
		  port: 80
		  targetPort: 80

通过该定义创建的是一个不带标签选择器的Service,即无法选择后端的Pod,系统不会自动创建Endpoint,因此需要手动创建一个和该Service同名的Endpoint,用于指向实际的后端访问地址。
创建Endpoint的配置文件内容如下:

kind: Endpoints
apiVersion: v1
metadata:
	name: my-service
subsets:
	- addresses:
		- IP: 1.2.3.4
	  ports:
	  	- port: 80

如此依赖,访问该Service将会被路由到由用户自定义的后端Endpoint上。

Headless Service

即不为Service设置ClusterIP(入口IP地址),仅通过Label Selector将后端的Pod列表搜返回给调用的客户端。

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels: null
app: nginx
spec:
  ports:
    - port: 80
  ClusterIP: None
  selector:
    app: nginx

Service就不再具有一个特定的ClusterIP地址,对其进行访问降火的包含Label "app=nginx"的全部Pod IP列表。

从集群外部访问Pod或Service

可以将PodService的端口号映射到宿主机,以使客户端应用能够通过物理机访问容器应用。

1. 单一容器级别的 hostPort 设置

---
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  containers:
    - name: webapp
      image: tomcat
      ports:
        - containerPort: 8080
          hostPort: 8081		// 这里设置单一容器级别的 hostPort 端口

2. Pod级别的 hostNetwork 设置

通过设置Pod级别的hostNetwork=true,该Pod中的所有容器的端口号都将被直接映射到物理机上。

在这是hostNetwork=true时需要注意,在容器的ports定义部分如果不指定hostPort,则默认hostPort等于containerPort
如果指定了hostPort,则该hostPort必须等于containerPort的值:

apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  hostNetwork: true				// 这里设置Pod级别的 hostNetwork 
  containers:
    - name: webapp
      image: tomcat
      ports:
        - containerPort: 8080

将 Service 通过 nodePort 方式将端口号映射到物理机

  1. 通过设置nodePort映射到物理机,同时设置Service的类型为NodePort
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: NodePort		// type设置为 NodePort
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 8081	// 设置 nodePort 端口,将所有节点上的该端口映射到该Service
  selector:
    app: webapp

外部子系统通过该集群内所有 Node 节点的该端口,即可访问到该 Service 。

  1. 通过设置 LoadBalancer 映射到云服务商提供的 LoadBalancer 地址。 这种做法仅用于在公有云服务提供商的云平台上设置 Service 的场景。
    以下示例,对该Service的访问请求将会通过LoadBalancer转发到后端Pod上,负载分发的实现方式则依赖于云服务提供商的LoadBalancer 的实现机制:
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: LoadBalancer			// type设置为LoadBalancer
  loadBalancerIP: 78.11.24.19	// 设置集群的LoadBalancerIP
  clusterIP: 10.0.171.239
  ports:
    - port: 80
      targetPort: 9376
      nodePort: 30061
  selector:
    app: webapp
status:
  loadBalancer:
    ingress:
      - ip: 146.148.47.155		// 将会设置为云服务提供商提供的LB IP地址

DNS 服务搭建和配置指南

KubeDNS

KubeDNS 由 3 个容器组成:kubednsdnsmasqsidecar,将DNS记录直接保存在内存中,以提高查询性能。
kubedns容器监控Kubernetes中Service资源的变化,根据Service的名称和IP地址生成DNS记录,并将DNS记录保存在内存中;dnsmasq容器从kubedns中获取DNS记录,提供DNS缓存,为客户端容器应用提供DNS查询服务;sidecar提供对kubednsdnsmasq服务的健康检查功能。
9704ffc23165cd8ce7094b9ea5bffc0e.png

CoreDNS

从 Kubernetes 1.11 版本开始,Kubernetes集群的DNS服务由 CoreDNS 提供。 CoreDNS是 CNCF基金会的一个项目,是用 Go 语言实现的高性能、插件式、以扩展的DNS服务端。 CoreDNS解决了KubeDNS的一些问题,例如dnsmasq的安全漏洞、externalName不能使用stubDomains设置,等等。

CoreDNS支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS。

CoreDNS 没有使用多个容器的架构,只用一个容器便实现了 KubeDNS 内 3 个容器的全部功能。
image.png

在创建 DNS 服务之前修改每个 Node 上的 kubelet 的启动参数

修改每个kubelet的启动参数,加上以下两个参数:

--cluster-dns=clusterIP  #clusterIP是具体配置的k8s可用的ip地址
--cluster-domain=cluster.local #配置DNS服务中设置的域名

修改启动参数可在:10-kubeadm.conf 或在kubelet其他加载的配置文件中添加配置(比如1.18的, /etc/sysconfig/kubelet)

使用kubeadm安装的集群,可以在/var/lib/kubelet/config.yaml修改clusterDNS的地址信息,以及clusterDomain的域名信息。

配置完之后重启kubelet服务。

创建 CoreDNS 应用

在部署 CoreDNS 应用前,至少需要创建一个 ConfigMap、一个Deployment和一个Service共3个资源对象。
在启用了 RBAC 的集群中,还可以设置 ServiceAccountClusterRoleClusterRoleBinding对CoreDNS容器进行权限设置。

CoreDNS 的配置说明

CoreDNS 的主要功能是通过插件系统实现的。 CoreDNS 实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。

常用插件如下:

  • loadbalance:提供基于 DNS 的负载均衡功能。
  • loop:检测在 DNS 解析过程中出现的简单循环问题。
  • cache:提供前端缓存功能。
  • health:对 Endpoint 进行健康检查。
  • kubernetes:从 Kubernetes 中读取 zone 数据。
  • etcd:从 etcd 中读取 zone 数据,可以用于自定义域名记录。
  • file:从 RFC1035 格式文件中读取 zone 数据。
  • hosts:使用 /etc/hosts 文件或其他文件读取 zone 数据,可以用于自定义域名记录。
  • auto:从磁盘中自动加载区域文件。
  • reload:定时自动加载 Corefile 配置文件的内容。
  • forward:转发域名查询到上游 DNS 服务器。
  • proxy:转发特定的域名查询到多个其他 DNS 服务器,同时提供到多个 DNS 服务器的负载均衡功能。
  • prometheus:为 Promethus 系统提供采集性能指标数据的 URL。
  • pprof:在 URL 路径 /debug/pprof 下提供运行时的性能数据。
  • log:对 DNS 查询进行日志记录。
  • errors:对错误信息进行日志记录。

例如使用 file 插件配置自定义域解析
(1). 编辑deployment 定义 zone 文件挂载路径(注意CoreDNS pod所在的每一个宿主机都需要有该文件)

      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: Corefile
            path: Corefile
          name: coredns
        name: config-volume
      - hostPath:
          path: /tmp/test.org.zone   // 宿主机上zone文件存放的位置
          type: FileOrCreate		// 如果不存在该文件,则默认创建空白文件
        name: test-zone

(2). 编辑 deployment 定义 zone 文件的容器挂载位置

        volumeMounts:
        - mountPath: /etc/coredns
          name: config-volume
          readOnly: true
        - mountPath: /tmp/test.org.zone   // 在容器内部的挂载路径
          name: test-zone
          readOnly: true

(3). 编辑 ConfigMap 配置文件,添加自定义域的解析规则

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
    test.org:53 {                 // 添加自定义域的转发规则
        file /tmp/test.org.zone   // 使用 file 插件读取 zone 文件
    }

(4). 添加 zone 文件权威域的解析记录(默认动态加载)

$ORIGIN test.org.
@   3600   IN   SOA    ns1.test.org.   mail.test.org. (
    2022051501
    20M
    5M
    5D
    1D
)
@    86400  IN  NS   ns1.test.org.
     3600   IN  NS   ns2.test.org.

www IN  A   1.1.1.1
    IN  TXT "Hello"

(5). 测试

##### 获取 kube-dns 的 svc IP地址
# kubectl get svc kube-dns -n kube-system

##### 开始解析
# dig www.test.org @10.96.0.10

例如使用 etcd 插件配置自定义域解析
(1). 编辑 deployment 定义etcd所使用的证书文件挂载路径

        volumeMounts:
        - mountPath: /etc/coredns
          name: config-volume
          readOnly: true
        - mountPath: /server.crt   // 挂载到根路径
          name: etcd-cert
          readOnly: true
        - mountPath: /server.key
          name: etcd-key
          readOnly: true
        - mountPath: /ca.crt
          name: etcd-ca
          readOnly: true

      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: Corefile
            path: Corefile
          name: coredns
        name: config-volume
      - hostPath:
          path: /etc/kubernetes/pki/etcd/server.crt
          type: FileOrCreate
        name: etcd-cert
      - hostPath:
          path: /etc/kubernetes/pki/etcd/server.key
          type: FileOrCreate
        name: etcd-key
      - hostPath:
          path: /etc/kubernetes/pki/etcd/ca.crt
          type: FileOrCreate
        name: etcd-ca

(2). 编辑 coredns 的 configmap 配置文件,添加 etcd 插件的配置

        etcd test2.com {
          path /test2_dns_test
          endpoint http://192.168.22.210:2379
          tls /server.crt /server.key /ca.crt
          fallthrough
        }

其中,tls指令需要根据先后顺序依次指定服务端证书服务端私钥自签ca证书
参考文档链接:https://coredns.io/plugins/etcd/#syntax

(3). 在 etcd 库中添加解析记录

kubectl exec -n kube-system etcd-k8s01.localdomain -it -- etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key put /test2_dns_test/com/test2/www '{"host": "2.2.2.2", "ttl": 60}'

注意:这里需要指定证书路径。

(4). 开始测试。
这部分暂未达成。跳过。


Pod 级别的 DNS 配置说明

除了使用集群范围的 DNS 服务(比如CoreDNS),在Pod级别也能设置DNS的相关策略和配置。
在 Pod 的 YAML 配置文件中通过spec.dnsPolicy字段设置 DNS 策略。

可选取值如下:

  • Default:继承Pod所在宿主机的DNS设置。
  • ClusterFirst:优先使用Kubernetes环境的DNS服务,将无法解析的域名转发到从宿主机继承的DNS服务器。
  • ClusterFirstWithHostNet:与ClusterFirst相同,对于以hostNetwork模式运行的Pod,应明确指定使用该策略。
  • None:忽略Kubernetes环境的DNS配置,通过spec.dnsConfig自定义DNS配置。 该选项在 1.14 版本升级为稳定版。

自定义DNS配置可以通过 spec.dnsConfig 字段设置:

  • nameservers:一组DNS服务器的列表,最多可以设置3个。
  • searches:一组用于域名搜索的DNS域名后缀,最多可以设置6个。
  • options:配置其他可选DNS参数,例如ndotstimeout等,以namename/value对的形式表示。
    以下是dnsConfig为例:
apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsPolicy: None
  dnsConfig:
    nameservers:
      - 1.2.3.4
    searches:
      - ns1.svc.cluster.local
      - my.dns.search.suffix
    options:
      - name: ndots
        value: '2'
      - name: edns0

该 Pod 被成功创建之后,容器内的DNS配置文件/etc/resolv.conf的内容将被系统设置为:

nameserver:  1.2.3.4
search ns1.svc.cluster.local my.dns.search.suffix
options ndots:2 edns0

表示该 Pod 完全使用自定义的 DNS 配置,不再使用 Kubernetes 环境的 DNS 服务。


Ingress: HTTP 7层路由机制

从 Kubernetes 1.1 开始新增 Ingress 资源对象,用于将不同的URL的访问请求转发到后端不同的 Service,以实现 HTTP 层的业务路由机制。
Kubernetes 使用了一个 Ingress 策略定义和一个具体的 Ingress Controller,两者结合实现了一个完整的 Ingress 负载均衡器。

使用 Ingress 进行负载分发时,Ingress Controller 基于 Ingress 规则将客户端请求直接转发到 Service 对应的后端 Endpoint(Pod) 上,这样会跳过kube-proxy的转发功能,kube-proxy不再起作用。

为使用 Ingress,需要创建 Ingress Controller(带一个默认backend服务)和Ingress策略设置来共同完成。 下面通过一个例子分三步说明 Ingress Controller 和 Ingress 策略的配置方法,以及客户端如何访问 Ingress 提供的服务。

创建 Ingress Controller 和默认的 backend 服务

在 Kubernetes 中,Ingress Controller 将以 Pod 的形式运行,监控 APIServer/ingress接口后端的backend services,如果Service发生变化,则Ingress Controller应自动更新其转发规则。

下面的例子使用 Nginx 来实现一个 Ingress Controller,需要实现的基本逻辑如下:

  1. 监听 API Server,获取全部 Ingress 的定义。
  2. 基于 Ingress 的定义,生成 Nginx 所需的配置文件/etc/nginx/nginx.conf
  3. 执行 nginx -s reload命令,重新加载nginx.conf配置文件的内容。

这里使用谷歌提供的nginx-ingress-controller镜像来创建Ingress Controller。 该Ingress Controller以 DaemonSet 的形式进行创建,在每个 Node 上都将启动一个 Nginx 服务。

这里为Nginx容器设置了hostPort,将容器应用监听的80和443端口号映射到物理机上,是的客户端应用可以通过常见形式的 URL 地址来访问该 Ingress Controller。 这使得 Nginx 类似于通过 NodePort 映射到物理机的 Service,成为替代kube-proxy的 HTTP 层的 LoadBalancer:

以下为 ingress_deploy_aliyun.yaml 配置文件。

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx
  namespace: ingress-nginx
automountServiceAccountToken: true
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  allow-snippet-annotations: 'true'
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
  name: ingress-nginx
rules:
  - apiGroups:
      - ''
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
      - namespaces
    verbs:
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ''
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingressclasses
    verbs:
      - get
      - list
      - watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
  name: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx
subjects:
  - kind: ServiceAccount
    name: ingress-nginx
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx
  namespace: ingress-nginx
rules:
  - apiGroups:
      - ''
    resources:
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ''
    resources:
      - configmaps
      - pods
      - secrets
      - endpoints
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ''
    resources:
      - configmaps
    resourceNames:
      - ingress-controller-leader
    verbs:
      - get
      - update
  - apiGroups:
      - ''
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ''
    resources:
      - events
    verbs:
      - create
      - patch
---
# Source: ingress-nginx/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx
subjects:
  - kind: ServiceAccount
    name: ingress-nginx
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller-admission
  namespace: ingress-nginx
spec:
  type: ClusterIP
  ports:
    - name: https-webhook
      port: 443
      targetPort: webhook
      appProtocol: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ipFamilyPolicy: SingleStack
  ipFamilies:
    - IPv4
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
      appProtocol: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
      appProtocol: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/component: controller
  revisionHistoryLimit: 10
  minReadySeconds: 0
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/component: controller
    spec:
      dnsPolicy: ClusterFirst
      containers:
        - name: controller
          image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1
          imagePullPolicy: IfNotPresent
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown
          args:
            - /nginx-ingress-controller
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
            - --election-id=ingress-controller-leader
            - --controller-class=k8s.io/ingress-nginx
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
            - --validating-webhook=:8443
            - --validating-webhook-certificate=/usr/local/certificates/cert
            - --validating-webhook-key=/usr/local/certificates/key
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            runAsUser: 101
            allowPrivilegeEscalation: true
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: LD_PRELOAD
              value: /usr/local/lib/libmimalloc.so
          livenessProbe:
            failureThreshold: 5
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
            - name: webhook
              containerPort: 8443
              protocol: TCP
          volumeMounts:
            - name: webhook-cert
              mountPath: /usr/local/certificates/
              readOnly: true
          resources:
            requests:
              cpu: 100m
              memory: 90Mi
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
        - name: webhook-cert
          secret:
            secretName: ingress-nginx-admission
---
# Source: ingress-nginx/templates/controller-ingressclass.yaml
# We don't support namespaced ingressClass yet
# So a ClusterRole and a ClusterRoleBinding is required
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: nginx
  namespace: ingress-nginx
spec:
  controller: k8s.io/ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
# before changing this value, check the required kubernetes version
# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  name: ingress-nginx-admission
webhooks:
  - name: validate.nginx.ingress.kubernetes.io
    matchPolicy: Equivalent
    rules:
      - apiGroups:
          - networking.k8s.io
        apiVersions:
          - v1
        operations:
          - CREATE
          - UPDATE
        resources:
          - ingresses
    failurePolicy: Fail
    sideEffects: None
    admissionReviewVersions:
      - v1
    clientConfig:
      service:
        namespace: ingress-nginx
        name: ingress-nginx-controller-admission
        path: /networking/v1/ingresses
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress-nginx-admission
  namespace: ingress-nginx
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-nginx-admission
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
rules:
  - apiGroups:
      - admissionregistration.k8s.io
    resources:
      - validatingwebhookconfigurations
    verbs:
      - get
      - update
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ingress-nginx-admission
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx-admission
subjects:
  - kind: ServiceAccount
    name: ingress-nginx-admission
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ingress-nginx-admission
  namespace: ingress-nginx
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
rules:
  - apiGroups:
      - ''
    resources:
      - secrets
    verbs:
      - get
      - create
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ingress-nginx-admission
  namespace: ingress-nginx
  annotations:
    helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx-admission
subjects:
  - kind: ServiceAccount
    name: ingress-nginx-admission
    namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: ingress-nginx-admission-create
  namespace: ingress-nginx
  annotations:
    helm.sh/hook: pre-install,pre-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
spec:
  template:
    metadata:
      name: ingress-nginx-admission-create
      labels:
        helm.sh/chart: ingress-nginx-4.0.15
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/version: 1.1.1
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/component: admission-webhook
    spec:
      containers:
        - name: create
          image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
          imagePullPolicy: IfNotPresent
          args:
            - create
            - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
            - --namespace=$(POD_NAMESPACE)
            - --secret-name=ingress-nginx-admission
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          securityContext:
            allowPrivilegeEscalation: false
      restartPolicy: OnFailure
      serviceAccountName: ingress-nginx-admission
      nodeSelector:
        kubernetes.io/os: linux
      securityContext:
        runAsNonRoot: true
        runAsUser: 2000
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: ingress-nginx-admission-patch
  namespace: ingress-nginx
  annotations:
    helm.sh/hook: post-install,post-upgrade
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
spec:
  template:
    metadata:
      name: ingress-nginx-admission-patch
      labels:
        helm.sh/chart: ingress-nginx-4.0.15
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/version: 1.1.1
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/component: admission-webhook
    spec:
      containers:
        - name: patch
          image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
          imagePullPolicy: IfNotPresent
          args:
            - patch
            - --webhook-name=ingress-nginx-admission
            - --namespace=$(POD_NAMESPACE)
            - --patch-mutating=false
            - --secret-name=ingress-nginx-admission
            - --patch-failure-policy=Fail
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          securityContext:
            allowPrivilegeEscalation: false
      restartPolicy: OnFailure
      serviceAccountName: ingress-nginx-admission
      nodeSelector:
        kubernetes.io/os: linux
      securityContext:
        runAsNonRoot: true
        runAsUser: 2000

定义 Ingress 策略

本例对mywebsite.com网站的访问设置 Ingress 策略,定义对其/demo路径的访问转发到后端webapp Service 的规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mywebsite-test-ingress
spec:
  defaultBackend:
    service:
      name: nginx-svc
      port:
        number: 80
  rules:
    - host: test.com
      http:
        paths:
          - path: /demo
            pathType: Prefix
            backend:
              service:
                name: nginx-svc
                port:
                  number: 80

这个Ingress的定义,说明对目标地址http://mywebsite.com/demo的访问都将被转发到集群中的Service webapp即 webapp:8080/demo上。

在Ingress 生效之前,需要先将webapp服务部署完成。 否则需要注意Ingress中path的定义,需要与后端真实 Service 提供的 path 一致,否则将被转发到一个不存在的path上,引发错误。

posted @ 2022-06-03 12:21  Professor哥  阅读(108)  评论(0编辑  收藏  举报