kubernetes之Ingress部署

1,如何访问K8S中的服务:

1,Ingress介绍

Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、NodePort Service、Ingress;前两种估计都应该很熟悉,下面详细的了解下这个 Ingress

Ingress由两部分组成:Ingress Controller 和 Ingress 服务。

Ingress Contronler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段 Nginx 配置,再写到 Nginx-ingress-control的 Pod 里,这个 Ingress Contronler 的pod里面运行着一个nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,然后 reload 一下 使用配置生效。以此来达到域名分配置及动态更新的问题。

看个简单的图方便理解:

ingress控制器有两种:nginx和haproxy 这里是以nginx为讲解。

2,部署一个Nginx Ingress

ingress的部署文件在github Ingress 仓库找到. 针对官方配置我们单独添加了 nodeselector 指定,绑定LB地址 以方便DNS 做解析。

主要用到的文件:

$ ls
default-backend.yaml  jenkins-ingress.yml  nginx-ingress-controller-rbac.yml  nginx-ingress-controller.yaml
- - - 
default-backend.yaml:这是官方要求必须要给的默认后端,提供404页面的。它还提供了一个http检测功能,检测nginx-ingress-controll健康状态的,通过每隔一定时间访问nginx-ingress-controll的/healthz页面,如是没有响应就
返回404之类的错误码。
nginx-ingress-controller-rbac.yml:这ingress的RBAC授权文件
nginx-ingress-controller.yaml:这是控制器的部署文件。
jenkins-ingress.yml:这是Ingress服务文件,这个可以是任意web程序,里面配置域名与service的对应关系,Ingress称之为规则。

第一个是要部署RBAC文件:

cat nginx-ingress-controller-rbac.yml
#apiVersion: v1
#kind: Namespace
#metadata:  #这里是创建一个namespace,因为此namespace早有了就不用再创建了
#  name: kube-system
---
apiVersion: v1
kind: ServiceAccount    
metadata:
  name: nginx-ingress-serviceaccount #创建一个serveerAcount
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole   #这个ServiceAcount所绑定的集群角色
rules:
  - apiGroups:
      - "" 
    resources:    #此集群角色的权限,它能操作的API资源 
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
        - events
    verbs:
        - create
        - patch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses/status
    verbs:
      - update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:         
  name: nginx-ingress-role  #这是一个角色,而非集群角色 
  namespace: kube-system
rules:  #角色的权限 
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get
      - create
      - update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding       #角色绑定
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount #绑定在这个用户 
    namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding      #集群绑定
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount   #集群绑定到这个serviceacount
    namespace: kube-system   #集群角色是可以跨namespace,但是这里只指明给这个namespce来使用

创建:

$ kubectl create -f nginx-ingress-controller-rbac.yml 
serviceaccount "nginx-ingress-serviceaccount" created
clusterrole "nginx-ingress-clusterrole" created
role "nginx-ingress-role" created
rolebinding "nginx-ingress-role-nisa-binding" created
clusterrolebinding "nginx-ingress-clusterrole-nisa-binding" created

RBAC创建完后,就创建default backend服务:

$ cat default-backend.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    k8s-app: default-http-backend
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        # Any image is permissable as long as:
        # 1. It serves a 404 page at /
        # 2. It serves 200 on a /healthz endpoint
        image: gcr.io/google_containers/defaultbackend:1.0
        livenessProbe:
          httpGet:
            path: /healthz   #这个URI是 nginx-ingress-controller中nginx里配置好的localtion 
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30   #30s检测一次/healthz
          timeoutSeconds: 5
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
      nodeSelector:            #指定调度到些Node, 以便后面DNS解析
        kubernetes.io/hostname: 10.3.1.17    
---
apiVersion: v1
kind: Service     #为default backend 创建一个service
metadata:
  name: default-http-backend
  namespace: kube-system
  labels:
    k8s-app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    k8s-app: default-http-backend

创建:

$ kubectl create -f default-backend.yaml 
deployment "default-http-backend" created
service "default-http-backend" created

创建之后查看:

[email protected]:/data/ingress# kubectl get rs,pod,svc  -n kube-system 
NAME                                 DESIRED   CURRENT   READY     AGE
rs/default-http-backend-857b544d94   1         1         1         1m

NAME                                       READY     STATUS    RESTARTS   AGE
po/default-http-backend-857b544d94-bwgjd   1/1       Running   0          1m

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
svc/default-http-backend   ClusterIP   10.254.208.144   <none>        80/TCP          1m

