一、上集回顾

  1、Service 3种模型:userspace,iptables,ipvs

  2、Service类型

    ClusterIP,NodePort

      NodePort:client -> NodeIP:NodePort -> ClusterIP:ServicePort -> PodIP:containerPort

      LoadBalancer

      ExternelName

    No ClusterIP: Hedless Service

      serviceName -> PodIP

二、ingress

  1、在客户端访问我们k8s服务时,四层调度器本身是没有办法解除ssl会话的,这就意味着客户端必须与后端服务器(pod)之间直接建立ssl会话,这里还有个显著的问题在于如果调度器在ssl会话建立以后的下一个请求被调度到第二台服务器上那么这个ssl还要重新建立,因此我们只要认为内部网络是安全的那么我们可以把会话在前端调度器上卸载,但是四层调度是不能卸载的,因此我们需要七层的负载均衡机制。因此如果他们是http服务我们又期望构建https,那么我们只需要他在互联网上这个不安全的网络中传输实现https,内网中使用http,因此我们需要使用卸载器,但是我们Service调度时,无论是iptables还是ipvs都只是四层调度,因此也就意味着如果你想要在k8s上运行一个应用基于https提供服务,我们就必须得在后端每一个pod上配置https,因为只有这样他们才会建立起https联系,所以我们现在也期望在接入那一层上就能够卸载ssl,向内部调度时就不再是ssl了。对这种需求,k8s采用一种很独特的方式来实现,我们在整个集群中,在进行调度时后端被代理的pod资源是不配置https的,就是明文的http,但是我使用一个独特的调度器(运行在pod中),对于此pod来讲,其是一个运行在七层(用户空间)的正常的应用程序,比如nginx,haproxy等,当用户试图访问某一服务时,我们不让他先去到达前端的service,而是先到这个pod,然后pod与pod之间不需要service而是直接通信来完成反向代理,我们用一个pod来反代至后端我们真正提供服务的pod,此前我们用service代理的,现在用pod,而这个pod如果需要被访问到那么还是需要经过service,因此客户端经过此pod的service调度以后,与我们专门配置了https的此pod进行交互,这里的service我们定义成nodePort,依然没有什么问题,依然老路径还是存在的,但是等到达这个pod以后由此pod直接代理至两个明文的pod,因此此pod就成为https的会话卸载器了。如果这种方式进行调度那么调度方式如下:  client --> LB --> nodePort --> service -->会话卸载器pod --> 后端pod  这种方式性能肯定会非常非常差,如图。

    

  2、其实我们还可以这样干,可以让我们pod直接共享我们节点的网络名称空间,于是,上述中的会话卸载器pod我们可以直接让他共享节点网络名称空间,这就意味着其监听着宿主机的地址,这样我们客户端的请求就可以之间到达这个pod,然后再由他进行调度。

    

  3、在一个节点上运行的容器,容器可以使用自己的虚拟网络,也可以共享宿主机的网络,如果这个容器共享宿主机的网络也就意味着这个容器内的进程一旦监听套接字时它监听的是宿主机的地址,相当于一个进程运行在宿主机上一样的,这样一来这个pod在每个节点上就只能运行一个了,一般来讲集群中只有一个,那么其只需要运行在集群的某一个节点即可,但是如果 监听在节点的端口时就会有问题,service时无论访问哪一个节点的端口都行,因为你访问哪一个节点的nodePort他都能通过它的ip地址送达到后端pod上,但是现在这个Pod要监听节点的网络名称空间,并且通过这个节点的网络名称空间直达这个pod,那么如果运行这种类型的pod那么就一定只能运行在一个节点上,访问时客户端就只能访问这个节点,并且如果这个节点挂了呢?

  4、要解决这个问题,我们可以用DaemonSet控制器,它可以在每个节点上都运行相应的pod 副本并且只运行一个,这样假如我们有三个节点那么我们三个节点上都可以运行这个pod。这样就都能实现代理和负载均衡,但是又回到了调度到哪一个节点都可以的问题,这样无论哪个节点挂掉了都还是可以访问到,但是如果我们有太多的节点那么每个节点都运行一个这样的pod就太占资源。daemonset还可以让pod运行在有限的节点的范围上(部分节点),于是再将来做k8s集群时可以这样干,比如我们有三千个节点,那么我们专门拿三个节点出来做pod的接入式的负载均衡的专用主机,并且给这三个节点打上污点让其它pod无法调度上来,然后我们就定义这个DaemonSet控制器上的pod只运行在这三个节点上各自运行一份并且能容忍这些污点,所以这三个主机在集群中只允许这一个类型的pod,专门负责为集群接入外部的七层调度的流量。而这个pod在k8s中有个专门的称呼叫 Ingress Controller。这个Ingress Controller比较独特,之前讲的DaemonSet,deployment,replacSet等控制器都不一样,DaemonSet deployment,replaciSet等等都是作为Controller manager的一部分存在,众多控制器都是作为Controller manager的一个子组件作为其组成部分组成的。而Ingress Controller却是自己独立运行的一个或一组pod资源,它通常就是一个应用程序,这个应用程序就是拥有七层代理能力和调度能力的应用程序,目前k8s上的选择有四种,其中最不受待见的就是Haproxy,一般默认是nginx,现在在服务网格中大家比较倾向Envoy,当然还有其它与nginx相竞争的据说本来就是为微服务而生的Traefik,所以用Ingress Controller时会发现我们有三种选择:

    a、nginx:这是后来改造的

    b、Traefik:这种设计就是为微服务这种动态生成而生的

    c、Envoy :去做微服务的大家都比较倾向于Envoy

    

  5、作为调度器,有时候要调度不只一个后端服务,假如有一个调度器pod,后端有一组pod提供电商服务,第二组pod提供了社交服务,第三组pod提供了论坛服务,第四组pod提供了网关服务。那么我们这四组http服务怎么能够分别调度呢?

    

    a、从nginx的角度来讲,接入服务端时我们通过uptream_server即可,但是接入客户端时我们应该如何标识这四种不同的请求呢,首先我们可以在nginx上做四个虚拟主机,在四个主机名上做四个主机,每一个主机名对应一组后端的pod。那万一我们没那么多主机名呢?此时我们可以通过不同的路径来做url映射,然后每一组路径就映射到一组后端pod上,但是pod存在生命周期,随时都可能挂掉替换为一个新pod,新pod的ip就会变了,另外我们pod的应用的规模也可以动态伸缩的,我们简单改一下副本数其数量也会变,这种一变前面代理的配置也就无效了,我们service通过关联标签来解决这个问题,而且service随时 watch着api server上的api时刻来关注自己关联的slector的资源是否变动了,只要变动我们api server就会立即通知service然后service立即改变。 所以service通过label selector始终关联着对应label能适配的后端pod,无论怎么变都能应付而且能及时作出反应,那么此处nginx运行在pod中也就意味着这个配置是在pod内部并且后端pod随时还会发生变动,Ingress 也会时刻watch着api 中的后端pod资源的改变。那它怎么知道这是哪个pod资源呢?Ingress Controller自己没有这个能力,它并不知道目前符合自己条件关联的被代理的pod资源有哪些,它必须借助于service来实现,我们要想定义一个这种调度能力功能其实还是需要建service,这个service通过label selector关联至后端的pod上来,但这个service不是被当做被代理时的中间节点,它仅仅是帮忙分类的,这个service 关联了几个pod那么我们就将这几个pod配置写在这个upstream中,调度时是不会经过service的,service在此处仅仅是帮忙分组的,分完组以后我们需要得到的也不是service的IP,而是pod的ip,因此此时可以使用headless service,但是这个service却没有用,是不是headless都无所谓,它只要帮忙完成分组知道找哪几个pod就可以了,pod一变,service对应的资源也就变了,问题是变了后这个结果怎么反应到这个配置文件中来,此时需要依赖于一个专门的资源 Ingress。

  6、在k8s上有一种特殊的资源叫Ingress,Ingress 和Ingress Controller是两回事,我们定义一个Ingress 时就是说了它其实就是定义我们期望这个Ingress Controller是如何给我们建一个前端(可能是一个虚拟主机,也可能是一个url映射)接入层,同时又给我们定义一个后端upstream_server,这个upstream_server中有几个主机 Ingress是通过这个service 得到的,并且Ingress有一个特点,作为资源来讲他可以通过编辑注入到Ingress Controller里面来,直接把它注入并保存为配置文件,而且一旦Ingress发现Service选定的后端的pod资源发生改变了,这个改变一定会及时返回到Ingress中,这个Ingress会及时注入到这个前端调度器pod中,就是注入到upstream配置文件中,而且还能触发这个pod中的主容器中的进程重载配置文件。所以我们要想使用这个功能我们需要在集群中:

    a、要有个service去对后端某一个特定类型的pod资源进行分类,这个service只是起分类作用的。

    b、Ingress基于这个分类识别出有几个pod,并且识别其ip地址是什么,并且将这个ip地址返回的结果生成配置信息注入到upstream_server(以nginx为例),但是nginx又不是特别适用这个场景,每次变动都在重载,如果是Traefik和Envoy 等天生就是为这种场景而生的,只要动了就加载生效,不需要重载。(它可以监控这个配置文件发生变化,只要发生变化就会动态重载)。

  7、如果我们想要使用代理,我们应该怎么做?

    a、需要先部署一个Ingress Controller,然后部署一个pod进来,这个pod可能本来是空的,没有什么有效的东西,接下来我们要根据自己的需要 通过虚拟主机的方式或者通过url代理的方式来配置一个前端,然后再根据我们Service收集到的后端pod的IP定义成upstream_server,把这些信息反应在Ingress当中由Ingress动态注入到Ingress Controller中才可以

    

    

    b、从图中我们可以看到,当访问我们服务时首先由外部的负载均衡器将请求调度到我们nodePort的Service上,而nodePort上的Service再将请求调度至我们内部的一个pod 叫IngressController上来,Ingress Controller根据Ingress中的定义(虚拟主机或url),每一个主机名对应后面的一组pod资源(通过service分组),因此此处用到两组Service,第一个Service是帮集群接入外部流量的(当然也可以不用,可以把这个Ingress Controller pod运行为共享网络节点网络名称空间方式并且将其定义为Dameset方式运行在特定节点上就可以了),那么我们在定义pod资源时只需要在pod的一个配置选项中加入hostnetwork即可。第二个Service只用来做pod归组不被调度时使用。

    c、接下来我们要使用ingress的功能得先去安装部署Ingress Controller 这个pod,而后再定义Ingress,而后再定义后端pod生成Service,然后再建立关联关系。

