k8s service - ingress
为什么需要 ingress ?
k8s 默认提供 service 负载均衡 ,而传统的 service 只是 4 层负载( ip + port), 而 ingress 提供了 7 层负载,即可以通过域名访问
流程图
ingress-nginx 安装
ingress nginx 主页: ingress-nginx
[root@k8s-node2 ~]# kubectl apply \n
-f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml
执行成功:
[root@k8s-master ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create--1-qwk9n 0/1 Completed 0 4m30s
ingress-nginx-admission-patch--1-jf5w9 0/1 Completed 0 4m23s
ingress-nginx-controller-5ccb4b77c6-grp2n 1/1 Running 0 12m
docker 导出和导入
# 如果下载不下来,可以重新打tag, 然后导入
[root@k8s-node2 ~]# docker save -o ingress.nginx.controller.tar k8s.gcr.io/ingress-nginx/controller
[root@k8s-node2 ~]# docker load -i ingress.nginx.controller.tar
创建 pod 和 service
ingress 是需要提前创建好service资源 的
[root@k8s-master ingress]# cat nginx_pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: ingress-svc-ngx
labels:
app: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 32500
[root@k8s-master ingress]# kubectl apply -f nginx_pod.yaml
[root@k8s-master ingress]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-75b69bd684-hr52q 1/1 Running 0 4h12m
my-nginx-75b69bd684-qnkzd 1/1 Running 0 4h12m
[root@k8s-master ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-svc-ngx NodePort 10.107.74.75 <none> 80:32500/TCP 4h15m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d15h
[root@k8s-master ingress]# curl http://192.168.1.16:32500
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
# nodeport 方式访问正常
http 访问
[root@k8s-master ingress]# cat nginx_http.yaml
apiVersion: networking.k8s.io/v1 # kubernates 1.19 之后 api版本变成 networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-myservicea
spec:
rules:
- host: foo.example.com # 虚拟主机
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-svc-ngx
port:
number: 80
ingressClassName: nginx # 这里也变了!!
[root@k8s-master ingress]# kubectl apply -f nginx_http.yaml
ingress.networking.k8s.io/ingress-myservicea created
修改 hosts 文件
# 另一台机器
root@z:# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 z
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
# 虚拟主机
192.168.1.16 foo.example.com
## 访问
root@z:/home/xiao# curl http://foo.example.com:32500/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
# 访问正常
进入 ingress-nginx 容器
[root@k8s-master ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create--1-qwk9n 0/1 Completed 0 4h58m
ingress-nginx-admission-patch--1-jf5w9 0/1 Completed 0 4h57m
ingress-nginx-controller-5ccb4b77c6-grp2n 1/1 Running 0 5h5m ## 进入这个容器
[root@k8s-master ingress]# kubectl exec -it ingress-nginx-controller-5ccb4b77c6-grp2n
-n ingress-nginx -- bash
bash-5.1$ ls
bash-5.1$ pwd
/etc/nginx
bash-5.1$ cat nginx.conf
## start server foo.example.com
server {
server_name foo.example.com ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
location / {
set $namespace "default";
set $ingress_name "ingress-myservicea";
set $service_name "ingress-svc-ngx";
set $service_port "80";
set $location_path "/";
set $global_rate_limit_exceeding n;
rewrite_by_lua_block {
可以发现已经将 foo.example.com
进行了代理
https 访问
创建证书
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}"
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
# 在k8s 集群中创建 secret
# kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE}
$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
[root@k8s-master ingress]# cat nginx_https.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-https
spec:
tls: # 这里!!
- hosts:
- foo.example.com
secretName: tls-secret
rules:
- host: foo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-svc-ngx
port:
number: 80
ingressClassName: nginx
[root@k8s-master ingress]# kubectl apply -f nginx_https.yaml
ingress.networking.k8s.io/ingress-https created
[root@k8s-master ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.107.253.177 80:31692/TCP,443:30472/TCP 5h25m
ingress-nginx-controller-admission ClusterIP 10.97.237.20 443/TCP 5h25m
访问: https://foo.example.com:30472
, 看的是 443 对应的端口