创建好default backend后就要创建nginx-ingress-controller了:

$ cat nginx-ingress-controller.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  labels:
    k8s-app: nginx-ingress-controller
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: nginx-ingress-controller
    spec:
      # hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
      # however, it is not a hard dependency of the nginx-ingress-controller itself and it may cause issues if port 10254 already is taken on the host
      # that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
      # like with kubeadm
      # hostNetwork: true #注释表示不使用宿主机的80口,
      terminationGracePeriodSeconds: 60
      hostNetwork: true  #表示容器使用和宿主机一样的网络
      serviceAccountName: nginx-ingress-serviceaccount #引用前面创建的serviceacount
      containers:   
      - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.1      #容器使用的镜像
        name: nginx-ingress-controller  #容器名
        readinessProbe:   #启动这个服务时要验证/healthz 端口10254会在运行的node上监听。 
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10  #每隔10做健康检查 
          timeoutSeconds: 1
        ports:
        - containerPort: 80  
          hostPort: 80    #80映射到80
        - containerPort: 443
          hostPort: 443
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        args:
        - /nginx-ingress-controller
        - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
#        - --default-ssl-certificate=$(POD_NAMESPACE)/ingress-secret    #这是启用Https时用的
      nodeSelector:  #指明运行在哪,此IP要和default backend是同一个IP
        kubernetes.io/hostname: 10.3.1.17   #上面映射到了hostport80,确保此IP80,443没有占用.

这个控制器就是一个deployment ,里面运行一个容器gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.1 ,有点像nginx容器,现在创建:

$ kubectl create -f nginx-ingress-controller.yaml 
deployment "nginx-ingress-controller" created
[email protected]:/data/ingress# kubectl get rs,pod,svc  -n kube-system 
NAME                                     DESIRED   CURRENT   READY     AGE
rs/default-http-backend-857b544d94       1         1         1         12m
rs/nginx-ingress-controller-8576d4545d   1         1         0         27s

NAME                                           READY     STATUS              RESTARTS   AGE
po/default-http-backend-857b544d94-bwgjd       1/1       Running             0          12m
po/nginx-ingress-controller-8576d4545d-9tjnv   0/1       ContainerCreating   0          27s

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
svc/default-http-backend   ClusterIP   10.254.208.144   <none>        80/TCP          12m

现在ingress controller 控制器已部署好了,那么如何使用了,那就要写一个ingress规则了,此处就以已存在的jenkins服务为例,配置如何使用域名访问这个service:

 $ kubectl get svc,ep
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
svc/jenkinsservice    NodePort    10.254.70.47     <none>        8080:30002/TCP   3h

NAME                 ENDPOINTS                                         AGE
ep/jenkinsservice    172.30.10.15:8080,172.30.11.7:8080                3h

现在写个jenkins service的Ingress 规则:

$ cat jenkins-ingress.yml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: jenkins-ingress
  namespace: default #服务在哪个空间内就写哪个空间
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: ingress.jenkins.com   #此service的访问域名
    http:
      paths:
      - backend:
          serviceName: jenkinsservice  
          servicePort: 8080

创建它:

$ kubectl create -f jenkins-ingress.yml 
ingress "jenkins-ingress" created

$ kubectl get ingress 
NAME              HOSTS                 ADDRESS   PORTS     AGE
jenkins-ingress   ingress.jenkins.com             80        10s

到这里就已经部署完成了,配置好域名后,就可以用此域名来访问了:

部署完成了,现在看下nginx-ingress-controller 里nginx配置文件发生了哪些变化:

 upstream default-jenkinsservice-8080 {
        least_conn;
        server 172.30.10.15:8080 max_fails=0 fail_timeout=0;
        server 172.30.11.7:8080 max_fails=0 fail_timeout=0;
    }
    upstream upstream-default-backend {
        least_conn;
        server 172.30.11.6:8080 max_fails=0 fail_timeout=0;
    }
 
 server {
        server_name ingress.jenkins.com;
        listen [::]:80;

        location / {
            ...
            proxy_pass http://default-jenkinsservice-8080;
            ...
        }
    }

这些配置都是ingress-controller 自已写入的,动态更新就是它能通过K8S API感知到service的endpoint 发生了变化,然后修改nginx配置并执行reload.

至此,部署完成。

Ingress还有很多部署方式,比如配置https访问的, 以后再写。

原文地址:http://blog.51cto.com/newfly/2060587

