0%

服务端

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

准备环境

证书

[[Others/OpenSSL生成自签名证书|OpenSSL生成自签名证书]]

[[Kubernetes/K3s证书管理|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

导出Secret

1
kubectl get secret example-secret -o yaml > example-secret.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
apiVersion: v1
data:
ca.crt: ...
tls.crt: ...
tls.key: ...
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: '...'
cert-manager.io/certificate-name: ...
cert-manager.io/common-name: Tianjin Pengan
cert-manager.io/ip-sans: 192.168.0.2
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: selfsigned-cluster-issuer
cert-manager.io/subject-organizations: ...
cert-manager.io/uri-sans: ""
creationTimestamp: "2024-09-10T10:54:59Z"
labels:
controller.cert-manager.io/fao: "true"
name: tjpengan-io-secret
namespace: default
resourceVersion: "1730340"
uid: 1c7d877b-ed86-4a1a-ad8c-0d8466c46506
type: kubernetes.io/tls

Base64解码

1
2
3
4
5
# cert
cat example-secret.yaml | grep tls.crt | awk '{print $2}' | base64 --decode > example-secret.cert

#key
cat example-secret.yaml | grep tls.key | awk '{print $2}' | base64 --decode > example-secret.key

Kubectl部署

配置文件

Helm部署

添加helm库

1
2
3
4
5
6
7
8
9
10
11
# 添加库
helm repo add bitnami https://charts.bitnami.com/bitnami

# 更新库缓存
helm repo update

# 搜索redis镜像
helm search repo redis

# 获取package的values.yaml
helm show values bitnami/redis > values-default.yaml

配置 values.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
auth:
password: 123456 # redis 访问密码
master:
service:
type: NodePort # 服务对外暴露端口方式
persistence: # 配置点存储
storageClass: ""
size: 8Gi
replica:
service:
type: NodePort
persistence:
storageClass: ""
size: 8Gi

部署

1
helm install -f values.yaml redis bitnami/redis --namespace --create-namespace

参考

kubernetes环境部署单节点redis - 紫色飞猪 - 博客园 (cnblogs.com)

K8S如何部署Redis(单机、集群)_k8部署redis单节点-CSDN博客

4. K8S发布redis主从-CSDN博客

redis集群 - Helm3-安装Redis - 全栈工程师进阶 - SegmentFault 思否

手动管理证书

生成证书

参考
[[Others/OpenSSL生成自签名证书|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博客

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

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

使用cert-manager为Traefik IngressRoute自动签发Let’s Encrypt证书 – 桃又的技术笔记 (taoyouh.cn)

内网证书

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

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

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

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

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

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

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