一、Kubernetes是什么

是一个基于容器技术的分布式架构领先方案啊。我们不必再费心于负载均衡器的选型和部署实施问题,不必再考虑引入或自己开发一个复杂的服务治理框架,不必再头疼于服务监控和故障处理模块的开发。

kubernetes是一个开放性的开发平台。没有限定任何编程接口,无论是什么语言写的服务,都可以映射为kubernetes的Service,并且通过标准的TCP通信协议进行交换,并且Kubernetes对现有的编程语言、编程框架、中间件没有任何侵入性,因此系统也很容器改造升级并迁移到Kubernetes上。

Kubernetes是一个完备的分布式系统支撑平台。具有完备的集群管理能力,包括多层次的安全防护安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。同时,Kubernetes提供了完善的管理工具,这些工具涵盖了包括开发、部署测试、运维监控在内的各个环节。因此,Kubernetes是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。

在Kubernetes中,Service(服务)是分布式集群架构的核心,一个Service对象有如下关键特征:

  • 一个唯一指定的名字(mysql-server)。
  • 一个虚拟IP(Cluster IP、Service IP或VIP)和端口号。
  • 能提供某种远程服务能力。
  • 被映射到了提供这种服务能力的一组容器应用上。

Service 的服务进程目前都基于Socket通信方式对外提供服务,比如 Redis、Memcache,MySQL、Web Server,或者是实现了某个具体业务的一个特定的 TCP Server进程。虽然一个Service通常由多个相关的服务进程来提供服务,每个服务进程都有一个独立的 Endpoint(IP+Port)访问点,但Kubernetes能够让我们通过Service(虚拟Cluster IP +Service Port)连接到指定的Service 上。有了Kubernetes内建的透明负载均衡和故障恢复机制,不管后端有多少服务进程,也不管某个服务进程是否会由于发生故障而重新部署到其他机器,都不会影响到我们对服务的正常调用。更重要的是这个Service本身一旦创建就不再变化,这意味着在Kubernetes集群中,我们再也不用为了服务的P地址变来变去的问题而头疼了。

容器提供了强大的隔离功能,所以把为Service提供服务的这组进程放入容器中进行隔离。为此,Kubernetes 设计了Pod对象,将每个服务进程包装到相应的Pod中,使其成为Pod中运行的一个容器(Container)。为了建立Service和 Pod间的关联关系,Kubernetes首先给每个Pod贴上一个标签(Label),给运行MySQL的Pod贴上 name=mysql标签,然后给相应的Service定义标签选择器(Label Selector),比如 MySQLService 的标签选择器的选择条件为name=mysql,意为该Service要作用于所有包含name=mysqlLabel的Pod 上。这样一来,就巧妙地解决了Service 与 Pod的关联问题。

在集群管理方面,Kubernetes将集群中的机器划分为一个Master节点和一群工作节点(Node)。其中,在 Master节点上运行着集群管理相关的一组进程 kube-apiserverkube-controller-managerkube-scheduler,这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在 Node 上 Kubernetes管理的最小运行单元是Pod。Node 上运行着Kubernetes的kubeletkube-proxy服务进程,这些服务进程负责Pod 的创建、启动、监控、重启、销毁,以及实现软件模式的负载均衡器

最后,再来看看传统的IT系统中服务扩容和服务升级这两个难题,在Kubernetes 集群中,你只需为需要扩容的Service关联的Pod创建一个RC(ReplicationController),则该Service的扩容以至于后来的Service升级等头疼问题都迎刃而解。在一个RC定义文件中包括以下3个关键信息。

  • 目标Pod的定义。
  • 目标Pod需要运行的副本数量(Replicas)。
  • 要监按的目标Pod的标签(Label)。

