Chemmy's Blog

chengming0916@outlook.com

常用国内源

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

在K3s集群中部署Redis,需依托Kubernetes资源清单,完成组件配置、存储挂载、网络访问等全流程操作。本文基于实际可直接复用的YAML配置文件,详细拆解Redis在K3s环境中的部署步骤,解析核心配置要点,确保部署过程规范、可落地。

一、环境说明

本次部署基于K3s集群,选用Redis 6.0.8版本,所有相关资源统一部署在redis命名空间下(需提前执行命令kubectl create namespace redis完成命名空间创建)。部署采用StatefulSet控制器保障Redis实例的稳定运行,结合PersistentVolumeClaim(PVC)实现数据持久化,通过IngressRouteTCP暴露外部访问入口,借助ConfigMap统一管理Redis配置文件,形成完整的部署闭环。

二、核心配置文件与部署步骤

1. 配置Redis配置文件(ConfigMap)

创建redis-config.yaml文件,通过ConfigMap存储Redis核心配置参数,涵盖网络绑定、数据持久化策略、密码认证等关键配置,确保Redis运行参数可灵活调整、统一管理,具体配置如下:

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
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: redis
labels:
app: redis
data:
redis.conf: |
daemonize no
bind 0.0.0.0
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
pidfile /data/redis-server.pid
logfile /data/redis.log
loglevel notice
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
requirepass passwd

配置文件创建完成后,执行以下命令部署ConfigMap:

1
kubectl apply -f redis-config.yaml

2. 配置持久化存储(PV/PVC)

K3s集群默认内置local-path存储类,可满足日常Redis数据持久化需求。本次部署提供两种PVC配置方式,用户可根据实际存储场景灵活选择。

方式1:仅创建PVC(基于local-path存储类)

创建redis-pvc-local-path.yaml文件,申请2Gi存储容量,访问模式设为ReadWriteOnce(仅允许单个节点读写),适配单节点Redis部署场景,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: redis
labels:
app: redis
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 2Gi

执行部署命令:

1
kubectl apply -f redis-pvc-local-path.yaml

方式2:手动创建PV+PVC(hostPath模式)

若需自定义存储路径,可创建redis-pvc-host-path.yaml文件,手动定义PersistentVolume(PV)和PVC。其中PV指定宿主机/mnt/redis/data路径作为存储目录,容量设为5Gi;PVC关联local-path存储类,申请2Gi存储容量,配置如下:

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
apiVersion: v1
kind: PersistentVolume
metadata:
name: redis-pv
namespace: redis
labels:
app: redis
spec:
storageClassName: redis-persistent-storage
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/redis/data

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
labels:
app: redis
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 2Gi

执行部署命令:

1
kubectl apply -f redis-pvc-host-path.yaml

3. 部署Redis StatefulSet

创建redis-deployment.yaml文件,采用StatefulSet控制器管理Redis Pod,配置包含初始化容器(调整内核参数)、存储卷挂载、配置文件挂载、启动命令指定等核心内容,确保Redis实例稳定启动,配置如下:

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
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: redis
labels:
app: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
initContainers:
- name: init-0
image: busybox
imagePullPolicy: IfNotPresent
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
command: [ "sysctl", "-w", "net.core.somaxconn=511" ]
securityContext:
privileged: true
# - name: init-1
# image: busybox
# imagePullPolicy: IfNotPresent
# terminationMessagePath: /dev/termination-log
# terminationMessagePolicy: File
# command: [ "sh", "-c", "echo never > /sys/kernel/mm/transparent_hugepage/enabled" ]
# securityContext:
# privileged: true
containers:
- name: redis
image: redis:6.0.8
imagePullPolicy: IfNotPresent
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- name: redis-persistent-storage
mountPath: /var/lib/redis
- name: redis-config
mountPath: /usr/local/etc/redis/redis.conf
subPath: redis.conf
command: [ "redis-server" ,"/usr/local/etc/redis/redis.conf" ]
env:
- name: TZ
value: "Asia/Shanghai"
volumes:
- name: timezone
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
- name: redis-persistent-storage
persistentVolumeClaim:
claimName: redis-pvc
- name: redis-config
configMap:
name: redis-config

执行部署命令,启动Redis StatefulSet:

1
kubectl apply -f redis-deployment.yaml

4. 配置Service暴露集群内访问

创建redis-service.yaml文件,定义ClusterIP类型Service,暴露Redis 6379端口,供K3s集群内其他应用程序访问Redis服务,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: redis
labels:
app: redis
spec:
ports:
- name: redis
port: 6379
targetPort: 6379
protocol: TCP
selector:
app: redis
type: ClusterIP

执行部署命令:

1
kubectl apply -f redis-service.yaml

5. 配置IngressRouteTCP暴露外部访问

基于K3s默认集成的Traefik IngressController,创建redis-ingress.yaml文件,通过IngressRouteTCP暴露Redis的6379端口,实现集群外部对Redis服务的访问,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: redis-tcp
namespace: redis
labels:
app: redis
spec:
entryPoints:
- redis
routes:
- match: HostSNI(`*`)
services:
- name: redis
port: 6379

执行部署命令:

1
kubectl apply -f redis-ingress.yaml

注意:需提前在Traefik中配置名为redis的entryPoint(监听6379端口),否则IngressRouteTCP无法正常生效。

三、部署验证

Redis相关资源部署完成后,需通过以下命令检查资源状态,并验证服务可正常访问。

1. 检查资源状态

1
2
3
4
5
6
# 检查StatefulSet运行状态
kubectl get statefulset -n redis
# 检查Redis Pod运行状态
kubectl get pods -n redis
# 检查PVC绑定状态
kubectl get pvc -n redis

若所有资源状态均为Running/Bound,说明部署成功。

2. 访问Redis服务

  • 集群内访问:通过集群内部服务地址redis.redis.svc.cluster.local:6379访问,访问密码为配置文件中设置的passwd

  • 集群外访问:通过Traefik节点IP+6379端口访问,访问密码同样为passwd

四、关键配置说明

  • 内核参数调整:通过初始化容器(initContainers)执行sysctl -w net.core.somaxconn=511,提升Redis网络连接上限,避免因连接数不足导致服务异常。

  • 数据持久化:通过PVC挂载/var/lib/redis目录,结合Redis配置中的RDB和AOF双重持久化策略,确保数据不丢失;hostPath模式下,数据实际存储在宿主机/mnt/redis/data目录,local-path模式下存储在集群默认存储路径。

  • 配置管理:通过ConfigMap挂载redis.conf配置文件,后续需修改Redis运行参数时,仅需更新ConfigMap并重启Pod即可,无需重建镜像,提升维护效率。

  • 网络安全:采用ClusterIP类型Service限制集群内访问,通过IngressRouteTCP实现外部可控访问,同时Redis配置密码认证,多重保障服务安全。

五、总结

本文基于实际生产可用的YAML配置文件,完成了K3s集群中Redis的标准化部署,覆盖配置管理、数据持久化、网络访问、部署验证等核心环节。所有配置均保持原始内容不变,可直接复用至K3s环境,无需额外修改,能够满足中小规模业务场景下Redis的稳定运行需求,为K3s环境中Redis的部署提供了可落地的实践参考。

