Kubernetes之Ingress-nginx部署使用
2021-06-03 18:02
标签:规则 create 重复 data grep 详细信息 关联 sts client 博文大纲: 在Kubernetes中,服务和Pod的IP地址仅在集群内部网络内部使用,对于集群的应用是不可见的。 为了使外部的应用能够访问集群内的服务,在Kubernetes目前提供了以下几种方案: Ingress 是反向代理规则,用来规定 HTTP/S 请求应该被转发到哪个 Service 上,比如根据请求中不同的 Host 和 url 路径让请求落到不同的 Service 上; 1)Ingress controller通过与Kubernetes api进行交互,动态的感知集群中Ingress规则的变化; 1)动态配置服务 搭建私有仓库的目的,仅仅是为了更快的获取镜像,如果网络稳定,也可跳过此步骤! 创建ingress-nginx资源所使用的镜像链接:https://pan.baidu.com/s/1skhA3jSCH7-c-iStCXbuNQ 获取Ingress-nginx的yaml文件,方法如下: 关于上面yaml文件中写入的“hostNetwork: true”具体解释:如果添加了此字段,意味着pod中运行的应用可以直接使用node节点的端口,这样node节点主机所在网络的其他主机,就可以通过访问该端口访问此应用。(类似于docker映射到宿主机的端口。) 其实,至此已经实现了我们想要的功能,前提是自行配置DNS解析,或者直接修改client的hosts文件。访问页面如下(注意:一定要自己解决域名解析的问题,若不知道域名对应的是哪个IP,请跳过这两个图,看下面的文字解释): 访问httpd服务(自定义首页内容): 访问tomcat服务: 在上面的访问测试中,虽然访问到了对应的服务,但是有一个弊端,就是在做DNS解析的时候,只能指定Ingress-nginx容器所在的节点IP。而指定k8s集群内部的其他节点IP(包括master)都是不可以访问到的,如果这个节点一旦宕机,Ingress-nginx容器被转移到其他节点上运行(不考虑节点标签的问题,其实保持Ingress-nginx的yaml文件中默认的标签的话,那么每个节点都是有那个标签的)。随之还要我们手动去更改DNS解析的IP(要更改为Ingress-nginx容器所在节点的IP,通过命令“kubectl get pod -n ingress-nginx -o wide”可以查看到其所在节点),很是麻烦。 有没有更简单的一种方法呢?答案是肯定的,就是我们为Ingress-nginx规则再创建一个类型为nodePort的Service,这样,在配置DNS解析时,就可以使用www.lzj.com 绑定所有node节点,包括master节点的IP了,很是灵活。 在刚才获取Ingress-controller资源对象的yaml文件的页面,然后下拉页面,即可看到以下,可以根据k8s集群环境来选择适合自己的yaml文件。假如自己是在Azure云平台搭建的K8s集群,则选择复制Azure下面的命令即可,我这里是自己的测试环境,所以选择Bare-metal下面的yaml文件,如图: 至此,这个www.lzj.com 的域名即可和群集中任意节点的30487/31111端口进行绑定了。 测试如下(域名解析对应的IP可以是k8s群集内的任意节点IP): 如果需要将www.lzj.com 和www.zhj.com 都对应上后端的pod容器所运行的服务。应进行以下配置: 至此,即可实现访问www.lzj.com 和www.zhj.com 都可以访问到后端的httpd提供的页面(自行解决域名解析问题),如下: Ingress-nginx资源的流程总结,如图: 在真正的生产环境中,创建Ingress Controller肯定使用的是DaemonSet资源类型,来保证Ingress Controller的高可用! 在上面的操作中,实现了使用ingress-nginx为后端所有pod提供一个统一的入口,那么,有一个非常严肃的问题需要考虑,就是如何为我们的pod配置CA证书来实现HTTPS访问?在pod中直接配置CA么?那需要进行多少重复性的操作?而且,pod是随时可能被kubelet杀死再创建的。当然这些问题有很多解决方法,比如直接将CA配置到镜像中,但是这样又需要很多个CA证书。 在上面的一系列流程中,关键的点就在于ingress规则,我们只需要在ingress的yaml文件中,为域名配置CA证书即可,只要可以通过HTTPS访问到域名,至于这个域名是怎么关联到后端提供服务的pod,这就是属于k8s群集内部的通信了,即便是使用http来通信,也无伤大雅。 为了简单起见,以下配置在上述环境下执行以下配置: 访问测试: ———————— 本文至此结束,感谢阅读 ———————— Kubernetes之Ingress-nginx部署使用 标签:规则 create 重复 data grep 详细信息 关联 sts client 原文地址:https://blog.51cto.com/14157628/2472849
一、Ingress简介
1)Ingress组成
2)Ingress工作原理
3) Ingress可以解决什么问题?
二、配置Ingress-nginx
1)搭建registry私有仓库
2)创建用于测试的Pod
2)创建tomcat服务及其service
3)确保以上资源对象成功创建
4)创建Ingress-controller资源对象
5)创建Ingress资源对象
6)为Ingress-controller资源对象创建一个service资源对象
7)创建基于虚拟主机的Ingress规则
三、配置HTTPS一、Ingress简介
1)NodePort
2)LoadBalancer
3)Ingress1)Ingress组成
Ingress Controller 就是一个反向代理程序,它负责解析 Ingress 的反向代理规则,如果 Ingress 有增删改的变动,所有的 Ingress Controller 都会及时更新自己相应的转发规则,当 Ingress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service;2)Ingress工作原理
2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置;
3)再写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中;
4)然后reload一下使配置生效。以此达到域名分别配置和动态更新的问题;3) Ingress可以解决什么问题?
如果是按照传统方式,当新增加一个服务时,我们可能需要在流量入口部署一台反向代理服务器指向我们新的K8s服务,而如果使用了Ingress,则只需配置好这个服务,当服务启动时,便会自动注册到Ingress中,不需要额外的操作;
2)减少不必要的端口映射
配置过k8s的都清楚, 第一步是要关闭防火墙的, 主要原因是k8s的很多服务会以NodePort方式映射出去, 这样就相当于给宿主机打了很多孔, 既不安全也不优雅. 而Ingress可以避免这个问题, 除了Ingress自身服务可能需要映射出去, 其他服务都不用NodePort方式;二、配置Ingress-nginx
1)搭建registry私有仓库
[root@master ~]# docker run -itd --name registry --restart=always -p 5000:5000 -v /registry:/var/lib/registry registry:2
#搭建registry私有仓库
[root@master ~]# vim /usr/lib/systemd/system/docker.service
#修改docker的配置文件,指向私有仓库
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.1.4:5000
[root@master ~]# scp /usr/lib/systemd/system/docker.service root@node01:/usr/lib/systemd/system/
[root@master ~]# scp /usr/lib/systemd/system/docker.service root@node02:/usr/lib/systemd/system/
#将修改好的配置文件发送到Kubernetes集群中的各个节点
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart docker
#所有节点都需重新启动服务
[root@master ~]# docker pull httpd
[root@master ~]# docker pull tomcat:8.5.45
[root@master ~]# docker tag httpd:latest 192.168.1.4:5000/httpd:v1
[root@master ~]# docker tag tomcat:8.5.45 192.168.1.4:5000/tomcat:v1
[root@master ~]# docker push 192.168.1.4:5000/httpd:v1
[root@master ~]# docker push 192.168.1.4:5000/tomcat:v1
#下载使用的镜像,并将其上传到私有仓库
2)创建用于测试的Pod
1)创建httpd服务及其service
[root@master ~]# vim httpd01.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test-ns
#创建名称空间test-ns
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpd01
namespace: test-ns
spec:
replicas: 2
template:
metadata:
labels:
app: httpd-01
spec:
containers:
- name: httpd
image: 192.168.1.4:5000/httpd:v1
#使用httpd的镜像创建Deployment资源,副本数量为2个,并打标签为httpd-01
---
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
namespace: test-ns
spec:
selector:
app: httpd-01
ports:
- protocol: TCP
port: 80
targetPort: 80
#创建service资源对象与Deployment资源使用标签的方式进行关联
[root@master ~]# kubectl apply -f httpd01.yaml
2)创建tomcat服务及其service
[root@master ~]# vim tomcat01.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tomcat01
namespace: test-ns
spec:
replicas: 2
template:
metadata:
labels:
app: tomcat-01
spec:
containers:
- name: tomcat
image: 192.168.1.4:5000/tomcat:v1
#使用tomcat的镜像创建Deployment资源,副本数量为2个,并打标签为tomcat-01
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
namespace: test-ns
spec:
selector:
app: tomcat-01
ports:
- protocol: TCP
port: 8080
targetPort: 8080
#创建service资源对象与Deployment资源使用标签的方式进行关联
[root@master ~]# kubectl apply -f tomcat01.yaml
3)确保以上资源对象成功创建
[root@master ~]# kubectl get pod -n test-ns #确保pod正常运行
NAME READY STATUS RESTARTS AGE
httpd01-6575d9cdcd-kjcmm 1/1 Running 0 13m
httpd01-6575d9cdcd-tjkwk 1/1 Running 0 13m
tomcat01-65b74df4d4-6b9vz 1/1 Running 0 11m
tomcat01-65b74df4d4-wfhfz 1/1 Running 0 11m
[root@master ~]# kubectl get svc -n test-ns #确保service创建成功
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc ClusterIP 10.104.32.150
4)创建Ingress-controller资源对象
提取码:nx6o [root@master ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/mandatory.yaml
[root@master ~]# vim mandatory.yaml
#对下载的yaml文件进行简单的修改
spec: #定位到212行,也就是该行
hostNetwork: true #添加该行,表示使用主机网络
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
Ingress: nginx ##设置节点的标签选择器,指定在哪台节点上运行
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.29.0
#该资源使用的镜像,该镜像下载较慢,可使用步骤开头提供的网盘链接!
[root@master ~]# kubectl label nodes node01 Ingress=nginx
#对node01节点打相应的标签,以便指定Ingress-nginx运行在node01
[root@master ~]# kubectl get nodes node01 --show-labels
#查看node01的标签是否存在
[root@node01 ~]# docker load
[root@master ~]# kubectl get pod -n ingress-nginx -o wide
#确认Ingress-nginx容器正常运行
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-577ffd8c54-zntwl 1/1 Running 0 9s 192.168.1.5 node01
5)创建Ingress资源对象
[root@master ~]# vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
namespace: test-ns
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: www.lzj.com
http:
paths:
- path: /
backend:
serviceName: httpd-svc
servicePort: 80
- path: /tomcat
backend:
serviceName: tomcat-svc
servicePort: 8080
#通过www.lzj.com 来访问到我们后端httpd容器提供的服务;
#通过www.lzj.com/tomcat 来访问我们后端tomcat提供的服务
[root@master ~]# kubectl apply -f ingress.yaml
ingress.extensions/test-ingress created
[root@master ~]# kubectl get ingresses. -n test-ns
#创建Ingress资源对象
NAME HOSTS ADDRESS PORTS AGE
test-ingress www.lzj.com 80 23s
6)为Ingress-controller资源对象创建一个service资源对象
创建这个Service有两种方法:一是直接复制其web页面的命令到master节点上执行,二是将其链接地址复制到终端使用wget下载下来再执行,本次采用第二种方法,顺便可以查看文件中内容。[root@master ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@master ~]# cat service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
[root@master ~]# kubectl apply -f service-nodeport.yaml
[root@master ~]# kubectl get svc -n ingress-nginx
#查看运行的service对象
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.96.121.169
至此,就实现了最初的需求!7)创建基于虚拟主机的Ingress规则
[root@master ~]# vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
namespace: test-ns
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: www.lzj.com
http:
paths:
- path: /
backend:
serviceName: httpd-svc
servicePort: 80
- path: /tomcat
backend:
serviceName: tomcat-svc
servicePort: 8080
- host: www.zhj.com #就是将原本的域名对应的svc服务复制一份,更改一下域名而已!
http:
paths:
- path: /
backend:
serviceName: httpd-svc
servicePort: 80
- path: /tomcat
backend:
serviceName: tomcat-svc
servicePort: 8080
[root@master ~]# kubectl apply -f ingress.yaml
从图中可以看出:后端有多个pod,pod与service进行关联,service又被ingress规则发现并动态写入到ingress-nginx-controller容器中,然后又为ingress-nginx-controller创建了一个Service映射到群集节点上的端口,来供client来访问。三、配置HTTPS
配置如下:
[root@node01 ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
#创建CA证书
[root@node01 ~]# ls | grep tls #确认产生了以下两个文件
tls.crt
tls.key
[root@master ~]# kubectl create secret tls tls-secret --key=tls.key --cert tls.crt
#创建secret资源对象
[root@master ~]# kubectl describe secrets tls-secret
#查看secret资源对象详细信息
Name: tls-secret
Namespace: default
Labels:
下一篇:HTTP协议详解之消息报头篇
文章标题:Kubernetes之Ingress-nginx部署使用
文章链接:http://soscw.com/index.php/essay/90104.html