乐趣区

关于云原生:云原生-05安装-Minikube-并使用-Traefik-做为网关暴露到外网

系列专栏申明:比拟流水,次要是写一些踩坑的点,和实际中与文档差距较大的中央的思考。这个专栏的典型特色可能是 次佳实际 ,争取能在大量的最佳实际中生存。

一、怎么在墙内装置 minikube

minikube 默认应用的是源是 gcr.io,所以很多组件是装不上的。官网自某版本之后提供了指定镜像源的形式,能够指定到阿里云的源,但社区对这个源的风评不好,所以没有钻研这个计划。

选定的计划是在阿里云香港区用 Packer 制作镜像,在制作镜像的过程中把可能用到的组件都装好,而后将镜像复制回杭州区。要害脚本如下:

$ curl -LO https://github.com/kubernetes/minikube/releases/download/v1.24.0/minikube-linux-amd64
$ install minikube-linux-amd64 /usr/local/bin/minikube

$ su core -c "minikube config set WantUpdateNotification false"

$ su core -c "minikube start --kubernetes-version=1.22.3 --profile=prd"
$ su core -c "minikube profile prd"
$ su core -c "minikube addons enable ingress"
$ su core -c "minikube stop"

几个要留神的点是:

  1. minikube 和 kubernetes 都显式指明了版本,只管这与拥抱云原生的理念略有悖,但的确是一个老本绝对划算的策略;目前思考的版本升级策略是齐全新建镜像,等利用迁徙实现后把流量转过去
  2. minikube addons enable ingress 阶段也须要拜访源,所以也要在香港区实现
  3. 不确定 profile 的实际意义,实际中应该是物理隔离的多个集群吧,应该不会用同一套 k8s 的不同 profile 做软隔离吧?然而 minikube delete 删掉的是 profile,包含所有根底镜像,和 ingress,所以不要应用 delete,否则要去香港区重装

二、怎么应用自有镜像

官网有提供配置项能够指定公有源,不过也临时不钻研这个计划。大体的思路依然是去香港区下载须要的镜像,而后用 tar 传到杭州区,而后应用 docker load。须要留神的是,minikube 应用的是 host 上的 docker,然而独立的工作区,所以要从 host 往 minikube 外部再 load 一次。大体的脚本如下:

$ wget http://path/to/httpbin.latest.tar
$ docker load < httpbin.latest.tar
$ docker tag kennethreitz/httpbin:latest kennethreitz/httpbin:1.0
$ docker rmi kennethreitz/httpbin:latest
$ minikube image load kennethreitz/httpbin:1.0

几个须要留神的点是:

  1. k8s 对 :latest 这类 tag 的启动时的默认拉镜像策略是 Always,所以这里把它改成 :1.0 使得默认拉镜像策略变为 IfNotPresent,也就是优先应用本地镜像,不要尝试获取更新,因为连不上源

三、启动一个最简略的示例

$ kubectl create deployment httpbin --image=docker.io/kennethreitz/httpbin:1.0
$ kubectl describe deployment httpbin

$ kubectl expose deployment httpbin --type=ClusterIP --port=80
$ kubectl describe service httpbin

这个命令为什么不是 kubectl create service httpbin

察看失去的网络拓扑状况如下(非官方文档):

  1. ClusterIP 指的是 pod 的 ip;clusterprofile 看上去是同一个货色,一个 cluster 能够有多个 node,minikube 默认是单 node
  2. minikube 是跑在 host docker 里的,所以 minikube 和 node 应用的是 host docker 的网络,即 192.168.49.2;我试了一下新建第二个 profile,它的 ip 会是 192.168.58.2;所以仿佛 profile 之间是不会共享网络的
  3. ingress 的规定写的是 service,但实际上仿佛是指向 pod,所以 service 仅仅是提供了注册核心成果,但流量没有从这里做负载平衡吗
  4. 没有找到 host.minikube.internal,因为上面的计划不须要这个,所以没有持续钻研