在创建好RC(系统将自动创建好Pod)后,Kubernetes会通过RC中定义的Label筛选出对应的Pod实例并实时监控其状态和数量,如果实例数量少于定义的副本数量(Replicas),则会根据RC中定义的Pod模板来创建一个新的Pod,然后将此Pod调度到合适的Node上启动运行,直到Pod实例的数量达到预定目标。这个过程完全是自动化的,无须人工干预。有了RC,服务的扩容就变成了一个纯粹的简单数字游戏了,只要修改RC 中的副本数量即可。后续的Service升级也将通过修改RC来自动完成。

为什么要用Kubernetes

使用了kubernetes可以更好的专注于业务代码的开发。kubernetes是全面拥抱微服务架构。微服务架构的核心是将一个巨大的单体应用分解为很多小的互相连接的微服务一个微服务背后可能有多个实例副本在支撑,副本的数量可能会随着系统的负荷变化而进行调整,内嵌的负载均衡器在这里发挥了重要作用。微服务架构使得每个服务都可以由专门的开发团队来开发,开发者可以自由选择开发技术,这对于大规模团队来说很有价值,另外每个微服务独立开发、升级、扩展,因此系统具备很高的稳定性和快速迭代进化能力。

系统可以随时随地搬迁到公有云上,在kubernetes中,底层网络的细节完全被屏蔽,基于服务的Cluster IP无须改变运行期的配置文件,就鞥你从物理机的环境,无缝迁移到公有云上吗,或在服务高峰期将部分服务对应的Pod副本放入公有云提升系统吞吐量。

kubernetes具备很强的横向扩容能力。不同修改代码,一个kubernetes集群即可从只包含几个Node的小集群平滑扩展到拥有上百个Node的大规模集群。

二 、安装kubernetes

安装k8s之前需要卸载docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine

#查找docker的包
yum list installed | grep docker
yum -y remove ...

安装docker

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
yum install -y yum-utils

yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#安装
yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.6

#启动
systemctl enable docker --now

#配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

kubeadm创建集群

1.安装kubeadm

  • 一台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令

  • 每台机器 2 GB 或更多的 RAM (如果少于这个数字将会影响你应用的运行内存)

  • 2 CPU 核或更多

  • 集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)

    • 设置防火墙放行规则
  • 节点之中不可以有重复的主机名、MAC 地址或 product_uuid。请参见这里了解更多详细信息。

    • 设置不同hostname
  • 开启机器上的某些端口。请参见这里 了解更多详细信息。

    • 内网互信
  • 禁用交换分区。为了保证 kubelet 正常工作,你 必须 禁用交换分区。

    • 永久关闭
1.基础环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#各个机器设置自己的域名
hostnamectl set-hostname xxxx

# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

#关闭swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab

#允许 iptables 检查桥接流量
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
2.安装kubelet、kubeadm、kubectl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

sudo yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9 --disableexcludes=kubernetes

sudo systemctl enable --now kubelet

2.使用bubeadm引导集群

1.下载镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sudo tee ./images.sh <<-'EOF'
#!/bin/bash
images=(
kube-apiserver:v1.20.9
kube-proxy:v1.20.9
kube-controller-manager:v1.20.9
kube-scheduler:v1.20.9
coredns:1.7.0
etcd:3.4.13-0
pause:3.2
)
for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/$imageName
done
EOF

chmod +x ./images.sh && ./images.sh
2.初始化主节点
1
2
3
4
5
6
7
8
9
10
11
12
13
#所有机器添加master域名映射,以下需要修改为自己的
echo "192.168.0.100 cluster-endpoint" >> /etc/hosts

#主节点初始化
kubeadm init \
--apiserver-advertise-address=192.168.0.100 \
--control-plane-endpoint=cluster-endpoint \
--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \
--kubernetes-version v1.20.9 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=173.24.0.0/16

#所有网络范围不重叠
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
To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

kubeadm join cluster-endpoint:6443 --token hwqz83.0xk3r8xp6qttcj8p \
--discovery-token-ca-cert-hash sha256:659af1a423da443b839dcda5d1450a7ee182ff329d4ac4a1ada144371b29654c \
--control-plane

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join cluster-endpoint:6443 --token hwqz83.0xk3r8xp6qttcj8p \

