前言:
kubernetes的存储类大家应该都知道,常用的有nfs-client-provisioner这样插件形式,其实还有一种本地存储类的插件,只是这个估计很冷门,生产上网络存储持久卷还是主流的,本文将介绍一种本地存储类插件。
dashboard是kubernetes的web管理界面,大家也是十分熟悉的,但一般的dashboard是需要使用token登陆或者自行设置密码登陆,这个对于开发人员来说是不友好的,那么,本文将采用另一种方式部署dashboard,只需要简单的部署就可以打开浏览器直接输入IP+端口就登陆dashboard,不需要任何的验证,在二进制集群以及kubeadm集群中均验证通过。
一,本地存储类的部署
这个部署非常简单,两个文件就可以了
【A】
StorageClass.yaml
cat >storageclass.yaml <<EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
namespace: kube-system
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true"
labels:
addonmanager.kubernetes.io/mode: EnsureExists
provisioner: k8s.io/minikube-hostpath
EOF
【B】
storage-provisioner.yaml
cat >storage-provisioner.yaml <<EOF
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: storage-provisioner
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: storage-provisioner
labels:
addonmanager.kubernetes.io/mode: EnsureExists
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:persistent-volume-provisioner
subjects:
- kind: ServiceAccount
name: storage-provisioner
namespace: kube-system
---
apiVersion: v1
kind: Pod
metadata:
name: storage-provisioner
namespace: kube-system
labels:
integration-test: storage-provisioner
addonmanager.kubernetes.io/mode: Reconcile
spec:
serviceAccountName: storage-provisioner
hostNetwork: true
containers:
- name: storage-provisioner
image: /google_containers/storage-provisioner:v1.8.1
command: ["/storage-provisioner"]
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /tmp
name: tmp
volumes:
- name: tmp
hostPath:
path: /tmp
type: Directory
EOF
部署完成后,查看sc的状态:
[root@node3 addons]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) k8s.io/minikube-hostpath Delete Immediate false 9d
测试这个存储类:
cat > nginx-pvc.yaml <<EOF
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
annotations:
volume.beta.kubernetes.io/storage-class: "standard"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
EOF
cat >deploy-nginx.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.18
name: nginx
volumeMounts:
- name: nginx-persistent-storage
mountPath: "/usr/share/nginx/html" #不需要修改,映射到镜像内部目录
volumes:
- name: nginx-persistent-storage
persistentVolumeClaim:
claimName: test-claim #对应到pvc的名字
EOF
测试用pod部署完成后,查看该pod的clusterIP:
[root@node3 nginx]# kubectl get po -A -owide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default nginx-b7b6ff9f7-7hmqm 1/1 Running 3 47h 10.244.0.47 node3 <none> <none>
查看上面的pvc生成的pv,观察状态,可以看到部署正确无误:
[root@node3 nginx]# kubectl get pv,pvc -A
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-79fee6e2-e5a2-4fd6-8abc-ea4a1783f2c7 1Mi RWX Delete Bound default/test-claim standard 47h
NAMESPACE NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
default persistentvolumeclaim/test-claim Bound pvc-79fee6e2-e5a2-4fd6-8abc-ea4a1783f2c7 1Mi RWX standard 47h
到volume存储的目录下写入nginx的首页文件,查看前面的部署文件可以知道该目录在tmp目录下:
root@node3 nginx]# cd /tmp/hostpath-provisioner/pvc-79fee6e2-e5a2-4fd6-8abc-ea4a1783f2c7/
[root@node3 pvc-79fee6e2-e5a2-4fd6-8abc-ea4a1783f2c7]# pwd
/tmp/hostpath-provisioner/pvc-79fee6e2-e5a2-4fd6-8abc-ea4a1783f2c7
[root@node3 pvc-79fee6e2-e5a2-4fd6-8abc-ea4a1783f2c7]# ls
index.html
[root@node3 pvc-79fee6e2-e5a2-4fd6-8abc-ea4a1783f2c7]# cat index.html
this is a test page!!!!!!
curl访问这个pod的clusterIP,可以看到本地存储类完全正确:
[root@node3 ~]# curl 10.244.0.47
this is a test page!!!!!!
部署无token的开发专用dashboard:
我这里将各个模块分开了,总计10个文件,可以将这10个文件合并或者放置到一个空目录下,部署文件如下:
cat >dashboard-sa.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard
namespace: kubernetes-dashboard
EOF
cat >dashboard-role.yaml <<EOF
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
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"]
EOF
cat >dashboard-rolebinding.yaml <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
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
EOF
cat >dashboard-clusterrole.yaml<<EOF
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
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"]
EOF
cat >dashboard-clusterrolebinding.yaml<<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
EOF
cat >dashboard-ns.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: kubernetes-dashboard
labels:
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
EOF
cat >dashboard-configmap.yaml <<EOF
kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard-settings
namespace: kubernetes-dashboard
EOF
cat >dashboard-secret.yaml <<EOF
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
data:
csrf: ""
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
EOF
cat >dashboard-svc.yaml <<EOF
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons-endpoint: dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 80
targetPort: 9090
nodePort: 30001
selector:
k8s-app: kubernetes-dashboard
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
ports:
- port: 8000
targetPort: 8000
selector:
k8s-app: dashboard-metrics-scraper
EOF
cat >dashboard-dp.yaml <<EOF
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
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.4
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:
"beta.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: {}
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/minikube-addons: dashboard
addonmanager.kubernetes.io/mode: Reconcile
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
# WARNING: This must match pkg/minikube/bootstrapper/images/images.go
image: kubernetesui/dashboard:v2.0.1
ports:
- containerPort: 9090
protocol: TCP
args:
- --namespace=kubernetes-dashboard
- --enable-skip-login
- --disable-settings-authorizer
# 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:
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
path: /
port: 9090
initialDelaySeconds: 30
timeoutSeconds: 30
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"beta.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
EOF
假设以上10个文件放置在dashboard这个文件夹内,执行这些文件即可:
kubectl apply -f dashboard/
查看部署情况:
[root@k8s-master ~]# kubectl get po,secret,cm,sa,svc -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
pod/dashboard-metrics-scraper-dc6947fbf-hf26p 1/1 Running 0 86m
pod/kubernetes-dashboard-6dbb54fd95-795lj 1/1 Running 0 86m
NAME TYPE DATA AGE
secret/default-token-v6pkr kubernetes.io/service-account-token 3 87m
secret/kubernetes-dashboard-certs Opaque 0 87m
secret/kubernetes-dashboard-csrf Opaque 1 87m
secret/kubernetes-dashboard-key-holder Opaque 2 87m
secret/kubernetes-dashboard-token-l22q6 kubernetes.io/service-account-token 3 87m
NAME DATA AGE
configmap/kubernetes-dashboard-settings 0 86m
NAME SECRETS AGE
serviceaccount/default 1 87m
serviceaccount/kubernetes-dashboard 1 87m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.0.71.99 <none> 8000/TCP 87m
service/kubernetes-dashboard NodePort 10.0.133.27 <none> 80:30001/TCP 87m
打开任意一个浏览器,输入节点IP+30001 即可访问dashboard了:
这个版本还算可以,不是太低,用起来非常方便,十分适合开发人员适用哦。