三、Ingress 定义

  1、Ingress 也是标准的kubernetes资源对象,因此也拥有相应的对象属性。

[root@k8smaster ~]# kubectl explain ingress.spec
KIND: Ingress
VERSION: extensions/v1beta1 RESOURCE: spec <Object> DESCRIPTION:
Spec is the desired state of the Ingress. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status IngressSpec describes the Ingress the user wishes to exist. FIELDS:
backend <Object> #定义后端主机,定义后端有哪几个pod,其属性有serviceName和sericePort
A default backend capable of servicing requests that don't match any rule.
At least one of 'backend' or 'rules' must be specified. This field is
optional to allow the loadbalancer controller or defaulting logic to
specify a global default. rules <[]Object> #定义规则,分为主机和http,http又有paths路径定义调度到哪儿去。 (即主机调度和路径调度两种方式)
A list of host rules used to configure the Ingress. If unspecified, or no
rule matches, all traffic is sent to the default backend. tls <[]Object>
TLS configuration. Currently the Ingress only supports a single TLS port,
. If multiple members of this list specify different hosts, they will be
multiplexed on the same port according to the hostname specified through
the SNI TLS extension, if the ingress controller fulfilling the ingress
supports SNI.
[root@k8smaster ~]# kubectl explain ingress.spec.backend
KIND: Ingress
VERSION: extensions/v1beta1 RESOURCE: backend <Object> DESCRIPTION:
A default backend capable of servicing requests that don't match any rule.
At least one of 'backend' or 'rules' must be specified. This field is
optional to allow the loadbalancer controller or defaulting logic to
specify a global default. IngressBackend describes all endpoints for a given service and port. FIELDS:
serviceName <string> -required- #backend正是靠我们service的定义来找到我们后端相关联的有哪几个pod资源的,一旦pod资源发生变化这个service就发生变化,service变化Ingress就变化,
Ingress变化就开始注入到Ingress Controller中去。
     Specifies the name of the referenced service.

   servicePort    <string> -required-
