Kubernetes,简称K8S。一款开源、用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes 提供了应用部署、规划、更新、维护的一种机制。
传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。
新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。
容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在 build 或 release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更 “透明”,这更便于监控和管理。
Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。
在 Kubernetes 中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。
经典案例:
Infrastructure as a Service(阿里云)
Platform as a service(新浪云)
Software as a Service(Office 365)
集群资源管理器:
Apache MESOS(最新版本可以管理Kubernetes, 但增加软件层可能会增加故障节点)
Docker Swarm(功能较少, 缺乏滚动更新+回滚等功能)
Kubernetes(Google)
K8S是谷歌在2014年开源的容器化集群管理系统。
使用K8S进行容器化应用部署。
使用K8S利于应用扩展。
K8S目标:让部署容器化应用更加简介、高效。
Kubernetes 是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过Kubernetes 能够进行应用的自动化部署和扩缩容。在 Kubernetes 中,会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为 Google 生产环境运行工作负载15年的经验,并吸收了来自于社区的最佳想法与实践。
自动装箱
基于容器对应用运行环境的资源配置要求自动部署应用容器。
自我修复(自愈能力)
当容器失败时,会对容器进行重启。
当所部署的 Node 节点有问题时,会对容器进行重新部署、重新调度。
当容器未通过监控检查时,会关闭此容器。直到容器正常运行时,才会对外提供服务。
水平扩展
通过简单的命令、用户UI界面或基于CPU等资源的使用情况,对应用容器进行规模扩大或规模剪裁。
服务发现
用户无需使用额外的服务发现机制,就能基于 Kubernetes 自身能力实现服务发现和负载均衡。
滚动更新
可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新。
版本回退
可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退。
密钥和配置管理
在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署。
存储编排
启动实现存储系统挂载及应用,特别对有状态应用实现数据持久化非常重要。
存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph等)、公共云存储服务。
批处理
提供一次性任务,定时任务;满足批量数据处理和分析场景。
K8S集群控制节点,对集群进行调度管理,接受集群外用户去集群操作请求;Master Node 由 API Server、Scheduler、ClusterState Strore(ETCD数据库)和 Controller ManagerServer所组成。
集群工作节点,运行用户业务应用容器;
Worker Node 包含 kubelet、kube proxy 和 ContainerRuntime;
确保预期的Pod副本数量
应用部署状态
无状态应用部署
有状态应用部署 (依赖存储 / IP唯一)
确保所有的Node运行同一个Pod
一次性任务、定时任务
Master:CPU 2核、内存4GB、磁盘20GB
Node:CPU 4核、内存8GB、磁盘40GB
Master:CPU 8核+、内存16GB+、磁盘100GB+
Node:CPU 16核+、内存64GB+、磁盘500GB+
目前生产部署 Kubernetes 集群主要有两种方式:
kubeadm init
和 kubeadm join
,用于快速部署 Kubernetes 集群。Kubeadm 是官方社区推出的一个用于快速部署 Kubernetes 集群的工具,这个工具能通过两条指令完成一个 Kubernetes 集群的部署:
kubeadm init
kubeadm join
在开始之前,部署 Kubernetes 集群及其需要满足以下几个条件:
角色 | IP |
---|---|
K8S-Master | 192.168.1.136 |
K8S-Node1 | 192.168.1.135 |
K8S-Node2 | 192.168.1.134 |
1、关闭防火墙
$ systemctl stop firewalld # 临时
$ systemctl disable firewalld # 永久
2、关闭 selinux
$ sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
$ setenforce 0 # 临时
3、关闭 swap
$ swapoff -a # 临时
$ vim /etc/fstab # 永久(删除swap相关行 /mnt/swap swap swap defaults 0 0 这一行或者注释掉这一行)
$ free -m # 确认swap已经关闭(若swap行都显示 0 则表示关闭成功)
4、根据规划设置主机名
$ hostnamectl set-hostname <hostname>
5、在master添加hosts
$ cat >> /etc/hosts << EOF
192.168.1.136 k8smaster
192.168.1.135 k8snode1
192.168.1.134 k8snode2
EOF
6、将桥接的IPv4流量传递到iptables的链
$ cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 生效
7、时间同步
$ yum install ntpdate -y
$ ntpdate time.windows.com
Kubernetes 默认CRI(容器运行时)为Docker,因此先安装Docker。
$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum -y install docker-ce-18.06.1.ce-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version
Docker version 18.06.1-ce, build e68fc7a
$ cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors":["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
由于版本更新频繁,这里指定版本号部署:
$ yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
$ systemctl enable kubelet
在Master中执行命令:
$ kubeadm init \
--apiserver-advertise-address=192.168.1.136 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
由于默认拉区镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。
使用kubectl工具(省略权限修饰符):
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
此时,各个节点状态为Not Ready。
在Node执行命令,向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:
kubeadm join 192.168.1.136:6443 --token 3o69uv.pugf6vy6lq44wjrs \
--discovery-token-ca-cert-hash sha256:3150067383e9af1021776982a4100823564e7ab0a604fe59137409159042b9ec
默认token有效期为24小时,当过期后,该token就不可用了。这时就需要重新创建token,操作如下:
kubeadm token create --print-join-command
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
默认镜像地址无法访问,sed命令修改为docker hub 镜像仓库。(连接不上可查询IP并修改/etc/hosts
文件)
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl get pods -n kube-system
查看当前已加入节点:
kubectl get nodes
在Kubernetes集群中创建一个pod,验证是否正常运行:
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc
访问地址:http://Node_IP:Port
kubectl是Kubernetes集群的命令行工具没通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署
kubectl [command] [TYPE] [NAME] [flags]
command:指定要对资源执行的操作,例如create、get、describe、delete等
TYPE:指定资源类型,资源类型是大小写敏感的,开发者能够以单数、复数、缩略形式。
kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1
NAME:指定资源的名称,名称也大小写敏感。如果省略名称,则会显示所有的资源。例如:
kubectl get pods
kubectl get nodes
flags:指定可选的参数。例如:可用-s
或者-server
参数指定 Kubernetes API server 的地址、端口。
所有帮助信息:
kubectl --help
具体查看某个操作帮助信息:
kubectl [?] --help
命令 | 解释 |
---|---|
create | 通过文件或标准输入创建资源 |
expose | 将一个资源公开为一个新的Service |
run | 在集群中运行一个特定的镜像 |
set | 在对象上设置特定的功能 |
get | 显示一个/多个资源 |
explain | 文档参考资料 |
edit | 使用默认的编辑器编辑一个资源 |
delete | 通过文件名、标准输入、资源名称、标签选择器来删除资源 |
命令 | 解释 |
---|---|
rollout | 管理资源的发布 |
rolling-update | 给指定的复制控制器滚动更新 |
scale | 扩容/缩容Pod数量,Deployment、ReplicaSet、RC、Job |
autoscale | 创建一个自动选择扩容/缩容并设置Pod数量 |
命令 | 解释 |
---|---|
certificate | 修改证书资源 |
cluster-info | 显示集群信息 |
top | 显示资源(CPU/Memory/Storage)使用。需要Heapster运行。 |
cordon | 标记节点不可调度 |
uncordon | 标记节点可调度 |
drain | 驱逐节点上的应用,准备下线维护 |
taint | 修改节点taint标记 |
命令 | 解释 |
---|---|
describe | 显示特定资源或资源组的详细信息 |
logs | 在一个Pod中打印一个容器日志,如果Pod只有一个容器,容器名称是可选的 |
attach | 附加到一个运行的容器 |
exec | 执行命令到容器 |
port-forward | 转发一个/多个本地端口到一个Pod |
proxy | 运行一个proxy到Kubernetes API Server |
cp | 拷贝文件/目录到容器中 |
auth | 检查授权 |
命令 | 解释 |
---|---|
apply | 通过文件名/标准输入对资源应用配置 |
patch | 使用补丁修改、更新资源的字段 |
replace | 通过文件名/标准输入替换一个资源 |
convert | 不同的API版本之间转换配置文件 |
命令 | 解释 |
---|---|
label | 更新资源上的标签 |
annotate | 更新资源上的注释 |
completion | 用于实现kubectl工具自动补全 |
命令 | 解释 |
---|---|
api-versions | 打印受支持的API版本 |
config | 修改kubeconfig文件(用于访问API,比如配置认证信息) |
help | 所有命令帮助 |
plugin | 运行一个命令行插件 |
version | 打印客户端和服务版本信息 |
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc
kubectl get pods
kubectl get nodes
kubectl cs
kubectl apply -f [yaml文件本地/网络路径]
K8S集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,也就是可以把需要对资源对象操作编辑到YAML格式文件中,我们把这种文件叫做资源清单文件,通过kubectl
命令直接使用资源清单文件就可以实现对大量的资源对象进行编排部署了。
YAML:仍是一种标记语言。为了强调这种语言以数据作为中心,而不是以标记语言作为重点。
YAML是一个可读性高,用来表达数据序列的格式。
---
表示新的yaml文件开始# 控制器定义
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
# 被控制对象
template: # 开始定义规则
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
字段 | 含义 |
---|---|
apiVersion | API版本 |
kind | 资源类型 |
metadata | 资源元数据 |
spec | 资源规格 |
replicas | 副本数量 |
selector | 标签选择器 |
template | Pod模板 |
metadata | Pod元数据 |
spec | Pod规格 |
containers | 容器配置 |
举例:
产生yaml格式:
kubectl create deployment web --image=nginx -o yaml --dry-run
输出至具体文件:
kubectl create deployment web --image=nginx -o yaml --dry-run > m1.yaml
举例:
从已部署资源中导出yaml,并输出至文件:
kubectl get deploy nginx -o=yaml --export > m2.yaml
Pod是K8S系统中可以创建、管理的最小单元,是资源对象模型中由用户创建/部署的最小资源对象模型,也是在K8S上运行容器化应用的资源对象,其他资源对象都是用来支撑/扩展Pod对象功能的,比如Controller对象是用来管控Pod对象的,Service/Ingress资源对象是用来暴露Pod引用对象的,Persistent Volumn 资源对象是用来为Pod提供存储等等,K8S不会直接处理容器,而是Pod。Pod是由一个/多个container组成。
Pod是 Kubernetes 的最重要概念,每一个Pod都有一个特殊的被称为 “根容器” 的 Pause容器。Pause容器对应的镜像属于 Kubernetes 平台的一部分,除了Pause容器,每个Pod还包含一个/多个紧密相关的用户业务容器。
特点总结:
存在意义:
ps -ef
),一个容器运行一个应用程序(单进程+守护进程)Pod 两大实现机制:
容器本身之间相互隔离
前提条件:容器在同一个namespace中
实现机制:
通过Pause容器,把其他业务容器加入Pause容器,让所有容器在同一个namespace中,实现网络共享。
Pod持久化操作:
引入数据卷概念Volumn,使用数据卷进行持久化存储。
Pod镜像拉取策略 imagePullPolicy:
IfNotPresent:镜像在宿主机上不存在时才拉取(默认)
Always:每次创建Pod都会重新拉取一次镜像
Never:Pod永远不会主动拉取这个镜像
示例:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx:1.14
imagePullPolicy: Always
# Pod镜像拉取策略-imagePullPolicy
# IfNotPresent:默认值,镜像在宿主机上不存在时才拉取
# Always:每次创建Pod都会重新拉取一次镜像
# Never:Pod永远不会主动拉取这个镜像
示例:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests: # 资源请求(调度)
memory: "64Mi"
cpu: "250m"
limits: # 资源限制(最大)
memory: "128Mi"
cpu: "500m"
Pod和Container的资源请求和限制:
CPU资源举例解释:设 1c=1000m,则0.25c=250m、0.5=500m
Pod重启机制 restartPolicy:
Always:当容器终止退出后,总是重启容器(默认)
OnFailure:当容器异常退出(退出状态码非0)时,才重启容器
Never:当容器终止退出,从不重启容器
示例:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox:1.28.4
args:
- /bin/sh
- -c
- sleep 36000
restartPolicy: Never
# Pod重启机制-restartPolicy
# Always:当容器终止退出后,总是重启容器,默认策略
# OnFailure:当容器异常退出(退出状态码非0)时,才重启容器
# Never:当容器终止退出,从不重启容器
应用层面健康检查:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy
livenessProbe:
exec:
command:
- cat
- /temp/healthy
initialDelaySeconds: 5
periodSeconds: 5
健康检查策略:
livenessProbe(存活检查)
如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。
readinessPribe(就绪检查)
如果检查失败,Kubernetes会把Pod从service endpoints中剔除。
Porbe支持的检查方法:
httpGet
发送HTTP请求,返回200~400范围状态码为成功。
exec
执行shell命令返回状态码是0为成功。
echo $?
查看状态码为0;删除文件后,通过echo $?
查看状态码为1。tcpSocket
发起TCP Socket建立成功
master节点:
createpod – apiserver – etcd
scheduler – apiserver – etcd – 调度算法, 将Pod调度到Node节点
node节点:
影响调度的属性:
Pod资源限制
根据request找到足够node节点进行调度。
节点选择器nodeSelector标签
(对节点创建标签:kubectl label [node_name] env_role=dev
)
apiVersion: v1
kind: Pod
metadata:
name: pod-example
spec:
nodeSelector:
env_role: dev
containers:
- name: nginx
image: nginx:1.15
节点亲和性nodeAffinity标签
与nodeSelector基本一样,根据节点上标签的约束来决定Pod调度到哪些节点上,但功能更加强大。
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoreDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: evn_role
operator: In
values:
- dev
- test
preferredDuringSchedulingIgnoreDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: group
operator: In
values:
- otherprod
containers:
- name: webdemo
image: nginx
支持常用操作符operator:In、NotIn(反亲和性)、Exists、Gt、Lt、DoesNotExists(反亲和性)
污点&污点容忍
基本介绍:
场景:
具体演示:
查看节点污点情况:kubectl describe node [node_name] | grep Taint
污点值(taint_value)有三个:
为节点添加污点 (key, value自定义):kubectl taint node [node_name] key=value:[taint_value]
为节点删除污点 (key, value自定义):kubectl taint node [node_name] key=value-
污点容忍tolerations : 可能被调度 (部分YAML) :
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: webdemo
image: nginx
Pod通过Controller实现应用的运维
(如:伸缩、滚动升级 等)
Pod与Controller之间通过 label标签 建立关系
应用场景:Web服务、微服务
kubectl create deployment web --image=nginx --dry-run -o yaml > web.yaml
kubectl apply -f web.yaml
;并查看状态:kubectl get pods
kubectl expose deployment [app_name] --port=80 --type=NodePort --target-port=80 --name=[app_name]
升级应用至某指定版本:
kubectl set image deployment web [the_name]=[image_name]:[version_number]
# 举例
kubectl set image deployment web nginx=nginx:1.15
查看升级状态:
查看应用升级历史版本:
回滚至上一个版本:
kubectl rollout undo deployment web
查看回滚状态:
kubectl rollout status deployment web
回滚到指定版本(eg. 1):
kubectl rollout undo deployment web --to-revision=1
提供更多服务:
kubectl scale deployment web --replicas=10
查看新增9个副本:
YAML示例:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: nginx
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Deployment 和 StatefulSet区别:有身份(唯一标识):
nginx-statfulset-0.nginx.default.svc.cluster.local
部署守护进程DeamonSet
YAML示例:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-test
labels:
app: filebeat
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
containers:
- name: logs
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: varlog
mountPath: /tmp/log
volumes:
- name: varlog
hostPath:
path: /var/log
创建成功:
进入其中一个Pod (kubectl exec -it [pod_name] bash
),查看日志文件:
YAML示例:
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 create -f pi.yaml
):
计算完成:
通过日志(kubectl logs pi-gxztq
),查看计算结果:
通过删除K8S中缓存的yaml文件,移除一次性任务:
YAML示例:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
创建成功:
已成功运行一次:
通过日志,查看运行结果:
每隔一段时间执行一次,出现一个Pod (Complated):
删除K8S缓存yaml配置,移除定时任务:
根据 label 和 selector 标签建立关联
通过Service实现Pod的负载均衡,每个Service拥有一个 虚拟IP(Virtual IP),借助Service访问一组Pod通过虚拟IP访问。
ClusterIP:集群内部访问
NodePort:对外访问应用使用
LoadBalancer:对外访问应用使用 / 用于公有云
ExternalName:将服务映射到 DNS 名称,而非典型的选择器(需追加属性externalName)
type: ExternalName
externalName: [external_name]
使用kubectl expose deployment web --port=80 --target-port=80 --dry-run -o yaml > service.yaml
导出web的svc(Service)配置,并进行修改:
使用命令kubectl apply -f service.yaml
执行(若已自动生成svc, 可手动删除替换),创建Service:
从其他节点内部访问curl [ip_address]
:
更改名称并更改类型为NodePort:
创建成功,检查类型:
内部访问成功:
Node在内网进行部署,外网一般不能访问到:
作用:加密数据存在etcd中,让Pod容器以挂载 变量/Volume(数据卷) 方式进行访问
场景:凭证
echo -n [target_str] | base64
)创建Secrete加密数据(用户名密码已用base64加密, 命令kubectl create -f secret.yaml
)
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
以变量形式挂载到Pod容器中
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
以Volume(数据卷)形式挂载到Pod容器中
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
作用:存储不加密数据到etcd中,让Pod以变量或Volume数据卷形式挂载到容器中
场景:配置文件 (IP / 端口号 / 用户名)
创建配置文件(如:Redis配置文件)
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
创建configMap (命令:kubectl create configmap redis-config --from-file=redis.properties
)
查看所有kubectl get configmap
或kubectl get cm
,查看详细信息kubectl describe cm redis-config
以Volume挂载到Pod容器(cm.yaml)
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh","-c","cat /etc/config/redis.properties" ]
volumeMounts:
- name: config-volume
mountPath: "/etc/config"
volumes:
- name: config-volume
configMap:
name: redis-config
restartPolicy: Never
以变量形式挂载到Pod容器(myconfig.yaml)
① 创建yaml,声明变量信息 configmap 创建 kubectl apply -f myconfig.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfig
namespace: default
data:
special.level: info
special.type: hello
② 以变量挂载(config-var.yaml)
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh","-c","echo $(LEVEL) $(TYPE)" ]
env:
- name: LEVEL
valueFrom:
configMapKeyRef:
name: myconfig
key: special.level
- name: TYPE
valueFrom:
configMapKeyRef:
name: myconfig
key: special.type
restartPolicy: Never
通过日志查看输出:
基于角色的访问控制
kubectl get ns
)创建命名空间
在新创建的命名空间创建一个Pod
创建角色(rbac-role.yaml)
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: roledemo
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
查看角色:
创建角色绑定(rbac-rolebinding.yaml)
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: roledemo
name: read-pods
subjects:
- kind: User
name: lucy # Name is case sensive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # This must be Role or ClusterRole
name: pod-reader # This must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
使用证书识别身份(二进制搭建集群)
cat > lucy-csr.json << EOF
{
"CN": "lucy",
"host": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes lucy-csr.json | cfssljson -bare lucy
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.1.1.36:6443 \
--kubeconfig=lucy-kubeconfig
kubectl config set-certificate lucy \
--client-key=lucy-key.pem \
--client.certificate=lucy.pem \
--embed-certs=true \
--kubeconfig=lucy-kubeconfig
kubectl config set-context lucy \
--cluster=kubernetes \
--user=lucy \
--kubeconfig=lucy-kubeconfig
kubectl config use-context default --kubeconfig=lucy-kubeconfig
把端口号对外暴露,通过IP+端口号进行访问
NodePort缺陷
Ingress和Pod关系
Ingress工作流程
使用Ingress
创建nginx-pod应用,对外暴露端口使用NodePort
部署 Ingress Controller
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "-"
# Here: "-"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
hostNetwork: true
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: lizhenliang/nginx-ingress-controller:0.30.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 101
runAsUser: 101
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
---
apiVersion: v1
kind: LimitRange
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
limits:
- min:
memory: 90Mi
cpu: 100m
type: Container
创建ingress规则
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.ingredemo.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
在windows系统host文件(C:\Windows\System32\drivers\etc\hosts
)中添加域名访问规则后,并访问
此前部署应用的过程:
如果使用此前的方式 部署 单一应用/少数服务的应用 比较合适。
部署微服务项目,可能会有几十个服务,每个服务都有一套yaml文件,需要维护大量yaml文件,版本管理不方便。
使用helm可以解决哪些问题?
Helm介绍:
Helm是个Kubernetes的包管理工具,就想Linux下的包管理器,如yum/apt等,可以很方便的将之前打包好的yaml文件部署到kubernetes上。
Helm3个重要概念:
Helm v3 (2019) 版本变化:架构变化
/usr/bin
目录下。添加仓库 helm repo add [repo_name] [repo_address]
helm repo add stable http://mirror.azune.cn/kubernetes/charts/
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo update
查看仓库 helm repo list
更新仓库地址 helm repo update
删除仓库 helm repo remove [repo_name]
使用命令搜索应用: helm search repo [key_word]
根据搜索内容选择安装:helm install [name] [app_name]
查看安装后状态:helm list
或helm status [name]
使其可从外部访问:修改Service的yaml文件,type改为NodePort(kubectl edit svc ui-weave-scope
)
自定义Chart完成部署:
使用命令创建chart:helm create chart [chart_name]
在templates文件夹创建两个yaml文件
kubectl create deployment web1 --image=nginx --dry-run -o yaml > deployment.yaml
)kubectl expose deployment web1 --port=80 --target-port=80 --type=NodePort --dry-run -o yaml > service.yaml
)安装mychart
应用升级:helm upgrade [chart_name] [chart_dir]
实现yaml高效复用:
在具体yaml文件,获取使用定义变量值(格式:{{ .Values.[var_name]}}
;动态生成名称:{{ .Release.Name}}
)
deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name}}-dep
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.label}}
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: {{ .Values.label}}
spec:
containers:
- image: {{ .Values.image}}
name: nginx
resources: {}
status: {}
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name}}-svc
spec:
ports:
- port: {{ .Values.port}}
protocol: TCP
targetPort: 80
selector:
app: {{ .Values.label}}
type: NodePort
status:
loadBalancer: {}
使用helm install --dry-run web2 mychart/
命令查看生成yaml,验证结果,直接安装也可验证:
数据卷 empty dir,为本地存储。pod重启后,数据不存在,需对数据持久化存储。
nfs 网络存储
pod重启数据,仍存在。
找一台服务器作为nfs服务端,安装nfs(yum install -y nfs-utils
)
nfs服务端设置挂载路径:
vim /etc/exports
# 写入信息:
*(rw,no_root_squash)
nfs服务端创建挂载路径:
mkdir /data/nfs
在k8s集群node节点安装nfs(yum install -y nfs-utils
)
在nfs服务端启动nfs服务
在ks集群部署应用使用nfs网络持久存储
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep1
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
nfs:
server: 192.168.1.139 # nfs server ip
path: /data/nfs
在nfs服务器目录创建文件后,进入容器 寻找/usr/share/nginx/html
目录内主页信息,查看文件是否读取。
创建Service-NodePort,在浏览器查看主页信息是否发生变化。
PV
持久化存储,对存储资源进行抽象,对外提供一个可以调用的地方。
PVC
用于调用,不需要关心内部实现细节。
实现流程
应用部署
定义PVC(绑定PV)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep1
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim:
claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
定义PV(数据存储服务器IP、路径;定义存储容量storage、匹配模式accessModes-RW)
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /k8s/nfs
server: 192.168.1.139
组件: prometheus + Grafana
prometheus
Grafana:
开源
数据分析、可视化工具
支持多种数据源
部署守护进程 node.exporter.yaml(kubectl create -f node-exporter.yaml
):
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: kube-system
labels:
k8s-app: node-exporter
spec:
selector:
matchLabels:
k8s-app: node-exporter
template:
metadata:
labels:
k8s-app: node-exporter
spec:
containers:
- image: prom/node-exporter
name: node-exporter
ports:
- containerPort: 9100
protocol: TCP
name: http
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: node-exporter
name: node-exporter
namespace: kube-system
spec:
ports:
- name: http
port: 9100
nodePort: 31672
protocol: TCP
type: NodePort
selector:
k8s-app: node-exporter
部署 prometheus:
rbac-setup.yaml(kubectl create -f rbac-setup.yaml
):
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/proxy
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups:
- extensions
resources:
- ingresses
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: kube-system
configMap.yaml(kubectl create -f configMap.yaml
):
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: kube-system
data:
prometheus.yml: |
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'kubernetes-apiservers'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'kubernetes-nodes'
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics
- job_name: 'kubernetes-cadvisor'
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name
- job_name: 'kubernetes-services'
kubernetes_sd_configs:
- role: service
metrics_path: /probe
params:
module: [http_2xx]
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
action: keep
regex: true
- source_labels: [__address__]
target_label: __param_target
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
target_label: kubernetes_name
- job_name: 'kubernetes-ingresses'
kubernetes_sd_configs:
- role: ingress
relabel_configs:
- source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe]
action: keep
regex: true
- source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
regex: (.+);(.+);(.+)
replacement: ${1}://${2}${3}
target_label: __param_target
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance
- action: labelmap
regex: __meta_kubernetes_ingress_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_ingress_name]
target_label: kubernetes_name
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
prometheus.deploy.yaml(kubectl create -f prometheus.deploy.yaml
):
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: prometheus-deployment
name: prometheus
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
containers:
- image: prom/prometheus:v2.0.0
name: prometheus
command:
- "/bin/prometheus"
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention=24h"
ports:
- containerPort: 9090
protocol: TCP
volumeMounts:
- mountPath: "/prometheus"
name: data
- mountPath: "/etc/prometheus"
name: config-volume
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 500m
memory: 2500Mi
serviceAccountName: prometheus
volumes:
- name: data
emptyDir: {}
- name: config-volume
configMap:
name: prometheus-config
prometheus.svc.yaml(kubectl create -f prometheus.svc.yaml
):
---
kind: Service
apiVersion: v1
metadata:
labels:
app: prometheus
name: prometheus
namespace: kube-system
spec:
type: NodePort
ports:
- port: 9090
targetPort: 9090
nodePort: 30003
selector:
app: prometheus
部署 Grafana
grafana-deploy.yaml(kubectl create -f grafana-deploy.yaml
)
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana-core
namespace: kube-system
labels:
app: grafana
component: core
spec:
replicas: 1
selector:
matchLabels:
app: grafana
component: core
template:
metadata:
labels:
app: grafana
component: core
spec:
containers:
- image: grafana/grafana:4.2.0
name: grafana-core
imagePullPolicy: IfNotPresent
# env:
resources:
# keep request = limit to keep this container in guaranteed class
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
env:
# The following env variables set up basic auth twith the default admin user and admin password.
- name: GF_AUTH_BASIC_ENABLED
value: "true"
- name: GF_AUTH_ANONYMOUS_ENABLED
value: "false"
# - name: GF_AUTH_ANONYMOUS_ORG_ROLE
# value: Admin
# does not really work, because of template variables in exported dashboards:
# - name: GF_DASHBOARDS_JSON_ENABLED
# value: "true"
readinessProbe:
httpGet:
path: /login
port: 3000
# initialDelaySeconds: 30
# timeoutSeconds: 1
volumeMounts:
- name: grafana-persistent-storage
mountPath: /var
volumes:
- name: grafana-persistent-storage
emptyDir: {}
grafana-ing.yaml(kubectl create -f grafana-ing.yaml
)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: grafana
namespace: kube-system
spec:
rules:
- host: k8s.grafana
http:
paths:
- path: /
backend:
serviceName: grafana
servicePort: 3000
grafana-svc.yaml(kubectl create -f grafana-svc.yaml
)
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: kube-system
labels:
app: grafana
component: core
spec:
type: NodePort
ports:
- port: 3000
selector:
app: grafana
component: core
打开Grafana,配置数据源,导入显示模板。