一、核心定位

本文作为GitOps环境搭建系列的第四篇,聚焦cert-manager证书管理的部署与配置。在K3s集群环境中,TLS/SSL证书是保障服务通信安全的核心基础设施,无论是公网HTTPS服务还是内网私有服务,都需要规范的证书管理方案。

在GitOps环境中,cert-manager扮演”证书自动化管理中枢”角色,为所有组件(Traefik、Gitea、ArgoCD、Tekton、Harbor等)提供自动化的证书签发、续签和轮换服务。通过cert-manager,可以实现Let’s Encrypt公网证书的自动获取,或自签名证书的内网安全通信,确保整个GitOps环境的HTTPS安全访问。

二、部署前置检查

部署前需验证K3s集群状态及Traefik运行情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 验证K3s集群状态
kubectl get nodes

# 2. 验证Traefik运行状态(证书验证依赖Traefik)
kubectl get pods -n kube-system -l app=traefik

# 3. 验证Helm可用性
helm version --short

# 4. 验证域名解析(替换为实际域名)
nslookup traefik.example.io
nslookup harbor.example.io
nslookup gitea.example.io

# 5. 检查cert-manager命名空间
kubectl get ns cert-manager 2>/dev/null || echo "命名空间不存在,将自动创建"

前置条件检查清单:

  • K3s集群运行正常
  • Traefik Pod处于Running状态
  • 域名已正确解析至K3s节点IP
  • Helm工具可用
  • 具备集群管理权限

三、部署cert-manager

3.1 Helm部署(推荐方式)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 添加cert-manager官方Helm仓库
helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update

# 创建cert-manager命名空间
kubectl create namespace cert-manager

# 部署cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.8.0 \
--set installCRDs=true \
--set prometheus.enabled=false

3.2 验证部署状态

1
2
3
4
5
6
7
8
# 查看cert-manager组件状态
kubectl get pods -n cert-manager -w

# 查看CRD资源
kubectl get crd | grep cert-manager

# 验证组件就绪
kubectl wait --for=condition=Ready pods -l app.kubernetes.io/instance=cert-manager -n cert-manager --timeout=300s

四、配置签发机构(ClusterIssuer)

cert-manager通过ClusterIssuer定义证书签发规则,支持Let’s Encrypt(公网)和自签名(内网)两种模式。

4.1 公网证书:Let’s Encrypt签发

测试环境ClusterIssuer(无速率限制):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# letsencrypt-staging.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: admin@example.io # 替换为管理员邮箱
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: traefik # K3s默认使用Traefik

生产环境ClusterIssuer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# letsencrypt-prod.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: admin@example.io # 替换为管理员邮箱
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: traefik

Let’s Encrypt速率限制说明:

  • 测试环境:无限制,适合验证配置
  • 生产环境:每个域名每周50张证书,每个精确域名组合每周5张
  • 建议:先在测试环境验证,再切换到生产环境

4.2 内网证书:自签名签发

对于内网GitOps环境,推荐使用自签名CA证书。以下配置创建自签名CA并基于该CA签发子证书:

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
# selfsigned-issuer.yaml
# 参考:https://gitee.com/Chemmy/kube-template/blob/master/devops/cert-manager/selfsigned-cluster-issuer.yaml
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
namespace: cert-manager
spec:
isCA: true
commonName: selfsigned-ca
secretName: root-secret
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-cluster-issuer
spec:
ca:
secretName: root-secret

配置说明:

  1. 第一个ClusterIssuer:用于生成根CA证书
  2. Certificate资源:定义根CA证书的规格,生成后存储在root-secret
  3. 第二个ClusterIssuer:基于生成的根CA证书,用于签发其他子证书

应用配置:

1
2
3
4
5
6
7
8
9
# 应用自签名CA配置
kubectl apply -f selfsigned-issuer.yaml

# 验证CA证书生成
kubectl get certificate selfsigned-ca -n cert-manager
kubectl get secret root-secret -n cert-manager

# 等待CA证书就绪
kubectl wait --for=condition=Ready certificate selfsigned-ca -n cert-manager --timeout=300s

4.3 自定义CA证书导入(可选)

如果已有自定义CA证书,可先导入到Secret中,再创建引用该CA的ClusterIssuer:

1
2
3
4
5
# 导入自定义CA证书
kubectl create secret tls custom-ca-secret \
--namespace=cert-manager \
--cert=path/to/ca.crt \
--key=path/to/ca.key
1
2
3
4
5
6
7
8
# custom-ca-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: custom-ca-issuer
spec:
ca:
secretName: custom-ca-secret

K3s默认CA说明:
K3s会在首个Server节点启动时生成自签名CA证书,有效期为10年,存储在:

  • /var/lib/rancher/k3s/server/tls/client-ca.crt
  • /var/lib/rancher/k3s/server/tls/server-ca.crt

如需轮换K3s默认CA证书,可使用:

1
k3s certificate rotate-ca

4.4 应用签发机构配置

1
2
3
4
5
6
# 应用ClusterIssuer配置
kubectl apply -f letsencrypt-staging.yaml
kubectl apply -f selfsigned-issuer.yaml

# 验证签发机构状态
kubectl get clusterissuer

五、创建域名证书

5.1 GitOps组件证书配置

使用自签名CA签发GitOps环境通配符证书:

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
# gitops-certificates.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: gitops-wildcard-cert
namespace: cert-manager
spec:
secretName: gitops-wildcard-tls
issuerRef:
name: selfsigned-cluster-issuer # 使用自签名CA签发机构
kind: ClusterIssuer
duration: 2160h # 90天有效期
renewBefore: 360h # 过期前15天自动续签
commonName: "*.example.io"
dnsNames:
- "*.example.io" # 通配符证书,覆盖所有GitOps组件
- traefik.example.io
- harbor.example.io
- gitea.example.io
- tekton.example.io
- argocd.example.io
- notary.example.io
subject:
organizations:
- Example Organization
organizationalUnits:
- DevOps Team
localities:
- Beijing
provinces:
- Beijing
countries:
- CN
privateKey:
algorithm: RSA
size: 2048
rotationPolicy: Always
usages:
- server auth
- client auth

5.2 单个组件证书配置(示例:Traefik)

1
2
3
4
5
6
7
8
9
10
11
12
13
# traefik-certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: traefik-cert
namespace: kube-system
spec:
secretName: traefik-dashboard-tls
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
dnsNames:
- traefik.example.io

5.3 应用证书配置

1
2
3
4
5
6
7
# 应用证书配置
kubectl apply -f gitops-certificates.yaml
kubectl apply -f traefik-certificate.yaml

# 查看证书状态
kubectl get certificates -A
kubectl describe certificate gitops-wildcard-cert -n cert-manager

六、验证证书签发

6.1 检查证书状态

1
2
3
4
5
6
7
8
9
10
11
# 查看所有证书
kubectl get certificates --all-namespaces

# 查看证书详情
kubectl describe certificate gitops-wildcard-cert -n cert-manager

