基本概念
- Kubernetes 暴露服务的方式:
- Service NodePort: 后期维护困难,不支持虚拟路径 参考此文
- Service LoadBlancer: 需要云厂商支持,有局限性
- Ingress: 灵活,无依赖
简单来说Ingress可以配置为提供服务外部访问的URL,负载均衡,SSL,提供基于名称的虚拟主机等,并且可以自动检查后端Pod IP变化,自动Reload Upstream组,动态更新location等,
Service和Ingress处理请求流程
# 以Service的NodePort为入口,Service在转发到后端对应的Pod上提供服务
internet
|
------------
[ Services ]
--|------|--
[ Pod ]
# 以Ingress为入口,Ingress动态检查对应Service的Pod(通过Endpoints),然后直接将请求转发到Pod
internet
|
[ Ingress ]
--|-----|--
[ Services ]
--|-----|--
[ Pod ]
部署Ingress
定义namespace
# namespace配置文件
[root@k8s-master01 ingress]# vim namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
定义RBAC
[root@k8sMaster01 ingress]# cat rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
rules:
- apiGroups:
- ""
resources:
- 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: ingress-nginx
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
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
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
namespace: ingress-nginx
定义个默认service backend
# 定义个默认service backend 用于为ingress controller 响应404不存在的请求
[root@k8sMaster01 ingress]# cat default-backend.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
app: default-http-backend
namespace: ingress-nginx
spec:
replicas: 1
template:
metadata:
labels:
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: registry.cn-hangzhou.aliyuncs.com/google_containers/defaultbackend:1.4
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: ingress-nginx
labels:
app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: default-http-backend
定义ingress-controller
[root@k8sMaster01 ingress]# cat deployment.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
# replicas: 1
# selector:
# matchLabels:
# app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
serviceAccountName: nginx-ingress-serviceaccount
hostNetwork: true
containers:
- name: nginx-ingress-controller
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.17.1
args:
- /nginx-ingress-controller
- --default-backend-service=ingress-nginx/default-http-backend
- --configmap=ingress-nginx/nginx-configuration
- --tcp-services-configmap=ingress-nginx/tcp-services
- --udp-services-configmap=ingress-nginx/udp-services
# - --annotations-prefix=nginx.ingress.kubernetes.io
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
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
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
定义configmap
[root@k8sMaster01 ingress]# cat tcp-services-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
[root@k8sMaster01 ingress]# cat udp-services-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
apply启动资源清单
#写好的配置文件放到了个人网站下,方便下载
[root@k8s-master01 learning]# wget http://download.baiyongjie.com/kubernetes/yaml/ingress.tar.gz
[root@k8s-master01 learning]# tar zxf ingress.tar.gz
[root@k8s-master01 learning]# cd ingress/
# 开始启动
[root@k8s-master01 ingress]# kubectl apply -f namespace.yaml
namespace/ingress-nginx created
[root@k8s-master01 ingress]# kubectl apply -f rbac.yaml
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
[root@k8s-master01 ingress]# kubectl apply -f tcp-services-configmap.yaml
configmap/tcp-services created
[root@k8s-master01 ingress]# kubectl apply -f udp-services-configmap.yaml
configmap/udp-services created
[root@k8s-master01 ingress]# kubectl apply -f default-backend.yaml
deployment.extensions/default-http-backend created
service/default-http-backend created
[root@k8s-master01 ingress]# kubectl apply -f deployment.yaml
daemonset.extensions/nginx-ingress-controller created
[root@k8s-master01 ingress]# kubectl get configmaps -n ingress-nginx
NAME DATA AGE
ingress-controller-leader-nginx 0 9m31s
tcp-services 0 45m
udp-services 0 45m
[root@k8s-master01 ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default-http-backend ClusterIP 10.98.133.166 <none> 80/TCP 45m
[root@k8s-master01 ingress]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
default-http-backend-774686c976-k4pbg 1/1 Running 0 45m
nginx-ingress-controller-mhnn9 1/1 Running 0 45m
nginx-ingress-controller-wbsnl 1/1 Running 0 45m
为已有的svc配置Ingress
[root@k8s-master01 learning]# vim Ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo
namespace: learning
spec:
rules:
- host: ingress-demo.baiyongjie.com #主机域名,需要在本地绑定节点ip
http:
paths:
- backend:
serviceName: deploy-demo # 后端服务名
servicePort: 80 # 后端服务端口
测试Ingress
# 启动Ingress
[root@k8s-master01 learning]# kubectl apply -f Ingress.yaml
ingress.extensions/ingress-demo created
[root@k8s-master01 learning]# kubectl get ingresses.extensions -n learning
NAME HOSTS ADDRESS PORTS AGE
ingress-demo ingress-demo.baiyongjie.com 80 9s
# 在本机修改hosts文件为k8s的IP地址
192.168.88.137 ingress-demo.baiyongjie.com
# 浏览器访问, 多刷新几次看效果,可以看到IP地址在发生变化~