在Kubernetes中,Pod的IP地址和service的ClusterIP仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes目前提供了以下几种方案:
##创建deployment
kubectl create deployment deploy-demo1 --image=nginx:1.14 --port=80 --replicas=3
##创建 service
kubectl expose deployment deploy-demo1 --port=80 --target-port=80
apiVersion: v1
kind: Service
metadata:
labels:
app: deploy-demo1
name: deploy-demo1
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: deploy-demo1
externalIPs: ##设置 externalIP
- 192.168.10.22
status:
loadBalancer: {}
ingress
ingress-controller:
Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/
总结
###在线下载ingress-controller Pod及相关资源
wget https://gitee.com/mirrors/ingress-nginx/raw/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml
##修改镜像地址
修改镜像地址为:
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
##修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络
vim deploy.yaml
...
apiVersion: apps/v1
# 修改 kind
#kind: Deployment
kind: DaemonSet
......
spec:
......
template:
......
spec:
# 使用宿主机网络
hostNetwork: true
# 修改选择节点选择器
nodeSelector:
ingress: "true"
......
##创建
kubectl apply -f deploy.yaml
##在随便一个 node节点中查看
netstat -lntp | grep nginx
由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。
其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。
这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了
##创建pod资源
kubectl create deployment deploy-demo1 --image=nginx:1.14 --port=80 --replicas=3
##为pod节点创建service资源
kubectl expose deployment deploy-demo1 --port=8080 --target-port=80
##创建ingress
kubectl create ingress ingress-demo1 --class=nginx --rule="www.a.com/=deploy-demo1:8080" --dry-run=client -o yaml > ingress-demo1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-demo1
spec:
ingressClassName: nginx
rules:
- host: www.a.com
http:
paths:
- backend:
service:
name: deploy-demo1
port:
number: 8080
path: /
pathType: Prefix
status:
loadBalancer: {}
ingressClassName 指定 IngressClass,用来指定选择的 Ingress Controller
host 主机名可以是精确匹配,或者使用通配符来匹配,但通配符仅覆盖一个 DNS 标签(例如 *.foo.com 不匹配 baz.bar.foo.com)。
pathType 支持的路径类型有三种:
Exact:精确匹配 URL 路径,且区分大小写。
Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写。如果路径的最后一个元素是请求路径中最后一个元素的子字符串,则不会匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。
ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。
具体可详见:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/#the-ingress-resource
##在另外一台主机上
##修改host
vim /etc/hosts
192.168.10.20 www.a.com
##访问网址查看
curl http://www.a.com
###在创建一个 deployment和servoce
kubectl create deployment deploy-demo2 --image=nginx:1.15 --port=80 --replicas=3
kubectl expose deployment deploy-demo2 --port=9090 --target-port=80
##创建ingress
kubectl create ingress ingress-demo1 --class=nginx --rule="www.b.com/=deploy-demo2:9090" --dry-run=client -o yaml > ingress-demo2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-demo2
spec:
ingressClassName: nginx
rules:
- host: www.b.com
http:
paths:
- backend:
service:
name: deploy-demo2
port:
number: 9090
path: /
pathType: Prefix
status:
loadBalancer: {}
##修改配置文件
vim deploy.yaml
kind: Deployment
type: NodePort
externalTrafficPolicy: Cluster
##创建ingress资源
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-demo1
spec:
ingressClassName: nginx
rules:
- host: www.a.com
http:
paths:
- backend:
service:
name: deploy-demo1
port:
number: 8080
path: /
pathType: Prefix
- host: www.b.com
http:
paths:
- backend:
service:
name: deploy-demo2
port:
number: 9090
path: /
pathType: Prefix
status:
loadBalancer: {}
##访问验证
curl http://www.a.com:30080
curl http://www.b.com:30080
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.crt
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-https
spec:
ingressClassName: nginx
tls:
- hosts:
- www.a.com
secretName: tls-secret
rules:
- host: www.a.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: deploy-demo1
port:
number: 8080
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-http
spec:
ingressClassName: nginx
rules:
- host: www.b.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: deploy-demo2
port:
number: 9090
yum -y install httpd-tools
htpasswd -c auth zhangsan
New password: 123
Re-type new password: 123
Adding password for user zhangsan
kubectl create secret generic basic-auth --from-file=auth
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-http
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - zhangsan'
spec:
ingressClassName: nginx
rules:
- host: www.b.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: deploy-demo2
port:
number: 9090
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
ingressClassName: nginx
rules:
- host: www.a.com
http:
paths:
- path: /something(/|$)(.*)
pathType: Prefix
backend:
service:
name: deply-demo1
port:
number: 8080
K8S集群外的客户端应用访问K8S集群内部服务的方案
ingress 的组成:
ingress 的使用:
ingress 的配置:
kubectl create ingress <资源名称> --rule=<域名>/=: --class=
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: 资源名称
spec:
ingressClassName: 指定ingress控制器类
rules:
- host: 目标域名(可以精确匹配或通配符匹配,比如 *.kgc.com 可以匹配www.kgc.com或mail.kgc.com等,但不能匹配ky22.www.kgc.com)
http:
paths:
- path: 目标域名后的URL路径(比如 / 代表网页根路径,或者 /test)
pathType: Prefix|Exact(Exact用于精确匹配URL路径;Prefix用于前缀匹配,且只能匹配完整的字符串,/abc能匹配/abc/123,但不能匹配/abc123)
backend:
service:
name: 目标Service资源的名称
port:
number: 目标Service的端口
#基于不同的 URL路径 的代理转发
- path: URL路径2
....
#基于不同的 域名 的代理转发
- host: 域名2
http:
....
#基于 https 代理转发
1)先获取 tls 证书和私钥文件
2)创建 tls 类型的 Secret资源 kubectl create secret tls <资源名称> --cert=证书文件路径 --key=私钥文件路径
3)创建 ingress 资源,引用 tls 类型的 Secret资源
spec:
tls:
- hosts:
- 指定使用 https 访问的目标域名
secretName: 指定tls类型的Secret资源
#基于 basic-auth 访问认证
1)使用 htpasswd 创建用户数据文件,固定文件名为 auth
2)创建 Secret资源 kubectl create secret generic <资源名称> --from-file=auth
3)创建 ingress 资源,在 annotations 注释字段中添加配置信息
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: Secret资源名称
nginx.ingress.kubernetes.io/auth-realm: '窗口提示信息'
#基于 rewrite 重写访问路径
创建 ingress 资源,在 annotations 注释字段中添加配置信息
metadata:
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
....
spec:
rules:
- host: "www.kgc.com"
http:
paths:
- pathType: Prefix
path: /something(/|$)(.*)
backend:
service:
name: myapp-ky29
port:
number: 9090
捕获的正则表达式 任何字符(.*) 将其分配给占位符 $2,然后将其用作注释中的参数 rewrite-target
www.kgc.com[:端口]/something 重写为 www.kgc.com[:端口]/
www.kgc.com[:端口]/something/ 重写为 www.kgc.com[:端口]/
www.kgc.com[:端口]/something/new 重写为 www.kgc.com[:端口]/new
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: https://www.accp.com:30443
spec:
rules:
- host: "www.kgc.com"
将任何使用 www.kgc.com 作域名的访问请求,都重写成 https://www.accp.com:30443
metadata:
annotations:
nginx.ingress.kubernetes.io/app-root: /app1
spec:
rules:
- host: "www.kgc.com"
http:
paths:
- pathType: Prefix
path: /
将访问 www.kgc.com[:端口]/ 的请求,都重写成 www.kgc.com[:端口]/app1