Kubeadm使用配置文件安装集群

通过配置文件创建集群

1
kubeadm init --config=kubeadm-config.yaml

配置文件内容

v1beta3文档

配置类型

一个 kubeadm 配置文件可以包含多个配置类型,使用三个破折号(“—”)分隔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
# 配置集群范围的设置
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
# 用于更改将传递给集群中部署的所有 `kubelet` 实例的配置
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# 用于更改传递给集群中部署的 `kube-proxy` 实例的配置
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
# join 的配置
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: JoinConfiguration

打印 initjoin 的默认值

1
2
3
4
kubeadm config print init-defaults
kubeadm config print init-defaults --component-configs KubeletConfiguration
kubeadm config print init-defaults --component-configs KubeProxyConfiguration
kubeadm config print join-defaults

Kubeadm init 配置类型

使用 --config 选项执行 kubeadm init 时,可以使用以下配置类型:InitConfigurationClusterConfigurationKubeProxyConfigurationKubeletConfiguration

但只有 InitConfigurationClusterConfiguration 之间的一种是强制性的。

InitConfiguration

用于配置运行时设置,在 kubeadm init 的情况下是 bootstrap toke 的配置以及特定于执行 kubeadm 的节点的所有设置,包括:

  • NodeRegistration,包含与将新节点注册到集群相关的字段;使用它来自定义节点名称、要使用的 CRI 套接字或应仅适用于该节点的任何其他设置(例如节点 ip)。
  • LocalAPIEndpoint,表示要在该节点上部署的 API 服务器实例的端点;使用它,例如自定义 API 服务器广告地址。

ClusterConfiguration

用于配置集群范围的设置,包括以下设置:

  • Networking,保存集群网络拓扑的配置;使用它,例如自定义 pod 子网或服务子网。
  • Etcd ;使用它,例如自定义本地 etcd 或配置 API 服务器以使用外部 etcd 集群。
  • kube-apiserver、kube-scheduler、kube-controller-manager 配置;使用它通过添加自定义设置或覆盖 kubeadm 默认设置来自定义控制平面组件。

KubeProxyConfiguration

用于更改传递给集群中部署的 kube-proxy 实例的配置。如果未提供或仅部分提供此对象,kubeadm 将应用默认值。

kubernetes.io kube-proxy 官方文档

kubernetes.io kube-proxy 官方文档

KubeletConfiguration

用于更改将传递给集群中部署的所有 kubelet 实例的配置。如果未提供或仅部分提供此对象,kubeadm 将应用默认值。

kubernetes.io kubelet 官方文档

godoc.org/k8s.io kubelet 官方文档

Kubeadm join 配置类型

使用 --config 选项执行 kubeadm join 时,应提供 JoinConfiguration 类型。

JoinConfiguration 类型应该用于配置运行时设置,在 kubeadm join 的情况下,是用于访问集群信息的发现方法以及特定于执行 kubeadm 的节点的所有设置,包括:

  • NodeRegistration,包含与将新节点注册到集群相关的字段;使用它来自定义节点名称、要使用的 CRI 套接字或应仅适用于该节点的任何其他设置(例如节点 ip)。
  • APIEndpoint,表示最终将部署在该节点上的 API 服务器实例的端点。

本次实例

完整示例及字段说明

host158 master

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
mkdir -p  /etc/kubernetes/pki/etcd/
\cp /etc/certs/etcd/ca.pem /etc/kubernetes/pki/etcd/etcd-ca.crt
\cp /etc/certs/etcd/etcd-158.pem /etc/kubernetes/pki/etcd/etcd.crt
\cp /etc/certs/etcd/etcd-158-key.pem /etc/kubernetes/pki/etcd/etcd.key
# 生成 certificateKey
#默认证书 /etc/kubernetes/pki/ca.crt
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
# vim ~/kubeadm-config-init.yaml
# 查看host中是否有映射
cat /etc/hosts
# 写入每个节点的hosts
cat >> /etc/hosts << EOF
192.168.2.158 host158
192.168.2.159 host159
192.168.2.160 host160
192.168.2.161 host161
192.168.2.240 host240
192.168.2.240 host241
192.168.2.158 master-158
192.168.2.159 master-159
192.168.2.160 master-160
192.168.2.161 node-160
EOF
echo "192.168.2.158 cluster.158" >> /etc/hosts
#使用自己的ca证书,InitConfiguration.skipPhasesz 跳过 certs/ca
mkdir -p /etc/kubernetes/pki/
\cp /etc/certs/etcd/ca.pem /etc/kubernetes/pki/ca.crt
\cp /etc/certs/etcd/ca-key.pem /etc/kubernetes/pki/ca.key

参考
pkg.go.dev/k8s.io v1beta3/types.go
github.com/kubernetes v1beta3/types.go

kubelet-config:KubeletConfiguration

写入配置

  • 使用外部 etcd
  • 使用 ipvs
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# 写入配置
cat > ~/kubeadm-config-init.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: fk3wpg.gs0mcv4twx3tz2mc
ttl: 240h0m0s
usages:
- signing
- authentication
description: "描述设置了一个人性化的消息,为什么这个令牌存在以及它的用途"
# NodeRegistration 包含与将新控制平面节点注册到集群相关的字段
nodeRegistration:
name: master-158
criSocket: unix:///var/run/containerd/containerd.sock
ignorePreflightErrors:
- IsPrivilegedUser
# LocalAPIEndpoint表示部署在这个控制平面节点上的API服务器实例的端点。
localAPIEndpoint:
advertiseAddress: 192.168.2.158
bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
clusterName: k8s-cluster
etcd:
external:
endpoints:
- "https://192.168.2.158:2379"
- "https://192.168.2.159:2379"
- "https://192.168.2.160:2379"
caFile: "/etc/certs/etcd/ca.pem"
certFile: "/etc/certs/etcd/etcd-158.pem"
keyFile: "/etc/certs/etcd/etcd-158-key.pem"
# 网络持有集群的网络拓扑结构的配置
networking:
dnsDomain: cluster.158
serviceSubnet: 10.96.0.0/16
podSubnet: "10.244.0.0/16"
kubernetesVersion: 1.24.1
controlPlaneEndpoint: "192.168.2.158:6443"
# APIServer 包含 API 服务器控制平面组件的额外设置
apiServer:
extraArgs:
bind-address: 0.0.0.0
authorization-mode: "Node,RBAC"
#service-cluster-ip-range: 10.96.0.0/16
#service-node-port-range: 30000-32767
timeoutForControlPlane: 4m0s
certSANs:
- "localhost"
- "cluster.158"
- "127.0.0.1"
- "master-158"
- "master-159"
- "master-160"
- "node-161"
- "10.96.0.1"
- "10.244.0.1"
- "192.168.2.158"
- "192.168.2.159"
- "192.168.2.160"
- "192.168.2.161"
- "host158"
- "host159"
- "host160"
- "host161"
# 包含控制器管理器控制平面组件的额外设置
controllerManager:
extraArgs:
bind-address: 0.0.0.0
#"node-cidr-mask-size": "20"
#cluster-cidr: 10.244.0.0/16
#service-cluster-ip-range: 10.96.0.0/16
#config: /etc/kubernetes/scheduler-config.yaml
#extraVolumes:
# - name: schedulerconfig
# hostPath: /home/johndoe/schedconfig.yaml
# mountPath: /etc/kubernetes/scheduler-config.yaml
# readOnly: true
# pathType: "File"
# 调度程序包含调度程序控制平面组件的额外设置
scheduler:
extraArgs:
bind-address: 0.0.0.0
#config: /etc/kubernetes/kubescheduler-config.yaml
#extraVolumes:
# - hostPath: /etc/kubernetes/kubescheduler-config.yaml
# mountPath: /etc/kubernetes/kubescheduler-config.yaml
# name: kubescheduler-config
# readOnly: true
# DNS 定义集群中安装的 DNS 插件的选项。
dns: {}
certificatesDir: /etc/kubernetes/pki
#imageRepository: k8s.gcr.io
imageRepository: registry.aliyuncs.com/google_containers
#用户启用的 FeatureGates。
#featureGates:
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
bindAddress: 0.0.0.0
bindAddressHardFail: false
clientConnection:
acceptContentTypes: ""
burst: 0
contentType: ""
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
qps: 0
clusterCIDR: 10.244.0.0/16
configSyncPeriod: 2s
conntrack:
maxPerCore: null
min: null
tcpCloseWaitTimeout: 60s
tcpEstablishedTimeout: 2s
# 默认 LocalModeClusterCIDR
detectLocalMode: ""
detectLocal:
bridgeInterface: ""
interfaceNamePrefix: ""
enableProfiling: false
healthzBindAddress: "0.0.0.0:10256"
hostnameOverride: "kube-proxy-158"
ipvs:
excludeCIDRs: null
minSyncPeriod: 1m
scheduler: ""
strictARP: true
syncPeriod: 1m
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
metricsBindAddress: "127.0.0.1:10249"
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: null
portRange: ""
showHiddenMetricsForVersion: ""
udpIdleTimeout: 0s
winkernel:
enableDSR: false
forwardHealthCheckVip: false
networkName: ""
rootHnsEndpointName: ""
sourceVip: ""
EOF