Specifies the port of the referenced service.

  2、部署Ingress,k8s集群由master,node和附件组成,一共有四个核心附件:

    a、dns

    b、Heapster

    c、Dashboard

    d、Ingress Controller

四、Ingress创建

  1、首先下载github上对应的yaml文件

[root@k8smaster ingress-nginx]# for file in namespace.yaml configmap.yaml rbac.yaml tcp-services-configmap.yaml with-rbac.yaml udp-services-configmap.yaml default-backend.yaml; \
> do wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.17.1/deploy/$file; done
...

  2、将下载yaml文件创建使用

[root@k8smaster ingress-nginx]# ls
configmap.yaml namespace.yaml rbac.yaml tcp-services-configmap.yaml udp-services-configmap.yaml with-rbac.yaml
[root@k8smaster ingress-nginx]# kubectl apply -f namespace.yaml
namespace/ingress-nginx created
[root@k8smaster ingress-nginx]# kubectl apply -f ./
configmap/nginx-configuration created
namespace/ingress-nginx configured
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
configmap/tcp-services created
configmap/udp-services created
deployment.extensions/nginx-ingress-controller created

  也可直接使用一次性部署yaml文件

  kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
[root@k8smaster ingress-nginx]# kubectl get pods -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
default-http-backend-846b65fb5f-ggwwp / Running 29m 10.244.1.77 k8snode1
nginx-ingress-controller-d658896cd-nqt4b / Running 2h 10.244.2.76 k8snode2

  3、尝试创建Ingress,为了让某个Ingress能显现真正的效果来我们要做一些前提准备,比如我们要部署几个后端被代理的应用

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations: #此属性至关重要,因为在annotations中我们必须指明ingress controller类型是nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort:

  4、直接部署在裸机上时要额外加上一项叫做service-nodeport.yaml,如果不加上这一项会发现ingress controller部署完以后在集群内部可以被访问,在集群外部是无法被访问到的,因为ingress controller无法接入外部的流量,如果要接入流量则需要再部署一个nodePort的service,或者也可以将ingress controller部署为直接共享节点网络名称空间的方式,但这个时候我们需要手动改造with-rbac.yaml这个文件中的kind 类型由Deployent改为DaemonSet,然后去掉replicas,然后在pod template上的spec中加一项hostnetwork用于共享宿主机的网络名称空间,当然需要保证监听的端口不被冲突。 

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
  5、接下来可以尝试使用ingress规则来应用
    a、首先创建一组应用pod和对应的service
