前面讲了如何使用k8s以及对应的k8s的集群如何搭建,对相应的组件的使用也是慢慢了解了,例如pod,deployment等。但是只是使用还不够,本文主要是针对k8s常用的组件进行进阶介绍。
1、Pod进阶
1.1、生命周期(Lifecycle)
官网:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
Pod的生命周期分为五种状态:挂起、运行中、成功、失败、未知状态,平时运行apply命令创建pod以后通过kubectl get pods -o wide
可以看到创建的pod到哪个生命周期了。
挂起(Pending): Pod已经被Kubernetes系统接受,但有一个或者多个镜像尚未创建。可能会等待的时间分为两个部分,一个是调度Pod的时间,另一个是通过网络下载镜像的时间,可提前下载好需要的镜像减少等待的时间;
运行中(Running): 该Pod已经绑定到了一个节点上,Pod中所有的容器都已经被创建,至少有一个容器正在运行,或者正在处于启动或重启状态;
成功(Succeeded): Pod中所有的容器都被成功终止,并且不会再重启;
失败(Failed): Pod中的所有容器都已经终止,并且最少有一个容器因为失败终止,也就是说容器以非0的状态退出或者被系统终止;
未知(Unknown): 因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败。
1.2、重启策略
官网:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
Pod的重启策略有三种,但是重启策略只适用于同一节点的容器。
Always: 容器失效时立即重启;
OnFailure: 容器终止运行且退出码不为0时重启;
Never: 永远不重启。
1.3、静态Pod
静态Pod是由kubelet进行管理的,并且存在于特定的Node上。
不能通过API Server进行管理,无法与ReplicationController、Deployment、DaemonSet进行关联,也无法进行健康检查。
1.4、健康检查
官网:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
通过官网我们可以看到健康检查的方式有三种,检查的结果也是三种,检查结果分为通过检查,检查失败和未知情况(不做任何处理)。
livenessProbe: 判断容器是否存活;如果检查结果失败,则kubelet会杀死所有容器,容器是否重启依赖于其重启策略。如果容器没有提供该探针,则默认为通过检查。
readinessProbe: 判断容器是否能够响应请求;如果检查结果为失败,则将Pod从所有与之匹配的节点中删除。第一次延迟响应之前的检查结果默认为失败,如果容器没有提供该探针,则默认为通过检查。
startupProbe: 判断容器是否启动;如果容器提供了该探针,那么其他探针失败直到该探针的检查结果通过才能继续使用。如果检查结果失败,则kubelet会杀死所有容器,容器是否重启依赖于其重启策略。如果容器没有提供该探针,则默认为通过检查。
1.5、ConfigMap
官网 :https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
ConfigMap说白了就是用来保存配置数据的键值对,也可以保存单个属性,也可以保存配置文件。所有的配置内容都存储在etcd中,创建的数据可以供Pod使用。
1.5.1、如何创建ConfigMap
1.5.1.1、命令行创建
创建一个名称为my-config的configMap,key值是port,value值是’3306’,可以直接使用以下命令:
kubectl create configmap my-config --from-literal=port='3306'
查看该ConfigMap:kubectl get configmap
获取该ConfigMap的yml文件详细信息:kubectl get configmap myconfig -o yaml
1.5.1.2、从配置文件中创建
创建一个文件,名称为my-config.propertie,然后在里面加上port=3306 name = mysql
然后再运行以下命令将该配置文件变成ConfigMap:
kubectl create configmap app --from-file=./my-config.properties
查看命令跟上面一样
1.5.1.3、从目录中创建
创建一层层文件夹,然后再运行命令创建:
mkdir config
cd config
mkdir a
mkdir b
cd ..
kubectl create configmap config --from-file=config/
1.5.1.4、通过yml文件创建
创建一个ConfigMaps.yml文件,可以在里面创建多个ConfigMap,不同的ConfigMap存储的数据不一样,下面yml中data就是每个ConfigMap存储的数据键值对。
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
kubectl apply -f ConfigMaps.yml
1.5.2、Pod中ConfigMap的使用
注意: (1)ConfigMap必须在Pod使用它之前创建;(2)Pod只能使用同一个命名空间下的ConfigMap;
1.5.2.1、通过环境变量使用
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:# Define the environment variable
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config #匹配ConfigMap的name
key: special.how #匹配ConfigMap的data中的key
restartPolicy: Never
可以运行kubectl logs pod-name
命令查看打印出来的数据
1.5.2.2、用作命令行参数
在命令行下引用时,需要先设置为环境变量,之后可以用过$(VAR_NAME)设置容器启动命令的启动参数
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod2
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY)" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config #匹配ConfigMap的name
key: special.how #匹配ConfigMap的data中的key
restartPolicy: Never
运行kubectl logs pod-name
命令查看打印出来的数据
1.5.2.3、作为volume挂载使用
将创建的ConfigMap直接挂载到Pod的/etc/config目录下,其中每一个key-value键值对都会生成一个文件,key为文件名,value为内容。
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap2
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
restartPolicy: Never
创建pod:kubectl apply -f pod-myconfigmap-v2.yml
进入Pod:kubectl exec -it pod-name bash
查看运行日志:kubectl logs pod-name
1.5.3、ConfigMap在IngressController中的使用
前面将的IngressController还记得吧(Kubernetes的核心详解),我使用了Ingress Nginx Controller,从官网下载了Ingress Nginx Controller创建需要的yml文件,文件中有很多configMap。如下:
然后我们继续看,能看到Ingress Nginx Controller的Deployment使用名字为ingress-nginx-controller的configMap来作为配置文件,也就是上图我们截图的那个ConfigMap。
其实通过Ingress Nginx Controller的讲解,我们知道Ingress Nginx Controller其实核心就是一个nginx,其肯定也有对应的配置文件/etc/nginx/nginx.conf。如果我们要修改配置文件,之前的方法是直接改配置文件,但是现在既然用了ConfigMap,那么我们就可以创建ConfigMap来更新里面的配置文件。
我们可以新创建一个ingress-nginx-controller的ConfigMap,然后创建以后其会自动跟上面的合并,没有必要直接改上面的ConfigMap的data。
新的ingress-nginx-controller的yml文件如下,我们可以在里面修改nginx的proxy超时时间,默认为208,我们改成200:
apiVersion: v1
kind: ConfigMap
metadata:
labels:
helm.sh/chart: ingress-nginx-3.10.1
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.41.2
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
data:
proxy-read-timeout: "200"
运行:kubectl ingress-nginx-controller.yml
然后再次进入IngressController查看/etc/nginx/nginx.conf中proxy-read-timeout就会发现已经更新成了200.
其实关于使用ConfigMap设置nginx的配置文件在官网有介绍:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/
1.6、Secret
官网:https://kubernetes.io/docs/concepts/configuration/secret/
通过官网可以很清楚的看到,Secrets可以存储敏感信息的一个组件。
Secret有不同的类型,大致可以分为以下几类:
(1)Opaque:使用base64编码存储信息,可以通过base64 -decode解码获得原始数据,因此安全性弱;
(2)kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息;
(3)kubernetes.io/service-account-token:用于被service account引用。servicea ccount创建是k8s会默认创建对应的secret。Pod如果使用了service account,对应的secret会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中。
1.6.1、Opaque Secret
Opaque类型的Secret的value为base64位编码后的值
1.6.1.1、Secret创建
1.6.1.1.1、从文件中创建
echo -n "admin" > ./username.txt
echo -n "1f2d1e2e67df" > ./password.txt
kubectl create secret generic db-user-pass --from-file=./username.txt --from- file=./password.txt
1.6.1.1.2、使用yaml文件创建
(1)对数据进行base64为编码
echo -n 'admin' | base64
echo -n '1f2d1e2e67df' | base64
(2)定义mysecret.yml文件
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
(3)根据yml文件创建资源并查看
kubectl create -f ./secret.yaml
kubectl get secret
kubectl get secret mysecret -o yaml
1.6.1.2、Secret使用
1.6.1.2.1、以Volume方式
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
kubectl exec -it pod-name bash
ls /etc/foo
cat /etc/foo/username
cat /etc/foo/password
1.6.1.2.2、以环境变量的方式
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
1.6.2、kubernetes.io/dockerconfigjson
kubernetes.io/dockerconfigjson用于存储docker registry的认证信息,可以直接使用 kubectl create secret 命令创建
1.6.3、 kubernetes.io/service-account-token
用于被 serviceaccount 引用。
serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的secret 会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount 目录中。
kubectl get secret # 可以看到service-account-token
kubectl run nginx --image nginx
kubectl get pods
kubectl exec -it nginx-pod-name bash
ls /run/secrets/kubernetes.io/serviceaccount
kubectl get secret
kubectl get pods pod-name -o yaml
# 找到 volumes选项,定位到-name,secretName
# 找到 volumeMounts选项,定位到 mountPath: /var/run/secrets/kubernetes.io/serviceaccount
**小结:**无论是ConfigMap,Secret,还是DownwardAPI,都是通过ProjectedVolume实现的,可以通过APIServer将信息放到Pod中进行使用。
1.7、指定Pod所运行的Node
(1)给node打上标签label
kubectl get nodes
kubectl label nodes worker02-kubeadm-k8s name=testPod
(2)查看node是否有上述label
kubectl describe node worker02-kubeadm-k8s
(3)部署一个mysql的pod
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql-rc
labels:
name: mysql-rc
spec:
replicas: 1
selector:
name: mysql-pod
template:
metadata:
labels:
name: mysql-pod
spec:
nodeSelector:
name: testPod
containers:
- name: mysql
image: mysql
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "mysql"
---
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
labels:
name: mysql-svc
spec:
type: NodePort
ports:
- port: 3306
protocol: TCP
targetPort: 3306
name: http
nodePort: 32306
selector:
name: mysql-pod
(4)查看pod运行详情
kubectl apply -f mysql-pod.yaml
kubectl get pods -o wide
2、Controller进阶
之前的Controller中我们学过也用过RC,RS以及Deployment,但是除此之外还有很多类型的Controller需要我们学习。
Controller的官网地址:https://kubernetes.io/docs/concepts/architecture/controller/
2.1、Jobs
官网:https://kubernetes.io/docs/concepts/workloads/controllers/job/
看名字就能知道这个controller大致是干什么的。我们之前创建的Pod都是根据副本的设置而按照固定的数量持久的运行下去,当有Pod出现问题时也会有新的Pod被创建然后继续运行下去。但是如果我们需要的是执行完某个任务以后就终止的Pod,这就需要Job了。
官网给了一个job的yml文件用来演示用的,计算 π 到小数点后 2000 位,并将结果打印出来。
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
kubectl apply -f job.yaml
kubectl describe jobs/pi
kubectl logs pod-name
Job有不同的类型:
非并行Job: 通常只运行一个Pod,Pod成功结束job就退出;
固定完成次数的并行Job: 并发运行指定数量的Pod,直到指定数量的Pod成功,Job结束;
带有工作队列的并行Job:
用户可以指定并行的Pod的数量,当任何Pod成功结束后,不会再创建新的Pod;
一旦有一个Pod成功结束,并且所有的Pods都结束了,该job就成功结束;
一旦有一个Pod成功结束,其他Pods都会准备退出。
2.2、CronJob
官网:https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/
这个通过名字也能大致知道是干什么的。CronJob是基于时间进行任务的定时管理的Controller。
特点:(1)在特定的时间点运行任务;
(2)反复在指定的时间点运行任务:比如定时进行数据备份等;
2.3、StatefulSets
官网:https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
之前接触的Pod的管理对象比如RC、Deployment、DaemonSet和Job都是面向无状态的服务,但是现实中有很多服务是有状态的,比如MySQL集群、MongoDB集群、ZK集群等,它们都有以下共同的特点:
(1)每个节点都有固定的ID,通过该ID,集群中的成员可以互相发现并且通信;
(2)集群的规模是比较固定的,集群规模不能随意变动;
(3)集群里的每个节点都是有状态的,通常会持久化数据到永久存储中;
(4)如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。
而之前的RC/Deployment没办法满足要求,所以从Kubernetes v1.4版本就引入了PetSet资源对象,在v1.5版本时更名为StatefulSet。从本质上说,StatefulSets可以看作是Deployment/RC对象的特殊变种:
(1)StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内其他的成员
(2)Pod的启动顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态
(3)StatefulSet里的Pod采用稳定的持久化存储卷,通过PV/PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷
(4)StatefulSet需要与Headless Service配合使用
可以用以下yml文件实践一下:
# 定义Service
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector: app: nginx
---
# 定义StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
kubectl apply nginx-st.yaml
watch kubectl get pods # 观察pod的创建顺序,以及pod的名字
2.4、DaemonSet
官网:https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
DaemonSet是用来管理Pod的,让每个节点都存在该Pod。我们前面讲过集群内的Pod可以互相通信是用为默认装了calico插件,其实calico插件的资源方式就是DamonSet的类型,保证每个节点都有calico这样才能通信。
2.5、Horizontal Pod Autoscaler
官网:https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
Horizontal Pod Autoscaler可以根据CPU的使用率水平扩缩容RC、Deployment、RS、StatefuSet中Pod的数量,也可以根据其他维度的条件进行水平扩缩容。但是无法适用于无法扩缩容的Pod,例如上面讲到的DaemonSet。
可以根据以下步骤实践一下:
(1)准备yml文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
(2)创建Horizontal Pod Autoscaler
# 使nginx pod的数量介于2和10之间,CPU使用率维持在50%
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=50
(3)查看所有创建的资源
kubectl get pods
kubectl get deploy
kubectl get hpa
(4)修改replicas值为1或者11
kubectl edit deployment nginx-deployment
可以发现最终最小还是2,最大还是10
总结:
Horizontal Pod Autoscaling可以根据CPU使用率或应用自定义metrics自动扩展Pod数量(支持 replication controller、deployment和replica set)。
01-控制管理器每隔30s查询metrics的资源使用情况;
02-通过kubectl创建一个horizontalPodAutoscaler对象,并存储到etcd中;
03-APIServer:负责接受创建hpa对象,然后存入etcd
3、Resource和Dashboard
3.1、Resource
官网:https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
因为k8s集群最小的操作单元是Pod,所以我们这里主要讨论的是Pod的资源。在k8s集群中Node节点的资源信息会上报给API Server。我们创建Pod的时候可以根据需要设置Pod需要的资源空间大小,最常见的就是设定CPU和内存的大小还有其他的设置条件。
当你设置了条件以后,由于node节点的资源信息会上报给API Server,调度器也能从API Server中获取node节点的信息,然后根据信息决定新创建的Pod应该运行在哪个节点。
官网介绍了可以使用requests和limits来设置:
可以根据以下yml文件实践一下:
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi" # 表示64M需要内存
cpu: "250m" # 表示需要0.25核的CPU
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
3.2、Dashboard
官网:https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/
控制台,图形化界面
(1)yml文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: kubernetes-dashboard
# Allows editing resource and makes sure it is created first.
addonmanager.kubernetes.io/mode: EnsureExists
name: kubernetes-dashboard-settings
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-dashboard
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
spec:
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
spec:
priorityClassName: system-cluster-critical
containers:
- name: kubernetes-dashboard
image: registry.cn-hangzhou.aliyuncs.com/itcrazy2016/kubernetes-dashboard-amd64:v1.8.3
resources:
limits:
cpu: 100m
memory: 300Mi
requests:
cpu: 50m
memory: 100Mi
ports:
- containerPort: 8443
protocol: TCP
args:
# PLATFORM-SPECIFIC ARGS HERE
- --auto-generate-certificates
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
- name: tmp-volume
mountPath: /tmp
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
k8s-app: kubernetes-dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
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 from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
addonmanager.kubernetes.io/mode: Reconcile
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
# Allows editing resource and makes sure it is created first.
addonmanager.kubernetes.io/mode: EnsureExists
name: kubernetes-dashboard-certs
namespace: kube-system
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
# Allows editing resource and makes sure it is created first.
addonmanager.kubernetes.io/mode: EnsureExists
name: kubernetes-dashboard-key-holder
namespace: kube-system
type: Opaque
---
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
spec:
selector:
k8s-app: kubernetes-dashboard
ports:
- port: 443
targetPort: 8443
nodePort: 30018
type: NodePort
(2)查看资源
kubectl get pods -n kube-system
kubectl get pods -n kube-system -o wide
kubectl get svc -n kube-system
kubectl get deploy kubernetes-dashboard -n kube-system
(3)使用火狐浏览器访问,谷歌需要装插件
https://xxx.xxx.xx.xx:30018/
(4)生成token
# 创建service account
kubectl create sa dashboard-admin -n kube-system
# 创建角色绑定关系
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin -- serviceaccount=kube-system:dashboard-admin
# 查看dashboard-admin的secret名字
ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}')
echo ADMIN_SECRET
# 打印secret的token
kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}'