0%

启用Dashboard

默认情况下,K3s 1.20 及更早版本默认安装 Traefik v1,并且默认没有启用 Traefik Dashboard。如果要在 K3s 中启用 Traefik v1 的 Dashborad,我们可以借助 HelmChartConfig 来自定义由 Helm 部署的 Traefik v1 并启用 Dashboard.

不建议手动编辑 /var/lib/rancher/K3s/server/manifests/traefik.yaml 来修改 Traefik 配置文件,因为 K3s 重启后会覆盖修改的内容。

建议通过在 /var/lib/rancher/K3s/server/manifests 中创建一个额外的 HelmChartConfig 清单来自定义 Traefik 配置,请参考:http://docs.rancher.cn/docs/K3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat >> /var/lib/rancher/K3s/server/manifests/traefik-config.yaml << EOF
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
dashboard:
enabled: true
ports:
traefik:
expose: true
logs:
access:
enabled: true
EOF

配置Service及路由规则

此方法适用于traefik2.x

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
cat >> traefik-dashboard.yaml << EOF
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: kube-system
spec:
allocateLoadBalancerNodePorts: true
ports:
- name: web
nodePort: 80
port: 80
protocol: TCP
targetPort: web
- name: websecure
nodePort: 443
port: 443
protocol: TCP
targetPort: websecure
selector:
app.kubernetes.io/instance: traefik-kube-system
app.kubernetes.io/name: traefik
type: LoadBalancer

---

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-web
spec:
entryPoints:
- web
routes:
- kind: Rule
match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
services:
- name: api@internal
kind: TraefikService

---

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-websecure
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
services:
- name: api@internal
kind: TraefikService
tls:
secretName: traefik-dashboard-tls
EOF
1
kubectl apply -f traefik-dashboard.yaml

[^注意]: 访问Dashboard需要在最后加一个/ 否则可能出现page not found

配置IngressRoute

1
2
3
# 搭建测试环境
kubectl create deploy whoami --image=traefik/whoami --replicas=2
kubectl expose deploy whoami --port=80

HTTP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#whoami-no-tls-ingress-route.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-ingress-web
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`192.168.0.202`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80

HTTPS

1
2
3
4
# 用 openssl 来创建一个自签名的证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=domain.example.com"

kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# whoami-tls-ingress-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-ingress-websecure
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`192.168.0.202`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls

TCP/UDP

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP #IngressRouteUDP
metadata:
name: redis
namespace: devops
spec:
entryPoints:
- redis
routes:
- match: HostSNI(`*`)
services:
- name: redis
port: 6379
TCP Routers与HTTP Routers的routes有所不同:
  • TCP Routers match采用HostSNI,而HTTP Routers match直接匹配Host。
  • TCP Routers只能定位TCP服务(不能定位HTTP服务)。
  • 如果HTTP Routers和TCP Routers都侦听相同的入口点,则TCP Routers将在HTTP Routers之前应用。如果找不到与TCP Routers匹配的路由,则HTTP Routers将接管。

参考

K3s版本 > v.121(Traefik 2.x)

K3S 中 Traefik v2 安装及采坑纪实 - 知乎 (zhihu.com)

k3s开启traefik的dashboard网页-CSDN博客

Step by Step!教你如何在k3s集群上使用Traefik 2.x - k3s中文社区 - 博客园 (cnblogs.com)

traefik系列之一 | 简介、部署和配置-腾讯云开发者社区-腾讯云 (tencent.com)

还不会Traefik?看这篇文章就够了! - 知乎 (zhihu.com)

k3s 使用 Letsencrypt 和 Traefik 完成 https 入口部署-腾讯云开发者社区-腾讯云 (tencent.com)