[root@k8smaster ingress]# cat deploy-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
ports:
- name: http
targetPort:
port:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas:
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v2
ports:
- name: http
containerPort:

    b、创建nodePort service

[root@k8smaster ingress-nginx]# cat service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
type: NodePort
ports:
- name: http #服务为http
port: #service端口为80
targetPort: #容器端口为80
protocol: TCP
nodePort:
- name: https
port: #service 端口为443
targetPort: #容器端口为443
protocol: TCP
nodePort:
selector:
app: ingress-nginx
--- [root@k8smaster ingress-nginx]# kubectl apply -f ./
configmap/nginx-configuration unchanged
deployment.extensions/default-http-backend unchanged
service/default-http-backend unchanged
namespace/ingress-nginx configured
serviceaccount/nginx-ingress-serviceaccount unchanged
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole configured
role.rbac.authorization.k8s.io/nginx-ingress-role unchanged
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding unchanged
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding configured
service/ingress-nginx created
configmap/tcp-services unchanged
configmap/udp-services unchanged
deployment.extensions/nginx-ingress-controller unchanged

[root@k8smaster ingress]# kubectl get pods -n ingress-nginx -o wide --show-labels
  NAME READY STATUS RESTARTS AGE IP NODE LABELS
  default-http-backend-846b65fb5f-ggwwp 1/1 Running 1 1d 10.244.1.82 k8snode1 app=default-http-backend,pod-template-hash=4026219619
  nginx-ingress-controller-d658896cd-nqt4b 1/1 Running 22 1d 10.244.2.81 k8snode2 app=ingress-nginx,pod-template-hash=821445278

    此时访问我们节点端口显示  default backend - 404 ,此时表示我们调度器已经正常工作。

    c、此时将步骤a中创建的myapp Deploymet开始使用我们b中这个Service发布出去而不在我们里面同时创建的这个service上自己改成nodePort发布出去了

