系列专栏申明:比拟流水,次要是写一些踩坑的点,和实际中与文档差距较大的中央的思考。这个专栏的典型特色可能是 次佳实际
,争取能在大量的最佳实际中生存。
一、怎么在墙内装置 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"
几个要留神的点是:
- minikube 和 kubernetes 都显式指明了版本,只管这与拥抱云原生的理念略有悖,但的确是一个老本绝对划算的策略;目前思考的版本升级策略是齐全新建镜像,等利用迁徙实现后把流量转过去
minikube addons enable ingress
阶段也须要拜访源,所以也要在香港区实现- 不确定 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
几个须要留神的点是:
- 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
?
察看失去的网络拓扑状况如下(非官方文档):
ClusterIP
指的是pod
的 ip;cluster
和profile
看上去是同一个货色,一个cluster
能够有多个node
,minikube 默认是单node
- minikube 是跑在 host docker 里的,所以 minikube 和 node 应用的是 host docker 的网络,即
192.168.49.2
;我试了一下新建第二个profile
,它的 ip 会是192.168.58.2
;所以仿佛profile
之间是不会共享网络的 ingress
的规定写的是service
,但实际上仿佛是指向pod
,所以service
仅仅是提供了注册核心成果,但流量没有从这里做负载平衡吗- 没有找到 host.minikube.internal,因为上面的计划不须要这个,所以没有持续钻研
以下才是重点:
pod
之间能够通过ClusterIP
相互拜访,即172.17.0.4
能够拜访172.17.0.5
,既然它叫做Cluster
IP,那我猜是在整个 cluster 范畴内失效的;但感觉实际意义不大,因为 ip 是动态变化的,写在代码里的应该还是用httpbin.default.svc.cluster.local
相互拜访pod
能够拜访192.168.49.1
,这很重要,比方能够在host
上装置MySQL
,并将MySQL container
的port
和host
的port
绑定起来,这样就能够在pod
里拜访192.168.49.1:3306
pod
也能够拜访192.168.49.3
即 host docker 上的traefik
,细节前面会讲,这是因为咱们将traefik
放在了prd
这个网络里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"
这个计划不肯定是最佳实际,然而实现 / 演示了两个重要的观点:
- 拆掉 https 证书的工作应该在网关上实现,不应该交给 k8s,曾经进入 k8s 的流量应该是信赖的;在 k8s 外部做流量的权限管制,应该应用 role 等策略,不应该应用裸露给用户的那张证书,那张证书是有品牌意义的,有可能是另外一些非运维部门负责的
- 目前 traefik 是在 host docker 上用 docker-compose 保护的,这是把之前的用法间接复制过去了,而且间接用同一个网络不便反诘。如果也要应用 k8s 治理的话,应该是再起一个独立的 cluster,外面只有这个 traefik,而后做集群间流量。即整个入口网关都不应该和利用放在同一个集群里,这样的设计另一个益处是,利用集群人造是分布式的,人造是反对两地三核心的;单点故障管制在网关集群这里
参考文献:
- Minikube Start
- Kubernetes 的三种内部拜访形式:NodePort、LoadBalancer 和 Ingress
- Set up Ingress on Minikube with the NGINX Ingress Controller
- Ingress Nginx Controller Troubleshooting
- Kompose