创建集群

1
2
3
4
kubeadm init --config=/root/kubeadm-config-init.yaml --v=5
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

其它操作

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
# 执行结束后
# `host158`上生成加入节点的脚本:
kubeadm token create --print-join-command
# 查看步骤
kubeadm init --help
# 更新配置文件
kubeadm init phase upload-config all --config=/root/kubeadm-config-init.yaml --v=5
# 更新配置文件 kubeconfig
kubeadm init phase kubeconfig all --config=/root/kubeadm-config-init.yaml --v=5
# 更新 kube-proxy
kubeadm init phase addon kube-proxy --config=/root/kubeadm-config-init.yaml --v=5
# 查询 kubeadm 配置文件
kubectl describe cm -n kube-system kubeadm-config
kubectl get cm -n kube-system kubeadm-config -o yaml
kubectl describe cm -n kube-system kubelet-config
kubectl describe cm -n kube-system kube-proxy
kubectl get cm -n kube-system kube-proxy -o yaml
kubectl describe cm -n kube-system
# 编辑
kubectl edit cm -n kube-system kubeadm-config
kubectl edit cm -n kube-system kubelet-config
kubectl edit cm -n kube-system kube-proxy
# 更新 ConfigMap 内容到本地文件 /var/lib/kubelet/config.conf
kubeadm upgrade node phase kubelet-config --v=10
systemctl restart kubelet
kubeadm upgrade node phase control-plane --v=5
kubeadm upgrade node phase preflight --v=5

使用启动引导令牌

启动引导令牌的 Secret 格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat > bootstrap-token-fk3wpg.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
# name 必须是 "bootstrap-token-<token id>" 格式的
name: bootstrap-token-fk3wpg
namespace: kube-system
# type 必须是 'bootstrap.kubernetes.io/token'
type: bootstrap.kubernetes.io/token
stringData:
# 供人阅读的描述,可选。
description: "启用 kubeadm init 时token ."
# 令牌 ID 和秘密信息,必需。
token-id: fk3wpg
token-secret: base64(gs0mcv4twx3tz2mc)
# 可选的过期时间字段
expiration: "2022-06-10T03:22:11Z"
# 允许的用法
usage-bootstrap-authentication: "true"
usage-bootstrap-signing: "true"
# 令牌要认证为的额外组,必须以 "system:bootstrappers:" 开头
auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress,system:bootstrappers:maxzhao-ca
EOF
kubectl apply -f bootstrap-token-fk3wpg.yaml

使用 kubeadm 管理令牌

被签名的 ConfigMapkube-public 名字空间中的 cluster-info。 典型的工作流中,客户端在未经认证和忽略 TLS 报错的状态下读取这个 ConfigMap。 通过检查 ConfigMap 中嵌入的签名校验 ConfigMap 的载荷。

查看 kube-public cluster-info

1
kubectl get configmap -n kube-public cluster-info -o 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
cat > kube-public-cluster-info.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: "2022-06-01T08:02:52Z"
name: cluster-info
namespace: kube-public
data:
jws-kubeconfig-fk3wpg: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
kubeconfig: |
apiVersion: v1
clusters:
- cluster:
# cat ~/.kube/config
certificate-authority-data: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR3RENDQXFpZ0F3SUJBZ0lVTUh4Y1p0SFJwbVFpelViUElwLzl3Z2JtdjA4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd2VERUxNQWtHQTFVRUJoTUNRMDR4RVRBUEJnTlZCQWdUQ0VwcFlXNW5JRk4xTVJBd0RnWURWUVFIRXdkTwpZVzVLYVc1bk1SVXdFd1lEVlFRS0V3eGxkR05rTFcxaGVIcG9ZVzh4RmpBVUJnTlZCQXNURFdWMFkyUWdVMlZqCmRYSnBkSGt4RlRBVEJnTlZCQU1UREdWMFkyUXRjbTl2ZEMxallUQWVGdzB5TWpBMU1qa3hOREl6TURCYUZ3MHkKTnpBMU1qZ3hOREl6TURCYU1IZ3hDekFKQmdOVkJBWVRBa05PTVJFd0R3WURWUVFJRXdoS2FXRnVaeUJUZFRFUQpNQTRHQTFVRUJ4TUhUbUZ1U21sdVp6RVZNQk1HQTFVRUNoTU1aWFJqWkMxdFlYaDZhR0Z2TVJZd0ZBWURWUVFMCkV3MWxkR05rSUZObFkzVnlhWFI1TVJVd0V3WURWUVFERXd4bGRHTmtMWEp2YjNRdFkyRXdnZ0VpTUEwR0NTcUcKU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzR2UVcxN0wxNkw3RWtYcFozTXJpSVhKek8ySTRyV2pMSQpKeDU1SFQ2czJFQjRQbE5DS3c4aFJtOWRjQVl2TVB6OEY1WVc4R3AxcWNLNk8vRW94T1grNkVXVzlYazh1RXQxCkxyZUUyUVo2b1JVenZTZFNXdllkRnhPUXM0VFBJcUNOcGFUNHgyZkFEU21sNDdaNWlkYnQrQ3M2ZEo0Z1Ftb2QKSkIxOWMvbDY3VnlwNmxPMWMwVWtNdFNod0xSZ2NFdGpKY1pmd0xPQXFibkRtYzg5Uks2cTh6b1AxMDhuZkwxbwpXZHBoREpsSVRHTmd6UTBGZU10aHZGUHJlU25EOEhWcHlqdjZtZ0pSZWlIWExhSWtEZ0tOQmh4UHRSdzdZb0pQCjNQSStuWkpBTVFOVW1nTWtoeC9mVGVzdW11VUs4RjI3R0N1b0VrNTZYRHJ0R042aEdGenhBZ01CQUFHalFqQkEKTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlJISkVWWgp0WEl5RXpJaThndy80SFh0cTg3RllEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFHYzZoR0Vqd010TDVUeDVVCmxBTUZSTlprRHJlMGRrL2t4Rmlra01EOWIvdUxkYTB5TXRSeEhLUjZYUTNDV3pyNDVINGh1SHRjZXlrL3BzZTIKbzdvSXZySnFzbThJRHBJTVU4Wk9qSGpBdVE0TytRenBtOEpHSXQrNy9JelpkMG1iSW5KdWJZZ2dtZG5GUG5UdQowbFpyTG5JL04vZHA5eVNJUGVnY252QnREaHdUa0tkbkRLZEtLdFdaalRMa1crNmJGUDZSaTZBWmpuczc1cmpvClhEaUtyTGZRS2Y1RlJFbHRHL3N1YnhkNlFDWFNpWDVqUTZlSk9xR1d1UkpRRHovWlZoWGhvdWFWaTVWOGpuRWcKNkVJZWxtR1A5QWRJaE4raFVMYTJZclRLMDJ4OTk3TlBQRnpDMm55NWV3VlFYdzZlNTE1QWU2S3BLUnZBcEE2RQplQWdwTVE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
server: https://192.168.2.158:6443
name: ""
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []
EOF
kube-public-cluster-info.yaml

