service的作用体现在两个方面,对集群内部,它不断跟踪pod的变化,更新endpoint(端点)中对应pod的对象,提供了ip不断变化的pod的服务发现机制;对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。
在Kubernetes中,Pod的IP地址和service的ClusterIP仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes目前提供了以下几种方案:
Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginxIngress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/
ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到 ingress-controller, 而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名、哪些URL要转发到哪些service等等。
mkdir /opt/ingresscd /opt/ingress官方下载地址:wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml上面可能无法下载,可用国内的 giteewget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yamlwget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml#mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。
mkdir /opt/ingress
cd /opt/ingress
官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
上面可能无法下载,可用国内的 gitee
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
#mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。
vim mandatory.yaml......apiVersion: rbac.authorization.k8s.io/v1beta1#RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用kind: ClusterRolemetadata: name: nginx-ingress-clusterrole labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxrules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" # (0.25版本)增加 networking.k8s.io Ingress 资源的 api resources: - ingresses verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" # (0.25版本)增加 networking.k8s.io/v1 Ingress 资源的 api resources: - ingresses/status verbs: - update
vim mandatory.yaml
......
apiVersion: rbac.authorization.k8s.io/v1beta1
#RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- get
- services
- "extensions"
- "networking.k8s.io" # (0.25版本)增加 networking.k8s.io Ingress 资源的 api
- ingresses
- events
- create
- patch
- "networking.k8s.io" # (0.25版本)增加 networking.k8s.io/v1 Ingress 资源的 api
- ingresses/status
- update
采用方式二:DaemonSet+HostNetwork+nodeSelector
kubectl label node node02 ingress=truekubectl get nodes --show-labels
kubectl label node node02 ingress=true
kubectl get nodes --show-labels
vim mandatory.yaml...apiVersion: apps/v1# 修改 kind# kind: Deploymentkind: DaemonSetmetadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginxspec:# 删除Replicas# replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: # 使用主机网络 hostNetwork: true # 选择节点运行 nodeSelector: ingress: "true" serviceAccountName: nginx-ingress-serviceaccount......
...
apiVersion: apps/v1
# 修改 kind
# kind: Deployment
kind: DaemonSet
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
# 删除Replicas
# replicas: 1
selector:
matchLabels:
template:
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
# 使用主机网络
hostNetwork: true
# 选择节点运行
nodeSelector:
ingress: "true"
serviceAccountName: nginx-ingress-serviceaccount
cd /opt/ingresstar zxvf ingree.contro.tar.gzdocker load -i ingree.contro.tar
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar
kubectl apply -f mandatory.yaml#nginx-ingress-controller 已经运行 node02 节点kubectl get pod -n ingress-nginx -o widekubectl get cm,daemonset -n ingress-nginx -o wide
kubectl apply -f mandatory.yaml
#nginx-ingress-controller 已经运行 node02 节点
kubectl get pod -n ingress-nginx -o wide
kubectl get cm,daemonset -n ingress-nginx -o wide
到 node02 节点查看
netstat -lntp | grep nginx
由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了。如果要 nginx 高可用的话,可以在多个 node上部署,并在前面再搭建一套 LVS+keepalived 做负载均衡。
创建一个 deploy 和 svc
vim service-nginx.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: nginx-appspec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: nginx-app-svcspec: type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 80 selector: app: nginx
vim service-nginx.yaml
kind: Deployment
name: nginx-app
replicas: 2
app: nginx
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
name: nginx-app-svc
type: ClusterIP
- protocol: TCP
port: 80
targetPort: 80
创建 ingress
用的是方法二
#方法一:(extensions/v1beta1 Ingress 在1.22版本即将弃用)vim ingress-app.yamlapiVersion: extensions/v1beta1kind: Ingressmetadata: name: nginx-app-ingressspec: rules: - host: www.mcl.com http: paths: - path: / backend: serviceName: nginx-app-svc servicePort: 80#方法二:vim ingress-app.yaml apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: nginx-app-ingressspec: rules: - host: www.mcl.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-app-svc port: number: 80
#方法一:(extensions/v1beta1 Ingress 在1.22版本即将弃用)
vim ingress-app.yaml
apiVersion: extensions/v1beta1
kind: Ingress
name: nginx-app-ingress
- host: www.mcl.com
http:
paths:
- path: /
backend:
serviceName: nginx-app-svc
servicePort: 80
#方法二:
apiVersion: networking.k8s.io/v1
pathType: Prefix
service:
port:
number: 80
kubectl apply -f service-nginx.yamlkubectl apply -f ingress-app.yamlkubectl get podskubectl get ingress
kubectl apply -f service-nginx.yaml
kubectl apply -f ingress-app.yaml
kubectl get pods
kubectl get ingress
本地 host 添加域名解析
vim /etc/hostscurl www.mcl.com
vim /etc/hosts
curl www.mcl.com
kubectl get pod -n ingress-nginx -o widekubectl exec -it nginx-ingress-controller-p7tdq -n ingress-nginx /bin/bash
kubectl exec -it nginx-ingress-controller-p7tdq -n ingress-nginx /bin/bash
可以看到从 start server www.mcl.com 到 end server www.mcl.com 之间包含了此域名用于反向代理的配置
mkdir /opt/ingress-nodeportcd /opt/ingress-nodeport官方下载地址:wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yamlwget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml国内 gitee 资源地址:wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yamlwget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
mkdir /opt/ingress-nodeport
cd /opt/ingress-nodeport
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
国内 gitee 资源地址:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
tar zxvf ingree.contro-0.30.0.tar.gzdocker load -i ingress-controller-0.30.0.tar
tar zxvf ingree.contro-0.30.0.tar.gz
docker load -i ingress-controller-0.30.0.tar
kubectl apply -f mandatory.yamlkubectl apply -f service-nodeport.yaml
kubectl apply -f service-nodeport.yaml
如果K8S Pod 调度失败,在 kubectl describe pod资源时显示:Warning FailedScheduling 18s (x2 over 18s) default-scheduler 0/2 nodes are available: 2 node(s) didn't match node selector
解决方案:
创建 deployment、Service、Ingress Yaml 资源
vim ingress-nginx.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-myappspec: replicas: 2 selector: matchLabels: name: nginx template: metadata: labels: name: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: nginx-svcspec: ports: - port: 80 targetPort: 80 protocol: TCP selector: name: nginx---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: nginx-testspec: rules: - host: www.long.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-svc port: number: 80
vim ingress-nginx.yaml
name: nginx-myapp
name: nginx
name: nginx-svc
- port: 80
protocol: TCP
name: nginx-test
- host: www.long.com
kubectl get pods,svc -o wide
kubectl exec -it pod/nginx-myapp-57dd86f5cc-l48l2 bashkubectl exec -it pod/nginx-myapp-57dd86f5cc-lpnfz bash
kubectl exec -it pod/nginx-myapp-57dd86f5cc-l48l2 bash
kubectl exec -it pod/nginx-myapp-57dd86f5cc-lpnfz bash
curl 10.244.1.18kubectl get svc -n ingress-nginx
curl 10.244.1.18
kubectl get svc -n ingress-nginx
vim /etc/hosts192.168.160.20 master192.168.160.40 node01192.168.160.90 node02192.168.160.70 hub.mcl.com192.168.160.90 www.mcl.com#添加域名解析192.168.160.40 www.mcl.com www.long.com#外部访问curl http://www.long.com:31751
192.168.160.20 master
192.168.160.40 node01
192.168.160.90 node02
192.168.160.70 hub.mcl.com
192.168.160.90 www.mcl.com
#添加域名解析
192.168.160.40 www.mcl.com www.long.com
#外部访问
curl http://www.long.com:31751
mkdir /opt/ingress-nodeport/vhostcd /opt/ingress-nodeport/vhost#创建虚拟主机1资源vim deployment1.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: deployment1spec: replicas: 2 selector: matchLabels: name: nginx1 template: metadata: labels: name: nginx1 spec: containers: - name: nginx1 image: soscscs/myapp:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: svc-1spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: name: nginx1 kubectl apply -f deployment1.yaml
mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost
#创建虚拟主机1资源
vim deployment1.yaml
name: deployment1
name: nginx1
- name: nginx1
image: soscscs/myapp:v1
name: svc-1
kubectl apply -f deployment1.yaml
#创建虚拟主机2资源vim deployment2.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: deployment2spec: replicas: 2 selector: matchLabels: name: nginx2 template: metadata: labels: name: nginx2 spec: containers: - name: nginx2 image: soscscs/myapp:v2 imagePullPolicy: IfNotPresent ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: svc-2spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: name: nginx2 kubectl apply -f deployment2.yaml
#创建虚拟主机2资源
vim deployment2.yaml
name: deployment2
name: nginx2
- name: nginx2
image: soscscs/myapp:v2
name: svc-2
kubectl apply -f deployment2.yaml
#创建ingress资源vim ingress-nginx.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress1spec: rules: - host: www1.mcl.com http: paths: - path: / pathType: Prefix backend: service: name: svc-1 port: number: 80---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress2spec: rules: - host: www2.mcl.com http: paths: - path: / pathType: Prefix backend: service: name: svc-2 port: number: 80kubectl apply -f ingress-nginx.yaml
#创建ingress资源
name: ingress1
- host: www1.mcl.com
name: ingress2
- host: www2.mcl.com
kubectl apply -f ingress-nginx.yaml
kubectl get svc -n ingress-nginx#做主机映射vim /etc/hostscurl www1.mcl.com:31751curl www2.mcl.com:31751
#做主机映射
curl www1.mcl.com:31751
curl www2.mcl.com:31751
mkdir /opt/ingress-nodeport/httpscd /opt/ingress-nodeport/https
mkdir /opt/ingress-nodeport/https
cd /opt/ingress-nodeport/https
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
kubectl create secret tls tls-secret --key tls.key --cert tls.crtkubectl get secretkubectl describe secret tls-secret
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
kubectl get secret
kubectl describe secret tls-secret
vim ingress-https.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: nginx-appspec: replicas: 2 selector: matchLabels: name: nginx template: metadata: labels: name: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: nginx-svcspec: ports: - port: 80 targetPort: 80 protocol: TCP selector: name: nginx---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: nginx-httpsspec: tls: - hosts: - www3.long.com secretName: tls-secret rules: - host: www3.kgc.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-svc port: number: 80 kubectl apply -f ingress-https.yaml
vim ingress-https.yaml
name: nginx-https
tls:
- hosts:
- www3.long.com
secretName: tls-secret
- host: www3.kgc.com
kubectl apply -f ingress-https.yaml
mkdir /opt/ingress-nodeport/basic-authcd /opt/ingress-nodeport/basic-auth
mkdir /opt/ingress-nodeport/basic-auth
cd /opt/ingress-nodeport/basic-auth
yum -y install httpdhtpasswd -c auth mcl #认证文件名必须为 authkubectl create secret generic basic-auth --from-file=authkubectl get secretskubectl describe secrets basic-auth
yum -y install httpd
htpasswd -c auth mcl #认证文件名必须为 auth
kubectl create secret generic basic-auth --from-file=auth
kubectl get secrets
kubectl describe secrets basic-auth
vim ingress-auth.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-auth annotations: #设置认证类型basic nginx.ingress.kubernetes.io/auth-type: basic #设置secret资源名称basic-auth nginx.ingress.kubernetes.io/auth-secret: basic-auth #设置认证窗口提示信息 nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - mcl'spec: rules: - host: auth.mcl.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-svc port: number: 80 //具体详细设置方法可参考官网https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
vim ingress-auth.yaml
name: ingress-auth
#设置认证类型basic
nginx.ingress.kubernetes.io/auth-type: basic
#设置secret资源名称basic-auth
nginx.ingress.kubernetes.io/auth-secret: basic-auth
#设置认证窗口提示信息
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - mcl'
- host: auth.mcl.com
//具体详细设置方法可参考官网https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
kubectl apply -f ingress-auth.yamlkubectl get svc -n ingress-nginxecho '192.168.160.40 auth.mcl.com' >> /etc/hosts浏览器访问:http://auth.mcl.com:31751
kubectl apply -f ingress-auth.yaml
echo '192.168.160.40 auth.mcl.com' >> /etc/hosts
浏览器访问:http://auth.mcl.com:31751
metadata.annotations 配置说明
nginx.ingress.kubernetes.io/rewrite-target: <字符串> #必须重定向流量的目标URInginx.ingress.kubernetes.io/ssl-redirect: <布尔值> #指示位置部分是否仅可访问SSL(当Ingress包含证书时,默认为true)nginx.ingress.kubernetes.io/force-ssl-redirect: <布尔值> #即使Ingress未启用TLS,也强制重定向到HTTPSnginx.ingress.kubernetes.io/app-root: <字符串> #定义Controller必须重定向的应用程序根,如果它在'/'上下文中nginx.ingress.kubernetes.io/use-regex: <布尔值> #指示Ingress上定义的路径是否使用正则表达式
nginx.ingress.kubernetes.io/rewrite-target: <字符串> #必须重定向流量的目标URI
nginx.ingress.kubernetes.io/ssl-redirect: <布尔值> #指示位置部分是否仅可访问SSL(当Ingress包含证书时,默认为true)
nginx.ingress.kubernetes.io/force-ssl-redirect: <布尔值> #即使Ingress未启用TLS,也强制重定向到HTTPS
nginx.ingress.kubernetes.io/app-root: <字符串> #定义Controller必须重定向的应用程序根,如果它在'/'上下文中
nginx.ingress.kubernetes.io/use-regex: <布尔值> #指示Ingress上定义的路径是否使用正则表达式
编写ingress-rewrite.yaml
vim ingress-rewrite.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: nginx-rewrite annotations: nginx.ingress.kubernetes.io/rewrite-target: http://www1.mcl.com:31751spec: rules: - host: re.mcl.com http: paths: - path: / pathType: Prefix backend: #由于re.kgc.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义 service: name: nginx-svc port: number: 80
vim ingress-rewrite.yaml
name: nginx-rewrite
nginx.ingress.kubernetes.io/rewrite-target: http://www1.mcl.com:31751
- host: re.mcl.com
#由于re.kgc.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义
访问测试
kubectl apply -f ingress-rewrite.yamlecho '192.168.160.40 re.mcl.com' >> /etc/hosts浏览器访问:http://re.mcl.com:31751
kubectl apply -f ingress-rewrite.yaml
echo '192.168.160.40 re.mcl.com' >> /etc/hosts
浏览器访问:http://re.mcl.com:31751
ingress是k8s集群的请求入口,可以理解为对多个service的再次抽象通常说的ingress一般包括ingress资源对象及ingress-controller两部分组成ingress-controller有多种实现,社区原生的是ingress-nginx,根据具体需求选择ingress自身的暴露有多种方式,需要根据基础环境及业务类型选择合适的方式
原文链接:https://www.cnblogs.com/mcl0914/p/17176465.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728