[Kubernetes环境Traefik部署与应用 - Tiscs - 博客园 (cnblogs.com)](https://www.cnblogs.com/tiscs/p/notes-k8s-traefik.html#:~:text=安装Traefik 1 配置 Helm Repo helm repo add, … 3 其他准备工作 获取 traefik 服务的负载均衡器地址。 )

Traefik - Kubernetes 配置TCP/HTTP服务-腾讯云开发者社区-腾讯云 (tencent.com)

cert-manager管理内网k8s开发环境证书 - hueidou163 - 博客园 (cnblogs.com)

Kubernetes (K8S)中Traefik路由(ingressRoute)-腾讯云开发者社区-腾讯云 (tencent.com)

K3s版本 < v.121(Traefik 1.x)

基础指南:如何在K3s中配置Traefik? - k3s中文社区 - 博客园 (cnblogs.com)

K3s 集群如何使用 Traefik_k3s traefik-CSDN博客

k3s 使用 Letsencrypt 和 Traefik 完成 https 入口部署-腾讯云开发者社区-腾讯云 (tencent.com)

Kubernetes 集群部署 Ingress Traefik-腾讯云开发者社区-腾讯云 (tencent.com)

Dashboard无法访问问题参考

如何在 K3s 中启用 Traefik Dashborad - RancherLabs - 博客园 (cnblogs.com)

How to Expose and Enable K3s with Traefik Dashboard (thriveread.com)

kubernetes - How to expose traefik v2 dashboard in k3d/k3s via configuration? - Stack Overflow

kubernetes - 云原生 07:改用 K3s,并使用 K3s 内置的 Traefik 做 Ingress 网关 - 小鲜 - SegmentFault 思否

K8s中使用traefik(基础) - AGou’s Blog

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 # 安装nfs服务
sudo apt install nfs-common nfs-kernel-server portman -y

# 创建共享目录
sudo mkdir -p /mnt/share/
sudo chmod 777 /mnt/share

# 编辑映射文件
sudo vim /etc/exports

# 共享目录
/mnt/share *(rw,sync)

# 设置ACL赋予nfsnobody权限
sudo setfacl -m u:nfsbody:rw /mnt/share

# 启动NFS服务
sudo /etc/init.d/nfs-kernel-server start
sudo /etc/init.d/nfs-common start

# 检查服务启动
sudo showmount -e

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装nfs
sudo apt install nfs-common

# 新建本地文件夹
sudo mkdir /mnt/nfs

# sudo mount [nfs_server]:[server_dir] [local_mount_point]
# [nfs_server] nfs服务器ip
# [server_dir] 服务器共享路径
# [local_mount_point] 本地挂载路径
sudo mount [nfs_server]:[server_dir] [local_mount_point]
# 示例
sudo mount 192.168.1.100:/mnt/share /mnt/nfs

# 查看挂载是否成功
df -Th

编辑fstab 配置自动挂载

1
2
3
sudo vim /etc/fstab
# 在最后一行添加
[nfs_server]:/mnt/share /mnt/nfs nfs defaults 0 0

卸载

1
2
3
sudo umount [local_mount_point] 
#示例
sudo umount /mnt/nfs

需要认证参考为 Linux 客户端设置具有基于 Kerberos 的身份验证的 NFS 服务器 (linux-console.net)

安全相关参考如何确保NFS服务安全-腾讯云开发者社区-腾讯云 (tencent.com)

用户身份映射参考NFS服务的用户身份映射 - wangmo - 博客园 (cnblogs.com)

本地路径映射(HostPath)

HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。 当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 宿主机上目录位置
path: /data
# 此字段为可选
type: Directory

支持的 type 值如下:

取值 行为
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory 在给定路径上必须存在的目录。
FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File 在给定路径上必须存在的文件。
Socket 在给定路径上必须存在的 UNIX 套接字。
CharDevice 在给定路径上必须存在的字符设备。
BlockDevice 在给定路径上必须存在的块设备。
1
2
3
4
5
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-vol-default
provisioner: vendor-name.example

local

local 卷只能用作静态创建的持久卷。不支持动态配置。

hostPath 卷相比,local 卷能够以持久和可移植的方式使用,而无需手动将 Pod 调度到节点。系统通过查看 PersistentVolume 的节点亲和性配置,就能了解卷的节点约束。

使用 local 卷时,你需要设置 PersistentVolume 对象的 nodeAffinity 字段。 Kubernetes 调度器使用 PersistentVolume 的 nodeAffinity 信息来将使用 local 卷的 Pod 调度到正确的节点。

PersistentVolume 对象的 volumeMode 字段可被设置为 “Block” (而不是默认值 “Filesystem”),以将 local 卷作为原始块设备暴露出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node

NFS映射

1

Minio

1

Ceph

1

准备环境

证书

OpenSSL生成自签名证书 K3s证书管理

默认配置文件

1
helm show values harbor/harbor > harbor-values.yaml

安装

配置清单

harbor-value.yaml

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
34
35
36
37
38
39
40
41
42
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: "example.io"
notarySecretName: "example.io"
ingress:
hosts:
core: harbor.example.io
notary: notary.example.io
controller: default
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-body-size: "0"
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure

externalURL: https://harbor.example.io

harborAdminPassword: "Harbor123456"

logLevel: info

chartmuseum:
enabled: true

database:
type: external
external:
host: "postgres.devops.svc.cluster.local"
port: "5432"
username: "harbor"
password: "harbor"
redis:
type: external
external:
addr: "redis.devops.svc.cluster.local:6379"
password: "passwd"

harbor-ingress.yaml

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-http
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/`)
kind: Rule
services:
- name: harbor-portal
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-api
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/api/`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-service
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/service/`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-v2
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/v2`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-chartrepo
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/chartrepo/`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-c
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/c/`)
kind: Rule
services:
- name: harbor-core
port: 80