[root@k8smaster ingress]# cat ingress-myapp.yaml
apiVersion: extensions/v1beta1
Kind: Ingress
metadata:
name: ingress-myapp
namespaces: default
annotations: #进行说明我们接下来要用到的规则是nginx,就是靠annotations来识别类型的,只有进行注解了才能转化为对应的与controller相匹配的规则
kubernetes.io/ingress.class: "nginx"
spec:
rules: #定义把谁转到谁那儿去
- host: myapp.wohaoshuai.com #要确保在外部通过互联网访问时能解析此主机名,并且解析结果刚好能到达我们Service nodePort映射的主机上去
http: #定义前后端路径
paths: #不给默认为/
- path: #前端路径,空表示默认的/
backend: #匹配后端service
serviceName: myapp
servicePort: [root@k8smaster ingress]# kubectl apply -f ingress-myapp.yaml
ingress.extensions/ingress-myapp created
[root@k8smaster ingress]# kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-myapp myapp.wohaoshuai.com 10s
[root@k8smaster ingress]# kubectl describe ingress ingress-myapp
Name: ingress-myapp
Namespace: default
Address:
Default backend: default-http-backend: (<none>)
Rules:
Host Path Backends
---- ---- --------
myapp.wohaoshuai.com
myapp: (<none>)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-my
app","namespace":"default"},"spec":{"rules":[{"host":"myapp.wohaoshuai.com","http":{"paths":[{"backend":{"serviceName":"myapp","servicePort":80},"path":null}]}}]}}
kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 30s nginx-ingress-controller Ingress default/ingress-myapp

    d、上述创建完成的ingress一旦应用其会自动注入到ingress controller中去,也就是说其会自动转换成nginx的配置文件(从下面信息中可看到),访问myapp.wohaoshuai.com:30080即可

[root@k8smaster ingress]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
default-http-backend-846b65fb5f-ggwwp / Running 1h
nginx-ingress-controller-d658896cd-nqt4b / Running 4h
[root@k8smaster ingress]# kubectl exec -it nginx-ingress-controller-d658896cd-nqt4b /bin/bash -n ingress-nginx
www-data@nginx-ingress-controller-d658896cd-nqt4b:/etc/nginx$ ls
fastcgi.conf fastcgi_params.default koi-win mime.types.default nginx.conf owasp-modsecurity-crs template win-utf
fastcgi.conf.default geoip lua modsecurity nginx.conf.default scgi_params uwsgi_params
fastcgi_params koi-utf mime.types modules opentracing.json scgi_params.default uwsgi_params.default
www-data@nginx-ingress-controller-d658896cd-nqt4b:/etc/nginx$ cat nginx.conf|grep wohaoshuai
## start server myapp.wohaoshuai.com
server_name myapp.wohaoshuai.com ;
## end server myapp.wohaoshuai.com

    从上面配置文件中可以看出svc只是起到了识别后端pod信息的作用而不起调度作用

五、创建一个真正可用的ingress 实例

  1、我们现在做这么一个东西,本来我们起了两到三个tomcat pod,每个pod监听自己的8080和8009端口,因此我们在三个pod之前做一个Service作为一个固定访问端点代理,但是这个Service待会儿不会用到,它只是用来识别而已,我们Service对应的8080和8009端口对应后端pod的8080和8009端口。我们定义一个deployment来部署这三个tomcat,用来监听8080和8009端口,然后定义一个Service把8080和8009暴露出去,但是没有真正向集群外部暴露,因为其是cluster IP类型的,他只是用来被前端等会儿叫ingress  controller定义ingress规则向里面映射的时候所识别后端有哪几个Pod而已。

    

  2、创建Deployment 和 Service,然后创建ingress

