JavaEE 企业级分布式高级架构师(十八)容器虚拟化技术(5)

七层负载均衡Ingress

  • 回顾: 通过service访问内网服务的,需要在物理机开辟一些端口,当 Service 越来越多的时候,需要开辟的端口也越来越多,这些庞大的端口的管理就会成为的灾难?

Ingress是什么?

  • Ingress 是 kubernetes 为了实现在应用层进行转发,对 nginx 进行云原生模式的封装(增强),使得 Ingress 可以对Service 实现请求的转发,且实现动态转发规则的改写。

在这里插入图片描述

为什么引入Ingress?

  • 我们说 K8S 的服务(Service)时说暴露了 Service 的三种方式 ClusterIP、NodePort 与 LoadBalance,这几种方式都是在 Service 的维度提供的。Service 的作用体现在两个方面:对集群内部,它不断跟踪 POD 的变化,更新 Endpoint 中对应 POD 的对象,提供了 IP 不断变化的 POD 的服务发现机制;对集群外部,它类似负载均衡,可以在集群内外部对 POD 进行访问。但是,单独用 Service 暴露服务的方式,在实际生产环境中不太合适:
    • ClusterIP 的方式只能在集群内部访问。
    • NodePort 方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理是灾难。
    • LoadBalance 方式受限于云平台,且通常在云平台部署 ELB 还需要额外的费用。
  • 所幸 K8S 还提供了一种集群维度暴露服务的方式,也就是 Ingress。Ingress 可以简单理解为 Service 的 Service。它通过独立的 Ingress 对象来制定请求转发规则,把请求路由到一个或多个 Service 中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个 Service 单独考虑。
  • 举个例子:现在集群有api、文件存储、前端3个service,可以通过一个 ingress 对象来实现图中的请求转发

在这里插入图片描述

  • ingress规则是很灵活的,可以根据不同域名、不同path转发请求到不同的service,并且支持https/http。

Ingress部署

Ingress-nginx工作流程

在这里插入图片描述

  • Ingress-nginx工作流程: 建立一个统一的入口,根据 Ingress 访问规则(部署的时候建立的)动态修改 nginx 配置文件,通过动态的nginx来进行转发。

部署文件介绍

在这里插入图片描述

在这里插入图片描述

  • namespace.yaml:创建独立的命名空间 ingress-nginx。

在这里插入图片描述

  • configmap.yaml:创建 ConfigMap 对象

在这里插入图片描述

  • rbac.yaml:负载 Ingress 的 RBAC 授权控制,其创建了 Ingress 用到的 ServiceAccount、ClusterIP、Role、RoleBinding、ClusterRoleBinding。

在这里插入图片描述

在这里插入图片描述

  • with-rbac.yaml:使用带 rbac 的方式创建 ingress-controller,是整个 ingress 的核心部署文件。

在这里插入图片描述

  • mandatory.yaml:该文件整合了前面四项文件的内容,是用于实际部署ingress服务的yaml文件。即只需要使用该文件就可以完成ingress-controller的全部部署工作。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • service-nodeport.yaml:建立统一的入口

在这里插入图片描述

部署 Ingress-controller

在这里插入图片描述

  • 下载所需的 Ingress 相关配置文件,如上图所示。
# 部署ingress-controller,注意这个配置文件下载的地址需要解决科学上网的问题,建议从github下载即可
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
# 对外部提供服务所需
wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
# 修改mandatory.yaml,替换镜像地址 使用阿里云镜像地址 registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.30.0

在这里插入图片描述

  • 修改service-nodeport.yaml,增加NodePort,固定端口:
  • 执行部署命令:部署nginx-ingress-controller
kubectl apply -f 05-mandatory.yaml
kubectl apply -f 06-service-nodeport.yaml

在这里插入图片描述

  • 查看Ingress组件:
kubectl get pods -n ingress-nginx
kubectl get pod -n ingress-nginx --show-labels
kubectl get svc -n ingress-nginx

在这里插入图片描述

  • 查看daemonset的状态:
kubectl get daemonset -n ingress-nginx

在这里插入图片描述

  • 验证 ingress-nginx 服务:
curl http://192.168.254.108:30080/healthz -I

在这里插入图片描述

ingress应用部署

  • 部署一个 Ingress 资源对象:ingress-01.yaml 配置文件如下
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
spec:
  rules:
  - host: ingress.veli.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
  • 创建一个后端服务的 yaml 配置文件:nginx-app.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: hub.veli.com/library/nginx:latest
        ports:
        - containerPort: 80

