ingress做为k8s集群的入口非常重要,能实现ingress功能的软件很多,可根据自身需求选择。本篇博客主要使用nginx官方提供的nginx-ingress完成了http/https7层代理和tcp四层代理的环境配置。
系统环境
1,k8s的版本为1.8.2
2,docker ce的版本为19.03.8-3
3,五台主机操作系统版本为centos7,kernel版本3.10.0-957
4,使用五台主机部署,3台master节点+2台work节点
5,Ingress测试域名t.myk8s.com
部署nginx和apache应用
使用Deployment部署nginx
nginx服务的manifest:
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17
livenessProbe: # 设置存活探针,如果检测失败则重启pod
httpGet:
path: /
port: 80
scheme: HTTP
initialDelaySeconds: 30 # 启动容器手册监控检查的等待时间
timeoutSeconds: 5 # 健康检查请求的超时时间,如果超时,则重启该pod
readinessProbe: # 设置存活探针,通过探针检测的Pod才会像其转发请求
httpGet:
path: /
port: 80
scheme: HTTP
ports:
- containerPort: 80 # 设置为pod中应用监听的端口
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
ports:
- name: http
port: 80 # service服务访问的端口
protocol: TCP
targetPort: 80 # 设置为pod中应用监听的端口
selector:
app: nginx
apache服务的manifests:
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: httpd
spec:
selector:
matchLabels:
app: httpd
replicas: 1 # tells deployment to run 2 pods
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: httpd:2.4
livenessProbe: # 设置存活探针,如果检测失败则重启pod
httpGet:
path: /
port: 80
scheme: HTTP
initialDelaySeconds: 30 # 启动容器手册监控检查的等待时间
timeoutSeconds: 5 # 健康检查请求的超时时间,如果超时,则重启该pod
readinessProbe: # 设置存活探针,通过探针检测的Pod才会像其转发请求
httpGet:
path: /
port: 80
scheme: HTTP
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpd
namespace: default
labels:
app: httpd
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: httpd
通过manifest配置k8s,使用--record选项记录命令和版本信息方便后续的升级或者回滚等操作:
# kubectl apply -f nginx-dp.yaml --record
# kubectl apply -f httpd-dp.yaml --record
查看应用状态:
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-7c456f6cf9-gb7gk 1/1 Running 0 3m15s 10.107.199.77 work2
nginx-5577575ddd-499wr 1/1 Running 0 46m 10.109.125.196 work3
nginx-5577575ddd-7zwmv 1/1 Running 0 48m 10.99.1.85 work1
查看services状态,通过services暴露出来的固定ip可以实现对应应用的访问:
# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd ClusterIP 10.104.235.200 80/TCP 45m
kubernetes ClusterIP 10.96.0.1 443/TCP 6d5h
nginx ClusterIP 10.111.5.31 80/TCP 57m
Ingress配置http访问应用
Ingress控制器的部署方式使用daemon-set+hostNetwork方式,且使用nginx官方提供的nginx-ingress控制器(https://blog.51cto.com/leejia/2495558)。
生成配置Ingress的manifests:
# vim http-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: http-ingress
spec:
rules:
- host: t.myk8s.com
http:
paths:
- path: /index.html
backend:
serviceName: nginx
servicePort: 80
- path: /
backend:
serviceName: httpd
servicePort: 80
# kubectl apply -f http-ingress.yaml
查看状态:
# kubectl get ingress -o wide
NAME CLASS HOSTS ADDRESS PORTS AGE
http-ingress t.myk8s.com 80 102m
master集群中其中一台master的ip为172.18.2.175,在本地pc测试访问:
~ curl -H 'Host: t.myk8s.com' 172.18.2.175
It works!
➜ ~ curl -H 'Host: t.myk8s.com' 172.18.2.175/index.html
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
Ingress配置https访问应用
我们使用自签名证书来实现https的访问:
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ingress.key -out ingress.crt -subj "/CN=t.myk8s.com/O=t.myk8s.com"
通过secret存储证书:
# kubectl create secret tls ingress-secret --key ingress.key --cert ingress.crt
# kubectl get secrets
NAME TYPE DATA AGE
ingress-secret kubernetes.io/tls 2 2s
注意如下ingress资源要和上面的secret资源在同一个namespace下面:
# vim nginx-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: http-ingress
spec:
tls:
- hosts:
- t.myk8s.com
secretName: ingress-secret
rules:
- host: t.myk8s.com
http:
paths:
- path: /index.html
backend:
serviceName: nginx
servicePort: 80
- path: /
backend:
serviceName: httpd
servicePort: 80
使用本地pc测试访问,默认http访问也会强制转https:
➜ ~ curl https://t.myk8s.com -k
It works!
➜ ~ curl http://t.myk8s.com -I -k
HTTP/1.1 301 Moved Permanently
Server: nginx/1.17.10
Date: Thu, 21 May 2020 03:53:06 GMT
Content-Type: text/html
Content-Length: 170
Connection: keep-alive
Location: https://t.myk8s.com:443/
➜ ~ curl https://t.myk8s.com/index.html -k
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
可以通过配置nginx-ingress控制器实现http和https同时支持访问,config map的name以及namespace要和nginx -ingress控制器使用的相同:
# vim nginx-cf.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
data:
ssl-redirect: "false"
# kubectl apply -f nginx-cf.yaml -n nginx-ingress
# kubectl get configmap -n nginx-ingress
NAME DATA AGE
nginx-config 1 6d19h
默认nginx-ingress控制器不提供tcp和udp代理功能,但是nginx是支持的,故也可以通过调整nginx-ingress控制器来提供tcp和udp代理服务
配置nginx-ingress做4层tcp代理
打开nginx官方的nginx-ingress仓库,然后修改mainifests,使nginx加载tcp和udp代理的相关配置(即在nginx-ingress.yaml的args下面添加global-configuration配置):
# git clone https://github.com/nginxinc/kubernetes-ingress/
# cd kubernetes-ingress/deployments
# git checkout v1.7.0
# vim daemon-set/nginx-ingress.yaml
- -global-configuration=$(POD_NAMESPACE)/nginx-configuration
# kubectl apply -f daemon-set/nginx-ingress.yaml
生成tcp代理相关的manifests:
# vim global-configuration.yaml
apiVersion: k8s.nginx.org/v1alpha1
kind: GlobalConfiguration
metadata:
name: nginx-configuration
namespace: nginx-ingress
spec:
listeners:
- name: nginx-tcp
port: 8000
protocol: TCP
# vim global-configuration.yaml
apiVersion: k8s.nginx.org/v1alpha1
kind: GlobalConfiguration
metadata:
name: nginx-configuration
namespace: nginx-ingress
spec:
listeners:
- name: nginx-tcp
port: 8000
protocol: TCP
[root@master1 manifests]# cat transport-server-passthrough.yaml
apiVersion: k8s.nginx.org/v1alpha1
kind: TransportServer
metadata:
name: nginx-tcp
spec:
listener:
name: nginx-tcp
protocol: TCP
upstreams:
- name: nginx-app
service: nginx
port: 80
action:
pass: nginx-app
# kubectl apply -f global-configuration.yaml
# kubectl apply -f transport-server-passthrough.yaml
在本地pc测试访问
➜ ~ curl http://172.18.2.175:8000/index.html
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
手动对nginx-ingress的后端nginx服务扩缩容和升级回滚
由2台水平扩容为3台,扩容期间服务无影响:
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-7c456f6cf9-gb7gk 1/1 Running 0 27h 10.107.199.77 work2
nginx-5577575ddd-pz59n 1/1 Running 0 18s 10.99.1.91 work1
nginx-5577575ddd-qsrb2 1/1 Running 0 18s 10.109.125.207 work3
# kubectl scale deployment nginx --replicas 3
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-7c456f6cf9-gb7gk 1/1 Running 0 27h 10.107.199.77 work2
nginx-5577575ddd-j4nq4 1/1 Running 0 13s 10.107.199.84 work2
nginx-5577575ddd-pz59n 1/1 Running 0 68s 10.99.1.91 work1
nginx-5577575ddd-qsrb2 1/1 Running 0 68s 10.109.125.207 work3
由3台水平缩容为1台,缩容期间服务无影响:
# kubectl scale deployment nginx --replicas 1
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-7c456f6cf9-gb7gk 1/1 Running 0 27h 10.107.199.77 work2
nginx-5577575ddd-pz59n 1/1 Running 0 102s 10.99.1.91 work1
平滑升级,先启动一个新版本的pod,然后流量切到新pod之后,再关闭老版本的pod
# kubectl set image deployment nginx nginx=nginx:1.18 --record
# kubectl rollout status deployment nginx
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
deployment "nginx" successfully rolled out
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-7c456f6cf9-gb7gk 1/1 Running 0 27h 10.107.199.77 work2
nginx-648f9b4559-m2b8m 1/1 Running 0 19s 10.109.125.208 work3
# kubectl get deployment nginx -o yaml|grep '\- image:'
- image: nginx:1.18
查看历史操作deployment的命令
# kubectl rollout history deployment nginx
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 kubectl apply --filename=nginx-dp.yaml --record=true
2 kubectl set image deployment nginx nginx=nginx:1.18 --record=true
可以通过两种方式回滚:
第一种:回滚最近一次操作
# kubectl rollout undo deployment nginx
# kubectl get deployment nginx -o yaml|grep '\- image:'
- image: nginx:1.17
第二种:回滚到指定的命令版本,即执行对应的命令
# kubectl rollout undo deployment nginx --to-revision=1
参考文档
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#deploymentspec-v1-apps
https://kubernetes.github.io/ingress-nginx/user-guide/tls/
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/globalconfiguration-resource/
https://docs.nginx.com/nginx-ingress-controller/configuration/transportserver-resource/