host159加入集群

证书

1
2
3
# 在 158 上执行
ssh root@192.168.2.159 "mkdir -p /etc/kubernetes/pki"
scp -r /etc/kubernetes/pki/* root@192.168.2.159:/etc/kubernetes/pki

加入

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
cat > /root/kubeadm-config-join.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: JoinConfiguration
# NodeRegistration 包含与将新控制平面节点注册到集群相关的字段
nodeRegistration:
name: master-159
criSocket: unix:///var/run/containerd/containerd.sock
ignorePreflightErrors:
- IsPrivilegedUser
imagePullPolicy: IfNotPresent
caCertPath: "/etc/kubernetes/pki/ca.crt"
# Discovery 指定 kubelet 在 TLS 引导过程中使用的选项
discovery:
# BootstrapToken用于设置基于引导令牌的发现选项。
# BootstrapToken和File是互斥的
bootstrapToken:
token: fk3wpg.gs0mcv4twx3tz2mc
# APIServerEndpoint 是从其获取信息的 API 服务器的 IP 或域名
apiServerEndpoint: 192.168.2.158:6443
caCertHashes:
- sha256:011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025
# UnsafeSkipCAVerification允许基于令牌的发现,无需通过CACertHashes进行CA验证。
# 这可能会削弱kubeadm的安全性,因为其他节点可以模拟控制平面。
unsafeSkipCAVerification: false
tlsBootstrapToken: fk3wpg.gs0mcv4twx3tz2mc
# 超时修改发现超时
timeout: 4m0s
# 如果为零,则不会部署额外的控制平面实例。
controlPlane:
# LocalAPIEndpoint 表示要在此节点上部署的 API 服务器实例的端点。
localAPIEndpoint:
# AdvertiseAddress 设置 API 服务器发布的 IP 地址。
advertiseAddress: 192.168.2.159
# BindPort 设置 API Server 绑定的安全端口。
bindPort: 6443
certificateKey: 011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025
#skipPhases:
# - addon/kube-proxy
EOF
kubeadm join --config=/root/kubeadm-config-join.yaml --v=10

配置和校验

1
2
3
4
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

host160加入集群

证书

1
2
3
# 在 158 上执行
ssh root@192.168.2.160 "mkdir -p /etc/kubernetes/pki"
scp -r /etc/kubernetes/pki/* root@192.168.2.160:/etc/kubernetes/pki

加入

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
cat > /root/kubeadm-config-join.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: JoinConfiguration
# NodeRegistration 包含与将新控制平面节点注册到集群相关的字段
nodeRegistration:
# 如果未提供,则默认为节点的主机名。
name: master-160
# CRISocket 用于检索容器运行时信息。此信息将被注释到 Node API 对象,以供以后重用
criSocket: unix:///var/run/containerd/containerd.sock
taints: null
# kubeletExtraArgs:
# v: 4
# IgnorePreflightErrors 提供了在当前节点注册时要忽略的 pre-flight 错误片段。
ignorePreflightErrors:
- IsPrivilegedUser
imagePullPolicy: IfNotPresent
#caCertPath: "/etc/kubernetes/pki/ca.crt"
# Discovery 指定 kubelet 在 TLS 引导过程中使用的选项
discovery:
# BootstrapToken用于设置基于引导令牌的发现选项。
# BootstrapToken和File是互斥的
bootstrapToken:
token: fk3wpg.gs0mcv4twx3tz2mc
# APIServerEndpoint 是从其获取信息的 API 服务器的 IP 或域名
apiServerEndpoint: 192.168.2.158:6443
#caCertHashes:
#- sha256:011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025
# UnsafeSkipCAVerification允许基于令牌的发现,无需通过CACertHashes进行CA验证。
# 这可能会削弱kubeadm的安全性,因为其他节点可以模拟控制平面。
unsafeSkipCAVerification: true
#file:
#kubeConfigPath: /etc/kubernetes/admin.conf
tlsBootstrapToken: fk3wpg.gs0mcv4twx3tz2mc
# 超时修改发现超时
timeout: 4m0s
# 如果为零,则不会部署额外的控制平面实例。
controlPlane:
# LocalAPIEndpoint 表示要在此节点上部署的 API 服务器实例的端点。
localAPIEndpoint:
# AdvertiseAddress 设置 API 服务器发布的 IP 地址。
advertiseAddress: 192.168.2.160
# BindPort 设置 API Server 绑定的安全端口。
bindPort: 6443
certificateKey: 011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025
#skipPhases:
# - addon/kube-proxy
EOF
kubeadm join --config=/root/kubeadm-config-join.yaml --v=10

配置和校验

1
2
3
4
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

host161加入集群

1
2
kubeadm join 192.168.2.158:6443 --node-name node-161 --token fk3wpg.gs0mcv4twx3tz2mc \
--discovery-token-ca-cert-hash sha256:011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025

导出kubeadm 配置文件

1
2
3
4
kubectl describe cm -n kube-system kubeadm-config > ./kubeadm-config.yaml
kubectl describe cm -n kube-system kubelet-config > ./kubelet-config.yaml
#更新配置文件
kubeadm init phase kubeconfig all --config=./kubeadm-config.yaml --v=5

kubelet 配置

  • 用于 TLS 引导程序的 KubeConfig 文件为 /etc/kubernetes/bootstrap-kubelet.conf, 但仅当 /etc/kubernetes/kubelet.conf 不存在时才能使用。
  • 具有唯一 kubelet 标识的 KubeConfig 文件为 /etc/kubernetes/kubelet.conf
  • 包含 kubelet 的组件配置的文件为 /var/lib/kubelet/config.yaml
  • 包含的动态环境的文件 KUBELET_KUBEADM_ARGS 是来源于 /var/lib/kubelet/kubeadm-flags.env
  • 包含用户指定标志替代的文件 KUBELET_EXTRA_ARGS 是来源于 /etc/default/kubelet(对于 DEB),或者 /etc/sysconfig/kubelet(对于 RPM)。 KUBELET_EXTRA_ARGS 在标志链中排在最后,并且在设置冲突时具有最高优先级

KubeProxy 配置

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
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
bindAddress: 0.0.0.0
bindAddressHardFail: false
clientConnection:
acceptContentTypes: ""
burst: 0
contentType: ""
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
qps: 0
clusterCIDR: 10.244.0.0/16
configSyncPeriod: 2s
conntrack:
maxPerCore: null
min: null
tcpCloseWaitTimeout: 60s
tcpEstablishedTimeout: 2s
# 默认 LocalModeClusterCIDR
detectLocalMode: ""
detectLocal:
bridgeInterface: ""
interfaceNamePrefix: ""
enableProfiling: false
healthzBindAddress: "0.0.0.0:10256"
hostnameOverride: "kube-proxy-158"
ipvs:
excludeCIDRs: null
minSyncPeriod: 1m
scheduler: ""
strictARP: true
syncPeriod: 1m
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
metricsBindAddress: "127.0.0.1:10249"
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: null
portRange: ""
showHiddenMetricsForVersion: ""
udpIdleTimeout: 0s
winkernel:
enableDSR: false
forwardHealthCheckVip: false
networkName: ""
rootHnsEndpointName: ""
sourceVip: ""

官方示例

这是一个完整的示例,其中包含要在 kubeadm init 运行期间使用的多个配置类型的单个 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: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
bootstrapTokens:
- token: "9a08jv.c0izixklcxtmnze7"
description: "kubeadm bootstrap token"
ttl: "24h"
- token: "783bde.3f89s0fje9f38fhf"
description: "another bootstrap token"
usages:
- authentication
- signing
groups:
- system:bootstrappers:kubeadm:default-node-token
nodeRegistration:
name: "ec2-10-100-0-1"
criSocket: "unix:///var/run/containerd/containerd.sock"
taints:
- key: "kubeadmNode"
value: "someValue"
effect: "NoSchedule"
kubeletExtraArgs:
v: 4
ignorePreflightErrors:
- IsPrivilegedUser
imagePullPolicy: "IfNotPresent"
localAPIEndpoint:
advertiseAddress: "10.100.0.1"
bindPort: 6443
certificateKey: "e6a2eb8581237ab72a4f494f30285ec12a9694d750b9785706a83bfcbbbd2204"
skipPhases:
- addon/kube-proxy
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
etcd:
# one of local or external
local:
imageRepository: "k8s.gcr.io"
imageTag: "3.2.24"
dataDir: "/var/lib/etcd"
extraArgs:
listen-client-urls: "http://10.100.0.1:2379"
serverCertSANs:
- "ec2-10-100-0-1.compute-1.amazonaws.com"
peerCertSANs:
- "10.100.0.1"
# external:
# endpoints:
# - "10.100.0.1:2379"
# - "10.100.0.2:2379"
# caFile: "/etc/kubernetes/pki/ca.crt"
# certFile: "/etc/kubernetes/pki/etcd/etcd.crt"
# keyFile: "/etc/kubernetes/pki/etcd/etcd.key"
networking:
serviceSubnet: "10.96.0.0/16"
podSubnet: "10.244.0.0/16"
dnsDomain: "cluster.local"
kubernetesVersion: "v1.21.0"
controlPlaneEndpoint: "10.100.0.1:6443"
apiServer:
extraArgs:
authorization-mode: "Node,RBAC"
extraVolumes:
- name: "some-volume"
hostPath: "/etc/some-path"
mountPath: "/etc/some-pod-path"
readOnly: false
pathType: FileOrCreate
certSANs:
- "10.100.1.1"
- "ec2-10-100-0-1.compute-1.amazonaws.com"
timeoutForControlPlane: 4m0s
controllerManager:
extraArgs:
"node-cidr-mask-size": "20"
extraVolumes:
- name: "some-volume"
hostPath: "/etc/some-path"
mountPath: "/etc/some-pod-path"
readOnly: false
pathType: FileOrCreate
scheduler:
extraArgs:
address: "10.100.0.1"
extraVolumes:
- name: "some-volume"
hostPath: "/etc/some-path"
mountPath: "/etc/some-pod-path"
readOnly: false
pathType: FileOrCreate
certificatesDir: "/etc/kubernetes/pki"
imageRepository: "k8s.gcr.io"
clusterName: "example-cluster"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# kubelet specific options here
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
# kube-proxy specific options here

配置文件

kubelet 配置

/var/lib/kubelet/config.yaml

master-158

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
cat > /var/lib/kubelet/config.yaml << EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# kubelet specific options here
# 启用 kubelet 的安全服务器。 注意:kubelet 的不安全端口由 readOnlyPort 选项控制。
enableServer: true
#发送给 kubelet 服务器的请求是如何进行身份认证的
authentication:
#包含与匿名身份认证相关的配置信息。
anonymous:
# enabled允许匿名用户向 kubelet 服务器发送请求。 未被其他身份认证方法拒绝的请求都会被当做匿名请求。
# 匿名请求对应的用户名为system:anonymous,对应的用户组名为 system:unauthenticated。
enabled: false
# 包含与 Webhook 持有者令牌认证相关的配置。
webhook:
# cacheTTL启用对身份认证结果的缓存。
cacheTTL: 2m
#enabled允许使用tokenreviews.authentication.k8s.io API 来提供持有者令牌身份认证。
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
# 发送给 kubelet 服务器的请求是如何进行鉴权的
authorization:
#鉴权模式:AlwaysAllow和Webhook
mode: Webhook
# WebHook 配置
webhook:
#设置来自 Webhook 鉴权组件的 'authorized' 响应的缓存时长。
cacheAuthorizedTTL: 5m
#设置来自 Webhook 鉴权组件的 'unauthorized' 响应的缓存时长。
cacheUnauthorizedTTL: 10s
# kubelet 用来操控宿主系统上控制组 (CGroup) 的驱动程序(cgroupfs 或 systemd)。
cgroupDriver: systemd
# 集群的 DNS IP 地址
#clusterDNS是集群 DNS 服务器的 IP 地址的列表。
# 如果设置了,kubelet 将会配置所有容器使用这里的 IP 地址而不是宿主系统上的 DNS 服务器来完成 DNS 解析。
clusterDNS:
- 10.96.0.10
# clusterDomain是集群的 DNS 域名。如果设置了此字段,kubelet 会配置所有容器,使之在搜索主机的搜索域的同时也搜索这里指定的 DNS 域。
clusterDomain: cluster.158
cpuManagerReconcilePeriod: 0s
evictionPressureTransitionPeriod: 0s
fileCheckFrequency: 0s
#healthz 服务器用来提供服务的 IP 地址。
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimumGCAge: 0s
# 日志
logging:
# 设置日志消息的结构。默认的格式取值为 text。
format: "text"
# 对日志进行清洗的最大间隔纳秒数 (例如,1s = 1000000000)
flushFrequency: 1000
# verbosity 用来确定日志消息记录的详细程度阈值。默认值为 0, 意味着仅记录最重要的消息。数值越大,额外的消息越多。出错消息总是会被记录下来。
# vmodule 会在单个文件层面重载 verbosity 阈值的设置。 这一选项仅支持 "text" 日志格式。
# options 中包含特定于不同日志格式的配置参数。 只有针对所选格式的选项会被使用,但是合法性检查时会查看所有选项配置。
options:
json:
# splitStream 将错误信息重定向到标准错误输出(stderr), 而将提示信息重定向到标准输出(stdout),并为二者提供缓存。 默认设置是将二者都写出到标准输出,并且不提供缓存。
# infoBufferSize 在分离数据流时用来设置提示数据流的大小。 默认值为 0,相当于禁止缓存。
infoBufferSize: "0"
verbosity: 0
memorySwap: {}
# 指向要运行的本地(静态)Pod 的目录, 或者指向某个静态 Pod 文件的路径。
staticPodPath: /etc/kubernetes/manifests
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
rotateCertificates: true
runtimeRequestTimeout: 0s
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s
EOF

/etc/kubernetes/kubelet.conf

master-158
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat > /etc/kubernetes/kubelet.conf << EOF
apiVersion: v1
clusters:
- cluster:
# certificate-authority-data: cat /etc/kubernetes/pki/ca.crt | base64 -w 0
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1EVXlNakl4TkRRd04xb1hEVE15TURVeE9USXhORFF3TjFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUFMCjRkN2xWekIwZnlhazYrcFdaaGJiNzBqOWFqa3NveXkrTnIvaWYzV2RxVHRXNUNHZVcyRzEwRldaenNLd3RUWnoKYjRTSGRBV21LL1dTNUJocWVEeFVENVNPcTVXNXpqUHZFNWpGanlONThlN0RVM1gzS0NJSGcxbXUyVnRQSzZWWQpob2RISHJIaXBEM3lOalBQTk1ERzRGU1V3NUFMWmRsRTFLV3VMdWVlWHhnbEd5WlRodHFBUkU1N1Q4MUFNMm5zCkN1cmI5N3AwKyt1L3pnZHdDRG1iWmtWYUFrTUM3MjB3cTdsUWs2UnpLbHVHMHJreVVLb0lQTk9YTkhxby9UdXMKNUh1ditFby9SbGo4MUlyMkh2OUE1dCt4YUo0SDB6NS9GajQxNnAwQ0xENjBrWi9YQlJoNE5MTC9EYkNQQll6cgorUzhwbEQ2Y0VRMi8xellSeWI4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZEL2EzQ0JYT2h1Y2hrYzNkY3JhR291TDNLYzNNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSStQdnZPK2VnMk5idUIrUUN2aQo3RktGUjJzOUQzSGxRNWtsRVZTbWJvSGRsN2Z5dkZhTUNPLzVQSk56cWUwRDNOL3F0MlJsWk43UEw0Q2VNaVFrCnM5Nk8zS2U4WVkrRmRUeXFJTW9MN2FKODNDTjE2NFR2S29Ld3JmL1pVaHZkQW1xS2NhM3I5blNGcjZreXVPZVAKV2cxMGlxcDMzS3ZqQjlJVFJBckxscDdRWm5JdmhMOVRVUk9YOW84amJvTVpjbU1QbG1lOEppRDcySkYzS0diUQpOMEJoTDYrVHo4RkJWSkNJYW9BRVQrQXlBdVFKdTl6cjMvd2FsZk9PcEdTSlhENmpjWGVsMldRVVFGQTJjUEpICndLSEtKNkRSL3pwKzNlTVRDWnhLMmloV2oyT0ZNbkV2UE9TcDZ5M0VtNmxmd0lXMktKSjVjakhnWTZOUTN1UWEKUUFBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://192.168.2.158:6443
name: cluster.158
contexts:
- context:
cluster: cluster.158
user: system:node:master-158
name: system:node:master-158@cluster.158
current-context: system:node:master-158@cluster.158
kind: Config
preferences: {}
users:
- name: system:node:master-158
user:
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
EOF

/var/lib/kubelet/pki/kubelet-client-current.pem

1
2
3
4
5
cat > /var/lib/kubelet/pki/kubelet-client-current.pem << EOF
# 这里面是公钥私钥
# Issuer: CN=kubernetes
# Subject: CN=kubernetes
EOF

错误处理

join 时的 JWS 问题

1
The cluster-info ConfigMap does not yet contain a JWS signature for token ID "j2lxkq", will try again

这里 kubeadm token list 可以看到 token 都很正常。

cluster info中的 JWS 需要在kube-controller-manager运行后创建。

1
kubectl get pods -A

image-20220602104516917

1
2
3
4
# 查看
kubectl describe -n kube-system kube-controller-manager-master-158
kubectl logs -n kube-system kube-controller-manager-master-158
kubectl logs -n kube-system kube-controller-manager-master-158 --v=10

image-20220602104739590

节点NotReady

1
kubectl describe nodes master-160

image-20220603102357056

cni plugin not initialized

1
sudo systemctl restart containerd

卸载集群

1
2
3
4
5
6
7
8
9
10
11
12
# 删除对集群的本地引用,集群名称 k8s-cluster
kubectl config delete-cluster k8s-cluster
# 重置 `kubeadm` 安装的状态
echo "y" | kubeadm reset
# 删除节点信息
rm -rf /etc/kubernetes/
# 删除本地配置
rm -rf $HOME/.kube/config
# 删除网路
rm -rf /var/lib/kubelet/
# 重启kubelet
systemctl restart kubelet

生成 token

一键生成

1
kubeadm token create --print-join-command --ttl=240h 

生成 certificateKey

安装etcd集群讲到 etcd-ca.crt

1
2
3
kubeadm token create
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'

完整示例

host158 master

1
2
3
4
5
6
7
8
9
mkdir -p  /etc/kubernetes/pki/etcd/
#\cp /etc/certs/etcd/ca.pem /etc/kubernetes/pki/ca.crt
\cp /etc/certs/etcd/etcd-158.pem /etc/kubernetes/pki/etcd/etcd.crt
\cp /etc/certs/etcd/etcd-158-key.pem /etc/kubernetes/pki/etcd/etcd.key
# 生成 certificateKey
#默认证书 /etc/kubernetes/pki/ca.crt
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
vim ~/kubeadm-config-init.yaml

参考
pkg.go.dev/k8s.io v1beta3/types.go
github.com/kubernetes v1beta3/types.go

kubelet-config:KubeletConfiguration

写入

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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
bootstrapTokens:
# Groups指定当使用/进行身份验证时,此令牌将作为身份验证的额外组
- groups:
- system:bootstrappers:kubeadm:default-node-token
# token id.secret
token: fk3wpg.gs0mcv4twx3tz2mc
# 过期时间
ttl: 240h0m0s
# 用法描述了这个标记可以被使用的方式。默认情况下可用于建立双向信任,但这里可以更改。
usages:
- signing
- authentication
description: "描述设置了一个人性化的消息,为什么这个令牌存在以及它的用途"
# NodeRegistration 包含与将新控制平面节点注册到集群相关的字段
nodeRegistration:
# Name 是将在此 `kubeadm init` 或 `kubeadm join` 操作中创建的 Node API 对象的 `.Metadata.Name` 字段。
# 该字段也用于 kubelet 的客户端证书到 API 服务器的 CommonName 字段。
# 如果未提供,则默认为节点的主机名。
name: master-158
# CRISocket 用于检索容器运行时信息。此信息将被注释到 Node API 对象,以供以后重用
criSocket: unix:///var/run/containerd/containerd.sock
# Taints指定节点API对象应该注册的 taints 。如果该字段未设置,即为nil,它将默认带有控制平面 taints 的控制平面节点。
# 如果你不想 taints 你的控制平面节点,将这个字段设置为一个空片,即。' taints:[] '在YAML文件中。此字段仅用于节点注册。
# 挺复杂 https://pkg.go.dev/k8s.io/api/core/v1#Taint
taints: []
# taints:
# - key: "kubeadmNode"
# value: "someValue"
# effect: "NoSchedule"
# KubeletExtraArgs传递额外的参数给kubelet。
# 这里的参数通过kubeadm在运行时为kubelet写入源代码的环境文件传递到kubelet命令行。
# 这覆盖了kubelet-config中通用的基本级配置,ConfigMap Flags在解析时具有更高的优先级。
# 这些值是本地的,并且特定于kubeadm正在执行的节点。这个映射中的键是出现在命令行上的标志名,除非没有前导破折号。
kubeletExtraArgs:
v: 4
# IgnorePreflightErrors 提供了在当前节点注册时要忽略的 pre-flight 错误片段。
ignorePreflightErrors:
- IsPrivilegedUser
# ImagePullPolicy 指定在 kubeadm "init" 和 "join" 操作期间拉取镜像的策略。
# The value of this field must be one of "Always", "IfNotPresent" or "Never".
# 如果未设置此字段,kubeadm 将默认为“IfNotPresent”,或者如果主机上不存在所需的图像,则拉取所需的图像。
imagePullPolicy: IfNotPresent
# LocalAPIEndpoint表示部署在这个控制平面节点上的API服务器实例的端点。
# ControlPlaneEndpoint的意义是,ControlPlaneEndpoint是集群的全局端点,然后将请求负载均衡到每个单独的API服务器。
# 这个配置对象允许您自定义本地API服务器发布的可访问的IP/DNS名称和端口。
# 默认情况下,kubeadm尝试自动检测默认接口的IP并使用它,但如果这个过程失败,您可以在这里设置所需的值
localAPIEndpoint:
# AdvertiseAddress 设置 API 服务器发布的 IP 地址。
advertiseAddress: 192.168.2.158
# BindPort 设置 API Server 绑定的安全端口。
bindPort: 6443
# 设置一个秘钥,该秘钥将对 uploadcerts init 阶段上传到集群中某 Secret 内的秘钥和证书加密。
certificateKey: "011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025"
# SkipPhases是执行命令时要跳过的阶段列表。
# 阶段列表可以通过“kubeadm init——help”命令获取。
# 标记"——skip-phases"优先于此字段。
skipPhases: []
# - addon/kube-proxy
# Patches 包含与将补丁应用于 kubeadm 部署的组件相关的选项
# https://pkg.go.dev/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3#Patches
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
clusterName: k8s-cluster
etcd:
# one of local or external
# local:
# imageRepository: "k8s.gcr.io"
# imageTag: "3.2.24"
# dataDir: "/var/lib/etcd"
# extraArgs:
# listen-client-urls: "http://10.100.0.1:2379"
# serverCertSANs:
# - "ec2-10-100-0-1.compute-1.amazonaws.com"
# peerCertSANs:
# - "10.100.0.1"
# 外部
external:
endpoints:
- "https://192.168.2.158:2379"
- "https://192.168.2.159:2379"
- "https://192.168.2.160:2379"
caFile: "/etc/kubernetes/pki/etcd/etcd-ca.crt"
certFile: "/etc/kubernetes/pki/etcd/etcd.crt"
keyFile: "/etc/kubernetes/pki/etcd/etcd.key"
# 网络持有集群的网络拓扑结构的配置
networking:
# DNSDomain 是 k8s 服务使用的 dns 域。默认为“cluster.local”。
dnsDomain: cluster.158
# ServiceSubnet 是 k8s 服务使用的子网。默认为“10.96.0.0/12”。
serviceSubnet: 10.96.0.0/16
# Pod 使用的子网
podSubnet: "10.244.0.0/16"
kubernetesVersion: 1.24.1
#设置一个稳定的 IP 地址或 DNS 名称
# 如果 controlPlaneEndpoint 未设置,则使用 advertiseAddress + bindPort。
controlPlaneEndpoint: "192.168.2.158:6443"
# APIServer 包含 API 服务器控制平面组件的额外设置
apiServer:
# ExtraArgs是传递给控制面组件的额外标志集。
# 这个映射中的键是出现在命令行上的标志名,除非没有前导破折号。
# 待办事项:这是暂时的,理想情况下,我们想要切换所有组件,使用ComponentConfig + ConfigMaps。
extraArgs:
# 在安全端口上进行鉴权的插件的顺序列表。 逗号分隔的列表:AlwaysAllow、AlwaysDeny、ABAC、Webhook、RBAC、Node。
# 默认 AlwaysAllow
authorization-mode: "Node,RBAC"
# ExtraVolumes is an extra set of host volumes, mounted to the control plane component.
extraVolumes:
- name: "some-volume"
# HostPath 是主机中将被挂载的路径
hostPath: "/etc/some-path"
# MountPath 是 pod 内将挂载 hostPath 的路径。
mountPath: "/etc/some-pod-path"
readOnly: false
# https://pkg.go.dev/k8s.io/api/core/v1#HostPathType
pathType: FileOrCreate
# certSANs:
# - "10.100.1.1"
# - "ec2-192.168.2.158.compute-1.maxzhao.com"
timeoutForControlPlane: 4m0s
# 包含控制器管理器控制平面组件的额外设置
controllerManager:
extraArgs:
"node-cidr-mask-size": "20"
extraVolumes:
- name: "some-volume"
hostPath: "/etc/some-path"
mountPath: "/etc/some-pod-path"
readOnly: false
pathType: FileOrCreate
# 调度程序包含调度程序控制平面组件的额外设置
scheduler:
extraArgs:
address: "192.168.2.158"
extraVolumes:
- name: "kube-config"
hostPath: "/etc/kubernetes/scheduler.conf"
mountPath: "/etc/some-pod-path"
readOnly: false
pathType: FileOrCreate
- name: "kube-config"
hostPath: "/etc/kubernetes/kubescheduler-config.yaml"
mountPath: "/etc/some-pod-path"
readOnly: false
pathType: FileOrCreate
# DNS 定义集群中安装的 DNS 插件的选项。
dns: {}
# CertificatesDir 指定存储或查找所有必需证书的位置。
certificatesDir: /etc/kubernetes/pki
#imageRepository: k8s.gcr.io
imageRepository: registry.aliyuncs.com/google_containers
#用户启用的 FeatureGates。
#featureGates:
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# kubelet specific options here
# 启用 kubelet 的安全服务器。 注意:kubelet 的不安全端口由 readOnlyPort 选项控制。
enableServer: true
#发送给 kubelet 服务器的请求是如何进行身份认证的
authentication:
#包含与匿名身份认证相关的配置信息。
anonymous:
# enabled允许匿名用户向 kubelet 服务器发送请求。 未被其他身份认证方法拒绝的请求都会被当做匿名请求。 匿名请求对应的用户名为system:anonymous,对应的用户组名为 system:unauthenticated。
enabled: false
# 包含与 Webhook 持有者令牌认证相关的配置。
webhook:
# cacheTTL启用对身份认证结果的缓存。
cacheTTL: 2m
#enabled允许使用tokenreviews.authentication.k8s.io API 来提供持有者令牌身份认证。
enabled: true
x509:
# 是一个指向 PEM 编发的证书包的路径。
# 如果设置了此字段,则能够提供由此证书包中机构之一所签名的客户端证书的请求会被成功认证,
# 并且其用户名对应于客户端证书的CommonName、组名对应于客户端证书的 Organization。
# clientCAFile: /etc/kubernetes/pki/ca.crt
clientCAFile: /etc/kubernetes/pki/etcd/etcd-ca.crt
# 发送给 kubelet 服务器的请求是如何进行鉴权的
authorization:
#鉴权模式:AlwaysAllow和Webhook
mode: Webhook
# WebHook 配置
webhook:
#设置来自 Webhook 鉴权组件的 'authorized' 响应的缓存时长。
cacheAuthorizedTTL: 5m
#设置来自 Webhook 鉴权组件的 'unauthorized' 响应的缓存时长。
cacheUnauthorizedTTL: 30s
# kubelet 用来操控宿主系统上控制组 (CGroup) 的驱动程序(cgroupfs 或 systemd)。
cgroupDriver: systemd
# 集群的 DNS IP 地址
#clusterDNS是集群 DNS 服务器的 IP 地址的列表。
# 如果设置了,kubelet 将会配置所有容器使用这里的 IP 地址而不是宿主系统上的 DNS 服务器来完成 DNS 解析。
clusterDNS:
- 10.96.0.10
# clusterDomain是集群的 DNS 域名。如果设置了此字段,kubelet 会配置所有容器,使之在搜索主机的搜索域的同时也搜索这里指定的 DNS 域。
clusterDomain: cluster.local
#healthz 服务器用来提供服务的 IP 地址。
healthzBindAddress: 192.168.2.158
healthzPort: 10248
# 日志
logging:
# 设置日志消息的结构。默认的格式取值为 text。
format: "text"
# 对日志进行清洗的最大间隔纳秒数 (例如,1s = 1000000000)
flushFrequency: 1000
# verbosity 用来确定日志消息记录的详细程度阈值。默认值为 0, 意味着仅记录最重要的消息。数值越大,额外的消息越多。出错消息总是会被记录下来。
# vmodule 会在单个文件层面重载 verbosity 阈值的设置。 这一选项仅支持 "text" 日志格式。
# options 中包含特定于不同日志格式的配置参数。 只有针对所选格式的选项会被使用,但是合法性检查时会查看所有选项配置。
options:
json:
# splitStream 将错误信息重定向到标准错误输出(stderr), 而将提示信息重定向到标准输出(stdout),并为二者提供缓存。 默认设置是将二者都写出到标准输出,并且不提供缓存。
# infoBufferSize 在分离数据流时用来设置提示数据流的大小。 默认值为 0,相当于禁止缓存。
infoBufferSize: "0"
verbosity: 0
# 配置容器负载可用的交换内存。
memorySwap: {}
# 指向要运行的本地(静态)Pod 的目录, 或者指向某个静态 Pod 文件的路径。
staticPodPath: /etc/kubernetes/manifests
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
# kube-proxy specific options here
# 代理服务器提供服务时所用 IP 地址(设置为 0.0.0.0 时意味着在所有网络接口上提供服务)。
bindAddress: 0.0.0.0
#设置为 true 时, kube-proxy 将无法绑定到某端口这类问题视为致命错误并直接退出。
bindAddressHardFail: false
clientConnection:
#定义客户端在连接到服务器时所发送的 Accept 头部字段。 此设置值会覆盖默认配置 'application/json'。 此字段会控制某特定客户端与指定服务器的所有链接。
acceptContentTypes: ""
#允许客户端超出其速率限制时可以临时累积的额外查询个数。
burst: 0
#从此客户端向服务器发送数据时使用的内容类型(Content Type)
contentType: ""
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
#控制此连接上每秒钟可以发送的查询请求个数。
qps: 0
#集群中 Pods 所使用的 CIDR 范围。 这一地址范围用于对来自集群外的请求流量进行桥接。 如果未设置,则 kube-proxy 不会对非集群内部的流量做桥接。
clusterCIDR: ""
# 从 API 服务器刷新配置的频率。此值必须大于 0。
configSyncPeriod: 2s
#包含与 conntrack 相关的配置选项。
conntrack:
#每个 CPU 核所跟踪的 NAT 链接个数上限 (0 意味着保留当前上限限制并忽略 min 字段设置值)。
maxPerCore: null
# 要分配的链接跟踪记录个数下限。 设置此值时会忽略 maxPerCore 的值(将 maxPerCore 设置为 0 时不会调整上限值)。
min: null
#用来设置空闲的、处于 CLOSE_WAIT 状态的 conntrack 条目 保留在 conntrack 表中的时间长度(例如,'60s')。 此设置值必须大于 0。
tcpCloseWaitTimeout: 60s
#空闲 TCP 连接的保留时间(例如,'2s')。 此值必须大于 0。
tcpEstablishedTimeout: 2s
#确定检测本地流量的方式,默认为 LocalModeClusterCIDR
detectLocalMode: ""
#确定检测本地流量的方式,默认为 LocalModeClusterCIDR
detectLocal:
#一个表示单个桥接接口名称的字符串参数。 Kube-proxy 将来自这个给定桥接接口的流量视为本地流量。 如果 DetectLocalMode 设置为 LocalModeBridgeInterface,则应设置该参数。
bridgeInterface: ""
#一个表示单个接口前缀名称的字符串参数。 Kube-proxy 将来自一个或多个与给定前缀匹配的接口流量视为本地流量。 如果 DetectLocalMode 设置为 LocalModeInterfaceNamePrefix,则应设置该参数。
interfaceNamePrefix: ""
#通过 '/debug/pprof' 处理程序在 Web 界面上启用性能分析。 性能分析处理程序将由度量值服务器执行
enableProfiling: false
#健康状态检查服务器提供服务时所使用的的 IP 地址和端口, 默认设置为 '0.0.0.0:10256'。
healthzBindAddress: "0.0.0.0:10256"
#非空时, 所给的字符串(而不是实际的主机名)将被用作 kube-proxy 的标识。
hostnameOverride: "kube-proxy-158"
iptables:
#通知 kube-proxy 在使用纯 iptables 代理模式时对所有流量执行 SNAT 操作。
masqueradeAll: false
# iptables fwmark 空间中的具体一位, 用来在纯 iptables 代理模式下设置 SNAT。此值必须介于 [0, 31](含边界值)。
masqueradeBit: null
# iptables 规则被刷新的最小周期(例如,'5s'、'1m'、'2h22m')。
minSyncPeriod: 1m
# iptables 规则的刷新周期(例如,'5s'、'1m'、'2h22m')。此值必须大于 0。
syncPeriod: 1m
ipvs:
#取值为一个 CIDR 列表,ipvs 代理程序在清理 IPVS 服务时不应触碰这些 IP 地址。
excludeCIDRs: null
minSyncPeriod: 1m
#IPVS 调度器。
scheduler: ""
#配置 arp_ignore 和 arp_announce,以避免(错误地)响应来自 kube-ipvs0 接口的 ARP 查询请求。
strictARP: true
syncPeriod: 1m
#设置 IPVS TCP 会话在收到 FIN 之后的超时值。 默认值为 0,意味着使用系统上当前的超时值设置。
tcpFinTimeout: 0s
#用于设置空闲 IPVS TCP 会话的超时值。 默认值为 0,意味着使用系统上当前的超时值设置。
tcpTimeout: 0s
#设置 IPVS UDP 包的超时值。 默认值为 0,意味着使用系统上当前的超时值设置。
udpTimeout: 0s
#度量值服务器提供服务时所使用的的 IP 地址和端口, 默认设置为 '127.0.0.1:10249'(设置为 0.0.0.0 意味着在所有接口上提供服务)。
metricsBindAddress: "127.0.0.1:10249"
# 代理模式 'userspace'(相对较老,即将被淘汰)、 'iptables'(相对较新,速度较快)、'ipvs'(最新,在性能和可扩缩性上表现好)

mode: "ipvs"
# kube-proxy 进程的 --nodeport-addresses 命令行参数设置。
#此值必须是合法的 IP 段。所给的 IP 段会作为参数来选择 NodePort 类型服务所使用的接口。
#如果有人希望将本地主机(Localhost)上的服务暴露给本地访问,同时暴露在某些其他网络接口上 以实现某种目标,可以使用 IP 段的列表。
#如果此值被设置为 "127.0.0.0/8",则 kube-proxy 将仅为 NodePort 服务选择本地回路(loopback)接口。
#如果此值被设置为非零的 IP 段,则 kube-proxy 会对 IP 作过滤,
#仅使用适用于当前节点的 IP 地址。 空的字符串列表意味着选择所有网络接口。
nodePortAddresses: null
#主机端口的范围,形式为 ‘beginPort-endPort’(包含边界), 用来设置代理服务所使用的端口。如果未指定(即‘0-0’),则代理服务会随机选择端口号。
portRange: "0-0"
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: JoinConfiguration
# NodeRegistration 包含与将新控制平面节点注册到集群相关的字段
nodeRegistration:
# Name 是将在此 `kubeadm init` 或 `kubeadm join` 操作中创建的 Node API 对象的 `.Metadata.Name` 字段。
# 该字段也用于 kubelet 的客户端证书到 API 服务器的 CommonName 字段。
# 如果未提供,则默认为节点的主机名。
name: master-158
# CRISocket 用于检索容器运行时信息。此信息将被注释到 Node API 对象,以供以后重用
criSocket: unix:///var/run/containerd/containerd.sock
# Taints指定节点API对象应该注册的 taints 。如果该字段未设置,即为nil,它将默认带有控制平面 taints 的控制平面节点。
# 如果你不想 taints 你的控制平面节点,将这个字段设置为一个空片,即。' taints:[] '在YAML文件中。此字段仅用于节点注册。
# 挺复杂 https://pkg.go.dev/k8s.io/api/core/v1#Taint
taints: null
# taints:
# - key: "kubeadmNode"
# value: "someValue"
# effect: "NoSchedule"
# KubeletExtraArgs传递额外的参数给kubelet。
# 这里的参数通过kubeadm在运行时为kubelet写入源代码的环境文件传递到kubelet命令行。
# 这覆盖了kubelet-config中通用的基本级配置,ConfigMap Flags在解析时具有更高的优先级。
# 这些值是本地的,并且特定于kubeadm正在执行的节点。这个映射中的键是出现在命令行上的标志名,除非没有前导破折号。
kubeletExtraArgs:
v: 4
# IgnorePreflightErrors 提供了在当前节点注册时要忽略的 pre-flight 错误片段。
ignorePreflightErrors:
- IsPrivilegedUser
# ImagePullPolicy 指定在 kubeadm "init" 和 "join" 操作期间拉取镜像的策略。
# The value of this field must be one of "Always", "IfNotPresent" or "Never".
# 如果未设置此字段,kubeadm 将默认为“IfNotPresent”,或者如果主机上不存在所需的图像,则拉取所需的图像。
imagePullPolicy: IfNotPresent
# CACertPath is the path to the SSL certificate authority used to
# secure comunications between node and control-plane.
# Defaults to "/etc/kubernetes/pki/ca.crt".
caCertPath: "/etc/kubernetes/pki/etcd/etcd-ca.crt"
# Discovery 指定 kubelet 在 TLS 引导过程中使用的选项
discovery:
# BootstrapToken用于设置基于引导令牌的发现选项。
# BootstrapToken和File是互斥的
bootstrapToken:
token: fk3wpg.gs0mcv4twx3tz2mc
# APIServerEndpoint 是从其获取信息的 API 服务器的 IP 或域名
apiServerEndpoint: 192.168.2.158:6443
# CACertHashes指定一组公钥引脚,以便在使用基于令牌的发现时进行验证。
# 发现期间发现的根CA必须与这些值中的一个匹配。
# 指定空集将禁用根CA固定,这可能是不安全的。
# 每个散列都被指定为“:”,其中目前唯一支持的类型是“sha256”。
# 这是在DER-encoded ASN.1中主题公钥信息(SPKI)对象的一个十六进制编码的SHA-256哈希值。这些散列可以使用OpenSSL等进行计算。
caCertHashes: sha256:011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025
# UnsafeSkipCAVerification允许基于令牌的发现,无需通过CACertHashes进行CA验证。
# 这可能会削弱kubeadm的安全性,因为其他节点可以模拟控制平面。
unsafeSkipCAVerification: false
# File 用于指定 kubeconfig 文件的文件或 URL,从中加载集群信息
# BootstrapToken和File是互斥的
#file:
# KubeConfigPath 用于指定 kubeconfig 文件的实际文件路径或 URL,从中加载集群信息
#kubeConfigPath:
# TLSBootstrapToken 是用于 TLS 引导的令牌。
# 如果设置了 .BootstrapToken,则该字段默认为 .BootstrapToken.Token,但可以被覆盖。
# 如果设置了.File,则该字段**必须设置**,以防 KubeConfigFile 不包含任何其他身份验证信息
tlsBootstrapToken: fk3wpg.gs0mcv4twx3tz2mc
# 超时修改发现超时
timeout: 4m0s
# ControlPlane 定义要在加入节点上部署的附加控制平面实例。
# 如果为零,则不会部署额外的控制平面实例。
controlPlane:
# LocalAPIEndpoint 表示要在此节点上部署的 API 服务器实例的端点。
localAPIEndpoint:
# AdvertiseAddress 设置 API 服务器发布的 IP 地址。
advertiseAddress: 192.168.2.158
# BindPort 设置 API Server 绑定的安全端口。
bindPort: 6443
certificateKey: 011acbb00e4983761f3cbe774f45477b75a99a42d14004f72c043ffbb6e5b025
# SkipPhases 是命令执行期间要跳过的阶段列表。
# 阶段列表可以通过“kubeadm init——help”命令获取。
# 标记"——skip-phases"优先于此字段。
skipPhases:
- addon/kube-proxy
# Patches 包含与将补丁应用于 kubeadm 部署的组件相关的选项
# https://pkg.go.dev/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3#Patches

本文地址: https://github.com/maxzhao-it/blog/post/cdb1e23h/