k8s无脑系列(九)- Ingress

1.了解下Ingress

1.1 Ingress的流量走向

图中所出现的内容,在配置文件中均有体现

ingress怎么携带header ingress path_nginx

流量基本的流向图所示,LoadBalancer可以是云服务所提供,也可以是一个Nginx/HAProxy/istio,甚至“它”不存在都可以。

糙一点可以直接让IngressService拿外网IP提供服务,本文就这么干的!

1.2 Ingress组件依赖

ingress怎么携带header ingress path_IP_02

1.3 基础术语与关系

术语

作用

关联

IngressController

Ingress控制器,内置的是ingress-nginx,

可以认为是真正运行流量分发的地方。k8s系统

自带的是Nginx

Ingress

IngressService

就是个Service,但它是IngressController的前端

IngressController

Ingress

相当于Nginx的主机配置文件

IngressController

ingress annotations

通过注解详细配置主机

Github Ingress Doc

2.部署前的基础描述

  1. Ingress可以有很多种Controller,Ingress-nginx只是其中一个
  2. Ingress在一个命名空间中工作
  3. Ingress运行时需要操作resource,所以涉及到rbac,Service Account,Role等配置

2.1 部署ingress-nginx

  1. 准备ingress-nginx的镜像地址
registry.cn-beijing.aliyuncs.com/smokelee/nginx-ingress-controller:0.30.0
  1. 下载部署用的yaml

地址会因为项目不停的开发而变化,到Ingress-Nginx Github去看一眼会拿到新链接

$wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
  1. 编辑mandatory.yaml
    镜像地址调整为registry.cn-beijing.aliyuncs.com/smokelee/nginx-ingress-controller:0.30.0
    私有仓库有密码的情况,在ingress-nginx的命名空间中加一个secret,并在yaml中增加 imagePullSecrets配置
    该文件作用
  1. 权限声明Role、ClusterRole、Binding、ServiceAccount
  2. 命名空间声明ingress-nginx
  3. 3个ConfigMap
  4. Deployment(部署nginx-controller),也就是说部署了一个nginx意味着它需要一个Service
  1. 准备上面需要的Service来公布服务
kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels: <===这两个Selector会被ingress-nginx-controller拿到,并读取数据。找不到这个Service,ingress-nginx会不停输出错误。但状态时Running和Ready
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  externalIPs: 这里直接指定IP了,条件允许应该用LB。NodePort也行,我嫌麻烦
    - 192.168.56.5
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
  1. 坑!
    就算不部署上面的Service,ingress-controller安装完成后也会提示Running/Ready。并且只有到Node节点打印log才发现,它需要一个Service。
kubectl get all  -n ingress-nginx
NAME                                            READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-controller-648f9697ff-rwxxr   1/1     Running   0          24h

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-ingress-controller   1/1     1            1           24h

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-ingress-controller-648f9697ff   1         1         1       24h

2.2 搭建App运行环境

  1. 用Vue脚手架搭建一个vue并编译
  2. 编译完成后目录中有一个dist目录
  3. 编写Docker文件
    觉得上两步麻烦,直接弄个目录,写一个html随便写点啥都行!和Dockerfile在一个目录即可。换成COPY index.html .就行啦
FROM nginx:latest
ENV NODE_ENV production
WORKDIR /usr/share/nginx/html
COPY dist .
  1. 编译并推送到仓库
$docker build -t <镜像地址>:latest
$docker push <镜像地址>:latest
这里假设地址是:registry.cn-beijing.aliyuncs.com/smokelee/app/vue-demo:latest
  1. 编写APP的部署文件
apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: vue-demo-deployment
 spec:
   selector:
     matchLabels:
       app: vue-demo-pod
   template:
     metadata:
       labels:
         app: vue-demo-pod
     spec:
       imagePullSecrets:
       - name: registry-secret-smokelee.com
       containers:
       - name: vue-demo
         image: registry.i.smokelee.com/app/vue-demo:latest
         imagePullPolicy: IfNotPresent
         ports:
         - containerPort: 80
           name: web
           protocol: TCP
 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: vue-demo-svc
   labels:
     app: vue-demo-svc
 spec:
   selector:
     app: vue-demo-pod
   ports:
   - name: web
     port: 80
     targetPort: web
  1. 编写app的Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: simple-nginx-example
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    关于ingress-nginx的注解,在1.3中的表格有描述
spec:
  rules:
  - host: vue.smokelee.com 定义域名
    http:
      paths:
      - path: /
        backend:
          serviceName: vue-demo-svc  内部DNS找到主机,对应见app的部署内容
          servicePort: 80
  1. kubectl 创建上述两个资源
    创建完成后,通过命令找到ingress-nginx service的IP地址,并在/etc/hosts中增加记录
kubectl get svc -n ingress-nginx
 NAME            TYPE        CLUSTER-IP     EXTERNAL-IP    PORT(S)          AGE
 ingress-nginx   ClusterIP   10.254.7.143   192.168.56.5   80/TCP,443/TCP   15s
  1. 通过curl来测试访问结果
$curl http://vue.smokelee.com 
返回HTML

3. 关于灰度/蓝绿/金丝雀发布

去看看2.2.7的注解吧,比较粗的发布都能做到!网上有阿里云的示例,并不适用默认的nginx-ingress-controller,人家自己开发了一些。