Chemmy's Blog

chengming0916@outlook.com

在K3s集群环境中,TLS/SSL证书是保障服务通信安全的核心基础设施,无论是对外提供HTTPS服务的公网域名证书,还是内网私有服务所用的自签名证书,都需要一套规范、高效的全生命周期管理方案。本文将从手动证书管理的基础操作切入,逐步深入至基于cert-manager的自动化管理实践,全面覆盖证书生成、部署、续签、轮换等关键环节,帮助开发者与运维人员高效管控K3s集群中的证书资源,筑牢集群通信安全防线。

一、手动管理证书:基础操作与适用场景

手动管理证书适用于证书数量少、变更频率低、场景临时的场景(如内网测试、短期验证),其核心操作主要分为「证书生成」与「集群导入」两个关键步骤,操作简单且无需依赖额外组件。

1.1 生成证书

自签名证书是内网测试、私有服务场景的首选,可通过OpenSSL工具快速生成,生成后将获得两个核心文件:私钥文件(如example.io.key)和证书文件(如example.io.crt),具体生成步骤可参考OpenSSL生成自签名证书

1.2 导入证书到K3s

K3s集群中,TLS类型的Secret是标准的证书存储载体,需将生成的证书文件导入至Secret中,方可被Ingress、Service等资源引用。执行以下命令即可完成导入操作:

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

导入完成后,可在Ingress规则或Service配置中直接引用该Secret,快速实现服务的HTTPS访问配置。

注意:手动管理证书存在明显局限,需人工实时关注证书过期时间,且无法实现自动续签,一旦遗漏续签可能导致服务中断,仅建议在临时测试、小规模场景中使用。

二、cert-manager:K3s证书自动化管理核心工具

cert-manager作为Kubernetes生态中主流的证书管理组件,具备自动签发、自动续签、多证书类型兼容等核心优势,支持Let’s Encrypt(公网免费证书)、自签名CA、自定义CA等多种签发来源,能够完美适配K3s集群的轻量化特性,是生产环境中K3s证书管理的首选方案,可大幅降低运维成本并提升证书管理的安全性与可靠性。

2.1 部署cert-manager

推荐使用Helm部署cert-manager,该方式支持自定义配置、版本管控与后续升级,也可通过kubectl快速部署以满足快速上手需求,两种部署方式详细步骤如下:

方式一:Helm部署(推荐)

1
2
3
4
5
6
7
8
9
10
11
# 添加jetstack镜像源(cert-manager官方仓库,确保资源拉取稳定性)
helm repo add jetstack https://charts.jetstack.io
# 更新镜像源索引
helm repo update
# 导出默认配置文件(可选,用于自定义部署参数,适配集群环境)
helm show values jetstack/cert-manager > cert-manager-values.yaml
# 部署cert-manager(创建独立命名空间,启用CRD资源,确保组件独立运行)
helm upgrade cert-manager jetstack/cert-manager \
--namespace cert-manager \
--install --create-namespace \
--set crds.enabled=true

方式二:kubectl部署(快速上手)

根据Kubernetes版本选择对应部署文件,K3s默认版本通常满足1.16+要求,具体命令如下:

1
2
3
4
# Kubernetes 1.16+(K3s默认版本适配)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml
# Kubernetes <1.16(老旧版本兼容,需使用legacy版本)
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager-legacy.yaml

部署完成后,可通过以下命令验证组件运行状态,所有Pod均处于Running状态即表示部署成功:

1
kubectl get pods -n cert-manager

2.2 创建签发机构(ClusterIssuer/Issuer)

cert-manager通过「签发机构(Issuer/ClusterIssuer)」定义证书的签发规则与来源,两者的核心区别在于作用范围:

  • Issuer:仅作用于当前命名空间,适用于单一命名空间内的证书管理场景;

  • ClusterIssuer:全局生效,可跨所有命名空间使用,适用于集群级别的统一证书管理,推荐在K3s集群中优先使用。

2.2.1 公网域名证书:Let’s Encrypt签发

Let’s Encrypt提供免费的公网SSL证书,支持测试环境(staging)和生产环境(prod)两种模式:测试环境无速率限制,适合前期验证配置;生产环境有严格的速率限制,需测试通过后再切换使用,避免触发限制导致证书签发失败。