1
2
3
4
5
6
7
8
9
10
#查看集群所有节点
kubectl get nodes

#根据配置文件,给集群创建资源
kubectl apply -f xxxx.yaml

#查看集群部署了哪些应用?
docker ps === kubectl get pods -A
# 运行中的应用在docker里面叫容器,在k8s里面叫Pod
kubectl get pods -A
3.根据提示继续

1、设置.kube/config

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

2、安装网络组件

flannel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

#修改net-conf.json:
{
"Network": "173.24.0.0/16 ",
"Backend": {
"Type": "vxlan"
}
}


kubectl apply -f kube-flannel.yml

#当容器启动失败时
kubectl describe pod -n kube-system kube-flannel-ds-amd64-c4h6p
#可以手动拉取镜像
docker pull container
#可以去官网下载并导入
docker load -i flannel.tar

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
metadata :
name : mysql
#RC的名称,全局唯一
spec :
replicas : 1
#pod副本期待数量
selector :
app : mysql
#符合目标的pod拥有此标签
template :
#根据此模板创建Pod的副本(实例)
metadata :
labels:
app : mysql
#pod副本拥有的标签,对应RC的Selector
spec :
containers :
#pod内容器的定义部分
- name : mysql
#容器的名称
image : mysql
#容器对应的Docker Image
ports :
- containerPort : 3306
#容器应用监听的端口
env :
#注入容器内的环境变量
- name : MYSQL_ROOT_PASSWORD
value : "123456"

yaml定义文件中的 kind 属性,用来表明此资源对象的类型,比如这里的值为“ReplicationController“,表示这是一个RC;spec一节中是RC的相关属性定义,比如 spec.selectorRC的Pod标签(Label)选择器,即监控和管理拥有这些标签的Pod实例,确保当前集群上始终有且仅有replicas 个Pod实例在运行,这里我们设置replicas=1表示只能运行一个MySQL Pod实例。当集群中运行的Pod数量小于replicas 时,RC会根据spec.template一节中定义的Pod模板来生成一个新的Pod实例,spec.template.metadata.labels 指定了该Pod 的标签,需要特别注意的是:这里的labels 必须匹配之前的spec.selector,否则此RC每次创建了一个无法匹配Label的Pod,就会不停地尝试创建新的Pod。

创建好mysql-rc.yaml文件以后,为了将它发布到Kubernetes集群中,我们在 Master节点执行命令:

1
2
kubectl create -f mysql-rc.yaml
#replicationcontroller "mysql" created

主节点允不允许创建pod

1
2
3
4
5
6
7
8
#允许master节点部署pod
kubectl taint nodes --all node-role.kubernetes.io/master-
#如果不允许调度
kubectl taint nodes master1 node-role.kubernetes.io/master=:NoSchedule
#污点可选参数
NoSchedule: 一定不能被调度
PreferNoSchedule: 尽量不要调度
NoExecute: 不仅不会调度, 还会驱逐Node上已有的Pod

接下来,查看创建的pod和rc

1
2
3
4
5
6
7
#kubectl命令查看刚刚创建的RC:
kubectl get rc

#查看pod
kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default mysql-7gh6f 0/1 ContainerCreating 0 6m52s

k8s根据mysql的rc自动创建的Pod。由于 Pod 的调度和创建需要花费一定的时间,比如需要一定的时间来确定调度到哪个节点上,以及下载Pod里容器的镜像需要一段时间,所以一开始我们看到Pod的状态将显示为Pending。当Pod 成功创建完成以后,状态最终会被更新为Running

创建一个与之关联的k8s service :

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
#表明是Kubernetes Service
metadata:
name: mysql
#Service 的全局唯一名称
spec:
ports:
- port: 3306
# service提供服务的端口号
selector:
#Service对应的Pod拥有这里定义的标签
app: mysql

