k8s无脑系列(九)- Ingress
1.了解下Ingress
1.1 Ingress的流量走向
图中所出现的内容,在配置文件中均有体现
流量基本的流向图所示,LoadBalancer可以是云服务所提供,也可以是一个Nginx/HAProxy/istio,甚至“它”不存在都可以。
糙一点可以直接让IngressService拿外网IP提供服务,本文就这么干的!
1.2 Ingress组件依赖
1.3 基础术语与关系
术语 | 作用 | 关联 |
IngressController | Ingress控制器,内置的是ingress-nginx, 可以认为是真正运行流量分发的地方。k8s系统 自带的是Nginx | Ingress |
IngressService | 就是个Service,但它是IngressController的前端 | IngressController |
Ingress | 相当于Nginx的主机配置文件 | IngressController |
ingress annotations | 通过注解详细配置主机 |
2.部署前的基础描述
- Ingress可以有很多种Controller,Ingress-nginx只是其中一个
- Ingress在一个命名空间中工作
- Ingress运行时需要操作resource,所以涉及到rbac,Service Account,Role等配置
2.1 部署ingress-nginx
- 准备ingress-nginx的镜像地址
registry.cn-beijing.aliyuncs.com/smokelee/nginx-ingress-controller:0.30.0
- 下载部署用的yaml
地址会因为项目不停的开发而变化,到Ingress-Nginx Github去看一眼会拿到新链接
$wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
- 编辑mandatory.yaml
镜像地址调整为registry.cn-beijing.aliyuncs.com/smokelee/nginx-ingress-controller:0.30.0
私有仓库有密码的情况,在ingress-nginx的命名空间中加一个secret,并在yaml中增加 imagePullSecrets配置
该文件作用
- 权限声明Role、ClusterRole、Binding、ServiceAccount
- 命名空间声明ingress-nginx
- 3个ConfigMap
- Deployment(部署nginx-controller),也就是说部署了一个nginx意味着它需要一个Service
- 准备上面需要的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
- 坑!
就算不部署上面的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运行环境
- 用Vue脚手架搭建一个vue并编译
- 编译完成后目录中有一个dist目录
- 编写Docker文件
觉得上两步麻烦,直接弄个目录,写一个html随便写点啥都行!和Dockerfile在一个目录即可。换成COPY index.html .就行啦
FROM nginx:latest
ENV NODE_ENV production
WORKDIR /usr/share/nginx/html
COPY dist .
- 编译并推送到仓库
$docker build -t <镜像地址>:latest
$docker push <镜像地址>:latest
这里假设地址是:registry.cn-beijing.aliyuncs.com/smokelee/app/vue-demo:latest
- 编写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
- 编写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
- 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
- 通过curl来测试访问结果
$curl http://vue.smokelee.com
返回HTML
3. 关于灰度/蓝绿/金丝雀发布
去看看2.2.7的注解吧,比较粗的发布都能做到!网上有阿里云的示例,并不适用默认的nginx-ingress-controller,人家自己开发了一些。