安装Harbor

1
2
3
4
5
6
7
# 添加Harbor仓库
helm repo add harbor https://helm.goharbor.io

# 使用部署或升级Harbor
helm upgrade harbor harbor/harbor --namespace harbor \
--install --create-namespace \
-f harbor-values.yaml

配置

配置library仓库源

1
2
3
4
5
6
7
kubectl edit configmap harobr-registry -n harbor

# 在auth: 后边添加新节点
proxy:
remoteurl: "https://registry-1.docker.io"


使用Harbor

配置镜像缓存

参考

Harbor 搭建镜像代理 | Northes

Kubernetes ≥ 1.25 Containerd配置Harbor私有镜像仓库_containerd登录镜像仓库-CSDN博客

结合Cert-Manager完成Harbor的Https证书自动签发 | 风格 | 风起于青萍之末 (lusyoe.github.io)

Containerd容器镜像管理-腾讯云开发者社区-腾讯云 (tencent.com)

通过helm在k8s上搭建Harbor - 简书 (jianshu.com)

Kubernetes 集群仓库 harbor Helm3 部署-腾讯云开发者社区-腾讯云 (tencent.com)

containerd基本使用命令 - 杨梅冲 - 博客园 (cnblogs.com)

Kubernetes1.21搭建harbor-腾讯云开发者社区-腾讯云 (tencent.com)

Helm部署

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
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/

#helm会使用kubectl默认的KUBECONFIG配置,这里我们需要将KUBECONFIG换成k3s的否则会链接失败。
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

#注意要指定端口号等信息,方便访问
# service.type=NodePort 默认是ClusterIP只能本机访问
# service.nodePort=30080 指定访问端口号
# replicaCount=2 2个节点

# helm v2
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard \
--create-namespace \
--namespace kubernetes-dashboard \
# --set service.type=NodePort \
# --set service.nodePort=30080 \
# --set replicaCount=2

# helm v3+
helm install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard \
--create-namespace \
--namespace kubernetes-dashboard \
# --set service.type=NodePort \
# --set service.nodePort=30080 \
# --set replicaCount=2

配置远程访问

NodePort暴露端口