其中,metadata.nameService的服务名(ServiceName);port属性则定义了Service的虚端口; spec.selector确定了哪些Pod副本(实例)对应到本服务。类似地,我们通过kubectl create命令创建Service对象。

1
2
3
4
5
6
7
kubectl create -f mysql-svc.yaml 
# service/mysql created

# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47m
mysql ClusterIP 10.96.99.220 <none> 3306/TCP 97s

注意到MySQL服务被分配了一个值为10.96.99.220Cluster IP地址,这是一个虚地址,随后,Kubernetes集群中其他新创建的Pod就可以通过Service的 Cluster IP+端口号3306来连接和访问它了。

在通常情况下,Cluster IP是在Service创建后由Kubernetes系统自动分配的,其他Pod无法预先知道某个Service的 Cluster IP地址,因此需要一个服务发现机制来找到这个服务。为此,最初时,Kubernetes巧妙地使用了Linux环境变量(Environment Variable)来解决这个问题。现在我们只需知道,根据Service的唯一名字,容器可以从环境变量中获取到Service对应的Cluster IP地址和端口,从而发起TCP/IP连接请求了。

4.配置dashboard

1.部署

kubernetes官方提供的可视化界面
https://github.com/kubernetes/dashboard

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.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
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
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: Namespace
metadata:
name: kubernetes-dashboard

---

apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard

---

kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard

---

apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque

---

apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
data:
csrf: ""

---

apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque

---

kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-settings
namespace: kubernetes-dashboard

---

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster", "dashboard-metrics-scraper"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard

---

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

---

kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
ports:
- port: 8000
targetPort: 8000
selector:
k8s-app: dashboard-metrics-scraper

---

kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: dashboard-metrics-scraper
template:
metadata:
labels:
k8s-app: dashboard-metrics-scraper
annotations:
seccomp.security.alpha.kubernetes.io/pod: 'runtime/default'
spec:
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.6
ports:
- containerPort: 8000
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 8000
initialDelaySeconds: 30
timeoutSeconds: 30
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
volumes:
- name: tmp-volume
emptyDir: {}

2.设置访问端口

1
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard

type: ClusterIP 改为 type: NodePort

1
2
kubectl get svc -A |grep kubernetes-dashboard
## 找到端口,在安全组放行

访问: https://集群任意IP:端口 https://192.168.0.100:30662

3.创建访问账号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#创建访问账号,准备一个yaml文件; vi dash.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard

应用:

1
kubectl apply -f dash.yaml

4.令牌访问

1
2
#获取访问令牌
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"

密码

1
eyJhbGciOiJSUzI1NiIsImtpZCI6IlNDTWVDM2pKYmRhM290RUE2eXNtMXA4TlZwcVdUV2xJbHV6bmVJcVJ4d2MifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLWh2bnNoIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxZDMzYWZkZC1kN2I5LTQ4NzAtODljYS0xMzk2MTBkYTIyMjUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.Aruhe_ZQ2FuAfXx2YUmsePTE1kg2B0TPFcTYSfvuNMhyJsUvByy5tGtH3rxs3kZu6zVRrgsxeRGMRdYqyhTqfcoSEpdcwcrMNUFTA3Sdyp5-jH1ScfofpIDPQHxipqNAPrNUM2GbZbEre91dUp4ZWZaoOL7yB3gLp9STuAIGDD2jqOD-pKu37Jd9Pi7i7WN27PApba2_KRWzFAPE-WS_HaYNO0zUKQ7CjTqZ_9E-3TolyMQa012MWVEyldBHQd-6yO4EtAPESWz9JOXRRbKZuzhhP1VQ-FLJR1upTaZ4IrCG6Y-1hphyQfSdU2dsYIQDlmiKcCwKs9o5-mXfgc5RdQ