以下才是重点:

  1. pod 之间能够通过 ClusterIP 相互拜访,即 172.17.0.4 能够拜访 172.17.0.5,既然它叫做 ClusterIP,那我猜是在整个 cluster 范畴内失效的;但感觉实际意义不大,因为 ip 是动态变化的,写在代码里的应该还是用 httpbin.default.svc.cluster.local 相互拜访
  2. pod 能够拜访 192.168.49.1,这很重要,比方能够在 host 上装置 MySQL,并将 MySQL containerporthostport 绑定起来,这样就能够在 pod 里拜访 192.168.49.1:3306
  3. pod 也能够拜访 192.168.49.3 即 host docker 上的 traefik,细节前面会讲,这是因为咱们将 traefik 放在了 prd 这个网络里
  4. pod 能够拜访 10.1.x.x,即能够在整个 VPC 内畅通无阻(当然我猜须要对 IP 端做一些布局,不要抵触),所以 pod 能够拜访到另一台虚机上的任何产品,和托管的产品如 RDS,只有纳入到 VPC 范畴里

四、裸露服务到外网

deployment 有 3 种形式:ClusterIP,NodePort,Load Balancer。粗粗看了一下,主观感觉最云原生的形式应该是 Load Balancer,即间接应用云厂商提供的云原生网关,间接将流量打到 service 甚至是 pod,连 ingress 都不要走。k8s 只是一个容器管理工具,可能恰好提供了 ingress 等能力,然而在 网关 方面,感觉 k8s 并不是一个最佳实际,将网关包成容器部署在 k8s 内也不是一个最佳实际。

上手教程举荐的是 NodePort 模式,十分奇怪,看下来感觉是一个十分差的实际,决定用这个形式来做上手演示的人应该被拖出去打死。

这里选用了 ingress 的形式,所以 deployment 应用了默认的 ClusterIP 模式。

$ kubectl apply -f ingress.yaml
$ kubectl describe ingress app-ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
    - host: httpbin.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: httpbin
                port:
                  number: 80

对于默认的 nginx ingress 文档有个很奇怪的坑,示例代码里开启了 annotation,会把所有的申请都 rewrite 到首页,即拜访 http://httpbin.example.com/a.js 会被 rewrite 到 http://httpbin.example.com,不晓得为什么要在老手文档里这么干。

minikube 会在 host docker 上创立一个和 profile 同名的 network,即 prd,并启动本人做为第一个 instance;同时应用了默认的单 Node 模式,所以这个 Node 的 ip 肯定是 192.168.49.2;多 Node 会怎么我没有尝试,然而猜想能够指定。

version: '3.8'

services:
  traefik:
    container_name: traefik
    image: traefik:v2.2.11
    networks:
      - prd
    ports:
      - 80:80
      - 443:443
    labels:
      - "traefik.enable=false"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # 省略其它配置文件 
    restart: always

networks:
  prd:
    external: true

/path/to/traefik/config/default.toml

[http.services]
  [http.services.noop.loadBalancer]
     [[http.services.noop.loadBalancer.servers]]
        url = ""

  [http.services.minikube.loadBalancer]
    [[http.services.minikube.loadBalancer.servers]]
      url = "http://192.168.49.2:80/"

[http.routers]
  [http.routers.https-redirect]
    entryPoints = ["http"]
    rule = "HostRegexp(`{app:[0-9a-z-]+}.example.com`)"
    middlewares = ["https-redirect"]
    service = "noop"

  [http.routers.example]
    entryPoints = ["https"]
    rule = "HostRegexp(`{app:[0-9a-z-]+}.example.com`)"
    service = "minikube"
  [http.routers.example.tls]

[http.middlewares.https-redirect.redirectScheme]
  scheme = "https"

这个计划不肯定是最佳实际,然而实现 / 演示了两个重要的观点:

  1. 拆掉 https 证书的工作应该在网关上实现,不应该交给 k8s,曾经进入 k8s 的流量应该是信赖的;在 k8s 外部做流量的权限管制,应该应用 role 等策略,不应该应用裸露给用户的那张证书,那张证书是有品牌意义的,有可能是另外一些非运维部门负责的
  2. 目前 traefik 是在 host docker 上用 docker-compose 保护的,这是把之前的用法间接复制过去了,而且间接用同一个网络不便反诘。如果也要应用 k8s 治理的话,应该是再起一个独立的 cluster,外面只有这个 traefik,而后做集群间流量。即整个入口网关都不应该和利用放在同一个集群里,这样的设计另一个益处是,利用集群人造是分布式的,人造是反对两地三核心的;单点故障管制在网关集群这里

参考文献:

  1. Minikube Start
  2. Kubernetes 的三种内部拜访形式:NodePort、LoadBalancer 和 Ingress
  3. Set up Ingress on Minikube with the NGINX Ingress Controller
  4. Ingress Nginx Controller Troubleshooting
  5. Kompose
退出移动版