1
kubectl -n kubernetes-dashboard edit service kubernetes-dashboard-web
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
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
...
name: kubernetes-dashboard
namespace: kubernetes-dashboard
resourceVersion: "343478"
selfLink: /api/v1/namespaces/kubernetes-dashboard/services/kubernetes-dashboard
uid: 8e48f478-993d-11e7-87e0-901b0e532516
spec:
clusterIP: 10.100.124.90
externalTrafficPolicy: Cluster
ports:
- port: 443
protocol: TCP
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
# 修改开放端口方式
#type: ClusterIP
type: NodePort
status:
loadBalancer: {}

Traefik Ingress反向代理

创建证书请求文件dashboard-cert-manager.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: k3s-chemmy-io
namespace: default
spec:
secretName: k3s-chemmy-io-tls
issuerRef:
name: letsencrypt-staging
kind: ClusterIssuer
commonName: k3s.chemmy.io
dnsNames:
- k3s.sample.net

此配置文件是测试版,正式版参考K3s部署cert-manager(证书管理)

1
2
3
4
5
6
7
8
9
10
11
kubectl apply -f dashboard-cert-manager.yaml

# 查看
kubectl get certificates

# 如果状态不是READY,检查
kubectl describe certificates k3s-chemmy-io

# 清理证书
kubectl delete certificates k3s-chemmy-io
kubectl delete secrets k3s-chemmy-io-tls

配置账户

新建dashboard-admin.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
#创建clusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard

新建用户

1
2
# 部署用户资源
kubectl apply -f dashboard-admin.yaml

获取token

1
2
3
4
5
# v1.24+
sudo k3s kubectl -n kubernetes-dashboard create token admin-user

# v1.23 及之前的版本
sudo k3s kubectl -n kubernetes-dashboard describe secret admin-user-token | grep '^token'

Kubectl部署

最新版本只支持Helm,旧版本v2.7支持Kubectl部署

下载 recommended.yaml

1
kubectl apply -f recommended.yaml

修改recommended.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
# 直接暴露端口使用NodePort,Traefik使用ClusterIP
#type: ClusterIP
type: NodePort
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
---
...

dashboard的默认webui证书是自动生成的,由于时间和名称存在问题,导致谷歌和ie浏览器无法打开登录界面,经过测试Firefox可以正常打开。解决证书问题参考Kubernetes Dashboard的安装与坑 - 简书 (jianshu.com)

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
---

# 注释内置自动生成的证书
#apiVersion: v1
#kind: Secret
#metadata:
# labels:
# k8s-app: kubernetes-dashboard
# name: kubernetes-dashboard-certs
# namespace: kubernetes-dashboard
#type: Opaque

---
...
---

kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.1.0
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
# 注释自动生成证书
# - --auto-generate-certificates
- --namespace=kubernetes-dashboard
# 添加证书配置及证书文件映射
- --token-ttl=3600
- --bind-address=0.0.0.0
- --tls-cert-file=tls.crt
- --tls-key-file=tls.key
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule

---
...

生成证书文件 tls.crt,tls.csr,tls.key

1
2
3
4
5
6
7
8
9
# 生成key
openssl genrsa -out tls.key 2048
# 生成csr
openssl req -new -out tls.csr -key tls.key -subj '/CN=0.0.0.0'
# 生成
openssl x509 -req -in tls.csr -signkey tls.key -out tls.crt

#创建secret
kubectl create secret generic kubernetes-dashboard-certs --from-file=tls.crt --from-file=tls.key -n kubernetes-dashboard

subj子参数解释

缩写 翻译 英文对照
C 国家名称缩写 Country Name (2 letter code)
ST 州或省名称 State or Province Name (full name)
L 城市或区域称 Locality Name (eg, city)
O 组织名(或公司名) Organization Name (eg, company)
OU 组织单位名称(或部门名) Organizational Unit Name (eg, section)
CN 服务器域名/证书拥有者名称 Common Name (e.g. server FQDN or YOUR name)
emailAddress 邮件地址 Email