在这里插入图片描述

  • 执行部署:
kubectl apply -f nginx-app.yaml
kubectl apply -f ingress-01.yaml

在这里插入图片描述

在这里插入图片描述

动态映射

  • 登录到 ingress 控制器动态映射的 nginx.conf 的 POD:
kubectl exec -it nginx-ingress-controller-h65nm -n ingress-nginx -- sh

在这里插入图片描述

多个域名、多个服务

  • 配置多个域名,通过配置两个域名进行分别转发到不同的服务上面:ingress-02.yaml 配置文件如下
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
spec:
  rules:
  - host: ingress.nginx.veli.com
    http:
      paths:
        - path: /
          backend:
            serviceName: nginx
            servicePort: 80
  - host: ingress.tomcat.veli.com
    http:
      paths:
        - path: /
          backend:
            serviceName: tomcat
            servicePort: 8080
  • 部署两个服务:前面已经部署过一个 nginx 服务了,再部署一个 tomcat 服务,tomcat-app.yaml 配置文件如下:
apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
  ports:
  - port: 8080
    targetPort: 8080

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: tomcat
        image: hub.veli.com/library/tomcat:latest
        ports:
        - containerPort: 8080

在这里插入图片描述

  • 执行部署:
# kubectl apply -f nginx-app.yaml # 前面已经部署
kubectl apply -f tomcat-app.yaml
kubectl apply -f ingress-02.yaml

在这里插入图片描述

一个域名、多个服务

在这里插入图片描述

  • 说明:
path: /nginx
	ingress.veli.com/nginx  ===>>  URL: /nginx/xxx/ooo
path: /tomcat
	ingress.veli.com/tomcat  ===>>  URL: /tomcat/xxx/ooo
  • 后端服务 nginx 中没有部署任何的服务程序,tomcat 服务中也没有部署任何服务程序,因此在做请求转发的时候,没有与之对应的映射的请求。
# 请求重写,重写写入到根路径下面,实现服务访问
annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /
  • 执行部署:
kubectl apply -f ingress-03.yaml
  • 访问成功:

在这里插入图片描述

重定向

  • 案例:使用 permanent-redirect 重定向到百度

在这里插入图片描述

  • 执行部署:
kubectl apply -f ingress-redirect.yaml

https协议访问

  • 创建 https 证书:
# 生成私钥
openssl genrsa -out tls.key 2048
# 自签发证书
openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Shenzhen/L=Shenzhen/O=Veli/CN=ingress.veli.com
# 创建K8S使用的证书配置文件Secret
kubectl create secret tls https-ingress-secret --cert=tls.crt --key=tls.key
# 查看Secret描述
kubectl describe secret https-ingress-secret

在这里插入图片描述

  • 部署yaml文件:ingress-04.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat-tls
  namespace: default
  labels:
    app: tomcat
  annotations:
    kubernetes.io/ingress.claa: "nginx"
spec:
  tls:
  - hosts:
    - ingress.veli.com
    secretName: https-ingress-secret
  rules:
  - host: ingress.veli.com
    http:
      paths:
        - backend:
            serviceName: tomcat
            servicePort: 8080
  • 执行部署:
kubectl apply -f ingress-04.yaml
  • 访问一下:由于证书是自己伪造的一个证书,浏览器任务此证书不是一个受信任的证书

在这里插入图片描述

  • 点击高级,选择继续前往访问即可:

在这里插入图片描述

问题

  • Ingress与微服务的Gateway,是否二选一?还是一起分工使用?

在这里插入图片描述

Kubernetes的存储资源对象

ConfigMap资源对象

什么是ConfigMap对象

  • ConfigMap 就是一个配置中心,类似于微服务架构中(nacos、spring-cloud-confg、zookeeper)配置中心服务,用来存储一些配置文件,或者是环境变量。
  • 例如:部署 Redis,可以将 redis.conf 配置存储在 ConfigMap 对象中。部署 MySQL,可以把 my.cnf 存储在 ConfigMap 中。
  • ConfigMap 资源对象存储数据结构:Key-Value,Value可以是单个字符串,也可以是文件内容。

在这里插入图片描述

  • Kubenetes 云原生架构体系中提供的一套配置中心对象,使得配置和服务进行解耦,一旦配置发生变化,就不需要重新打包,重新部署,服务立马感知到配置文件变化,立马做出调整。

