一、部署Ingress Controller

1.从k8s官方下载ingress相关的yaml

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

2.创建相关的资源

# kubectl create -f mandatory.yaml 
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-5694ccb578-9m8j8   1/1     Running   0          33m

3.部署ingress-nginx service

ingress-controller对外提供服务还需要手动给ingress-controller建立一个servcie,接收集群外部流量

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
# 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
      nodePort: 30080
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
      nodePort: 30443
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

此处指定了外部访问端口分别为30080,30443

# kubectl apply -f service-nodeport.yaml
# kubectl get svc -n ingress-nginx 
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.97.155.141           80:30080/TCP,443:30443/TCP   4m22s

4.检查ingress-nginx服务,验证配置

# curl 20.0.20.101:30080

404 Not Found

404 Not Found


nginx/1.15.10

5.部署一个后端服务

# cat deploy-myapp.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  selector:
    app: myapp
    release: canary
  ports:
  - name: http
    targetPort: 80
    port: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-backend-pod
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - name: http
          containerPort: 80
# kubectl create -f deploy-myapp.yaml 
service/myapp created
deployment.apps/myapp-backend-pod created
# kubectl get pod
NAME                                 READY   STATUS    RESTARTS   AGE
myapp-backend-pod-675558bfc5-f9nql   1/1     Running   0          33s
myapp-backend-pod-675558bfc5-p2tnh   1/1     Running   0          33s
myapp-backend-pod-675558bfc5-xvfhh   1/1     Running   0          33s
# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
myapp        ClusterIP   10.109.227.104           80/TCP    97s

6.定义访问myapp的ingress策略

# cat ingress-myapp.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-myapp
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: myapp.test.com
    http:
      paths:
      - backend:
          serviceName: myapp
          servicePort: 80
# kubectl create -f ingress-myapp.yaml 
ingress.extensions/ingress-myapp created
# kubectl get ingress
NAME            HOSTS            ADDRESS   PORTS   AGE
ingress-myapp   myapp.test.com             80      6s

7.查看nginx-ingress-controller中的配置

# kubectl exec -n ingress-nginx -ti nginx-ingress-controller-5694ccb578-9m8j8 -- /bin/bash
www-data@nginx-ingress-controller-5694ccb578-9m8j8:/etc/nginx$ cat nginx.conf
    ## start server myapp.test.com
    server {
        server_name myapp.test.com ;

        listen 80;

        set $proxy_upstream_name "-";
        set $pass_access_scheme $scheme;
        set $pass_server_port $server_port;
        set $best_http_host $http_host;
        set $pass_port $pass_server_port;

        location / {

            set $namespace      "default";
            set $ingress_name   "ingress-myapp";
            set $service_name   "myapp";
            set $service_port   "80";
            set $location_path  "/";

            rewrite_by_lua_block {
                lua_ingress.rewrite({
                    force_ssl_redirect = false,
                    use_port_in_redirects = false,
                })
                balancer.rewrite()
                plugins.run()
            }

8.验证

修改本地hosts文件添加:
20.0.20.101 myapp.test.com

K8S实践Ⅴ(Ingress)_第1张图片

二、Ingress的配置策略

1.转发到单个后端服务上

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  backend:
    serviceName: myweb
    servicePort: 80

通过该设置,对Ingress Controller的访问请求都将被转发到“myweb:80”这个Service上

2.同一域名不同路径

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  rules:
  - host: mywebsite.com
    http:
      paths:
      - path: /web
        backend:
          serviceName: web-service
          servicePort: 80
      - path: /api
        backend:
          serviceName: api-service
          servicePort: 80

对“mywebsite.com/web” 的访问请求将被转发到svc:“web-servece:80”上
对“mywebsite.com/api” 的访问请求将被转发到svc:“api-servece:80”上

3.同一IP下不同域名

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: s1
          servicePort: 80
  - host: bar.foo.com
    http:
      paths:
      - backend:
          serviceName: s2
          servicePort: 80

三、部署一个Tomcat实例

1.创建配置清单

# cat deploy-tomcat.yaml 
apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
    release: canary
  ports:
  - name: http
    targetPort: 8080
    port: 8080
  - name: ajp
    targetPort: 8009
    port: 8009

---
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: tomcat-deploy
spec:
  replicas: 3
  selector: 
    matchLabels:
      app: tomcat
      release: canary
  template:
    metadata:
      labels:
        app: tomcat
        release: canary
    spec:
      containers:
      - name: tomcat
        image: tomcat:8
        ports:
        - name: httpd
          containerPort: 8080
        - name: ajp
          containerPort: 8009 
# kubectl get pod
tomcat-deploy-679fb5cfd4-6sl6h       1/1     Running   0          49s
tomcat-deploy-679fb5cfd4-mj4zz       1/1     Running   0          49s
tomcat-deploy-679fb5cfd4-tkbzl       1/1     Running   0          49s
# kubectl get svc
tomcat       ClusterIP   10.109.158.191           8080/TCP,8009/TCP   29s

2.创建tomcat的ingress

# cat ingress-tomcat.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat
  namespace: default
  annotations: 
    kubernets.io/ingress.class: "nginx"
spec:
  rules:
  - host: tomcat.test.com
    http:
      paths:
      - path: 
        backend:
          serviceName: tomcat
          servicePort: 8080
# kubectl get ingress
NAME            HOSTS            ADDRESS   PORTS   AGE
ingress-tomcat   tomcat.test.com             80      8s

3.在本地hosts文件中添加tomcat.test.com的解析并访问

K8S实践Ⅴ(Ingress)_第2张图片


4.生成私有证书

# openssl genrsa -out tls.key 2048
Generating RSA private key, 2048 bit long modulus
.............................+++
.....................................................................................................+++
e is 65537 (0x10001)
# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.test.com

5.创建secret

# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
secret/tomcat-ingress-secret created
# kubectl get secret 
NAME                    TYPE                                  DATA   AGE
default-token-dsgpz     kubernetes.io/service-account-token   3      29d
tomcat-ingress-secret   kubernetes.io/tls                     2      32s
# kubectl describe secret tomcat-ingress-secret
Name:         tomcat-ingress-secret
Namespace:    default
Labels:       
Annotations:  

Type:  kubernetes.io/tls

Data
====
tls.crt:  1289 bytes
tls.key:  1675 bytes

6.创建Ingress将secret应用至tomcat服务中

# cat ingress-tomcat-tls.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat-tls
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - tomcat.test.com
    secretName: tomcat-ingress-secret
  rules:
  - host: tomcat.test.com
    http:
      paths:
      - path:
        backend:
          serviceName: tomcat
          servicePort: 8080

7.使用https访问
K8S实践Ⅴ(Ingress)_第3张图片