参考

k3s集群单节点部署与集群内DashBoard部署 - 知乎 (zhihu.com)

k3s集群搭建并安装kubernetes-dashboard - 东峰叵,com - 博客园 (cnblogs.com)

[K8S 快速入门(十九)通过Helm 安装 Kubernetes Dashboard_helm安装dashboard ingress-CSDN博客](https://blog.csdn.net/weixin_41947378/article/details/111661539#:~:text=通过Helm 安装 Kubernetes Dashboard 1 1. 下载 %23,外网访问 %23 将svc的ClusterIP改为NotePort,外网访问 … 5 5. 令牌方式登录仪表盘)

使用 traefik ingress暴露kubernetes-dashbord - HTTPS版本_svclb-traefik-CSDN博客

Kubernetes dashboardv2.7.0安装指南:从零开始搭建可视化界面 - 知乎

常用国内源

1
2
3
4
5
6
7
https://pypi.tuna.tsinghua.edu.cn/simple

https://mirrors.ustc.edu.cn/pypi/web/simple # 已暂时移除并重定向到 BFSU PyPI

https://mirrors.aliyun.com/pypi/simple/

http://mirrors.cloud.tencent.com/pypi/simple

查看当前镜像地址

1
2
3
4
5
pip config list

# 查看数据中对应路径
global.index-url = 'https://pypi.tuna.tsinghua.edu.cn/simple'
install.trusted-host = 'https://pypi.tuna.tsinghua.edu.cn'

临时使用

1
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

全局修改

1
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

换回默认

1
pip config unset global.index-url

手动管理证书

生成证书

参考 OpenSSL生成自签名证书

导入证书

1
kubectl create secrets tls example-io-tls --key example.io.key --cert example.io.crt

手动管理证书可忽略下边的安装过程,跳转到证书配置

使用cert-manager管理证书

部署cert-manager

方式一: 使用Helm部署(推荐)

1
2
3
4
5
6
7
8
9
10
11
# 添加镜像源
helm repo add jetstack https://charts.jetstack.io

#获取配置文件
helm show values jetstack/cert-manager > cert-manager-values.yaml

# 部署cert-mangaer
helm upgrade cert-manager jetstack/cert-manager \
--namespace cert-manager \
--install --create-namespace \
--set crds.enabled=true

方式二: 使用kubectl部署

1
2
3
4
5
6
7
8
9
# Kubernetes 1.16+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml
# Kubernetes <1.16
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager-legacy.yaml

# Kubernetes 1.15+
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.16.1/cert-manager.yaml
# Kubernetes <1.15
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.16.1/cert-manager-legacy.yaml

创建ClusterIssuer/Issuer

公网域名证书

Issuer 与 ClusterIssuer 的区别是 ClusterIssuer 可跨命名空间使用,而 Issuer 需在每个命名空间下配置后才可使用。这里我们使用 ClusterIssuer,其类型选择 Let‘s Encrypt。

正式环境速率限制(每个注册域名可签发的证书数量(每周 50 份)),使用测试环境测试一切正常后再切换正式环境。

letsencrypt-issuer-staging.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: <YOUR EMAIL> # replice this
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: traefik
selector: {}

letsencrypt-issuer-prod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: <YOUR EMAIL> # replice this
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: traefik
selector: {}

说明:

metadata.name 创建的签发机构的名称,创建证书的时候会引用
spec.acme.email 邮箱,证书快过期的时候会有邮件提醒,不过cert-manager会利用acme协议自动给我们重新颁发证书来续期
spec.acme.server acme 协议的服务端,由官方给出
spec.acme.privateKeySecretRef 指示此签发机构的私钥将要存储到哪个Secret对象中
spec.acme.solvers.http01 指示签发机构使用HTTP-01的方式进行acme协议 (还可以用DNS方式,acme协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)

自签名证书

selfsigned-issuer.yaml

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
34
35
36
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-cluster-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: selfsigned-ca
spec:
isCA: true
commonName: selfsigned-ca
secretName: root-secret
privateKey:
algorithm: ECDSA
size: 256
subjects:
organizations:
-
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
group: cert-manager.io
#---
## 使用自定义根证书
## 导入根证书 kubectl create secret tls ca-secret --key root-ca.key --cert root-ca.crt
#apiVersion: cert-manager.io/v1
#kind: ClusterIssuer
#metadata:
# name: selfsigned-cluster-issuer
#spec:
# ca:
# secretName: ca-secret

spec.subjects.organizations:

创建域名证书

公网域名证书

example-io-tls.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-io-tls
spec:
secretName: example-io-secret #
issuerRef:
name: letsencrypt-staging # 使用自签名证书时替换为 selfsigned-cluster-issuer
kind: ClusterIssuer
duration: 2160h
renewBefore: 360h
dnsNames:
- example.io
ipAddresses:
- 192.168.1.1

生产环境使用建议

实际生产环境中使用cert-manager可以考虑以下建议:

  1. 将CA的SecretIssuer放在某个独立的命名空间中,与其它业务的命名空间隔离起来。
  2. 如果是CA类型的Issuer,要记得定期更新根CA证书。
  3. 如果服务可被公网访问,同时又不想花钱买域名证书,可以采用Letsencrypt类型的Issuer,目前支持两种方式验证域名的所有权,基于DNS记录的验证方案和基于文件的HTTP验证方案
  4. cert-manager还提供ingress-shim方式,自动为Ingress资源生成证书,只需要在Ingress资源上打上一些标签即可,详细可参考这里

spec.secretName 指示证书最终存到哪个 Secret 中

spec.issuerRef.kind 值为 ClusterIssuer 说明签发机构不在本 namespace 下,而是在全局

spec.issuerRef.name 我们创建的签发机构的名称 (ClusterIssuer.metadata.name)

spec.duration 证书过期时间

spec.renewBefore 在过期前自动更新

spec.dnsNames 指示该证书的可以用于哪些域名

spec.acme.config.http01.domains 指示该证书的可以用于哪些域名

Traefik配置证书

终端安装证书

获取CA证书,root-ca.crt,k3s导出证书 参考 K3s导出证书


k8s中使用cert-manager玩转证书-腾讯云开发者社区-腾讯云 (tencent.com)

k8s 使用cert-manager证书管理自签-CSDN博客

k8s部署cert-manager实现证书自动化_cert-manager.yaml-CSDN博客

Cert-Manager 实现 K8s 服务域名证书自动化续签 - 知乎 (zhihu.com)

手把手教你使用 cert-manager 签发免费证书 - 腾讯云原生 - 博客园 (cnblogs.com)

在 k3s 内使用 cert-manager 管理证书 (bowser1704.github.io)

用 k3s 轻松管理 SSL 证书 | Linux 中国 - 知乎

k8s中级篇-cert-manager+Let‘s Encrypt自动证书签发_cert-manager let’s encrypt-CSDN博客

容器服务 使用 cert-manager 签发免费证书-实践教程-文档中心-腾讯云 (tencent.com)

内网证书

cert-manager管理内网k8s开发环境证书 - hueidou163 - 博客园 (cnblogs.com)

SelfSigned - cert-manager (k8s-docs.github.io)

k8s 使用cert-manager证书管理自签-CSDN博客

k8s中使用cert-manager玩转证书-腾讯云开发者社区-腾讯云 (tencent.com)

k8s ingress配置自签名证书,并解决Kubernetes Ingress Controller Fake Certificate-CSDN博客

K8s & K3s 集群中应用自动签发 Https 证书 - 流雨声 - 博客园 (cnblogs.com)

Kubernetes (K8S) 中Traefik自动申请证书-腾讯云开发者社区-腾讯云