[root@k8smaster ingress]# cat tomcat-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: tomcat
namespace: default
spec:
selector:
app: tomcat
release: canary
ports:
- name: http
targetPort:
port:
- name: ajp
targetPort:
port:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deploy
namespace: default
spec:
replicas:
selector:
matchLabels:
app: tomcat
release: canary
template:
metadata:
labels:
app: tomcat
release: canary
spec:
containers:
- name: myapp
image: tomcat:8.5.-jre8-alpine
ports:
- name: http
containerPort:
- name: ajp
containerPort: [root@k8smaster ingress]# kubectl apply -f tomcat-deploy.yaml
service/tomcat created
deployment.apps/tomcat-deploy created
[root@k8smaster ingress]# cat ingress-tomcat.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-tomcat
namespace: default
annotations: #进行说明我们接下来要用到的规则是nginx,就是靠annotations来识别类型的,只有进行注解了才能转化为对应的与controller相匹配的规则
kubernetes.io/ingress.class: "nginx"
spec:
rules: #定义把谁转到谁那儿去
- host: tomcat.wohaoshuai.com #要确保在外部通过互联网访问时能解析此主机名,并且解析结果刚好能到达我们Service nodePort映射的主机上去
http: #定义前后端路径
paths: #不给默认为/
- path: #前端路径,空表示默认的/
backend: #匹配后端service
serviceName: tomcat
servicePort: #我们没有指ingress所以默认ingress是80端口
[root@k8smaster ingress]# kubectl apply -f ingress-tomcat.yaml
ingress.extensions/ingress-myapp configured

    创建完成后在各节点host文件添加tomcat.lwohaoshuai.com解析访问 tomcat.wohaoshuai.com:30080即可

  3、如果我们想要创建https的虚拟主机就稍微要麻烦一点,第一,这个虚拟主机要工作为https服务的话在nginx上这个虚拟主机得是ssl虚拟主机配置为ssl虚拟主机则需要证书和私钥,而这个证书和私钥我们需要将其创建为特定格式才能提供给我们的ingress.那么现在我们做一组证书和私钥并且把它们作为一个独特的对象,这个叫secret。  

    a、创建私钥和证书

[root@k8smaster ingress]# openssl genrsa -out tls.key  #创建私钥
Generating RSA private key, bit long modulus
..+++
........................................+++
e is (0x10001)
[root@k8smaster ingress]# ls
deploy-demo.yaml ingress-myapp.yaml ingress-tomcat.yaml tls.key tomcat-deploy.yaml
[root@k8smaster ingress]# openssl req -new -x509 -key tls.key -out tls.crt(自签证书) -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.wohaoshuai.com(国家为CN,所在的省为北京,地址为北京,组织为DevOps,此外,证书中应该包含的名字应该和此前定义的域名一致,为tomcat.wohaoshuai.com) #创建自签证书
[root@k8smaster ingress]# ls
deploy-demo.yaml ingress-myapp.yaml ingress-tomcat.yaml tls.crt tls.key tomcat-deploy.yaml

    b、注意生成的证书是不能直接贴到nginx的pod中去的,我们需要把它先转成特殊格式,这个特殊格式叫secret,它也是标准的k8s集群对象,它可以直接注入到pod中被pod所引用。因此接下来我们需要把它做成secret

[root@k8smaster ingress]# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
secret/tomcat-ingress-secret created
[root@k8smaster ingress]# kubectl get secret
NAME TYPE DATA AGE
default-token-jvtl7 kubernetes.io/service-account-token 36d
tomcat-ingress-secret kubernetes.io/tls 15s
[root@k8smaster ingress]# kubectl describe secret tomcat-ingress-secret
Name: tomcat-ingress-secret
Namespace: default
Labels: <none>
Annotations: <none> Type: kubernetes.io/tls Data
====
tls.crt: bytes
tls.key: bytes

    c、创建完以后我们就可以拿这个secret在ingress.spec.rules中定义了

 

