• 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上,引发错误。

  • 相关阅读:
    7.9 C++ STL算法
    7.8 C++容器适配器
    7.7 C++基本关联式容器
    Django项目静态文件加载失败问题
    Centos6.5安装mysql5.7详解
    使用Xshell上传下载文件
    linux中MySQL本地可以连接,远程连接不上问题
    Linux常用命令
    Linux环境安装python3
    python 字符串最长公共前缀
  • 原文地址:https://www.cnblogs.com/TopGear/p/16339823.html
Copyright © 2020-2023  润新知