时间: 2024-10-08 02:39:06

kubernetes之Ingress部署的相关文章

使用traefik作为kubernetes的ingress

[toc] 说明 关于kubernetes的服务暴露方式以及traefik的原理篇这里不作详细说明.traefik的原理可以参考官方文档:https://docs.traefik.io/ ,而关于kubernetes的服务暴露方式以及将traefik作为kubernetes的ingress使用的基本原理也可以参考这篇文档:https://mritd.me/2016/12/06/try-traefik-on-kubernetes/ .这篇文档主要阐述将traefik作为kubernetes的ing

Kubernetes之Ingress和Ingress Controller

目录 Kubernetes之Ingress和Ingress Controller 概念 Ingress资源类型 单Service资源型Ingress Ingress Nginx部署 部署Ingress controller 配置ingress后端服务 部署ingress-nginx service 部署Ingress 增加tomcat服务 总结 构建TLS站点 Kubernetes之Ingress和Ingress Controller 概念 通常情况下,service和pod的IP仅可在集群内部

12、kubernetes之ingress及Ingress Controller

一.概念 ClusterIP:例如svc所分配的ip地址 NodePort:k8s集群物理机机通信地址,client --> NodeIP:NodePort --> ClusterIP:ServicePort --> PodIP:containerPort No ClusterIP:Headless Service ,ServiceName --> PodIP Ingress:负责7层调度 二.ingress-nginx部署 # cat mandatory.yaml apiVers

kubernetes集群部署

鉴于Docker如此火爆,Google推出kubernetes管理docker集群,不少人估计会进行尝试.kubernetes得到了很多大公司的支持,kubernetes集群部署工具也集成了gce,coreos,aws等iaas平台,部署起来也相当的方便.鉴于网上众多资料基于的是不少老版本,本篇文章针对最新的kubernetes及其依赖组件的部署简要阐述.通过本文可以比较粗暴的运行你的kubernetes集群,要优雅还需要更多的工作.部署主要分为三步: 1.准备机器并打通网络 如果要部署kube

kubernetes nginx ingress 使用记录

前言 ingress是一种可以暴露k8s集群内部service的方式,用户编辑配置文件定义一个ingress资源即可实现外部网络访问内网service. ingress controller是来管理所有的Ingress的对象,ingress controller内部其实是一个nginx的容器,当ingress controll 通过与 Kubernetes API 交互,感知集群中Ingress规则变化时会按照模板文件生成nginx.conf文件,然后reload该配置文件. 相对于kubern

Kubernetes集群部署DNS服务

Kubernetes集群部署DNS服务在kubernetes中每一个service都会被分配一个虚拟IP,每一个Service在正常情况下都会长时间不会改变,这个相对于pod的不定IP,对于集群中APP的使用相对是稳定的. 但是Service的信息注入到pod目前使用的是环境变量的方式,并且十分依赖于pod(rc)和service的创建顺序,这使得这个集群看起来又不那么完美,于是kubernetes以插件的方式引入了DNS系统,利用DNS对Service进行一个映射,这样我们在APP中直接使用域

kubernetes 1.11 部署

kubernetes 1.11 部署 参考文档文档编译 [https://github.com/kubernetes/kubernetes/tree/release-1.11/cluster/images/hyperkube]() 参考文档文档编译 环境安装 1. docker install 所有节点都按照docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-rep

Kubernetes 通过statefulset部署redis cluster集群

Kubernetes 通过statefulset部署redis cluster集群 作者: 张首富 时间: 2019-02-19 个人博客地址: https://www.zhangshoufu.com QQ群: 895291458 需要有redis基础 Redis集群架构图 每个Mater 都可以拥有多个slave.当Master掉线后,redis cluster集群会从多个Slave中选举出来一个新的Matser作为代替,而旧的Master重新上线后变成 Master 的Slave. 部署re

Kubernetes之kubeadm部署集群

目录 Kubernetes之kubeadm部署集群 1.部署前准备 2.集群初始化 Kubernetes之kubeadm部署集群 kubeadm是Kubernetes项目自带的集群构建工具,它负责执行构建一个最小化的可用集群以及将其启动等的必要基本步骤,简单来讲,kubeadm是Kubernetes集群全生命周期的管理工具,可用于实现集群的部署.升级/降级及拆除. kubeadm集成了kubeadminit和kubeadmjoin等工具程序,其中kubeadminit用于集群的快速初始化,初始化