[root@k8smaster ingress]# kubectl explain ingress.spec.tls
KIND: Ingress
VERSION: extensions/v1beta1 RESOURCE: tls <[]Object> DESCRIPTION:
TLS configuration. Currently the Ingress only supports a single TLS port,
. If multiple members of this list specify different hosts, they will be
multiplexed on the same port according to the hostname specified through
the SNI TLS extension, if the ingress controller fulfilling the ingress
supports SNI. IngressTLS describes the transport layer security associated with an
Ingress. FIELDS:
hosts <[]string> #表示把哪个主机做成tls格式的
Hosts are a list of hosts included in the TLS certificate. The values in
this list must match the name/s used in the tlsSecret. Defaults to the
wildcard host setting for the loadbalancer controller fulfilling this
Ingress, if left unspecified. secretName <string> #用哪个secret来获取证书,私钥等相关信息
SecretName is the name of the secret used to terminate SSL traffic on .
Field is left optional to allow SSL routing based on SNI hostname alone. If
the SNI host in a listener conflicts with the "Host" header field used by
an IngressRule, the SNI host is used for termination and value of the Host
header is used for routing.
[root@k8smaster ingress]# kubectl apply -f ingress-tomcat-tls.yaml
ingress.extensions/ingress-tomcat-tls created
[root@k8smaster ingress]# cat ingress-tomcat-tls.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-tomcat-tls
namespace: default
annotations: #进行说明我们接下来要用到的规则是nginx,就是靠annotations来识别类型的,只有进行注解了才能转化为对应的与controller相匹配的规则
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- tomcat.wohaoshuai.com
secretName: tomcat-ingress-secret
rules: #定义把谁转到谁那儿去
- host: tomcat.wohaoshuai.com #要确保在外部通过互联网访问时能解析此主机名,并且解析结果刚好能到达我们Service nodePort映射的主机上去
http: #定义前后端路径
paths: #不给默认为/
- path: #前端路径,空表示默认的/
backend: #匹配后端service
serviceName: tomcat
servicePort: #我们没有指ingress所以默认ingress是80端口
[root@k8smaster ingress]# kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-myapp myapp.wohaoshuai.com 20h
ingress-tomcat tomcat.wohaoshuai.com 18h
ingress-tomcat-tls tomcat.wohaoshuai.com , 33s
[root@k8smaster ingress]# kubectl describe ingress ingress-tomcat-tls
Name: ingress-tomcat-tls
Namespace: default
Address:
Default backend: default-http-backend: (<none>)
TLS:
tomcat-ingress-secret terminates tomcat.wohaoshuai.com
Rules:
Host Path Backends
---- ---- --------
tomcat.wohaoshuai.com
tomcat: (<none>)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-to
mcat-tls","namespace":"default"},"spec":{"rules":[{"host":"tomcat.wohaoshuai.com","http":{"paths":[{"backend":{"serviceName":"tomcat","servicePort":8080},"path":null}]}}],"tls":[{"hosts":["tomcat.wohaoshuai.com"],"secretName":"tomcat-ingress-secret"}]}}
kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 1m nginx-ingress-controller Ingress default/ingress-tomcat-tls
[root@k8smaster ingress]# kubectl exec -it nginx-ingress-controller-d658896cd-nqt4b /bin/bash -n ingress-nginx
www-data@nginx-ingress-controller-d658896cd-nqt4b:/etc/nginx$ cat nginx.conf|grep ssl

      通过https://tomcat.wohaoshuai.com:30443访问即可。可以看到我们ssl主机建立起来了,但是我们后端pod并没有提供任何ssl功能

 