# 查看生成的TLS Secret
kubectl get secret gitops-wildcard-tls -n cert-manager -o yaml

# 查看证书签发事件
kubectl get events --field-selector involvedObject.name=gitops-wildcard-cert -n cert-manager

6.2 测试证书使用(使用IngressRoute)

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
# 创建测试IngressRoute使用证书
cat > test-ingressroute.yaml << EOF
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test-tls-ingressroute
namespace: default
annotations:
cert-manager.io/cluster-issuer: selfsigned-cluster-issuer
spec:
entryPoints:
- websecure
routes:
- match: Host(`test.example.io`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: test-tls-secret
EOF

# 应用测试配置
kubectl apply -f test-ingressroute.yaml

# 验证证书自动创建
kubectl get certificate test-tls-secret -n default

# 测试HTTPS访问
curl -k https://test.example.io

# 清理测试资源
kubectl delete -f test-ingressroute.yaml

6.3 验证自动签发功能

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
# 创建带自动签发注解的IngressRoute
cat > auto-cert-test.yaml << EOF
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: auto-cert-test
namespace: default
annotations:
cert-manager.io/cluster-issuer: selfsigned-cluster-issuer
spec:
entryPoints:
- websecure
routes:
- match: Host(`auto-test.example.io`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: auto-test-tls-secret
EOF

# 应用配置
kubectl apply -f auto-cert-test.yaml

# 等待证书自动创建(约1-2分钟)
sleep 60

# 验证证书状态
kubectl get certificate auto-test-tls-secret -n default
kubectl describe certificate auto-test-tls-secret -n default

# 清理测试
kubectl delete -f auto-cert-test.yaml

七、生产环境最佳实践

7.1 证书管理策略

  1. 命名空间隔离:将CA证书、ClusterIssuer等核心资源部署在独立命名空间
  2. 网络策略限制:配置网络策略,限制对cert-manager组件的访问
  3. 监控告警:配置证书过期告警,提前发现证书问题
  4. 备份策略:定期备份关键证书和私钥

7.2 IngressRoute自动签发

在IngressRoute资源中添加注解,实现证书自动签发。cert-manager会自动检测注解并创建对应的Certificate资源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# gitops组件自动签发示例
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: gitea-websecure
namespace: gitea
annotations:
cert-manager.io/cluster-issuer: "selfsigned-cluster-issuer" # 内网使用自签名
cert-manager.io/renew-before: "360h"
cert-manager.io/common-name: "Gitea Git Repository"
spec:
entryPoints:
- websecure
routes:
- match: Host(`gitea.example.io`)
kind: Rule
services:
- name: gitea-http
port: 3000
tls:
secretName: gitea-tls-secret

支持的高级注解:

  • cert-manager.io/cluster-issuer: 指定签发机构
  • cert-manager.io/issuer: 指定命名空间级签发机构
  • cert-manager.io/common-name: 证书通用名称
  • cert-manager.io/duration: 证书有效期(默认90天)
  • cert-manager.io/renew-before: 续签提前时间(默认30天)
  • cert-manager.io/usages: 证书用途(如server auth, client auth
  • cert-manager.io/private-key-algorithm: 私钥算法(如RSA, ECDSA

通配符证书配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: gitops-wildcard
namespace: gitops
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
cert-manager.io/dns-names: "*.example.io,example.io"
spec:
entryPoints:
- websecure
routes:
- match: HostRegexp(`{subdomain:[a-z]+}.example.io`)
kind: Rule
services:
- name: gitops-router
port: 80
tls:
secretName: gitops-wildcard-tls

优势:

  • 声明式配置:证书需求与路由配置一体化
  • 自动管理:cert-manager自动处理证书的签发、续签、轮换
  • 无缝集成:与Traefik IngressRoute深度集成
  • 多环境支持:通过注解轻松切换测试/生产环境签发机构

7.3 证书导出与备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 导出自签名CA证书和GitOps组件证书

# 导出根CA证书
kubectl get secret root-secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 --decode > ca.crt
kubectl get secret root-secret -n cert-manager -o jsonpath='{.data.tls\.crt}' | base64 --decode > root-ca.crt
kubectl get secret root-secret -n cert-manager -o jsonpath='{.data.tls\.key}' | base64 --decode > root-ca.key

# 导出GitOps通配符证书
kubectl get secret gitops-wildcard-tls -n cert-manager -o jsonpath='{.data.tls\.crt}' | base64 --decode > gitops.crt
kubectl get secret gitops-wildcard-tls -n cert-manager -o jsonpath='{.data.tls\.key}' | base64 --decode > gitops.key

# 查看证书链信息
openssl x509 -in ca.crt -text -noout | head -20
openssl x509 -in gitops.crt -text -noout | head -20

# 验证证书链
openssl verify -CAfile ca.crt gitops.crt

# 备份所有证书Secret
kubectl get secret root-secret gitops-wildcard-tls -n cert-manager -o yaml > cert-backup-$(date +%Y%m%d).yaml

八、常见问题修复

问题现象 排查方向 修复方案
证书签发失败 ClusterIssuer配置 检查ClusterIssuer状态:kubectl describe clusterissuer <name>
证书一直Pending 域名验证失败 检查域名解析,确认Traefik可访问,查看cert-manager日志
证书过期未续签 续签配置错误 检查renewBefore设置,查看cert-manager控制器日志
Let’s Encrypt速率限制 请求过于频繁 切换到测试环境,或等待限制解除
证书Secret不存在 签发过程错误 查看Certificate资源事件:kubectl describe certificate <name>
HTTPS访问证书错误 证书域名不匹配 检查证书dnsNames是否包含访问域名
自签名CA证书无效 CA证书未就绪 等待CA证书生成:kubectl wait --for=condition=Ready certificate selfsigned-ca

九、配置参考

所有cert-manager配置文件和部署脚本请参考:
https://gitee.com/Chemmy/kube-template/tree/master/devops/cert-manager

该目录包含:

  • cert-manager Helm配置
  • ClusterIssuer配置模板(包括自签名CA配置)
  • 证书配置示例
  • 生产环境优化配置
  • 监控和备份脚本

总结

本文完成了cert-manager在K3s集群中的标准化部署,实现了GitOps环境证书的自动化管理。通过cert-manager,可以轻松管理Let’s Encrypt公网证书和自签名内网证书,确保所有组件的HTTPS安全访问。

配置完成后,建议为每个GitOps组件配置相应的证书,并在IngressRoute资源中启用TLS自动签发。下一篇文章将部署Gitea代码仓库,为GitOps环境提供代码托管能力。

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搭建GitOps环境的系列文章总览,包含完整的组件规划和部署路线图。本系列旨在帮助您在K3s轻量级Kubernetes集群上构建完整的GitOps环境,实现从代码到部署的自动化流水线。

基础环境篇

  1. 基于K3s搭建GitOps环境1-K3s安装 - K3s集群部署与基础配置
  2. 基于K3s搭建GitOps环境2-配置Traefik - Traefik反向代理配置
  3. 基于K3s搭建GitOps环境3-配置内网域名 - CoreDNS内网域名解析
  4. 基于K3s搭建GitOps环境4-证书管理 - cert-manager证书管理

核心组件篇

  1. [[基于K3s搭建GitOps5-部署Gitea]] - 代码仓库部署
  2. [[基于K3s搭建GitOps6-部署ArgoCD]] - GitOps核心部署
  3. [[基于K3s搭建GitOps7-部署Tekton]] - CI流水线部署
  4. [[基于K3s搭建GitOps8-部署Harbor]] - 镜像仓库部署

GitOps环境架构

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

┌─────────────────────────────────────────────────────────────────┐
│ GitOps 完整链路 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ① 开发者 ──push──▶ Gitea (Git仓库) │
│ │
│ ② Tekton Pipeline ──webhook触发──▶ 克隆代码 │
│ │
│ ③ Tekton Pipeline ──构建──▶ Docker镜像 │
│ │ │
│ │ docker push │
│ ▼ │
│ ④ Harbor (镜像仓库) ◀── 推送镜像 │
│ │ • 存储镜像bits │
│ │ • Trivy CVE扫描 │
│ │ • Notary镜像签名(可选) │
│ │
│ ⑤ ArgoCD Application ──监听镜像Tag变化──▶ 检测到新镜像 │
│ │ │
│ │ 更新Deployment镜像Tag │
│ ▼ │
│ ⑥ K3s集群 ──kubectl apply──▶ 新Pod以新镜像启动 │
│ │
└─────────────────────────────────────────────────────────────────┘

组件规划

开放端口

端口 用途 说明
53 CoreDNS服务 内网域名解析
443, 80 Traefik入口 HTTPS/HTTP访问入口
5432/3306 数据库服务 PostgreSQL/MySQL(二选一)
6379 Redis缓存 缓存服务
8022 SSH管理 服务器管理端口
22 Git SSH git+ssh方式代码上传

域名规划(统一使用example.io)

组件 访问地址 说明
Traefik Dashboard https://traefik.example.io 反向代理管理界面
Harbor https://harbor.example.io 私有镜像仓库,支持镜像签名与安全扫描
Gitea https://gitea.example.io 轻量级代码仓库
Tekton https://tekton.example.io 云原生CI流水线
ArgoCD https://argocd.example.io GitOps持续部署核心
Notary https://notary.example.io 镜像签名服务(Harbor集成)

部署路线图

第一阶段:基础环境搭建(1-4天)

  1. 第1天:部署K3s集群,配置存储和网络
  2. 第2天:配置Traefik反向代理,启用Dashboard
  3. 第3天:配置CoreDNS内网域名解析
  4. 第4天:部署cert-manager,配置证书管理

第二阶段:核心组件部署(5-8天)

  1. 第5天:部署Gitea代码仓库,配置数据库连接
  2. 第6天:部署ArgoCD,配置GitOps工作流
  3. 第7天:部署Tekton,配置CI流水线
  4. 第8天:部署Harbor,配置镜像仓库和安全扫描

第三阶段:集成与优化(9-10天)

  1. 第9天:组件间联动配置,打通完整流水线
  2. 第10天:生产环境优化,配置监控和告警

环境要求

硬件要求

  • 最低配置:2核CPU,4GB内存,50GB存储
  • 推荐配置:4核CPU,8GB内存,100GB存储
  • 生产环境:根据业务规模弹性扩展

软件要求

  • 操作系统:Ubuntu 20.04+ / CentOS 7+ / RHEL 8+
  • 容器运行时:Containerd(K3s默认集成)
  • 网络:内网互通,可访问外网(用于拉取镜像)

配置参考

所有组件的详细配置文件和部署脚本请参考:KubeTemplate-devops

该仓库包含:

  • K3s集群部署脚本
  • 各组件Helm Chart配置
  • 示例应用部署文件
  • 监控和日志配置
  • 生产环境优化建议

注意事项

  1. 域名配置:所有示例域名使用example.io,实际部署时请替换为您的域名
  2. 证书管理:生产环境建议使用Let’s Encrypt证书,内网环境可使用自签名证书
  3. 存储配置:K3s默认使用local-path存储类,生产环境建议配置持久化存储
  4. 安全加固:部署完成后请及时修改默认密码,配置网络策略
  5. 备份策略:定期备份数据库和持久化卷数据

常见问题

Q1: K3s与其他Kubernetes发行版有何区别?

A: K3s是轻量级Kubernetes发行版,专为边缘计算和资源受限环境设计,相比标准K8s:

  • 安装包更小(约40MB)
  • 内存占用更低
  • 默认集成Containerd、Traefik、CoreDNS等组件
  • 简化了配置和管理

Q2: GitOps与传统CI/CD有何不同?

A: GitOps的核心思想是”Git作为单一可信源”:

  • 声明式配置:所有环境配置存储在Git仓库中
  • 自动同步:集群状态自动与Git仓库中的期望状态同步
  • 可追溯性:所有变更都有Git提交记录
  • 一键回滚:通过Git版本控制实现快速回滚

Q3: 如何选择数据库?

A: 本系列支持两种数据库方案:

  • PostgreSQL:功能丰富,适合复杂应用
  • MySQL:轻量快速,适合简单场景
    您可以根据实际需求选择一种,配置方法类似。

一、核心定位

本文作为GitOps环境搭建系列的第一篇,聚焦K3s集群的部署与基础配置。K3s是Rancher Labs推出的轻量级Kubernetes发行版,专为边缘计算、IoT设备和资源受限环境设计。相比标准Kubernetes,K3s具有安装包小(约40MB)、内存占用低、启动快速等优势,是构建轻量级GitOps环境的理想选择。

在GitOps环境中,K3s作为底层容器编排平台,承载所有GitOps组件(Gitea、ArgoCD、Tekton、Harbor等)的运行,提供容器调度、服务发现、存储管理、网络通信等核心能力。

二、部署前置检查

部署前需验证服务器环境,确保满足K3s运行要求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 检查操作系统版本(支持Ubuntu 20.04+/CentOS 7+/RHEL 8+)
cat /etc/os-release

# 2. 检查内核版本(需≥3.10)
uname -r

# 3. 检查内存和存储空间
free -h
df -h /

# 4. 检查网络连通性
ping -c 3 8.8.8.8

# 5. 检查防火墙状态(建议关闭或配置放行规则)
sudo systemctl status firewalld
# 或
sudo ufw status

前置条件检查清单:

  • 操作系统符合要求
  • 内核版本≥3.10
  • 内存≥2GB,存储≥20GB
  • 网络可访问外网(用于拉取镜像)
  • 防火墙已关闭或配置放行规则
  • 已配置sudo权限或root用户

三、K3s集群部署

3.1 Master节点安装

执行以下命令安装K3s Master节点:

1
2
3
4
# 使用国内镜像源加速安装
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
INSTALL_K3S_EXEC='--write-kubeconfig-mode=644' sh -

安装参数说明:

  • INSTALL_K3S_MIRROR=cn:使用中国区镜像源,加速安装过程
  • --write-kubeconfig-mode=644:设置kubeconfig文件权限为644,便于多用户访问
  • --service-node-port-range=1-65535:解除NodePort端口限制(默认30000-32767)
  • --advertise-address=192.168.1.100:指定集群管理IP(替换为实际IP)
  • --disable=traefik:禁用Traefik(如需自定义Traefik配置)
  • --disable=local-path:禁用本地存储(如需使用其他存储方案)

3.2 Worker节点加入集群

在Worker节点执行以下命令加入集群:

1
2
3
4
5
6
7
8
# 获取Master节点的token(在Master节点执行)
sudo cat /var/lib/rancher/k3s/server/node-token

# 在Worker节点执行加入命令(替换<k3s-server-ip>和<token>)
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>:Master节点的IP地址
  • <token>:从Master节点获取的加入令牌

3.3 配置kubeconfig

配置kubectl访问凭证:

1
2
3
4
5
6
7
# 设置KUBECONFIG环境变量
echo "export KUBECONFIG=/etc/rancher/k3s/k3s.yaml" >> ~/.bashrc
source ~/.bashrc

# 验证集群访问
kubectl get nodes
kubectl cluster-info

四、存储配置优化

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

K3s默认使用local-path存储类,其回收策略为Delete(删除Pod时会删除关联的PV)。生产环境建议改为Retain,防止数据误删。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看当前存储类配置
kubectl get storageclasses.storage.k8s.io local-path -o yaml

# 创建修改后的存储类配置
cat > storage-class.yaml << EOF
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
EOF

# 应用修改后的存储类
kubectl delete storageclasses.storage.k8s.io local-path
kubectl apply -f storage-class.yaml

4.2 自定义存储路径

如需自定义存储路径,可在安装时指定:

1
2
3
4
# 安装时指定存储路径
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
INSTALL_K3S_EXEC='--write-kubeconfig-mode=644 --default-local-storage-path=/mnt/storage/k3s' sh -

五、管理工具安装

5.1 Helm安装

Helm是Kubernetes的包管理工具,后续组件部署将大量使用:

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

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

# 验证安装
helm version --short

5.2 命令自动补全

配置命令自动补全,提升操作效率:

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

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

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

六、私有镜像库配置

K3s支持配置私有镜像库,加速镜像拉取或使用内网镜像仓库:

6.1 配置镜像加速器

1
2
3
4
5
6
7
8
9
10
11
# 创建registries.yaml配置文件
sudo cat > /etc/rancher/k3s/registries.yaml << EOF
mirrors:
"docker.io":
endpoint:
- "https://fogjl973.mirror.aliyuncs.com" # 阿里云镜像加速器
- "https://registry-1.docker.io"
EOF

# 重启K3s使配置生效
sudo systemctl restart k3s

6.2 配置私有Harbor仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 配置带认证的私有仓库
sudo cat > /etc/rancher/k3s/registries.yaml << EOF
mirrors:
"harbor.example.io": # 替换为您的Harbor域名
endpoint:
- "https://harbor.example.io"
configs:
"harbor.example.io":
auth:
username: admin
password: Harbor12345
tls:
ca_file: /opt/certs/ca.crt # 自签名证书路径
EOF

七、验证部署结果

7.1 基础功能测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 创建测试应用
kubectl create deploy whoami --image=traefik/whoami --replicas=2

# 2. 监控Pod启动状态
kubectl get pods --watch

# 3. 暴露服务
kubectl expose deploy whoami --port=80

# 4. 查看服务状态
kubectl get svc whoami -o wide

# 5. 扩容测试
kubectl scale deploy whoami --replicas=5
kubectl get pods

# 6. 清理测试资源
kubectl delete all --all

7.2 集群状态检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看所有节点状态
kubectl get nodes -o wide

# 查看所有命名空间资源
kubectl get all -A

# 查看核心组件状态
kubectl get pods -n kube-system

# 查看存储类
kubectl get storageclass

# 查看集群事件
kubectl get events --sort-by='.lastTimestamp'

八、常用运维命令

8.1 集群管理

1
2
3
4
5
6
7
8
9
10
11
12
# 查看集群信息
kubectl cluster-info

# 查看节点详细信息
kubectl describe node <node-name>

# 查看节点标签
kubectl get node --show-labels

# 查看资源使用情况
kubectl top nodes
kubectl top pods -A

8.2 应用管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看指定命名空间资源
kubectl get all -n <namespace>

# 查看Pod日志
kubectl logs -n <namespace> <pod-name>
kubectl logs -f -n <namespace> <pod-name> # 实时日志

# 进入Pod容器
kubectl exec -it -n <namespace> <pod-name> -- /bin/bash

# 重启Deployment
kubectl rollout restart deploy/<deploy-name> -n <namespace>

# 查看部署历史
kubectl rollout history deploy/<deploy-name> -n <namespace>

8.3 Helm管理

1
2
3
4
5
6
7
8
9
10
11
# 查看charts的values文件
helm show values bitnami/redis > values.yaml

# 添加Helm仓库
helm repo add <repo-name> <repo-url>

# 更新仓库索引
helm repo update

# 搜索chart
helm search repo <keyword>

九、常见问题修复

问题现象 排查方向 修复方案
节点NotReady 网络/容器运行时 检查网络连通性,重启containerd:sudo systemctl restart containerd
Pod一直Pending 资源不足/存储问题 检查节点资源:kubectl describe pod <pod-name>,查看事件
镜像拉取失败 镜像仓库/网络 检查镜像地址,配置镜像加速器或私有仓库
kubeconfig权限错误 文件权限 设置正确权限:sudo chmod 644 /etc/rancher/k3s/k3s.yaml
Helm安装失败 网络/版本 检查网络,使用国内镜像源或离线安装

十、配置参考

所有配置文件和部署脚本请参考:
https://gitee.com/Chemmy/kube-template/tree/master/devops/k3s

该目录包含:

  • K3s安装脚本
  • 存储类配置
  • 镜像仓库配置
  • 节点加入脚本
  • 生产环境优化配置

总结

本文完成了K3s集群的标准化部署,包括Master节点安装、Worker节点加入、存储配置优化、管理工具安装等核心步骤。K3s作为轻量级Kubernetes发行版,为后续GitOps组件部署提供了稳定可靠的底层平台。

部署完成后,建议进行全面的功能测试,确保集群各项功能正常。下一篇文章将基于此K3s集群,部署Traefik反向代理,为后续组件提供统一的访问入口。

一、问题背景与诊断

在某些云服务器环境(如本文提到的宿迁服务器)中,运营商可能会屏蔽标准的 NTP 端口(如 UDP 123),导致系统默认的时间同步服务失效。本文将介绍两种解决方案。

1.1 检查当前时间同步状态

首先,使用以下命令查看系统时间与同步状态:

1
timedatectl status

关键输出解读

  • **Local time**:本地时间(时区转换后)。
  • **Universal time**:协调世界时(UTC)。
  • System clock synchronized核心指标。显示 yes 表示已同步,no 表示未同步。
  • **NTP service**:显示当前活跃的时间同步服务(activen/a)。

如果 System clock synchronized 显示为 no,则需要按照本指南进行配置。

1.2 设置正确的时区(可选但推荐)

确保系统时区设置为中国标准时间:

1
sudo timedatectl set-timezone Asia/Shanghai

二、方法一:使用系统自带的 systemd-timesyncd(推荐)

Ubuntu 16.04 及更高版本默认使用 systemd-timesyncd 服务进行时间同步。它轻量、集成度高,是首选方案。

2.1 配置自定义 NTP 服务器

编辑配置文件:

1
sudo nano /etc/systemd/timesyncd.conf

找到 [Time] 部分,取消 NTP= 行的注释,并填入自定义的 NTP 服务器地址。可以指定多个,用空格分隔。

1
2
3
[Time]
NTP=ntp.aliyun.com ntp.tencent.com
#FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org

常用国内 NTP 服务器

  • 阿里云:ntp.aliyun.com
  • 腾讯云:ntp.tencent.com
  • 国家授时中心:cn.pool.ntp.orgntp.ntsc.ac.cn

2.2 重启服务并启用

1
2
3
4
5
6
# 重启 timesyncd 服务
sudo systemctl restart systemd-timesyncd
# 设置开机自启
sudo systemctl enable systemd-timesyncd
# 查看服务状态
sudo systemctl status systemd-timesyncd

2.3 验证同步结果

等待几分钟后,再次运行 timedatectl status。当 System clock synchronized 变为 yes 时,表示配置成功。

重要提示:同步不是即时的,需要等待服务完成一轮时间同步(通常几分钟内)。


三、方法二:安装并配置 ntp 服务

如果 systemd-timesyncd 因故无法工作(例如,安装了其他时间服务导致冲突),可以安装传统的 ntp 包。

3.1 安装 NTP 软件包

1
2
sudo apt update
sudo apt install ntp

安装过程会自动停止并禁用 systemd-timesyncd 服务。

3.2 配置 NTP 服务器

编辑 NTP 主配置文件:

1
sudo nano /etc/ntp.conf

找到 serverpool 配置行。注释掉默认的 pool *.debian.pool.ntp.org 行,添加自定义的服务器。

1
2
3
4
5
6
7
8
# 默认池(可注释掉)
# pool 0.debian.pool.ntp.org iburst
# pool 1.debian.pool.ntp.org iburst

# 添加自定义服务器(例如阿里云和腾讯云)
server ntp.aliyun.com iburst
server ntp.tencent.com iburst
server cn.pool.ntp.org iburst
  • iburst 选项可以在服务启动时快速进行初始同步。

3.3 重启 NTP 服务

1
2
3
sudo systemctl restart ntp
sudo systemctl enable ntp
sudo systemctl status ntp

3.4 检查 NTP 同步状态

使用 ntpq 工具查看与上游 NTP 服务器的连接状态:

1
ntpq -p

输出关键列解读

  • **remote**:NTP 服务器地址。
  • **refid**:服务器本身参考的上一级时间源。
  • **st**:层级(stratum),数值越小越接近权威时间源。
  • **t**:类型(u=单播,p=池)。
  • **when**:距上次查询的秒数。
  • **poll**:查询间隔(秒)。
  • **reach**:八进制表示的连接成功历史(值 377 表示最近8次查询全部成功)。
  • **delay**:网络延迟(毫秒)。
  • offset:时间偏移量(毫秒),关键指标,绝对值越小越好。
  • **jitter**:时间抖动(毫秒)。

理想状态:至少有一个服务器前有 *(当前主同步源)或 +(良好的备用源),且 reach 值不为 0

3.5 手动强制同步(可选)

如果自动同步不理想,可以手动触发:

1
sudo ntpdate -s ntp.aliyun.com

注意ntpdate 可能与正在运行的 ntpd 服务冲突。更安全的方式是重启 ntp 服务或使用 ntpd -gq(需先停止服务)。


四、故障排除与高级管理

4.1 查看详细的系统日志

1
2
3
4
# 查看 systemd-timesyncd 日志
sudo journalctl -u systemd-timesyncd
# 查看 ntp 服务日志
sudo journalctl -u ntp

4.2 处理服务冲突

如果同时安装了多个时间服务(如 chronyntpsystemd-timesyncd),它们会相互冲突。确保只启用一个:

1
2
3
4
# 禁用 systemd-timesyncd(如果使用 ntp)
sudo systemctl disable --now systemd-timesyncd
# 禁用 ntp(如果使用 systemd-timesyncd)
sudo systemctl disable --now ntp

4.3 检查硬件时钟(RTC)设置

确保硬件时钟设置为 UTC,避免双系统时间混乱:

1
2
3
4
# 查看当前设置
timedatectl | grep “RTC in local TZ”
# 如果显示 “yes”,则设置为 UTC
sudo timedatectl set-local-rtc 0

4.4 防火墙配置

如果使用自定义防火墙(如 ufw),确保放行 NTP 流量(UDP 123端口):

1
sudo ufw allow out 123/udp

五、总结与建议

特性 systemd-timesyncd (方法一) ntp (方法二)
复杂度 简单,集成于 systemd 稍复杂,功能更全
配置 编辑 /etc/systemd/timesyncd.conf 编辑 /etc/ntp.conf
控制 systemctl systemctlntpq
适用场景 大多数桌面和服务器,简单同步 需要更精确时间、复杂网络或作为 NTP 服务器

操作流程建议

  1. 首选方法一:配置 systemd-timesyncd。它更现代、更简单。
  2. 如果方法一失败:再考虑安装 ntp。安装前可尝试卸载冲突软件:sudo apt remove ntp chrony
  3. 验证:无论哪种方法,最终都以 timedatectl status 显示 System clock synchronized: yes 为准。
  4. 耐心等待:时间同步服务需要周期运行,配置后请等待数分钟再验证。

本文参考了 OPNsense中文手册OPNsense 防火墙系列一 等优秀资料。

一、简介与核心概念

1.1 什么是 OPNsense?

OPNsense® 是一个基于 FreeBSD开源、易用且易于构建的防火墙和路由平台。它集成了商业防火墙中的大部分高级功能,同时具备开源项目的透明性和可验证性。

使命:为用户、开发人员和企业提供友好、稳定和透明的环境,使其成为使用最广泛的开源安全平台。

1.2 核心功能概览

  • 防火墙与路由:状态检测防火墙、高级路由策略。
  • VPN支持:IPsec、OpenVPN(站点到站点、移动用户)。
  • 网络服务:DHCP/DHCPv6服务器、DNS转发器/解析器、动态DNS。
  • 高级功能
    • 流量整形与策略路由。
    • 入侵检测与防御(IDS/IPS)。
    • 正向缓存代理(Squid)。
    • 强制门户(多区域、凭证支持)。
    • 高可用性与硬件故障转移(含配置同步)。
  • 管理与监控:内置报告工具、RRD图表、数据包捕获、配置备份与还原。

1.3 重要注意事项(避坑指南)

在开始前,请务必了解以下关键点:

  1. NAT类型:OPNsense默认不支持全锥型NAT(NAT1),最高支持端口限制型NAT。可通过UPnP或端口转发缓解,但更推荐后者。
  2. 性能影响
    • PPPoE拨号等变动IP的接口上启用入侵检测,可能导致CPU占用过高。
    • 流量分析、图表等功能在异常断电后可能数据损坏,同样会引起高CPU占用。
  3. 网络规划:前期规划至关重要!随意添加网卡会导致标识符设备映射变动,影响高可用等功能的稳定性。
  4. 虚拟化平台选择
    • 强烈推荐使用PVE。在ESXi上运行高可用可能出现DUP!问题,且内存占用计算不准确。
    • ESXi上开启端口组混杂模式可解决DUP!,但会导致OpenWrt无法访问OPNsense,且影响Docker MacVlan。
  5. 硬件兼容性
    • 部分Intel 2.5G网卡存在BUG,可能导致无法发出DHCP Offer,请避免使用。
    • VLAN配置在物理机上可能存在问题。

二、安装准备与硬件要求

2.1 准备工作

  • 两台电脑(用于测试,双网口以上)。
  • 存储:大于20GB(推荐50GB)。
  • 其他:RJ45网线、显示器和键盘。

2.2 硬件要求参考

以下为作者环境(i5-1135G7, 64G DDR4, 1T NVMe, ESXi 8)下的占用情况:

场景 处理器占用 (ESXi) 内存占用 (ESXi/OPNsense) 存储
轻负载 761 MHz 16G / 7% 120G
满速下载 (92MB/s) 4.6 GHz 16G / 高 120G

2.3 官方硬件要求指南

等级 处理器 内存 存储目标
最低要求 500 MHz 单核 512 MB 4GB SD/CF卡 (使用nano镜像)
合理要求 1 GHz 双核 1 GB 40 GB SSD
推荐要求 1.5 GHz 多核 4 GB 120 GB SSD

注意:实际需求取决于吞吐量启用功能。例如,Squid代理、大型状态表、高并发强制门户会显著增加CPU和内存消耗。推荐使用英特尔(Intel)网卡以获得最佳性能和稳定性。

系统架构:支持 x86-32 (i386)x86-64 (amd64)。对于新部署,强烈建议使用64位版本


三、安装与基础配置

3.1 下载镜像

  1. 访问 OPNsense官网下载页
  2. 选择:Architecture: amd64 -> Image Type: DVD -> Mirror: AivianPeking University

3.2 安装系统

  1. 在虚拟机或物理机上启动镜像。
  2. 在登录提示符 (login:) 处输入:用户名 installer密码 opnsense
  3. 选择键盘布局(默认回车即可)。
  4. 选择 Install (UFS)
  5. 选择目标磁盘(通常为 da0)。
  6. 按提示创建交换空间并确认安装。
  7. 安装完成后,设置root密码并重启。务必在重启前移除安装介质

3.3 初始设置向导

  1. 使用同一网段的设备访问 https://192.168.1.1
  2. 跟随向导进行设置:
    • 语言:中文。
    • DNS:首选 223.5.5.5,辅助 119.29.29.29
    • 启用DNSSEC支持强化DNSSEC数据(推荐,可防DNS劫持。自建DNS请勿开启)。
    • 时区Asia/Shanghai
    • 配置WAN/LAN接口
    • 重设root密码(可选)。
    • 重载系统完成配置。

3.4 更换软件镜像源

默认源速度较慢,建议更换:

  1. 进入 系统 -> 固件 -> 设置
  2. 镜像 下拉框中选择 Aivian (HTTPS,Shangxing,CN)
  3. 或自定义源:选择 (custom),填入:
    • 北京大学镜像源:http://mirrors.pku.edu.cn/opnsense/
    • 网易镜像源:http://mirrors.163.com/opnsense/

      注意:请勿自行改为 https

  4. 保存后,进入 状态 选项卡,点击 检查升级

四、网络接口配置

4.1 接口分配

进入 接口 -> 分配,查看和管理接口。

  • 标识符:如 WAN, LAN
  • 接口设备:系统识别的网卡名称(如 vmx0)。
  • 如需添加新接口(如WAN),在下方 Assign a new interface 选择设备并填写描述(英文/数字)。

4.2 WAN口设置

进入 **接口 -> [WAN]**。

  1. 基本设置:勾选 阻止私有网络拦截bogon网络
  2. IPv4配置类型
    • PPPoE拨号:选择 PPPoE,在下方的PPPoE配置中填入宽带账号密码。
    • DHCP:选择 DHCP
    • 静态IP:选择 静态IPv4,填写IP、掩码,并添加上游网关(标记为默认网关)。
  3. 保存

4.3 LAN口设置

进入 **接口 -> [LAN]**。

  1. 基本设置取消勾选 阻止私有网络拦截bogon网络
  2. IPv4配置类型:选择 静态IPv4
  3. 静态IPv4配置:填写内网IP地址(如 192.168.1.1)和子网掩码(如 24)。
  4. 保存

4.4 终端紧急配置网卡

如果不慎删除了管理口,可通过控制台恢复:

  1. 登录终端,进入管理选项菜单。
  2. 选择 1) 接口分配,按提示重新分配WAN、LAN等接口的物理网卡。
  3. 选择 2) 接口设置,为指定接口(如LAN)重新配置IP地址等。
  4. 按提示完成并重启相关服务。

五、防火墙规则配置

5.1 创建允许规则(示例:允许LAN访问外网)

进入 防火墙 -> 规则 -> LAN,点击 + 添加。

选项 设置
操作 通过
接口 LAN
方向 in
TCP/IP版本 IPv4
协议 any
LAN网络
目标 any
目标端口范围 any
描述 Default allow LAN to any rule

5.2 创建阻断规则(示例:禁止访问阿里DNS)

同样在LAN规则页面,点击 + 添加。

选项 设置
操作 阻止(或拒绝)
接口 LAN
方向 in
TCP/IP版本 IPv4
协议 any
LAN网络
目标 223.5.5.5 (单个主机或网络)
目标端口范围 53
描述 禁止访问阿里DNS

阻止:直接丢弃数据包。拒绝:返回拒绝数据包。


六、基础服务配置

6.1 系统DNS与Unbound DNS

  1. 系统DNS(网关DNS)
    • 进入 系统 -> 设置 -> 常规
    • 网络 部分的 DNS服务器 中填入公共DNS(如 223.5.5.5),并为其选择对应的WAN网关。
  2. Unbound DNS(局域网DNS)
    • 进入 服务 -> Unbound DNS -> 常规,勾选 启用Unbound启用DNSSEC支持
    • 进入 查询转发,取消 使用系统DNS服务器,手动添加转发服务器(如 223.5.5.5)。
    • DoT加密查询(可选):进入 DoT 选项卡,添加服务器,例如:
      • 服务器IP: 223.5.5.5
      • 端口: 853
      • 验证CN: dns.alidns.com

6.2 DHCPv4 服务

进入 **服务 -> DHCPv4 -> [LAN]**。

  • 勾选 启用
  • 设置地址池范围,例如:从 192.168.1.10192.168.1.245
  • 网关和DNS可不填,默认使用路由器地址。

6.3 网络时间协议(NTP)

进入 服务 -> 网络时间 -> 常规,可添加以下推荐的NTP服务器:

  • 国内:ntp.aliyun.com, ntp.tencent.com, ntp.sjtu.edu.cn, cn.pool.ntp.org
  • 国际:time.google.com, time.cloudflare.com, pool.ntp.org

七、IPv6 配置

7.1 公网IPv6(有PD前缀)

  1. WAN口接口 -> [WAN]IPv6配置类型DHCPv6。在DHCPv6客户端配置中,打开 仅请求IPv6前缀发送IPv6前缀提示前缀委派大小 设为 60(需与运营商下发一致)。
  2. LAN口接口 -> [LAN]IPv6配置类型跟踪接口,并在 跟踪IPv6接口 中打开 允许手动调整DHCPv6和路由器通告
  3. 启用IPv6防火墙 -> 设置 -> 高级,在IPv6选项中打开 允许IPv6
  4. 分配地址
    • DHCPv6服务 -> DHCPv6 -> [LAN] 中启用并设置范围。
    • 或路由器通告服务 -> 路由器通告 -> [LAN]路由器通告Assisted,勾选 通告默认网关,填入DNS服务器(如 2400:3200::1)。

7.2 NATv6(无PD前缀,使用内网IPv6)

  1. WAN口:同上,配置DHCPv6获取地址。
  2. LAN口接口 -> [LAN]IPv6配置类型静态IPv6,使用ULA地址(如 fd00::1/64)。
  3. 启用IPv6:同上。
  4. 配置NAT出站规则
    • 防火墙 -> NAT -> 出站,模式改为 混合生成出站NAT规则
    • 添加两条手动规则(IPv4和IPv6),关键是将 转换/目标 设为 接口地址,并勾选 静态端口。这是实现端口限制型NAT的关键。
  5. 分配地址:同7.1第4步,为LAN配置DHCPv6或路由器通告。

7.3 解决IPv6大包问题

test-ipv6.com 提示大包错误,需调整MSS:

  • 接口 -> [WAN] -> 通用配置 中,设置 MSS 值。
  • 计算公式:MSS = PPPoE MTU(通常1492) - 60,约为 1430。可尝试 14201400
  • 测试命令(Windows):ping -l 1500 baidu.com 逐步减小 -l 后数值直到通,该值即为可用MSS。

八、进阶功能配置

8.1 流量整形(流控)

以创建HTTP流量优先级为例:

  1. 创建管道防火墙 -> 流控 -> 管道,创建上传/下载管道,设置带宽(如 160Mbit/s上传,1000Mbit/s下载)。
  2. 创建队列防火墙 -> 流控 -> 队列,为不同协议创建队列并绑定到管道,设置权重(值越低优先级越高)。
    • 例如:HTTP上传队列 权重50, 其他流量队列上传 权重80。
  3. 创建规则防火墙 -> 流控 -> 规则,创建规则将特定流量(如目标端口80/443)指向高优先级队列。
  4. 防火墙 -> 流控 -> 状态 中查看队列状态。

8.2 别名(Aliases)

别名用于批量管理IP、端口等,是防火墙规则的强大工具。

  • 类型:主机、网络、端口、URL Table (IPs)(可定期更新)、GeoIP等。
  • 创建防火墙 -> 别名,点击 **+**,选择类型并填入内容(如IP列表、URL)。
  • 嵌套:可以在一个别名中引用其他别名。

8.3 端口转发

相比UPnP更安全可控。

  1. 普通转发防火墙 -> NAT -> 转发,点击 **+**。
    • 接口:WAN
    • 协议:TCP/UDP
    • 目标:WAN地址
    • 目标端口:外部端口
    • 重定向目标IP:内网主机IP
    • 重定向目标端口:内部端口
  2. DNS重定向示例:将内网DNS请求重定向到指定服务器。
    • 接口:LAN
    • 勾选 目标 / 反转
    • 目标:LAN网络
    • 目标端口:DNS
    • 重定向目标IP:192.168.1.2
    • 重定向目标端口:DNS

8.4 高可用(HA)配置

前提:两台OPNsense,接口分配完全一致,并有一个专用HA接口用于心跳同步。

  1. 配置CARP虚拟IP:在主防火墙的 接口 -> 虚拟IP -> 设置 中,为LAN(或WAN)添加CARP虚拟IP(如 192.168.1.1/24),设置VHID和密码。
  2. 配置同步
    • 主防火墙:系统 -> 高可用 -> 设置,启用同步,指定同步接口(HA口)、对端IP和密码,选择同步模块。
    • 备防火墙:同样位置,启用同步并勾选 禁用抢占断开拨号接口
  3. 同步配置:在主防火墙状态页点击上传图标进行初始同步。
  4. 检查:在 接口 -> 概况 中,主防火墙的虚拟IP旁有绿色图标,备防火墙为灰色。

8.5 性能优化(可调参数)

进入 系统 -> 设置 -> 可调参数,可添加以下参数提升性能(部分):

1
2
3
4
5
6
7
hw.ibrs_disable=1                # 禁用Spectre V2缓解,提升性能
net.isr.maxthreads=-1 # 使用所有CPU核心处理网络中断
net.isr.bindthreads=1 # 将中断线程绑定到核心
net.inet.rss.enabled=1 # 启用接收方缩放
net.inet.rss.bits=2 # RSS位,根据核心数调整(核心数/4)
net.inet.tcp.soreceive_stream=1 # 启用优化的内核套接字接口
kern.ipc.maxsockbuf=16777216 # 增大套接字缓冲区(10G网卡)

注意:调整需谨慎,建议参考 FreeBSD网络性能调优指南

8.6 网关组(故障转移/负载均衡)

  1. 配置网关系统 -> 网关 -> 配置,确保各WAN口网关监控状态为“正常”。
  2. 创建网关组系统 -> 网关 -> 组,点击 **+**。
    • 添加网关并设置优先级(故障转移),例如:WAN_GW为层级1,WAN2_DHCP为层级2
    • 触发条件:丢包
  3. 修改策略路由:在LAN的防火墙出站规则中,将网关选项改为新建的网关组。

九、故障排除

9.1 CSRF check failure 错误

登录后出现此白色错误页,通常是因为浏览器缓存或会话问题。

  • 解决方法:清除浏览器缓存和Cookie,使用无痕模式,或直接访问 https://192.168.1.1/(不带后续路径)。如仍不行,可尝试重启OPNsense的Web服务(非重启系统)。

9.2 网页反向代理设置

若通过Nginx等反向代理访问OPNsense管理界面,需在OPNsense中关闭某些检查:

  • 进入 系统 -> 设置 -> 管理
  • 勾选:禁用Web GUI重定向规则禁用DNS重绑定检查禁用HTTP_REFERER强制检查

9.3 开启SSH访问

  • 进入 系统 -> 设置 -> 管理
  • 勾选:启用安全Shell允许root用户登录允许密码登录
  • 监听接口:可选择全部或指定接口。

版权声明:本文部分内容参考并整合了多位社区作者的经验,特别感谢 OPNsense中文手册 和博主“鐵血男兒”的分享。本文旨在为初学者提供一个清晰的指引,更多深入细节请查阅官方文档和社区论坛。

0%