(1)测试环境ClusterIssuer(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> # 替换为你的邮箱,证书过期前会收到提醒通知
server: https://acme-staging-v02.api.letsencrypt.org/directory # 测试环境ACME服务端地址
privateKeySecretRef:
name: letsencrypt-staging # 存储签发机构私钥的Secret名称,自动创建
solvers:
- http01:
ingress:
class: traefik # K3s默认Ingress控制器为Traefik,需与集群实际Ingress类型匹配
selector: {}
(2)生产环境ClusterIssuer(letsencrypt-issuer-prod.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-prod
spec:
acme:
email: <YOUR EMAIL> # 替换为你的邮箱,用于证书过期提醒与身份验证
server: https://acme-v02.api.letsencrypt.org/directory # 生产环境ACME服务端地址
privateKeySecretRef:
name: letsencrypt-prod # 存储签发机构私钥的Secret名称,自动创建
solvers:
- http01:
ingress:
class: traefik # 适配K3s默认Traefik Ingress控制器
selector: {}

核心配置说明:

  • spec.acme.solvers.http01:采用HTTP-01验证方式,用于证明域名归属权,适用于公网可访问的域名;若域名无法直接暴露公网,可选择DNS验证方式,适配更多场景;

  • spec.acme.server:Let’s Encrypt的ACME协议服务端地址,测试环境与生产环境地址不同,不可混淆使用;

  • 生产环境速率限制:每个注册域名每周最多签发50张证书,每个精确域名组合每周最多签发5张证书,单账号每3小时最多创建300个新订单,需合理规划证书签发策略,避免触发限制。

2.2.2 内网场景:自签名证书签发

内网服务无需公网域名验证,可通过自签名ClusterIssuer快速生成证书,满足内网服务的HTTPS通信需求,配置文件(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
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 # 标记为CA证书,用于签发其他子证书
commonName: selfsigned-ca # CA证书通用名称,可自定义
secretName: root-secret # 存储CA证书与私钥的Secret名称
privateKey:
algorithm: ECDSA # 加密算法,ECDSA比RSA更高效、更安全
size: 256 # 密钥长度,256位满足常规安全需求
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
group: cert-manager.io

若集群已存在自定义根CA证书,可先将其导入至Secret中,再修改ClusterIssuer配置引用该CA,实现基于自定义CA的证书签发:

1
2
# 导入自定义根CA证书(替换为实际的CA私钥与证书文件路径)
kubectl create secret tls ca-secret --key root-ca.key --cert root-ca.crt
1
2
3
4
5
6
7
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-cluster-issuer
spec:
ca:
secretName: ca-secret # 引用已导入的自定义CA Secret

补充说明:K3s默认会在首个Server节点启动时生成自签名CA证书,该CA证书有效期为10年,且不会自动更新,若需轮换CA证书,可使用k3s certificate rotate-ca命令执行轮换操作,确保CA证书的安全性。

2.3 创建域名证书

完成签发机构(ClusterIssuer/Issuer)配置后,通过cert-manager的Certificate资源定义具体的域名证书规则,cert-manager会自动根据规则向指定签发机构申请证书,并将签发成功的证书存储到指定Secret中,全程无需人工干预。

示例:公网域名证书(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 # 证书最终存储的Secret名称,自动创建
issuerRef:
name: letsencrypt-staging # 签发机构名称,测试环境使用;生产环境替换为letsencrypt-prod;内网替换为selfsigned-cluster-issuer
kind: ClusterIssuer # 签发机构类型,与创建的签发机构一致
duration: 2160h # 证书有效期(90天,Let's Encrypt默认有效期,不可修改)
renewBefore: 360h # 过期前15天自动触发续签,预留足够的续签缓冲时间
dnsNames:
- example.io # 证书绑定的公网域名,可添加多个域名
ipAddresses:
- 192.168.1.1 # 可选,绑定内网IP,适用于内网对外提供服务的场景

应用配置文件,cert-manager将自动启动证书签发流程:

1
kubectl apply -f example-io-tls.yaml

可通过以下命令查看证书签发状态,当Ready字段为True时,表示证书签发成功,可正常使用:

1
kubectl get certificates

三、生产环境最佳实践

结合cert-manager官方安全规范与K3s集群特性,总结以下生产环境证书管理最佳实践,兼顾安全性、可维护性与易用性,适配企业级集群部署需求:

1. 命名空间隔离,降低安全风险

将CA证书、ClusterIssuer等核心证书资源部署在独立命名空间(如cert-manager-ca),与业务命名空间严格隔离;同时配置最小权限的网络策略(如使用Calico),禁止非信任客户端访问cert-manager组件,限制cert-manager仅能与Kubernetes API Server、指定签发机构通信,遵循“最小权限”原则,降低权限泄露风险。

2. CA证书规范管理,避免全链路失效

自定义CA证书需定期手动更新,建议建立CA证书过期提醒机制,避免根证书过期导致集群内所有依赖该CA的证书失效;若使用K3s默认自签名CA,需定期通过k3s certificate rotate-ca命令轮换CA证书,确保CA证书的安全性;此外,自定义CA证书需按规范放置在/var/lib/rancher/k3s/server/tls目录下,确保K3s集群正常识别。

3. 启用Ingress自动签发,减少手动配置

利用cert-manager的ingress-shim功能,在Ingress资源中添加指定注解(如cert-manager.io/cluster-issuer: letsencrypt-prod),即可实现证书的自动签发与绑定,无需手动创建Certificate资源,大幅减少运维配置工作量;同时可结合kubernetes-reflector项目,实现Certificate生成的Secret跨命名空间自动同步,适配多命名空间业务场景。

4. 合理选择验证方式,兼顾安全与易用

公网域名优先使用DNS验证方式,无需将服务直接暴露到公网,更适合内网部署但需对外提供HTTPS服务的场景;内网域名无需公网验证,优先使用自签名CA,简化配置流程的同时保障内网通信安全;对于多域名场景,可在单张证书中绑定多个域名(最多100个),提升管理效率,但需注意控制域名数量,避免影响性能。

5. 证书轮换与故障排查

K3s客户端和服务器证书默认有效期为365天,每次启动K3s时,已过期或90天内过期的证书会自动更新;若需手动轮换单个或多个证书,可使用k3s certificate rotate --service <SERVICE>命令(支持轮换admin、api-server、kubelet等多种证书);cert-manager签发的证书若出现签发失败,可通过kubectl describe certificates <证书名称>查看详细日志,定位故障原因(如域名验证失败、速率限制触发等)。

四、总结

K3s证书管理的核心是“场景化选择适配方案”:手动管理适用于临时测试、小规模场景,操作简单但运维成本高;cert-manager自动化管理适用于生产环境,可实现证书的自动签发、续签、轮换,大幅降低运维成本,同时保障集群通信安全,是企业级K3s集群的最优选择。

在实际部署中,需结合业务场景选择合适的证书类型与签发方式:公网场景优先使用Let’s Encrypt免费证书,严格遵循速率限制;内网场景优先使用自签名CA或自定义CA,兼顾配置简化与安全;同时遵循生产环境最佳实践,通过命名空间隔离、最小权限配置、自动签发等方式,实现证书的全生命周期规范化管理,为K3s集群的稳定运行提供安全保障。

参考资料

  1. cert-manager官方文档:https://cert-manager.io/docs/

  2. Let’s Encrypt ACME协议说明:https://letsencrypt.org/docs/acme-protocol/

  3. K3s Traefik Ingress配置:https://docs.k3s.io/networking/traefik

  4. K3s证书管理官方文档:https://docs.k3s.io/zh/cli/certificate

  5. cert-manager生产环境最佳实践:https://cert-manager.io/v1.17-docs/installation/best-practice/

1
2
3
4
5
6
# 导出根证书
kubectl get secret example-secret -o jsonpath='{.data.ca\.crt}'| base64 --decode

kubectl get secret example-secret -o jsonpath='{.data.tls\.crt}'| base64 --decode

kubectl get secret example-secret -o jsonpath='{.data.tls\.key}'| base64 --decode

导出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

Linux 源

清华 https://mirrors.tuna.tsinghua.edu.cn

阿里 http://mirrors.aliyun.com

腾讯 https://mirrors.tencent.com

华为 https://mirrors.huaweicloud.com

中国科技大学 https://mirrors.ustc.edu.cn

华中科技大学 http://mirror.hust.edu.cn

Docker 镜像仓库

DockerHub(docker.io)

网易 http://hub-mirror.c.163.com

中国科技大学 https://docker.mirrors.ustc.edu.cn (不可用)

道客 https://docker.m.daocloud.cn (参考官方文档)

腾讯 https://mirror.ccs.tencentyun.com

华为 https://mirror.swr.myhuaweicloud.com

阿里云 https://registry.cn-hangzhou.aliyuncs.com

[^注]: 阿里可申请私有加速,需注册账号,注册后地址修改为 https://{私有ID}.mirror.aliyuncs.com。详细信息参考官方文档

谷歌镜像仓库(gcr.io k8s.gcr.io)

阿里 https://registry.aliyuncs.com/google_containers

中科大 https://gcr.mirrors.ustc.edu.cn (2022.8之后不再更新镜像,校外访问返回403)

华为 https://mirror.swr.myhuaweicloud.com

道客 https://m.daocloud.io/k8s.gcr.io 文档

CoreOS镜像仓库(quay.io )

道客 https://m.daocloud.io/quay.io 参考支持镜像列表

Github镜像仓库(ghcr.io )

道客 https://m.daocloud.io/ghcr.io 参考支持镜像列表

Helm 源

ArtifactHub https://artifacthub.io/

华为 https://mirrors.huaweicloud.com/helm/

bitnami https://charts.bitnami.com/bitnami

Google https://gcr.io/kubernetes-helm

容器配置

Docker(/etc/docker/daemon.json )

1
2
3
4
5
6
7
8
9
10
11
{

"registry-mirrors": [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
],
"insecure-registries": [],
"exec-opts":["native.cgroupdriver=systemd"]

}

Containerd(/etc/containerd/config.toml)

1
2
3
4
5
6
7
8

[plugins.cri.registry]
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."quay.io"]
endpoint = ["https://quay.tencentcloudcr.com"]
[plugins.cri.registry.mirrors."docker.io"]
endpoint = ["https://mirror.ccs.tencentyun.com"]

K3s中Containerd容器(/var/lib/rancher/k3s/agent/etc/containerd/config.toml)

K3s 默认的 containerd 配置文件目录为/var/lib/rancher/k3s/agent/etc/containerd/config.toml,但直接操作 containerd 的配置文件去设置镜像仓库或加速器相比于操作 docker 要复杂许多。K3s 为了简化配置 containerd 镜像仓库的复杂度,K3s 会在启动时检查/etc/rancher/k3s/中是否存在 文件,如果存在该文件,就会根据 registries.yaml 的内容转换为 containerd 的配置并存储到/var/lib/rancher/k3s/agent/etc/containerd/config.toml,从而降低了配置 containerd 镜像仓库的复杂度。

1
2
3
4
5
6
7
8
9
10
11
mirrors:
"172.31.6.200:5000":
endpoint:
- "http://172.31.6.200:5000"
"rancher.ksd.top:5000":
endpoint:
- "http://172.31.6.200:5000"
"docker.io":
endpoint:
- "https://fogjl973.mirror.aliyuncs.com"
- "https://registry-1.docker.io"

containerd 与 docker 都有默认仓库,并且都为 docker.io。如果配置中未指定 mirror 为 docker.io,重启 containerd 后会自动加载 docker.io 配置。与 docker 不同的是,containerd 可以修改 docker.io 对应的 endpoint( 默认为 https://registry-1.docker.io ),而 docker 无法修改。

docker 中可以通过 registry-mirrors 设置镜像加速地址。如果 pull 的镜像不带仓库地址(项目名+镜像名:tag),则会从默认镜像仓库去拉取镜像。如果配置了镜像加速地址,会先访问镜像加速仓库,如果没有返回数据,再访问默认吧镜像仓库。

k3s完整配置文件

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
mirrors:
"192.168.50.119":
endpoint:
- "http://192.168.50.119"
"docker.io":
endpoint:
- "https://7bezldxe.mirror.aliyuncs.com"
- "https://registry-1.docker.io"
configs:
"192.168.50.119":
auth:
username: '' # this is the registry username
password: '' # this is the registry password
tls:
cert_file: '' # path to the cert file used in the registry
key_file: '' # path to the key file used in the registry
ca_file: '' # path to the ca file used in the registry
"docker.io":
auth:
username: '' # this is the registry username
password: '' # this is the registry password
tls:
cert_file: '' # path to the cert file used in the registry
key_file: '' # path to the key file used in the registry
ca_file: '' # path to the ca file used in the registry

镜像转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#gcr.io
docker pull gcr.io/kubernetes-helm/tiller:v2.16.1
docker pull gcr.mirrors.ustc.edu.cn/kubernetes-helm/tiller:v2.16.1

#k8s.gcr.io
#docker pull k8s.gcr.io/kube-proxy:v1.15.5
docker pull gcr.mirrors.ustc.edu.cn/google-containers/kube-proxy:v1.15.5

#quay.io
docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
docker pull quay.mirrors.ustc.edu.cn/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1


转换为gcr.io镜像

1
2
3
docker pull registry.aliyuncs.com/google_containers/coredns:1.6.5
docker tag registry.aliyuncs.com/google_containers/coredns:1.6.5 k8s.gcr.io/coredns:1.6.5
docker rmi registry.aliyuncs.com/google_containers/coredns:1.6.5

K8S批量下载docker images

1
kubeadm config images list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

#!/bin/bash
images=( # 下面的镜像应该去除"k8s.gcr.io/"的前缀,版本换成上面获取到的版本
kube-apiserver:v1.12.1
kube-controller-manager:v1.12.1
kube-scheduler:v1.12.1
kube-proxy:v1.12.1
pause:3.1
etcd:3.2.24
coredns:1.2.2
)

for imageName in ${images[@]} ; do
docker pull registry.aliyuncs.com/google_containers/$imageName
docker tag registry.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.aliyuncs.com/google_containers/$imageName
done

更新版

1
2
3
4
5
6
7
8
9
10
11

#!/bin/bash
url=registry.aliyuncs.com
version=v1.16.4
images=(`kubeadm config images list --kubernetes-version=$version|awk -F '/' '{print $2}'`)
for imagename in ${images[@]} ; do
docker pull $url/$imagename
docker tag $url/$imagename k8s.gcr.io/$imagename
docker rmi -f $url/$imagename
done

或(V1.3以上)

1
2
kubeadm init --image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.13.0 --pod-network-cidr 192.168.1.100/24

K3s安装

参考 [[K3s安装|K3S安装]]

组件配置信息

开放端口

端口 用途
53 CoreDNS服务,替代修改Hosts方式实现内网域名访问
5432/3306 PostgreSQL/MySQL数据库(二选一即可)
443,80 HTTPS、HTTP访问入口,Traefik
6379 Redis缓存
8022 SSH管理端口
22 git+ssh方式代码上传

域名规划

组件 访问地址 说明
Cert-Manager 证书管理服务,有公网域名推荐使用,内网部署可生成自签名证书
Traefik Dashboard https://dashboard.example.io 反向代理/负载均衡
Harbor https://harbor.example.io 私有镜像库,镜像缓存
Gitea https://gitea.example.io 源代码仓库
Tekton https://tekton.example.io 云原生持续集成
Drone https://drone.example.io 容器化持续集成
Sonar Qube https://sonar.example.io 静态代码审查。
ArgoCD https://argocd.example.io 持续部署组件

组件部署

Traefik

1
2
3
4
5
6
7
```

### ArgoCD

Helm方式部署

```bash

MySQL

参考 K3s部署MySQL

1
2
3
4
5
6
7
8
9
10
11
# k3s使用 local-path 部署
kubectl apply -f https://gitee.com/Chemmy/kube-template/MySQL/mysql-pvc-local-path.yaml

# 部署mysql-config
kubectl apply -f https://gitee.com/Chemmy/kube-template/MySQL/mysql-config.yaml

# 部署deploy
kubectl apply -f https://gitee.com/Chemmy/kube-template/MySQL/mysql-deployment.yaml

# 部署service(NodePort 方式)
kubectl apply -f https://gitee.com/Chemmy/kube-template/MySQL/mysql-service.yaml

PostgresSQL

参考 K3s部署PostgreSQL

1
2
3
4
5
6
7
8
9
10
11
# k3s使用 local-path 部署
kubectl apply -f https://gitee.com/Chemmy/kube-template/PostgreSQL/postgres-pvc-local-path.yaml

# 部署config
kubectl apply -fhttps://gitee.com/Chemmy/kube-template/PostgreSQL/postgres-config.yaml

# 部署deploy
kubectl apply -fhttps://gitee.com/Chemmy/kube-template/PostgreSQL/postgres-deployment.yaml

# 部署service(NodePort 方式)
kubectl apply -fhttps://gitee.com/Chemmy/kube-template/PostgreSQL/postgres-service.yaml

cert-manager

参考[[K3s证书管理|K3s证书管理]]

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

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

Harbor

参考K3s部署Harbor私有镜像仓库

1

Gitea

参考K3s部署Gitea

1

Tekton

参考[[K3s部署Tenton]]

1
2
3
4
5
6
7
8
```

### Drone (已弃用)

参考[K3s部署Drone](K3s部署Drone.md)

```bash

SonarQube

参考K3s部署SonarQube

1

组件之间联动配置

参考

Gitea官方文档

Gitea README

Drone官方文档

Helm官方文档

Harbor官方文档

Traefik Proxy Documentation - Traefik

k3s 部署gitea+drone_golang k3s-CSDN博客

Harbor 结合 Traefik 的 HA 安装配置-腾讯云开发者社区-腾讯云 (tencent.com)

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

Drone CI使用docker插件构建和推送镜像 - wosperry - 博客园 (cnblogs.com)

在 Kubernetes 上部署 Drone 持续集成环境 | Hanggi - NGNL

Gitea 与 Drone 集成实践:完全基于 Docker 搭建的轻量级 CI/CD 系统 - Gitea - 博客园 (cnblogs.com)

Helm Chart Kubernetes安装SonarQube_helm安装sunaqube-CSDN博客

安装基础环境

新装环境

Master节点安装

1
2
3
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
INSTALL_K3S_EXEC='--write-kubeconfig-mode=644' sh -

Worker节点加入集群

1
2
3
4
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
K3S_URL=https://<k3s-server-ip>:6443 \
K3S_TOKEN=<token> \
INSTALL_K3S_EXEC='--write-kubeconfig-mode=644' sh -

参数说明:

  • <k3s-server-ip>: K3s服务器的IP地址
  • <token>: K3s服务器生成的唯一令牌,可通过以下命令获取:
    1
    sudo cat /var/lib/rancher/k3s/server/node-token

INSTALL_K3S_EXEC 参数

参数 说明
--write-kubeconfig-mode=644 设置配置文件权限
--service-node-port-range=1-65535 解除端口限制(默认30000-32767)
--advertise-address=192.168.1.1 指定集群管理IP,默认端口6443
--disable=traefik 禁用Traefik Ingress
--disable=local-path 禁用本地存储
--default-local-storage-path=/mnt/storage/k3s 自定义本地存储的默认存储路径

环境变量

  • INSTALL_K3S_MIRROR=cn: 设置中国区镜像
  • INSTALL_K3S_SKIP_SELINUX_RPM=true: 安装由于selinux导致失败时可加此配置跳过k3s selinux配置

配置kubeconfig

1
echo "export KUBECONFIG=/etc/rancher/k3s/k3s.yaml" >> ~/.bashrc

修改local-path存储类回收策略

local-path默认的storage class回收策略为Delete,当容器被删除时会删除容器关联的PV。生产环境建议改为Retain

![[K3s安装/IMG-20260331151812893.png]]

1
2
3
4
5
6
7
8
# 查看当前存储类
kubectl get storageclasses.storage.k8s.io local-path

# 删除原有存储类
kubectl delete storageclasses.storage.k8s.io local-path

# 应用修改后的存储类
kubectl apply -f storage-class.yaml

storage-class.yaml内容:

1
2
3
4
5
6
7
8
9
10
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
defaultVolumeType: local
storageclass.kubernetes.io/is-default-class: "true"
name: local-path
provisioner: rancher.io/local-path
reclaimPolicy: Retain # 此处修改为Retain
volumeBindingMode: WaitForFirstConsumer

现有环境修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 停止k3s服务
sudo systemctl stop k3s.service

# 编辑服务配置文件
vim /etc/systemd/system/k3s.service

# 修改ExecStart部分
# 原有内容:
ExecStart=/usr/local/bin/k3s \
server \
'--write-kubeconfig-mode=644'

# 修改后:
ExecStart=/usr/local/bin/k3s \
server \
'--write-kubeconfig-mode=644' \
'--service-node-port-range=1-65535' \
'--default-local-storage-path=/mnt/storage/k3s'

# 重新加载配置并启动服务
sudo systemctl daemon-reload
sudo systemctl start k3s.service

安装管理工具Helm

1
2
3
4
5
6
7
8
9
10
11
# 在线安装
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Ubuntu使用snap安装
sudo snap install helm --classic

# 离线安装
# 1. 下载最新版离线安装包:https://github.com/helm/helm/releases
# 2. 解压并安装
tar xf helm-v2.11.0-linux-amd64.tar.gz
cp linux-amd64/helm linux-amd64/tiller /usr/local/bin/

添加命令自动补全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 安装bash-completion
sudo apt install bash-completion
source /usr/share/bash-completion/bash_completion

# kubectl自动补全
# 临时使用
echo 'source <(kubectl completion bash)' >> ~/.bashrc

# 永久生效
kubectl completion bash | sudo tee /etc/bash_completion/kubectl > /dev/null

# helm自动补全
# 临时使用
echo 'source <(helm completion bash)' >> ~/.bashrc

# 永久生效
helm completion bash | sudo tee /etc/bash_completion/helm > /dev/null

常用命令

Kubernetes命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看集群所有资源
kubectl get all -A -o wide

# 查看指定命名空间
kubectl get all -n {namespace name}

# 查看容器日志
kubectl logs -n {namespace name} pod/{pod name}

# 查看资源详细信息
kubectl describe -n {namespace name} [service|pod|secret|certificate|...]

# 查看节点信息
kubectl get node --show-labels -o wide

# 重启Pod
kubectl rollout restart {pod name} -n {namespace}

# 伸缩实例数量
kubectl scale deploy whoami --replicas=5

# 查看集群信息
kubectl cluster-info

Helm命令

1
2
# 获取charts的values文件
helm show values bitnami/redis > values.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
# 创建2副本的whoami应用
kubectl create deploy whoami --image=traefik/whoami --replicas=2

# 查看部署应用信息
kubectl describe deploy whoami

# 监控Pod状态
kubectl get pods --watch

# 扩容到5个副本
kubectl scale deploy whoami --replicas=5

# 发布K3s内网的服务
kubectl expose deploy whoami --port=80

# 查看服务状态
kubectl get svc whoami -owide
kubectl describe svc whoami

# 映射端口到宿主机(LoadBalancer类型)
kubectl expose deploy whoami --type=LoadBalancer --port=80 --external-ip <PUBLIC_IP>

# 清空测试资源
kubectl delete all --all

请求链路理解:

1
request public-ip -> node-port -> svc-port -> pod-port -> container

配置国内源(私有镜像库)

K3s 默认的 containerd 配置文件目录为 /var/lib/rancher/k3s/agent/etc/containerd/config.toml。K3s 会在启动时检查 /etc/rancher/k3s/ 中是否存在 registries.yaml 文件,如果存在则根据其内容转换为 containerd 配置。

配置文件由两部分组成:

  • Mirrors: 定义专用镜像仓库的名称和 endpoint
  • Configs: 定义每个 mirror 的 TLS 和证书配置

非安全(http)私有仓库配置

无认证

1
2
3
4
mirrors:
"172.31.6.200:5000":
endpoint:
- "http://172.31.6.200:5000"

有认证

1
2
3
4
5
6
7
8
9
mirrors:
"35.182.134.80":
endpoint:
- "http://35.182.134.80"
configs:
"35.182.134.80":
auth:
username: admin
password: Harbor12345

安全(https)私有仓库配置

使用授信SSL证书

1
2
3
4
5
6
7
8
9
mirrors:
"harbor.kingsd.top":
endpoint:
- "https://harbor.kingsd.top"
configs:
"harbor.kingsd.top":
auth:
username: admin
password: Harbor12345

使用自签SSL证书

1
2
3
4
5
6
7
8
9
10
11
mirrors:
"harbor-ksd.kingsd.top":
endpoint:
- "https://harbor-ksd.kingsd.top"
configs:
"harbor-ksd.kingsd.top":
auth:
username: admin
password: Harbor12345
tls:
ca_file: /opt/certs/ca.crt

SSL双向认证

1
2
3
4
5
6
7
8
9
10
11
12
13
mirrors:
"harbor-ksd.kingsd.top":
endpoint:
- "https://harbor-ksd.kingsd.top"
configs:
"harbor-ksd.kingsd.top":
auth:
username: admin
password: Harbor12345
tls:
ca_file: /opt/certs/ca.crt
cert_file: /opt/certs/harbor-ksd.kingsd.top.cert
key_file: /opt/certs/harbor-ksd.kingsd.top.key

加速器配置

1
2
3
4
5
mirrors:
"docker.io":
endpoint:
- "https://fogjl973.mirror.aliyuncs.com"
- "https://registry-1.docker.io"

参考

0%