前言
在 上一章节中,我们知道有以下几种方式可以实现对外暴露服务:
NodePort
(Pod
设置HostNetWork
同理)LoadBalancer
ExternalIP
1.1 背景
但在实际环境中,我们很少直接使用这些方式来对外暴露服务,因为它们都有一个比较严重的问题,那就是需要占用节点端口。也就是说,占用节点端口的数量会随着服务数量的增加而增加,这就产生了很大的端口管理成本。
除此之外,这些方式也不支持域名以及 SSL 配置(LoadBalancer 的这些功能由云厂商提供支持),还需要额外配置其他具有丰富功能的反向代理组件,如Nginx
、Kong
等。
1.2 Ingress的作用
Ingress
就是为了解决这些问题而设计的,它允许你将 Service 映射到集群对外提供的某个端点上(由域名和端口组成的地址),
这样我们就可以在 Ingress 中将多个 Service 配置到同一个域名的不同路径下对外提供服务,避免了对节点端口的过多占用。
Ingress
还支持路由规则和域名配置等高级功能,就像 Nginx 那样能够承担业务系统最边缘的反向代理+网关的角色。
举个栗子:集群对外的统一端点是api.example.com:80
,可以这样为集群内的两个 Service(backend:8080
、frontend:8082
)配置对外端点映射:
api.example.com/backend
指向 backend:8080api.example.com/frontend
指向 frontend:8082
除此之外,Ingress 还可以为多个域名配置不同的路由规则,在仅占用单个节点端口的同时实现灵活的路由配置功能。
1.3 Ingress 的功能
总的来说,Ingress 提供以下功能:
- 路由规则:Ingress 允许你定义路由规则,使请求根据主机名和路径匹配路由到不同的后端服务。这使得可以在同一 IP
地址和端口上公开多个服务。 - Rewrite 规则:Ingress 支持 URL 重写,允许你在路由过程中修改请求的 URL 路径;
- TLS/SSL 支持:你可以为 Ingress 配置 TLS 证书,以加密传输到后端服务的流量;
- 负载均衡:Ingress 可以与云提供商的负载均衡器集成,以提供外部负载均衡和高可用性;
- 虚拟主机:你可以配置多个主机名(虚拟主机)来公开不同的服务。这意味着你可以在同一 IP 地址上托管多个域名;
- 自定义错误页面:你可以定义自定义错误页面,以提供用户友好的错误信息;
- 插件和控制器:社区提供了多个 Ingress 控制器,如
Nginx Ingress Controller
和Traefik
,它们为Ingress
提供了更多功能和灵活性。
ngress
可以简单理解为集群服务的网关(Gateway
),它是所有流量的入口,经过配置的路由规则,将流量重定向到后端的服务。
从网络分层上看,Ingress
是作为一个七层网络代理。
[!NOTE]
大部分托管集群的用户会选择 LoadBalancer 类型的 Service 而不是 Ingress 来暴露服务,因为前者由云厂商支持的优势明显,通常都是通过
Web 页面进行配置,
免去了管理清单的麻烦,而且也支持 Ingress 所支持的 SSL、负载均衡等功能,甚至包含 Ingress 不支持的四层协议代理功能!
[!IMPORTANT]
Ingress 资源不支持原生 TCP 代理服务!但大部分实现 Ingress API 的控制器(如 ingress Nginx Controller)是支持的,它们通过为
Ingress 资源添加注解的方式来实现对原生 TCP
服务的支持。参考 [Nginx: Exposing TCP and UDP services][Exposing TCP and UDP services]。
[!WARNING]
一般不会同时使用 LoadBalancer 类型的 Service 和 Ingress 资源来暴露服务,这会造成管理上的混乱。
2. Ingress 控制器
使用 Ingress
时一般涉及 2 个组件:
- Ingress 清单:是
Kubernetes
中的一种 API 资源类型,它定义了从集群外部访问集群内服务的规则。通常,这些规则涉及到 HTTP 和 HTTPS 流量的路由和负载均衡。Ingress 对象本身只是一种规则定义,它需要一个 Ingress 控制器来实际执行这些规则。 - Ingress 控制器:是
Kubernetes
集群中的一个独立组件或服务,以 Pod 形式存在。它实际处理 Ingress 规则,根据这些规则配置集群中的代理服务器(如Nginx、Traefik 等)来处理流量路由和负载均衡。- Ingress 控制器负责监视 Ingress 对象的变化,然后动态更新代理服务器的配置以反映这些变化。
Kubernetes
社区提供了一些不同的Ingress 控制器,您可以根据需求选择合适的控制器。 - Ingress 控制器是实际承载流量转发的组件。每次更新 Ingress 规则后,都会动态加载到控制器中。
- Ingress 控制器负责监视 Ingress 对象的变化,然后动态更新代理服务器的配置以反映这些变化。
使用 Ingress 访问服务的流量链路如下:
- 用户流量通过公网 DNS 流入
Ingress Controller Pod
Ingress Controller Pod
根据配置的规则找到并转发流量给对应后端服务所在的 Node,(下面描述的是在集群内通过 ServiceName 访问服务的流量转发流程):- 首先会通过集群内的 CoreDNS 服务查询 ServiceName 对应的 ClusterIP。
- 然后通过节点所在的
kube-proxy
所配置好的 iptables 规则将流量转发给 Pod 所在的 Node。- 在 iptables 规则中可以找到 ClusterIP 的下一跳,即 Pod 所在的 Node IP。
- 若有多个 Pod 后端,则 iptables 中也会存在多条能匹配目标 ClusterIP 的规则,此时会按规则概率进行转发(默认都具有相同概率,也就是均衡)。
- Node 接收到流量后再根据(kube-proxy 所配置好的)本地 iptables 将流量转发给本地的 Pod。
Ingress
控制器不会随集群一起安装,需要单独安装。可以选择的 Ingress
控制器很多,可查看官方提供的 Ingress 控制器列表,再根据情况自行选择,常用的是 Nginx、Traefik。
3. 安装 Nginx Ingress 控制器
传统架构中常用 Nginx
作为外部网关,所以这里也使用 Nginx 作为 Ingress 控制器来练习。当然,它也可应用到生产环境。
先通过官方仓库页面的版本支持表确认控制器与 k8s 匹配的版本信息,笔者使用的 k8s 版本是1.27.0
,准备安装的 Nginx
ingress 控制器版本是1.8.2
。
安装方式有 Helm 安装和手动安装,Helm 是一个很好用的 k8s 包管理器(在进阶教程中有介绍),但这里先使用手动安装。
# 下载Nginx Ingress控制器安装文件
# 已经 githubusercontent 替换为 gitmirror
wget https://raw.gitmirror.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml -O nginx-ingress.yaml
# 查看需要的镜像
$ cat nginx-ingress.yaml|grep image:
image: registry.k8s.io/ingress-nginx/controller:v1.8.2@sha256:74834d3d25b336b62cabeb8bf7f1d788706e2cf1cfd64022de4137ade8881ff2
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b
# 在node1上手动拉取镜像(部署的Pod会调度到非Master节点)
$ grep -oP 'image:\s*\K[^[:space:]]+' nginx-ingress.yaml | xargs -n 1 ctr image pull
# 安装
$ kk apply -f nginx-ingress.yaml
# 等待控制器的pod运行正常(这里自动创建了一个新的namespace)
$ kk get pods --namespace=ingress-nginx --watch
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-kt8lm 0/1 Completed 0 2m36s
ingress-nginx-admission-patch-rslxl 0/1 Completed 2 2m36s
ingress-nginx-controller-6f4df7b5d6-lxfsr 1/1 Running 0 2m36s
# 注意前两个 Completed 的pod是一次性的,用于执行初始化工作,现在安装成功。
# 等待各项资源就绪
$ kk wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=120s
#查看安装的各种资源
$ kk get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-smxkz 0/1 Completed 0 16m
pod/ingress-nginx-admission-patch-7c86x 0/1 Completed 1 16m
pod/ingress-nginx-controller-6f4df7b5d6-pz8cp 1/1 Running 0 16m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 20.1.115.216 <pending> 80:31888/TCP,443:30158/TCP 16m
service/ingress-nginx-controller-admission ClusterIP 20.1.102.149 <none> 443/TCP 16m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 16m
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-6f4df7b5d6 1 1 1 16m
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 5s 16m
job.batch/ingress-nginx-admission-patch 1/1 7s 16m
可能会遇到 image 拉取失败,解决如下:
$ kk get pod -ningress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-csfjc 0/1 ImagePullBackOff 0 5m55s
ingress-nginx-admission-patch-rgdxr 0/1 ImagePullBackOff 0 5m55s
ingress-nginx-controller-6f4df7b5d6-dhfg2 0/1 ContainerCreating 0 5m55s
$ kk describe pod ingress-nginx-admission-create-csfjc -ningress-nginx
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m6s default-scheduler Successfully assigned ingress-nginx/ingress-nginx-admission-create-csfjc to k8s-node1
Normal BackOff 2m19s kubelet Back-off pulling image "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b"
Warning Failed 2m19s kubelet Error: ImagePullBackOff
Normal Pulling 2m5s (x2 over 3m20s) kubelet Pulling image "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b"
Warning Failed 15s (x2 over 2m19s) kubelet Failed to pull image "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b": rpc error: code = DeadlineExceeded desc = failed to pull and unpack image "registry.k8s.io/ingress-nginx/kube-webhook-certgen@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b": failed to resolve reference "registry.k8s.io/ingress-nginx/kube-webhook-certgen@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b": failed to do request: Head "https://us-west2-docker.pkg.dev/v2/k8s-artifacts-prod/images/ingress-nginx/kube-webhook-certgen/manifests/sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b": dial tcp 142.251.8.82:443: i/o timeout
# 发现无法访问 registry.k8s.io,参考 https://github.com/anjia0532/gcr.io_mirror 来解决
# 笔者发起issue来同步nginx用到的几个镜像到作者的docker仓库,大概1min完成同步,然后现在在节点手动拉取这个可访问的docker.io下的镜像进行替代
# 在非master节点执行(ctr是containerd cli):
ctr image pull docker.io/anjia0532/google-containers.ingress-nginx.kube-webhook-certgen:v20230407
ctr image pull docker.io/anjia0532/google-containers.ingress-nginx.controller:v1.8.2
# 替换模板中的镜像(mac环境需要在-i后面加 "",即sed -i "" 's#...')
sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b#docker.io/anjia0532/google-containers.ingress-nginx.kube-webhook-certgen:v20230407#' nginx-ingress.yaml
sed -i 's#registry.k8s.io/ingress-nginx/controller:v1.8.2@sha256:74834d3d25b336b62cabeb8bf7f1d788706e2cf1cfd64022de4137ade8881ff2#docker.io/anjia0532/google-containers.ingress-nginx.controller:v1.8.2#' nginx-ingress.yaml
# 重新部署
kk delete -f nginx-ingress.yaml --force
kk apply -f nginx-ingress.yaml
这里重点关注service/ingress-nginx-controller
这一行,这是 Nginx Ingress 自动创建的LoadBalancer
类型的 service,它会跟踪 Ingress 配置中的后端 Pod 组端点变化,并实时更新 Pod ingress-nginx-controller
中的转发规则,后者再转发流量到 service-hellok8s-clusterip
,然后最终到达业务 pod。
所以 Nginx Ingress Controller
启动后会默认监听节点的两个随机端口(这里是 31888/30158),分别对应其 Pod 内的 80/443,后面讲如何修改为节点固定端口。
4. 开始测试
准备工作:
4.1 修改 main.go
为 [main_nginxingress.go
]
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
host, _ := os.Hostname()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, fmt.Sprintf("[v3] Hello, Kubernetes!, this is ingress test, host:%s\n", host))
})
http.ListenAndServe(":3000", nil)
}
4.2 重新构建并推送镜像
docker build . -t leigg/hellok8s:v3_nginxingress
docker push leigg/hellok8s:v3_nginxingress
4.3 更新 deployment 镜像
更新 deployment 镜像:kk set image deployment/hellok8s-go-http hellok8s=leigg/hellok8s:v3_nginxingress
,并等待更新完成
4.4 部署 [deployment_httpd_svc.yaml]作为 Ingress 后端之一
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd-container
image: httpd
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: service-httpd
spec:
type: ClusterIP
selector:
app: httpd
ports:
- port: 8080
targetPort: 80
4.5 部署 Ingress [ingress-hellok8s.yaml]
在ingress-hellok8s.yaml
配置文件种,定义了路由规则:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hellok8s-ingress
annotations: # 通过注解来进一步控制nginx控制器的行为,参考 https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
nginx.ingress.kubernetes.io/rewrite-target: / # 匹配路由后,重写为 /; 比如 /hello 重写为 /
spec:
ingressClassName: nginx # 指定ingress控制器
rules:
- http:
paths:
- path: /hello # 默认不区分大小写,匹配/hello/123 不匹配/hello123
# 路径匹配类型
# - Prefix:前缀匹配,路由直接透传不会截断;另外还有 Exact、ImplementationSpecific类型
# - Exact:精确匹配 URL 路径,且区分大小写
# - ImplementationSpecific:默认匹配方式,具体由 ingressClass 决定
pathType: Prefix
backend:
service:
name: service-hellok8s-clusterip
port:
number: 3000
- path: /httpd
pathType: Prefix
backend:
service:
name: service-httpd
port:
number: 8080
4.6 在节点上验证
# 查看部署的资源(省略了不相关的资源)
$ kk get pods,svc,ingress
NAME READY STATUS RESTARTS AGE
pod/hellok8s-go-http-6bb87f8cb5-57r86 1/1 Running 1 (12h ago) 37h
pod/hellok8s-go-http-6bb87f8cb5-lgtgf 1/1 Running 1 (12h ago) 37h
pod/httpd-69fb5746b6-5v559 1/1 Running 0 97s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/httpd-svc ClusterIP 20.1.140.111 <none> 8080/TCP 97s
service/service-hellok8s-clusterip ClusterIP 20.1.112.41 <none> 3000/TCP 28h
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/hellok8s-ingress nginx * 80 9m18s
# 1-通过clusterIP访问httpd
$ curl 20.1.140.111:8080
<html><body><h1>It works!</h1></body></html>
# 前一节讲到的nginx 以LoadBalancer类型部署的svc,所以要通过节点访问,需要先获知svc映射到节点的端口号,如下为 80:31504, 443:32548
$ kk get svc -ningress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 20.1.251.172 <pending> 80:31504/TCP,443:32548/TCP 19h
ingress-nginx-controller-admission ClusterIP 20.1.223.76 <none> 443/TCP 19h
# 2-通过节点映射端口访问 /httpd
$ curl 127.0.0.1:31504/httpd
<html><body><h1>It works!</h1></body></html>
# 3-通过节点映射端口访问 /hello
$ curl 127.0.0.1:31504/hello
[v3] Hello, Kubernetes!, this is ingress test, host:hellok8s-go-http-6df8b5c5d7-75qb6
这就是基本的 ingress 使用步骤,还可以通过kk describe -f ingress-hellok8s.yaml
查看具体路由规则。
若要更新路由规则,修改 Ingress yaml 文件后再次应用即可,通过kk logs -f ingress-nginx-controller-xxx -n ingress-nginx
可以看到请求日志。
这里列出几个常见的配置示例,供读者自行练习:
- [虚拟域名:
ingress-hellok8s-host.yaml
]
#$ echo '127.0.0.1 hellok8s.foo.com' >> /etc/hosts
#$ curl hellok8s.foo.com:31504/hello
# [v3] Hello, Kubernetes!, From host: hellok8s-go-http-6df8b5c5d7-ll82f
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hellok8s-ingress
spec:
ingressClassName: nginx # 指定ingress控制器
rules:
- host: hellok8s.foo.com # 一旦配置了host,就不能再通过IP访问(会得到404结果)
http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: service-hellok8s-clusterip
port:
number: 3000
- [配置证书:
ingress-hellok8s-cert.yaml
]
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hellok8s-ingress
annotations: # 键值对形式的注解 可以进一步配置控制器的行为,比如rewrite路由、强制https等
# nginx ingress提供的注解选项:https://kubernetes.github.io/ingress-nginx/examples/rewrite/#deployment
nginx.ingress.kubernetes.io/ssl-redirect: "false" # 禁用https重定向到http,若ingress配置了证书则默认true
spec:
ingressClassName: nginx # 指定ingress控制器
tls:
- hosts:
- hellok8s.foo.com
secretName: hellok8s-tls # 引用 secret-hellok8s-cert.yaml 中配置的secret name
rules:
- host: hellok8s.foo.com
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: service-hellok8s-clusterip
port:
number: 3000
- [默认后端:
ingress-hellok8s-defaultbackend.yaml
]
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hellok8s-ingress
spec:
ingressClassName: nginx # 指定ingress控制器
defaultBackend: # 【默认后端】接收那些 没有被任何规则匹配的流量
service:
name: service-hellok8s-clusterip
port:
number: 3000
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: service-hellok8s-clusterip
port:
number: 3000
- [正则匹配:
ingress-hellok8s-regex.yaml
]
# $ curl 127.0.0.1:31504/hello/now_time
# [v3] Hello, Kubernetes!, now time: 2023-10-29 14:42:58.419522481 +0800 CST m=+36.879122145
# $ curl 127.0.0.1:31504/hello/
# [v3] Hello, Kubernetes!, From host: hellok8s-go-http-6df8b5c5d7-ll82f
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hellok8s-ingress
annotations: # 键值对形式的注解 可以进一步配置控制器的行为,比如rewrite路由、强制https等
# nginx ingress提供的注解选项:https://kubernetes.github.io/ingress-nginx/examples/rewrite/#deployment
# nginx.ingress.kubernetes.io/ssl-redirect: "false" # 禁用https重定向到http,若ingress配置了证书则默认true
# 若要路径支持正则匹配,需要配置下面两个注解
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1 # 可选,若路径被带括号的正则表达式匹配,则转发后的路径为 第一个路径分组,若不匹配,则不重写
spec:
ingressClassName: nginx # 指定ingress控制器
rules:
- http:
paths:
- path: /hello/(.*) # 正则匹配,括号内的内容为一个分组
pathType: Prefix
backend:
service:
name: service-hellok8s-clusterip
port:
number: 3000
5. Ingress 高可用部署
一般通过多节点部署的方式来实现高可靠,同时 Ingress
作为业务的流量入口,也建议一个 ingress
服务独占一个节点的方式进行部署,
避免业务服务与 ingress
服务发生资源争夺。
也就是说,单独使用一台机器来部署
ingress
服务,这台机器可以是较低计算性能(如2c4g
),但需要较高的上行带宽。
然后再根据业务流量规模(定期观察 ingress
节点的上行流量走势)进行 ingress 节点扩缩容。若前期规模不大,也可以 ingress
节点与业务节点混合部署的方式,但要注意进行资源限制和隔离。
5.1 下面给出常用指令,根据需要使用
Ingress
控制器扩容:
kk -n kube-system scale --replicas=3 deployment/nginx-ingress-controller
指定节点部署 ingress(通过打标签):
$ kk label nodes k8s-node1 ingress="true"
$ kk get node k8s-node1 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-node1 Ready <none> 2d22h v1.27.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
# 修改ingress部署文件,搜索Deployment,在其spec.template.spec.nodeSelector下面添加 ingress: "true"
$ vi deploy.yaml
#apiVersion: apps/v1
#kind: Deployment
#...
# nodeSelector:
# kubernetes.io/os: linux
# ingress: "true" # <----- 添加这行
#...
$ kk apply -f deploy.yaml # 更新部署
注意:默认不能将应用 Pod 部署到 master
节点,存在污点问题,需要移除污点才可以,参考 k8s-master 增加和删除污点。
6. Ingress 推荐部署方案
6.1 Deployment + LoadBalancer
模式的 Service
说明:如果要把 Ingress 部署到公有云,那用这种方式比较合适。用 Deployment
部署 ingress-controller
,创建一个 type为 LoadBalancer
的 service 关联这组 Pod(这是 Nginx Ingress 的默认部署方式)。
大部分公有云,都会为 LoadBalancer
的 service自动创建(并关联)一个负载均衡器,通常还分配了公网 IP。只需要在负载均衡器上配置域名和证书,就实现了集群服务的对外暴露。
6.2 DaemonSet + HostNetwork + nodeSelector
说明:用 DaemonSet
结合 nodeSelector
来部署 ingress-controller
到特定的 node 上,然后使用 HostNetwork
直接把该 pod 与宿主机node 的网络打通,直接使用节点的 80/433 端口就能访问服务。
这时,ingress-controller
所在的 node 机器就很类似传统架构的边缘节点,比如机房入口的 nginx 服务器。该方式整个请求链路最简单,性能相对NodePort 模式更好。
有一个问题是由于直接利用宿主机节点的网络和端口,一个 node 只能部署一个 ingress-controller Pod
,但这在生产环境下也不算是问题,只要完成多节点部署实现高可用即可。然后将 Ingress 节点公网 IP 填到域名 CNAME 记录中即可。
笔者提供测试通过的 ingress-nginx 模板供读者练习:[ingress-nginx-daemonset-hostnetwork.yaml
],主要修改了 3 处:
Deployment
改为DaemonSet
。- 注释
DaemonSet
模块的strategy
部分(strategy 是 Deployment 模块下的字段)。 - 在 DaemonSet 模块的
spec.template.spec
下添加hostNetwork: true
,使用这个模板后,可以观察到在 k8s-node1 上会监听 80、443 和 8443 端口(ingress-nginx 需要的端口)。
apiVersion: v1
kind: Namespace
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
name: ingress-nginx
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
namespace: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resourceNames:
- ingress-nginx-leader
resources:
- leases
verbs:
- get
- update
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
namespace: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
- namespaces
verbs:
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
rules:
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
verbs:
- get
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: v1
data:
allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller
namespace: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
externalTrafficPolicy: Local
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- appProtocol: http
name: http
port: 80
protocol: TCP
targetPort: http
- appProtocol: https
name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller-admission
namespace: ingress-nginx
spec:
ports:
- appProtocol: https
name: https-webhook
port: 443
targetPort: webhook
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: ClusterIP
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
minReadySeconds: 0
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
# strategy:
# rollingUpdate:
# maxUnavailable: 1
# type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
spec:
hostNetwork: true
containers:
- args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
image: docker.io/anjia0532/google-containers.ingress-nginx.controller:v1.8.2
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: controller
ports:
- containerPort: 80
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
- containerPort: 8443
name: webhook
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 90Mi
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
runAsUser: 101
volumeMounts:
- mountPath: /usr/local/certificates/
name: webhook-cert
readOnly: true
dnsPolicy: ClusterFirst
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-create
namespace: ingress-nginx
spec:
template:
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-create
spec:
containers:
- args:
- create
- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
- --namespace=$(POD_NAMESPACE)
- --secret-name=ingress-nginx-admission
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: docker.io/anjia0532/google-containers.ingress-nginx.kube-webhook-certgen:v20230407
imagePullPolicy: IfNotPresent
name: create
securityContext:
allowPrivilegeEscalation: false
nodeSelector:
kubernetes.io/os: linux
restartPolicy: OnFailure
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
serviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-patch
namespace: ingress-nginx
spec:
template:
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-patch
spec:
containers:
- args:
- patch
- --webhook-name=ingress-nginx-admission
- --namespace=$(POD_NAMESPACE)
- --patch-mutating=false
- --secret-name=ingress-nginx-admission
- --patch-failure-policy=Fail
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: docker.io/anjia0532/google-containers.ingress-nginx.kube-webhook-certgen:v20230407
imagePullPolicy: IfNotPresent
name: patch
securityContext:
allowPrivilegeEscalation: false
nodeSelector:
kubernetes.io/os: linux
restartPolicy: OnFailure
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
serviceAccountName: ingress-nginx-admission
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: nginx
spec:
controller: k8s.io/ingress-nginx
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: ingress-nginx-controller-admission
namespace: ingress-nginx
path: /networking/v1/ingresses
failurePolicy: Fail
matchPolicy: Equivalent
name: validate.nginx.ingress.kubernetes.io
rules:
- apiGroups:
- networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- ingresses
sideEffects: None
6.3 Deployment + NodePort
模式的 Service
说明:同样用 Deployment 模式部署 ingress-controller,并创建对应的 service,但是 type 为NodePort
。这样,Ingress 就会暴露在集群节点ip 的特定端口上。然后可以直接将 Ingress 节点公网 IP 填到域名 CNAME 记录中。
笔者提供测试通过 ingress-nginx
模板供读者练习:[ingress-nginx-deployment-nodeport.yaml],主要修改了 2 处:
- Service 模块下spec.ports
部分新增nodePort: 30080
和nodePort: 30443
(注意nodePort
对应的端口范围受到限制:30000-32767)。
这种方式可以使用的节点端口受到了固定范围限制,具有一定局限性,应用规划端口时需要考虑到这一点。
apiVersion: v1
kind: Namespace
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
name: ingress-nginx
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
namespace: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resourceNames:
- ingress-nginx-leader
resources:
- leases
verbs:
- get
- update
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
namespace: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
- namespaces
verbs:
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
rules:
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
verbs:
- get
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: v1
data:
allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller
namespace: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
externalTrafficPolicy: Local
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- appProtocol: http
name: http
port: 80
protocol: TCP
targetPort: http
nodePort: 30080 # add --
- appProtocol: https
name: https
port: 443
protocol: TCP
targetPort: https
nodePort: 30443 # add --
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller-admission
namespace: ingress-nginx
spec:
ports:
- appProtocol: https
name: https-webhook
port: 443
targetPort: webhook
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
minReadySeconds: 0
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
strategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
spec:
containers:
- args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
image: docker.io/anjia0532/google-containers.ingress-nginx.controller:v1.8.2
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: controller
ports:
- containerPort: 80
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
- containerPort: 8443
name: webhook
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 90Mi
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
runAsUser: 101
volumeMounts:
- mountPath: /usr/local/certificates/
name: webhook-cert
readOnly: true
dnsPolicy: ClusterFirst
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-create
namespace: ingress-nginx
spec:
template:
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-create
spec:
containers:
- args:
- create
- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
- --namespace=$(POD_NAMESPACE)
- --secret-name=ingress-nginx-admission
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: docker.io/anjia0532/google-containers.ingress-nginx.kube-webhook-certgen:v20230407
imagePullPolicy: IfNotPresent
name: create
securityContext:
allowPrivilegeEscalation: false
nodeSelector:
kubernetes.io/os: linux
restartPolicy: OnFailure
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
serviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-patch
namespace: ingress-nginx
spec:
template:
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission-patch
spec:
containers:
- args:
- patch
- --webhook-name=ingress-nginx-admission
- --namespace=$(POD_NAMESPACE)
- --patch-mutating=false
- --secret-name=ingress-nginx-admission
- --patch-failure-policy=Fail
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: docker.io/anjia0532/google-containers.ingress-nginx.kube-webhook-certgen:v20230407
imagePullPolicy: IfNotPresent
name: patch
securityContext:
allowPrivilegeEscalation: false
nodeSelector:
kubernetes.io/os: linux
restartPolicy: OnFailure
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
serviceAccountName: ingress-nginx-admission
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: nginx
spec:
controller: k8s.io/ingress-nginx
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.2
name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: ingress-nginx-controller-admission
namespace: ingress-nginx
path: /networking/v1/ingresses
failurePolicy: Fail
matchPolicy: Equivalent
name: validate.nginx.ingress.kubernetes.io
rules:
- apiGroups:
- networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- ingresses
sideEffects: None
练习时,如对 ingress-nginx 模板有修改,建议完全删除该模板对应资源(使用kk delete -f deploy.yaml
,操作可能会耗时几十秒),否则直接应用可能不会生效。