前文安装k3s时禁用了traefik,之前在实习的时候公司自研SaaS平台就用了consul服务发现配合traefik路由的结构,整体感觉下来微服务后端的发现与治理无需太多人工干预,且这两个安装也很简单,体验确实不错。不过本系列没有那么重的需求,且ingress-nginx功能更多的说~

helm配置

helm简而言之就是k8s的模版仓库。helm v2需要在目标集群里安装Tiller,在越来越大的云环境下导致了越来越多的安全问题,所以在v3版本就没有Tiller这个东西了,配置也是简单到只需要搞定本地的kubeconfig文件再安装个helm v3命令行工具就可以了。Mac直接使用homebrew即可:

1
brew install helm

提一嘴,helm指向的集群是和本机kubectl指向的是一样的~所以切换集群就是直接切换kubectl的context即可。

安装ingess-nginx

helm部署很简单,按照这里的知道就行。首先添加repo并更新:

1
2
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

然后不知道为什么我这里直接install不可以,似乎是网络问题,首先的pull下来整个chart到本地再安装才行:

1
2
3
helm pull ingress-nginx/ingress-nginx
extract ingress-nginx.tgz # 解压
cd ingress-nginx

此时可以修改values.yaml内的配置,仅修改了资源限制,其他默认,安装:

1
helm install ingress-nginx --namespace=ingress-nginx -f ./values.yaml ./

等~等~等~

1
2
kubectl get pods -n ingress-nginx
kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller

当显示如下是就可以了:

image-20211112115809335

此时访问集群的外部ip:80会有nginx 404页面出来。

安装cert-manager

之前部署网页一直用caddy作为反向代理实现自动https,然而现在ingress-nginx不提供这个功能了😭,而且最便宜的通配符证书也要四位数一年,啥家庭玩得起?所以找到了cert-manager这个小宝贝~简而言之这玩意就是hook了ingress,自动获取并配置https证书。开心的是这个也支持白嫖Let’s Encrypt!而且官方提供了配合ingress-nginx食用的教程,这个教程基于helm v2安装ingress-nginx,无视就好,只看后面的配置部分以及测试部分。helm安装cert-manager教程也是有的:Installing with Helm,好评!

首先还是添加helm,虽然helm默认repo里面有cert-manager,但是版本很老所以不用:

1
2
helm repo add jetstack https://charts.jetstack.io
helm repo update

cert-manager有CRD(自定义资源定义),所以对helm、k3s版本有一点要求。这里还是pull下来修改再安装:

1
2
3
helm pull jetstack/cert-manager
extract cert-manager.tgz
cd cert-manager

修改values.yaml,将installCRDs的值设置为true保存,安装:

1
helm install cert-manager --namespace=cert-manager --create-namespace -f values.yaml ./

静待完成即可~

配置自动https并测试

Issuer & ClusterIssuer

简单说来就是https证书的签发者,可以是自签证书也可以是其他收费或免费机构签发的证书。Issuer只可以对本namespace的ingrss域名颁发证书,而ClusterIssuer就能对整个集群下任何namespace的ingress域名颁发证书。首先就偷懒直接配置个ClusterIssuer,依旧白嫖letsencrypt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: email@example.com # 你的邮箱
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx

这里采用http01进行校验,结合配置ingress-nginx挺方便的,另外一个DNS校验是需要云服务商域名解析服务联动的。

需要给EXTERNAL-IP分配个泛解析域名以便一会儿访问,由于穷人没有load balancer,就直接给一个ip分配个二级泛解析*.dev.example.com得了。

测试

部署个kuard进行测试,清单如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: v1
kind: Service
metadata:
name: kuard
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
selector:
app: kuard
---

apiVersion: apps/v1
kind: Deployment
metadata:
name: kuard
spec:
selector:
matchLabels:
app: kuard
replicas: 1
template:
metadata:
labels:
app: kuard
spec:
containers:
- image: gcr.io/kuar-demo/kuard-amd64:1
imagePullPolicy: Always
name: kuard
ports:
- containerPort: 8080

服务部署完毕,还得来个ingress配置把服务暴露出去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kuard
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"

spec:
tls:
- hosts:
- exkuard.dev.example.com
secretName: exkuard-example-tls
rules:
- host: exkuard.dev.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kuard
port:
number: 80

其中,exkuard-example-tls是获取到的证书secret名字,服务域名就是exkuard.dev.example.com

如若不想使用自动https,删除cert-manager.io/cluster-issuer: "letsencrypt-prod"注解就行了。若想要强制http跳转到https,加上注解nginx.ingress.kubernetes.io/ssl-redirect: "true"

查看证书获取状态,如下就代表成功了:

1
kubectl get certificate -n dev

image-20211112124145536

访问测试域名:

image-20211112124302886

最后清理下测试资源就可以愉快的玩耍了~