Kubernetes 学习11 kubernetes ingress及ingress controller的更多相关文章

  1. Kubernetes 学习15 kubernetes 认证及serviceaccount

    一.概述 1.通过此前描述可以知道k8s是以后运行我们生产环境中重要应用程序的尤其是无状态程序的一个非常重要的平台.这里面能托管一些核心应用以及核心数据,很显然对于k8s对应接口的访问不是任何人都可以 ...

  2. kubernetes学习01—kubernetes介绍

    本文收录在容器技术学习系列文章总目录 一.简介 1.Kubernetes代码托管在GitHub上:https://github.com/kubernetes/kubernetes/. 2.Kubern ...

  3. Kubernetes 学习5 kubernetes资源清单定义入门

    一.kubernetes是有一个restful风格的 API,把各种操作对象都一律当做资源来管理.并且可通过标准的HTTP请求的方法 GET,PUT,DELETE,POST,等方法来完成操作,不过是通 ...

  4. Kubernetes 学习4 kubernetes应用快速入门

    一.相关命令 1.kubectl 通过连接api server 进行各k8s对象资源的增删改查,如pod,service,controller(控制器),我们常用的pod控制器replicaset,d ...

  5. Kubernetes 学习23 kubernetes资源指标API及自定义指标API

    一.概述 1.上集中我们说到,官方文档提示说从k8s 1.11版本开始,将监控体系指标数据获取机制移向新一代的监控模型.也就意味着对于我们的k8s来讲现在应该有这样两种资源指标被使用.一种是资源指标, ...

  6. Kubernetes 学习22 kubernetes容器资源需求资源限制及HeapSter(翻车章节)

    一.概述 1.接下来介绍在k8s上运行pod对象时我们如何去监控我们系统级的资源指标以及业务级别的资源指标.数据如何获取和监控.在此之前先介绍一下Pod对象的资源请求和资源限制.即容器的资源需求和资源 ...

  7. Kubernetes 学习14 kubernetes statefulset

    一.概述 1.在应用程序中我们有两类,一种是有状态一种是无状态.此前一直演示的是deployment管理的应用,比如nginx或者我们自己定义的myapp它们都属于无状态应用. 2.而对于有状态应用, ...

  8. Kubernetes学习之Kubernetes架构

    架构 Kubernetes历史

  9. Kubernetes 学习13 kubernetes pv pvc configmap 和secret

    一.概述 1.我们在pvc申请的时候未必就有现成的pv能正好符合这个pvc在申请中指定的条件,毕竟上一次的成功是我们有意设定了有一些满足有一些不满足的前提下我们成功创建了一个pvc并且被pod绑定所使 ...

随机推荐

  1. python基础 — Queue 队列

    queue介绍 queue是python中的标准库,俗称队列. 在python中,多个线程之间的数据是共享的,多个线程进行数据交换的时候,不能够保证数据的安全性和一致性,所以当多个线程需要进行数据交换 ...

  2. Altium Designer 复制报错-奇怪的问题解决办法

    之前AD画原理图复制元件正常使用,今天使用时复制弹出了错误.很是诧异! 各种搜索查找问题,发现或许是因为前一段时间把,电脑上的所有打印机都删除了导致的. 就安装了一个打印机. 再复制,就不报错了. 或 ...

  3. canal+kafka订阅Mysql binlog将数据异构到elasticsearch(或其他存储方式)

    canal本质就是"冒充"从库,通过订阅mysql bin-log来获取数据库的更改信息. mysql配置(my.cnf) mysql需要配置my.cnf开启bin-log日志并且 ...

  4. quartz2.3.0(一)您的第一个Quartz程序

    任务类 package org.quartz.examples.example1; import java.util.Date; import org.slf4j.Logger; import org ...

  5. Java日志logback使用

    pom中添加: <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</ ...

  6. Redis之RDB和AOF持久化介绍

    什么是数据库状态 redis是一个键值对的数据库服务器,服务器中通常包含中任意个非空的数据库,而每个数据库又可以包含任意个键值对,为了方便起见,我们将服务器中的非空数据库以及他们的键值对统称为数据库状 ...

  7. ActiveX的AssemblyInof.cs文件 IObjectSafety  接口

    ActiveX的AssemblyInof.cs文件 IObjectSafety  接口 [Guid("D4176A17-2A33-4903-8F37-9EBDD7CAFFD3"), ...

  8. 并发编程-线程-死锁现象-GIL全局锁-线程池

    一堆锁 死锁现象 (重点) 死锁指的是某个资源被占用后,一直得不到释放,导致其他需要这个资源的线程进入阻塞状态. 产生死锁的情况 对同一把互斥锁加了多次 一个共享资源,要访问必须同时具备多把锁,但是这 ...

  9. Git和GitHub在线学习资源整理

    电子书 GotGitHub Git Workflow 沉浸式学习Git 文章 GitHub Fundamental visual-git-guide 图形化的Git参考手册 Linux下使用git命令 ...

  10. scrapy RuntimeError: maximum recursion depth exceeded while calling a Python object 超出python最大递归数异常

    2019-10-21 19:01:00 [scrapy.core.engine] INFO: Spider opened2019-10-21 19:01:00 [scrapy.extensions.l ...