如何创建ConfigMap

在这里插入图片描述

根据目录创建

在这里插入图片描述

# game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

# ui.propertes
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
  • 创建 configmap 指令:
kubectl create cm myconf-01 --from-file=docs
# 查看configmap文件
kubectl get cm
# 查看详细信息
kubectl get cm myconfig-01 -o yaml   
kubectl describe cm

在这里插入图片描述

在这里插入图片描述

根据文件创建
  • 创建 configmap 指令:
kubectl create cm myconf-02 --from-file=docs/ui-properties

在这里插入图片描述

Key-Value方式创建
  • 创建 configmap 指令:
kubectl create cm myconf-03 --from-literal=username=zhangsan --from-literal=age=23

在这里插入图片描述

直接创建
  • 创建 yaml 配置文件:
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  name: myconf-04
  namespace: default
  • 创建 configmap 指令:
kubectl apply -f myconf.yaml

在这里插入图片描述

POD服务内部应用

POD内部服务获取configmap
  • 方式一:valueFrom 只获取 value 值
  • 方式二:envFrom 获取 configmap 资源对象的 Key、Value。
  • 准备两个用于创建 ConfigMap 资源对象的 yaml 文件
# special-conf.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm

# env-conf.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO
  • 准备一个创建POD的yaml配置文件:
# hello-world.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-pod
      image: hub.veli.com/library/nginx:latest
      command: ["/bin/sh", "-c", "env"]
      env:
        - name: SPECIAL_LEVEL_KEY 
          valueFrom:
            configMapKeyRef: 
              name: special-config  # 第一种导入方式:在env中导入
              key: special.how              
        - name: SPECIAL_TYPE_KEY
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.type 
      envFrom:                      # 第二种导入方式,直接使用envFrom导入
        - configMapRef: 
            name: env-config 
  restartPolicy: Never

在这里插入图片描述

  • 执行创建:
kubectl apply -f special-conf.yaml 
kubectl apply -f env-conf.yaml 
kubectl apply -f test-pod.yaml

在这里插入图片描述

  • 另外一种方式:通过 ConfigMap 设置命令行参数【用作命令行参数,将 ConfigMap 用作命令行参数时,需要先把 ConfigMap 的数据保存在环境变量中,然后通过 $(VAR_NAME) 的方式引用环境变量】
apiVersion: v1
kind: Pod
metadata:
  name: test-pod2
spec:
  containers:
    - name: test-container
      image: hub.veli.com/library/nginx:latest
      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] 
      env:
        - name: SPECIAL_LEVEL_KEY 
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.how 
        - name: SPECIAL_TYPE_KEY 
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.type 
  restartPolicy: Never
数据卷挂载方式
  • 通过数据卷插件使用ConfigMap:在数据卷里面使用这个ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容。
  • POD的yaml配置文件如下
apiversion: v1
kind: Pod
metadata:
  name: test-pod3
spec:
  containers:
    - name: test-container
      image: hub.veli.com/library/nginx:latest
      command: [ "/bin/sh", "-c", "sleep 600s" ] 
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config # 表示把conifg-volume挂载卷挂载到容器的/etc/config目录下
  volumes:    # 开启挂载外部configmap
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

在这里插入图片描述

  • 执行创建:
kubectl apply -f test-pod-03.yaml

在这里插入图片描述

  • 数据卷挂载方式,发现数据已经被成功挂载到容器内部了。

热更新

# cat logconf.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
  namespace: default
data:
  log_level: INFO
# mynginx.yaml
apiVersion: extensions/v1beta1 
kind: Deployment 
metadata: 
  name: my-nginx 
spec:
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
        - name: my-nginx
          image: hub.veli.com/library/nginx:latest
          ports:
            - containerPort: 80 
          volumeMounts:
            - name: config-volume 
              mountPath: /etc/config 
      volumes:
        - name: config-volume 
          configMap:
            name: log-config
  • 执行创建:
kubectl apply -f logconf.yaml
kubectl apply -f mynginx.yaml

在这里插入图片描述

Secret资源对象

Secret是什么?

  • Secret对象也是一种存储数据的资源对象,但是Secret仅仅是被用来存储敏感数据,具有安全的作用。例如:秘钥、免密、token 等这些数据信息都需要存储在 Secret 资源对象中。
  • 当 POD 需要获取这些敏感数据的时候,只需要从 Secret 中获取即可(使用数据卷的挂载方式,动态的从 Secret 资源对象中获取数据),这样做的好处是防止直接把敏感数据暴露在镜像中,这样可以提高服务的安全性。

Kubernetes认证模式

在这里插入图片描述

Secret对象类型

  • Secret对象存储数据的方式是以键值方式存储数据,在Pod资源进行调用Secret的方式是通过环境变量或者存储卷的方式进行访问数据,解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。
  • 另外,Secret对象的数据存储和打印格式为Base64编码的字符串,因此用户在创建Secret对象时,也需要提供该类型的编码格式的数据。在容器中以环境变量或存储卷的方式访问时,会自动解码为明文格式。需要注意的是,如果是在Master节点上,Secret对象以非加密的格式存储在etcd中,所以需要对etcd的管理和权限进行严格控制。
  • Secret有4种类型:Service Account、Opaque、kubernetes.io/dockerconfigjson、kubernetes.io/tls
Service Account
  • 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 POD 的 /run/secrets/kubernetes.io/serviceaccount 目录中;

在这里插入图片描述

Opaque
  • base64 编码格式的Secret,用来存储密码、密钥、信息、证书等,类型标识符为 generic。
  • 创建示例:
# base64对用户名,密码加密效果演示
echo -n "admin" | base64
YWRtaW4=

echo -n "abcdefgh" | base64
YWJjZGVmZ2g=

# secret.yaml配置文件方式
apiVersion: v1
kind: Secret
metadata:
  name: secret-test
type: Opaque
data:
  username: YWRtaW4=
  password: YWJjZGVmZ2g=
kubernetes.io/dockerconfigjson
  • 用来存储私有docker registry的认证信息,类型标识为docker-registry。
kubernetes.io/tls
  • 用于为SSL通信模式存储证书和私钥文件,命令式创建类型标识为tls。

Secret使用

  • 定义 secret-pod.yaml 文件:
# 将secret挂载到volume中
apiVersion: v1
kind: Pod
metadata:
  name: secret-test
  labels:
    name: secret-test
spec:
  volumes:
  - name: secrets
    secret:
      secretName: secret-test
  containers:
  - image: hub.veli.com/library/nginx:latest
    name: db
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true

在这里插入图片描述

  • 执行创建:
kubectl apply -f secret.yaml 
kubectl apply -f secret-pod.yaml

在这里插入图片描述

  • 进入 POD 容器查看一下:

在这里插入图片描述

  • 另一种使用 secret 的方式:将secret导出到环境变量中:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: secret-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: pod-deployment
    spec:
      containers:
      - name: pod-1
        image: hub.veli.com/library/nginx:latest
        ports:
        - containerPort: 80
        env:
        - name: TEST_USER
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: TEST_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
开课吧-javaEE企业级分布式高级架构师是一门专注于培养企业级应用开发的高级技术课程。该课程旨在帮助学员全面掌握Java EE企业级开发的技能和知识,培养他们成为具备分布式应用系统设计和架构能力的高级架构师。 在这门课程中,学员将学习Java EE的核心概念和技术,包括Servlet、JSP、JDBC、EJB、JNDI等。同时,学员还将深入学习分布式应用开发的相关技术,如Web服务、消息队列、分布式缓存、负载均衡等。除此之外,课程还将涉及如何使用流行的Java EE开发框架(如Spring、Hibernate等)进行企业应用开发,并介绍分布式系统的设计原则和最佳实践。 通过学习这门课程,学员将能够了解分布式应用架构的基本原理,并具备设计和构建分布式应用系统的能力。他们将熟练掌握Java EE平台的各种技术和工具,能够灵活运用它们开发高性能、可扩展性强的企业级应用系统。此外,通过课程中的实战项目,学员还将锻炼解决实际问题和项目管理的能力。 作为一门高级架构师的课程,它将帮助学员进一步提升自己的职业发展。毕业后,学员可以在企业中担任分布式应用的架构师、系统设计师、技术经理等角色,负责企业级应用系统的设计和开发。此外,他们还可以选择独立开发,提供技术咨询和解决方案。 总之,开课吧-javaEE企业级分布式高级架构师是一门非常有价值的课程,它将帮助学员掌握Java EE企业级开发的核心技术和分布式应用架构的设计原理,培养他们成为具备高级架构师能力的软件开发专业人士。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值