- 第11章 Kubernetes核心概念
- 11.1 Kubernetes 对象
- 逻辑层次
- 11.2 集群资源管理
- 11.2.0 Node
- 11.2.1 Namespace
- 11.2.1.1 案例:Namespace操作
- 11.2.2 Label
- 11.2.2.1 案例一: 设置容器 Label
- 11.2.2.2 案例二: 设置Node Label
- 11.3 容器控制器 Pod
- 11.3.1 Pod (容器控制器)
- 11.3.1.1 案例一:创建Nginx Pod
- 11.3.2 ReplicationController与ReplicaSet (容器控制器)
- 11.3.2.1 案例一: 创建ReplicationController
- 11.3.4 调整RC Pod 数量
- 11.3.2.2 案例二: 创建ReplicaSet
- 11.3.3 Deployment
- 11.3.3 Pod 升级策略与检测机制
- 11.3.3.1 升级策略:
- 11.3.3.2 pod 启动与存活机制
- 11.3.3.3 案例一: 创建Deployment
- 扩容
- 11.3.4 DaemonSet(容器控制器)
- 11.3.4.1 案例一: 创建DaemonSet
- 11.3.5 StatefulSet
- 11.3.5.1 案例一:StatefulSet组建Elasticsearch 集群
- 11.3.6 POD基本操作
- 11.3.7 POD弹性伸缩
- 11.3.8 POD的管理方式
- 11.3.9 pod 状态信息
- 11.3.9.1 查看pod 运行状态
- 1.3.9.2 POD重启策略
- 1.3.9.2.1 配置pod重启策略
- 11.4 镜像策略
- 11.4.1 案例一: 配置镜像拉取策略
- 11.5 定时任务
- 11.5.1 Job
- 11.5.1.1 案例一: Job
- 11.5.2 CronJob
- 11.5.2.1 案例一: 创建定时任务#定时清理数据
- 11.6 服务发现
- 11.6.1 Service
- 11.6.1.1 案例一: 定义服务的Service
- 11.6.2 Service 网络代理模式
- 11.6.2.1 案例一: Node启用IPVS
- 11.6.2.2案例二: 通过IPVS 访问服务
- 11.6.3 Service服务类型
- 11.6.4 Service 端口类型
- 11.6.5 访问Service方式
- 11.7 DNS
- 11.7.1 案例一: 通过Service名称访问服务
- 11.8 存储- Secret
- 11.8.1 案例一: 导入Docker Registry认证信息
- 11.9 基于角色的访问控制- RBAC
- 11.9.1 RABC 可操作资源列表
- 11.9.2 资源列表可操作的权限列表
- 11.9.3 RBAC中的其他对象
- 11.9.3.1 授权角色绑定图解
- 11.9.4 案例一:创建登录Dashboard的用户
- 11.9.5 案例二:创建一个不受限制的SA账号, 用于集群内部的认证
- 11.9.6 案例三: RBAC之Yaml授权文件讲解
- 11.9.7 案例四: 实际操作授权命令操作
- 11.10 Yaml 文件详解
- 11.10.0 Yaml 是什么?
- 11.10.1 YAML语法规则
- 11.10.2 Yaml结构类型图解
- 11.10.3 Kubernetes
- 11.10.4 案例一: Kubernetes pod编排文件讲解
- 11.10.5 案例二: Kubernetes deployment运行
- 11.10.6 案例三: Kubernetes Services 运行
- 11.11 ConfigMap
- 11.11.1 案例一: 将ConfigMap中的所有键值对配置为容器环境变量
- 11.11.2 案例二: 将 ConfigMap 数据添加到容器中的特定路径
- 11.11.3 案例三: 将ConfigMap中的所有键值对配置为容器环境变量
在上章完成基本的部署之后,但是对Kubernetes的组件还不能完全理解, 尤其是各个组件的有哪些特征,用到什么位置, 都不是很明确。所以本章节会详细讲解各个组件的核心概念。
11.1 Kubernetes 对象- 服务网络访问: Ingress、Services
- 容器管理类型: Deployment、ReplicaSet、 ReplicationController、DaemonSet、StatefulSet
- 容器存储类型: Volume、Secret、ConfigMap、PersistentVolume
Node是kubernetes集群的工作节点,可以是物理机也可以是虚拟机。
11.2.1 Namespace节省资源的一种逻辑隔离技术。
Namespace类似于Linux系统中用户的概念,通过将系统内部的对象分配到不同的Namespace 中,形成逻辑上的区分,便于不同的分组在共享集群资源的同时还能被分别管理。
同一Namespace下的 Kubernetes 对象的Name必须唯一。
命名空间为名称提供了一个范围。 资源的名称需要在命名空间内是唯一的,但不能跨命名空间。命名空间不能嵌套在另外一个命名空间内,而且每个 Kubernetes 资源只能属于一个命名空间。
默认情况下,Kubernetes 集群会在配置集群时实例化一个默认命名空间default,用以存放集群所使用的默认 Pods、Services 和 Deployments 集合。
注意: 不需要使用多个命名空间来分隔轻微的且不同的资源,比如同一项目的不同发行版本。
11.2.1.1 案例:Namespace操作创建NS
[root@master-1 ~]# kubectl create namespace ns-system
通过Yaml 文件创建 test-ns.yaml
[root@master-1 test]# cat test-ns.yaml apiVersion: v1 kind: Namespace metadata: name: test-ns
查看NS列表
[root@master-1 ns]# kubectl apply -f test-ns.yaml namespace/test-ns created [root@master-1 ns]# kubectl get namespace NAME STATUS AGE default Active 4d2h kube-node-lease Active 4d2h kube-public Active 4d2h kube-system Active 4d2h kubernetes-dashboard Active 3d21h monitoring Active 3d6h test-ns Active 7s
查看ns详细信息
[root@master-1 ns]# kubectl describe namespace/test-ns Name: test-ns Labels:Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"test-ns"}} Status: Active No resource quota. No resource limits.
NS与Service(10.0.0.0/8)关系
- 创建 Service 时,它会创建相应的 DNS记录。
- 此记录的格式为
. .svc.cluster.local,这意味着如果容器只使用 ,它将解析为本地服务到命名空间(default)。 - 如果要跨命名空间访问, 则需要使用完全限定的域名(FQDN)。
#dns 解析的名称是 svc (service 名称, 非 pod 名称) dnstools# nslookup nginx Server: 10.0.0.2 Address: 10.0.0.2#53 Name:nginx.default.svc.cluster.local Address: 10.0.0.55
非默认的default, 需要写全名 nginx-n1.kube-system
dnstools# nslookup nginx-n1 Server: 10.0.0.2 Address: 10.0 0.2#53 ** server can't find nginx-n1: NXDOMAIN dnstools# nslookup nginx-n1 Server: 10.0.0.2 Address: 10.0 0.2#53 #解决方法(默认解析为 default 空间) dnstools# nslookup nginx-n1.kube-system.svc.cluster.local Server: 10.0.0.2 Address: 10.0 0.2#53 Name: nginx-n1.kube-system.svc.cluster.local Address: 10.0.0.19611.2.2 Label
Label 机制是Kubernetes 中的一个重要设计,通过Label 进行对象(pod,service,node)的关联,可以灵活地进行分类和选择。
对于Pod而言,需要设置其自身的Label 来进行标识,
Label 是一系列的 Key/value 对,在Pod–>metadata–>labels 中进行设置。Label 的定义是任一的,但是Label 必须具有可标识性,比如设置Pod 的应用名称和版本号等。另外Lable 是不具有唯一性的,为了更准确的标识一个Pod,应该为Pod设置多个维度的label。如下:
- "release" : "stable", "release" : "canary"
- "environment" : "dev", "environment" : "uat", "environment" : "production"
- "partition" : "customerA", "partition" : "customerB"
在 Job、Deployment、ReplicaSet 和DaemonSet 中,通常在容器中使用 metadata.labels字段,来为对象添加 Label, 例如:
配置标签
[root@master-1 ingress]# cat traefik-deploy.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: traefik-ingress-controller
labels:
app: traefik
查看标签
[root@master-1 ingress]# kubectl describe pod traefik-ingress-controller
Name: traefik-ingress-controller-4cn9t
Namespace: default
Priority: 0
Node: 192.168.91.21/192.168.91.21
Start Time: Sat, 18 Apr 2020 16:02:08 +0800
Labels: app=traefik
controller-revision-hash=846985d876
pod-template-generation=4
界面查看
11.2.2.2 案例二: 设置Node Label设置Node的label标签为IngressProxy=true
[root@master-1 ingress]# kubectl label nodes 192.168.31.7 IngressProxy=true
检查是否成功
[root@master-1 ~]# kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS 192.168.31.7 Ready4d1h v1.15.1 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.7,kubernetes.io/os=linux 192.168.31.8 Ready 4d1h v1.15.1 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.8,kubernetes.io/os=linux [root@master-1 ~]# kubectl get nodes -l IngressProxy=true NAME STATUS ROLES AGE VERSION 192.168.31.7 Ready 4d1h v1.15.1 192.168.31.8 Ready 4d1h v1.15.1
[root@master-1 ~]# kubectl label nodes 192.168.31.7 isNode=true node/192.168.31.7 labeled [root@master-1 ~]# kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS 192.168.31.7 Ready11.3 容器控制器 Pod 11.3.1 Pod (容器控制器)4d1h v1.15.1 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,isNode=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.7,kubernetes.io/os=linux 192.168.31.8 Ready 4d1h v1.15.1 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.8,kubernetes.io/os=linux [root@master-1 ~]# kubectl get nodes -l isNode=true NAME STATUS ROLES AGE VERSION 192.168.31.7 Ready 4d1h v1.15.1
Pod 是Kubernetes的基本操作的最小单元,也是应用运行的载体。
整个Kubernetes系统都是围绕着Pod 展开的; 比如:如何部署运行Pod、如何保证Pod的数量、如何访问Pod 等。
可以将 Pod 看作单个容器的包装,并且 Kubernetes 直接管理 Pod,而不是容器。
11.3.1.1 案例一:创建Nginx Pod当kubectl delete操作无效时可以尝试下面几个步骤来排查原因:
- 检查是否创建了deployments任务:kubectl get deployments
- 检查是否创建了副本控制器 ReplicationController:kubectl get rc
- 检查死否创建了副本集 replicasets:kubectl get rs
如果有,先执行kubectl delete deployment|rc|rs $name后在执行kubectl delete pod $pod_name方可真正实现删除目的。
删除之前的nginx pod
[root@master-1 ~]# kubectl delete deployment nginx-demo [root@master-1 ~]# kubectl delete rs nginx-demo-68749b58dc [root@master-1 ~]# kubectl delete rc nginx-demo-68749b58dc-xzk5c [root@master-1 ~]# kubectl delete pods nginx-demo [root@master-1 ~]# kubectl delete svc nginx-demo-svc
[root@master-1 nginx]# cat nginx.yaml
apiVersion: v1 #pod 接口
kind: Pod #控制器名称 pod
metadata:
name: nginx #pod 名称
labels:
app: nginx #pod 标签 app=nginx
spec:
containers:
- name: nginx #容器名称
image: nginx #镜像名称
ports:
- containerPort: 80 #容器端口
hostPort: 3000 #node 端口
运行
[root@master-1 nginx]# kubectl apply -f nginx.yaml pod/nginx created
查看运行状态
[root@master-1 nginx]# kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Node: 192.168.31.7/192.168.31.7
Start Time: Mon, 10 Aug 2020 17:55:55 +0800
Labels: app=nginx
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"nginx"},"name":"nginx","namespace":"default"},"spec":{"conta...
Status: Pending
IP:
Containers:
nginx:
Container ID:
Image: nginx
Image ID:
Port: 80/TCP
Host Port: 3000/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-7rdlr (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-7rdlr:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-7rdlr
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10s default-scheduler Successfully assigned default/nginx to 192.168.31.7
Normal Pulling 9s kubelet, 192.168.31.7 Pulling image "nginx"
11.3.2 ReplicationController与ReplicaSet (容器控制器)
ReplicationController用来确保容器应用的副本数始终保持在用户定义的副本数(容器数 量),即如果有容器异常退出,会自动创建新的Pod 来替代;而如果异常多出来的容器也会自动回收。
在新版本的 Kubernetes 中建议使用ReplicaSet来取代ReplicationController。ReplicaSet跟ReplicationController没有本质的不同,名称不同,并且ReplicaSet支持集合式(多标签选择)的selector。
11.3.2.1 案例一: 创建ReplicationController- 通过template.metadata.labels字段为即将新建的Pod附加Label, 即为app=nginx
- 通过spec.selector字段来指定这个RC管理哪些Pod
[root@master-1 nginx-rc]# cat nginx-rc.yaml
apiVersion: v1
kind: ReplicationController #容器控制器 RC
metadata:
name: nginx-rc #RC 名称
spec:
replicas: 1 #副本数 1
selector:
app: nginx-rc #控制器选择 app=nginx-rc (label)
template:
metadata:
labels:
app: nginx-rc #模板的 label: app=nginx
spec:
containers:
- name: nginx-rc #容器名称
image: nginx #镜像名称
ports:
- containerPort: 80 #容器端口
部署RC
[root@master-1 nginx]# kubectl apply -f nginx-rc.yaml replicationcontroller/nginx-rc created
查看状态
[root@master-1 nginx]# kubectl get rc
NAME DESIRED CURRENT READY AGE
nginx-rc 1 1 1 94s
[root@master-1 nginx]# kubectl describe rc nginx-rc
Name: nginx-rc
Namespace: default
Selector: app=nginx-rc
Labels: app=nginx-rc
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"ReplicationController","metadata":{"annotations":{},"name":"nginx-rc","namespace":"default"},"spec":{"replicas"...
Replicas: 1 current / 1 desired
Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx-rc
Containers:
nginx-rc:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment:
Mounts:
Volumes:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 2m1s replication-controller Created pod: nginx-rc-2rf4q
访问测试
[root@master-1 ~]# kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools dnstools# curl 172.17.98.1311.3.4 调整RC Pod 数量
[root@master-1 nginx]# kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-6d6f7ff69f-bk95b 1/1 Running 1 3d7h nginx 1/1 Running 0 13m nginx-rc-2rf4q 1/1 Running 0 4m8s [root@master-1 nginx]# kubectl scale rc nginx-rc --replicas=3 replicationcontroller/nginx-rc scaled [root@master-1 nginx]# kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-6d6f7ff69f-bk95b 1/1 Running 1 3d7h nginx 1/1 Running 0 15m nginx-rc-2rf4q 1/1 Running 0 5m17s nginx-rc-dvgqb 0/1 ContainerCreating 0 27s nginx-rc-gmddb 0/1 ContainerCreating 0 27s
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5s7z2vRL-1634538453109)(assets/CA49DA8A169A40A7B3A598161165D374.png)]
pod 不支持扩容(命令扩容)
[root@master-1 nginx]# kubectl scale pod nginx --replicas=2 error: could not find proper group-version for scale subresource of /v1, Resource=pods: could not find scale subresource for /v1, Resource=pods in discovery information
pod 不支持扩容(yaml)
[root@master-1 nginx1]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx #pod 名称
labels: #label 标签
app: nginx #定义 pod 的 label: app=nginx
spec:
replicas: 2 # 容器数量
containers:
- name: nginx #容器名称
image: nginx #镜像名称
ports:
- containerPort: 80 #容器端口
hostPort: 3000 #node 接口端口
出现错误,接口不支持replicas
[root@master-1 nginx]# kubectl apply -f nginx.yaml error: error validating "nginx.yaml": error validating data: ValidationError(Pod.spec): unknown field "replicas" in io.k8s.api.core.v1.PodSpec; if you choose to ignore these errors, turn validation off with --validate=false11.3.2.2 案例二: 创建ReplicaSet
- selector除了可以使用matchLabels,还支持集合式的操作。
- 通过修改.spec.replicas的值可以实时修改RS运行的Pod数量。
- 镜像下载有问题
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
matchexpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels: #定义多个 Label
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
env:
-name: GET_HOSTS_FROM
value: dns
ports:
-containerPort: 80
查看是否启动成功
[root@master-1 ~]# kubectl describe rs/frontend11.3.3 Deployment
Deployment同样为Kubernetes的一个核心内容,主要职责同样是为了保证pod的数量和健康,90% 的功能与Replication Controller完全一样,可以看做新一代的Replication Controller。但是,它又具备了Replication Controller之外的新特性:
- Deployment继承了上面描述的Replication Controller(副本数保持与扩容)全部功能。
- 容器在升级或者创建的过程中,可以查看详细进度和状态。
- 当升级pod镜像或者相关参数的过程中,如果出现问题,可以使用回滚操作回滚到上一个版本或者指定的版本。
- 每一次对Deployment的操作,都能保存下来(有操作记录),便于之后的回滚.
- 每一次pod升级,都能够随时暂停和启动(容易控制)。
- pod多种升级方案:
- Recreate:删除所有已存在的pod,重新创建新的;
- RollingUpdate:滚动升级,逐步替换的策略,同时滚动升级时,支持更多的附加参数,例如设置最大不可用pod数量,最小升级间隔时间等等。
容器控制器创建pod流程
- 使用Deployment来创建ReplicaSet, ReplicaSet则在在后台创建pod; 检查pod启动状态,是否成功。
- 通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。之后会创建一个新的ReplicaSet,
Deployment会按照默认的更新策略(RollingUpdate 所需副本数的25%, 生产建议配置为:1) 先启动新的ReplicaSet. - 如果新的ReplicaSet启动失败(检查端口策略), 则旧的ReplicaSet还会继续存在。
- 如果扩容成功, 则会清理掉旧的ReplicaSet
系统查看Deployment
[root@master-1 ~]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE nfs-client-provisioner 1/1 1 1 3d9h redis-tcp 1/1 1 1 96s
查看Deployment详细信息
[root@master-1 ~]# kubectl describe pod redis-tcp
Name: redis-tcp-5fcb54cd64-52p4d
Namespace: default
Priority: 0
Node: 192.168.31.7/192.168.31.7
Start Time: Mon, 10 Aug 2020 19:54:01 +0800
Labels: app=redis-tcp
pod-template-hash=5fcb54cd64
Annotations:
Status: Running
IP: 172.17.14.13
Controlled By: ReplicaSet/redis-tcp-5fcb54cd64
Containers:
redis-tcp:
Container ID: docker://bafe30e1911b6a4ae80aca46cbd240d693e7ab7bf2ffb3e9c3a38f582712aacc
Image: redis
Image ID: docker-pullable://redis@sha256:09c33840ec47815dc0351f1eca3befe741d7105b3e95bc8fdb9a7e4985b9e1e5
Port: 6379/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 10 Aug 2020 19:55:26 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-7rdlr (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-7rdlr:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-7rdlr
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulling 118s kubelet, 192.168.31.7 Pulling image "redis"
Normal Scheduled 117s default-scheduler Successfully assigned default/redis-tcp-5fcb54cd64-52p4d to 192.168.31.7
Normal Pulled 33s kubelet, 192.168.31.7 Successfully pulled image "redis"
Normal Created 33s kubelet, 192.168.31.7 Created container redis-tcp
Normal Started 33s kubelet, 192.168.31.7 Started container redis-tcp
11.3.3 Pod 升级策略与检测机制
11.3.3.1 升级策略:
strategy:
type: RollingUpdate #默认更新策略Deployment
rollingUpdate:
maxSurge: 1 # Pod的总数最多比所需的Pod数多1个
maxUnavailable: 1 # 更新过程中最多1个不可用Pod数
11.3.3.2 pod 启动与存活机制
pod 就绪探测 (Deployment控制器)
readinessProbe: #来确定容器是否已经启动正常
tcpSocket:
port: 8080 #检查端口
initialDelaySeconds: 5 # kubelet 会在容器启动 5 秒后发送第一个就绪探测
periodSeconds: 10 #每 10 秒执行一次存活探测
如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。
pod 存活探测 (Deployment控制器)
livenessProbe: #存活探测
tcpSocket:
port: 8080
initialDelaySeconds: 15 #kubelet 会在容器启动 15 秒后进行第一次存活探测
periodSeconds: 20 #每10秒执行一次存活探测
与就绪探测一样,Kubelet会尝试连接容器的 8080 端口。如果存活探测失败,这个容器会被重新启动。
11.3.3.3 案例一: 创建Deployment[root@master-1 demo]# cat nginx-deployment.yaml
apiVersion: apps/v1 #控制器接口版本
kind: Deployment #控制器类型
metadata:
name: nginx-deployment # Deployment 控制器名称
labels:
app: nginx-deployment # Deployment 控制器标签
spec:
replicas: 3 # Deployment 副本数(容器数量)
selector:
matchLabels:
app: nginx-deployment #标签选择器
minReadySeconds: 1 #pod 准备时间
strategy:
type: RollingUpdate #pod 升级策略
rollingUpdate:
maxSurge: 1 #最大允许 1 个pod 升级
maxUnavailable: 1 #最多允许 1 个pod 失效
template:
metadata:
labels:
app: nginx-deployment #模板标签
spec:
containers:
- name: nginx-deployment #容器名称
image: nginx:latest #镜像名称
ports:
- containerPort: 80 #容器端口
readinessProbe: #容器就绪检测
tcpSocket:
port: 80 #检测端口
initialDelaySeconds: 5 #容器启动之后 5 秒检测
periodSeconds: 10 #容器初始化之后每隔 10 秒检测
部署
[root@master-1 deployment]# kubectl apply -f nginx-deployment.yaml deployment.apps/nginx-deployment created
界面查看更新策略
查看状态
[root@master-1 deployment]# kubectl get pods -w NAME READY STATUS RESTARTS AGE nfs-client-provisioner-6d6f7ff69f-bk95b 1/1 Running 2 3d9h nginx 1/1 Running 1 140m nginx-deployment-8568b96ddb-f4fnc 1/1 Running 0 2m8s nginx-deployment-8568b96ddb-ljq9k 1/1 Running 0 2m8s nginx-deployment-8568b96ddb-qfgx7 1/1 Running 0 2m8s nginx-rc-2rf4q 1/1 Running 1 130m nginx-rc-dvgqb 1/1 Running 1 125m nginx-rc-gmddb 1/1 Running 1 125m redis-tcp-5fcb54cd64-52p4d 1/1 Running 0 22m
[root@master-1 deployment]# kubectl describe deployment.apps/nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Mon, 10 Aug 2020 20:13:54 +0800
Labels: app=nginx-deployment
Annotations: deployment.kubernetes.io/revision: 1
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"nginx-deployment"},"name":"nginx-deployment","na...
Selector: app=nginx-deployment
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 1
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx-deployment
Containers:
nginx-deployment:
Image: nginx:latest
Port: 80/TCP
Host Port: 0/TCP
Readiness: tcp-socket :80 delay=5s timeout=1s period=10s #success=1 #failure=3
Environment:
Mounts:
Volumes:
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets:
NewReplicaSet: nginx-deployment-8568b96ddb (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 2m38s deployment-controller Scaled up replica set nginx-deployment-8568b96ddb to 3
扩容
scale 支持容器控制器类型Deployment, ReplicaSet, Replication Controller, Job
[root@master-1 deployment]# kubectl scale deployment nginx-deployment --replicas 10 deployment.extensions/nginx-deployment scaled
查看Deployments
查看RS控制器
pod 正在扩容创建
- 修改配置文件, 检测更新策略
- 把镜像修改为不存在的镜像
- image: nginx111111:latest
[root@master-1 ~]# kubectl apply -f nginx-deployment.yaml
会创建一个新的RS
新的RS关联的pod出错
根据更新的策略,还会存在2个旧的pod,因为应用了新的配置文件,所以原来的10个pod, 只会留下3个,其中1个正在更新,所以只能看到两个pod是正常的.
查看更新的过程
[root@master-1 deployment]# kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Mon, 10 Aug 2020 20:13:54 +0800
Labels: app=nginx-deployment
Annotations: deployment.kubernetes.io/revision: 2
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"nginx-deployment"},"name":"nginx-deployment","na...
Selector: app=nginx-deployment
Replicas: 3 desired | 2 updated | 4 total | 2 available | 2 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 1
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx-deployment
Containers:
nginx-deployment:
Image: nginx1111:latest
Port: 80/TCP
Host Port: 0/TCP
Readiness: tcp-socket :80 delay=5s timeout=1s period=10s #success=1 #failure=3
Environment:
Mounts:
Volumes:
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True ReplicaSetUpdated
OldReplicaSets: nginx-deployment-8568b96ddb (2/2 replicas created)
NewReplicaSet: nginx-deployment-84c85b9846 (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 2m52s deployment-controller Scaled down replica set nginx-deployment-8568b96ddb to 3
Normal ScalingReplicaSet 2m52s deployment-controller Scaled up replica set nginx-deployment-84c85b9846 to 1
Normal ScalingReplicaSet 2m52s deployment-controller Scaled down replica set nginx-deployment-8568b96ddb to 2
Normal ScalingReplicaSet 2m52s deployment-controller Scaled up replica set nginx-deployment-84c85b9846 to 2
删除nginx
[root@master-1 ~]# kubectl delete deployment.apps/nginx-deployment [root@master-1 deployment]# kubectl delete -f nginx-deployment.yaml deployment.apps "nginx-deployment" deleted11.3.4 DaemonSet(容器控制器)
一个DaemonSet 对象能确保其创建的 Pod 在集群中的每一台(或指定 Label)Node 上都运行一个副本。
- 如果集群中动态加入了新的 Node,DaemonSet 中的 Pod 也会被添加在新加入 Node 上运行。
- 删除一个 DaemonSet 也会级联删除所有其创建的Pod。
使用场景:
- 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
- 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
- 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: log-pilot
namespace: kube-system
labels:
k8s-app: log-pilot
kubernetes.io/cluster-service: "true"
spec:
template:
metadata:
labels:
k8s-app: log-es
kubernetes.io/cluster-service: "true"
version: v1.22
log-pilot
每个节点运行一个pod
11.3.5 StatefulSetKubernetes从v1.4版本开始引入了PetSet这个新的资源对象,并且在v1.5版本时更名为StatefulSet,从本质上来讲,可以看作Deployment/RC的一个特殊类型。
- StatefulSet 适合有状态的服务;
- StatefulSet有唯一的pod名称标识,支持持久化存储(集群需要存储数据)与滚动更新。
假设StatefulSet运行集群的名字叫elasticsearch,那么第一个Pod叫elasticsearch-0,第二个Pod叫elasticsearch -1,以此类推。正是因为有序的pod 的名称, 才能够组件集群(需要安装DNS)。
11.3.5.1 案例一:StatefulSet组建Elasticsearch 集群apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: elasticsearch
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
spec:
replicas: 2
serviceName: "elasticsearch-service"
selector:
matchLabels:
app: es
template:
metadata:
labels:
app: es
11.3.6 POD基本操作
- 创建: kubectl create -f xxx.yaml
- 查询列表: kubectl get pod(资源类型)
- 获取pod详细信息:
- kubectl describe pod nginx
- 获取pod所在节点与IP:
- kubectl get pods -o wide
- 监听pods状态:
- kubectl get pods -w
- 列出所有pod :
- kubectl get pods -A
- 根据标签获取pod (run=nginx):
- kubectl get pods -l app=nginx-deployment
- 进入到pod:
- kubectl exec nginx-demo-68749b58dc-rr9rj -i -t bash -n default
- 查看pod内容(非进入) :
- kubectl exec nginx-deployment-8568b96ddb-psr74 -n default -i -t -- cat /etc/resolv.conf
- kubectl exec coredns-66db855d4d-26bvw -n kube-system -i -t -- cat /etc/resolv.conf
- 获取pod详细信息:
- 删除: kubectl delete pod yourPodName
- 更新: kubectl apply /path/to/yourNewYaml.yaml
- 日志: kubectl log -f yourPodName (容器日志在控制台显示,才能看到内容)
- kubectl logs --tail=20 nginx
注意:POD 所支持弹性伸缩的类型: Deployment, ReplicaSet, ReplicationController
弹性伸缩是指适应负载变化,以弹性可伸缩的方式提供资源。反映到Kubernetes 中,指的是可根据负载的高低动态调整Pod 的副本数量。
调整Pod 的副本数是通过修改RC中Pod 的副本是来实现的,示例命令如下:
#扩容Pod 的副本数目到10 [root@master-1 ~]# kubectl scale replicationcontroller nginx-deployment --replicas=1011.3.8 POD的管理方式 11.3.9 pod 状态信息
- 挂起(Pending):Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
- 运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
- 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
- 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
- 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
[root@master-1 job]# kubectl get pod NAME READY STATUS RESTARTS AGE demo-app-57756548d8-sltsg 1/1 Running 1 3d11h dnstools 1/1 Running 0 122m nfs-client-provisioner-5978c5f69c-k9lkb 1/1 Running 1 5d1.3.9.2 POD重启策略
当某个容器异常退出或者健康检查失败, kubelet将根据RestartPolicy的设置来进行相应的操作,重启策略有Always , OnFailure, Never
- Always: 当容器失效时, 由kubelet自动重启该容器;
- OnFailure: 当容器终止运行且退出码不为0时, 由kubelet自动重启该容器;
- Never: 不论容器运行状态如何, kubelet都不会重启该容器;
重启策略使用场景
- Deployment、RC和DaemonSet:必须设置为Always,需要保证该容器持续运行。
- Job和CronJob:OnFailure或Never,确保容器执行完成后不再重启。
- kubelet:在Pod失效时自动重启它,不论将RestartPolicy设置为什么值,也不会对Pod进行健康检查。
- RC控制器和DeamonSet控制器建议设置为Always,需要保证该容器持续运行。
- Job: OnFailure或Never, 确保容器执行完成后不再重启。
[root@linux-master1 ~]# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
restartPolicy: Always #容器重启策略
containers:
- name: nginx
image: nginx:1.12
imagePullPolicy: IfNotPresent #镜像拉取策略
ports:
- containerPort: 80
11.4 镜像策略
默认的镜像拉取策略是“IfNotPresent”,在镜像已经存在的情况下,kubelet将不在去拉取镜像。
- 如果总是想要拉取镜像,必须设置拉取策略为“Always”或者设置镜像标签为“:latest”。
- 如果没有指定镜像的标签,它会被假定为“:latest”,同时拉取策略为“Always”.
在生产环境中, 运行应用的时候(微服务),建议设置为Always
注意在拉取自建私有仓库镜像时, 需要通过创建Secret, 才能拉取镜像。在kubernetes 中有以下三种下载策略:
- Always:每次都下载最新的镜像。 微服务建议用此项
- Never:只使用本地镜像,从不下载。 单节点
- IfNotPresent:只有当本地没有的时候才下载镜像。 开源的第三方的应用建议用此项
[root@linux-master1 ~]# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
labels:
app: nginx-deployment
spec:
selector:
matchLabels:
app: nginx-deployment
replicas: 1
template:
metadata:
labels:
app: nginx-deployment
spec:
restartPolicy: Always
containers:
- name: nginx-deployment
image: nginx:1.12
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
11.5 定时任务
11.5.1 Job
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。
使用场景: 清理数据, 同步数据
11.5.1.1 案例一: JobJob 配置文件,只包含一个 pod,输出圆周率小数点后 2000 位,运行时间大概为 10s
[root@master-1 test]# kubectl create -f job.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
注意:perl镜像880M左右,需要提前下载到node节点上
[root@node-1 ~]# docker load < perl.tar 461719022993: Loading layer [==================================================>] 119.2MB/119.2MB f1d420c2af1a: Loading layer [==================================================>] 17.11MB/17.11MB a3c1026c6bcc: Loading layer [==================================================>] 17.85MB/17.85MB d35c5bda4793: Loading layer [==================================================>] 149.9MB/149.9MB 46829331b1e4: Loading layer [==================================================>] 520.3MB/520.3MB 28c01f06325c: Loading layer [==================================================>] 3.584kB/3.584kB 416facee2664: Loading layer [==================================================>] 55.49MB/55.49MB Loaded image ID: sha256:aebad195b013823cf83716d32039e016f7fa4e6acbd5d1eca2e494b42c85d2fa
运行
[root@master-1 job]# kubectl apply -f job.yaml job.batch/pi created
查看任务
[root@master-1 job]# kubectl describe jobs/pi
Name: pi
Namespace: default
Selector: controller-uid=73adcf03-0cf7-46cb-b583-ec7a2ce9f8e5
Labels: controller-uid=73adcf03-0cf7-46cb-b583-ec7a2ce9f8e5
job-name=pi
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"pi","namespace":"default"},"spec":{"backoffLimit":4,"template":...
Parallelism: 1
Completions: 1
Start Time: Mon, 10 Aug 2020 23:03:16 +0800
Pods Statuses: 1 Running / 0 Succeeded / 0 Failed
Pod Template:
Labels: controller-uid=73adcf03-0cf7-46cb-b583-ec7a2ce9f8e5
job-name=pi
Containers:
pi:
Image: perl
Port:
Host Port:
Command:
perl
-Mbignum=bpi
-wle
print bpi(2000)
Environment:
Mounts:
Volumes:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 14s job-controller Created pod: pi-xcv2b
获取job
[root@master-1 test]# pods=$(kubectl get pods
--selector=job-name=pi --output=jsonpath={.items..metadata.name})
[root@master-1 ~]# echo $pods
pi-xcv2b
获取结果
[root@master-1 job]# kubectl get pods | grep $pods pi-t596w 0/1 Completed 0 3m29s [root@master-1 job]# kubectl logs $pods 3.1415926535897932384626433832795028841971693993751058209749445923078164062 862089986280348253421170679821480865132823066470938446095505822317253594081 28481117450284102701938521105559644622948954930381964428810975665933446128
容器的状态为Completed
[root@master-1 ~]# kubectl get pods | grep $pods pi-xcv2b 0/1 Completed 0 10m
查看结果
[root@master-1 ~]# kubectl log $pods log is DEPRECATED and will be removed in a future version. Use logs instead. 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198938095257201065485863278865936153381827968230301952035301852968995773622599413891249721775283479131515574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012858361603563707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104752162056966024058038150193511253382430035587640247496473263914199272604269922796782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955321165344987202755960236480665499119881834797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548161361157352552133475741849468438523323907394143334547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383827967976681454100953883786360950680064225125205117392984896084128488626945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645995813390478027590111.5.2 CronJob
CronJob是用来管理基于时间的Job,即:
- 在给定的时间点运行一次Job
- 周期性的在给定的时间点运行
- Crontab的基本格式
- <分钟> <小时> <日> <月份> <星期> <命令>
- 分钟值从 0 到 59.
- 小时值从 0 到 23.
- 日值从 1 到 31.
- 月值从 1 到 12.
- 星期值从 0 到 6, 0 代表星期日
多个时间可以用逗号隔开,范围可以用连字符给出,*可以作为通配符。空格用来分开字段。
11.5.2.1 案例一: 创建定时任务#定时清理数据每个一分钟echo “Hello from the Kubernetes cluster”
[root@master-1 test]#cat cronjob.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
创建任务
[root@master-1 cronjob]# kubectl apply -f cronjob.yaml cronjob.batch/hello created
获取任务列表
[root@master-1 cronjob]# kubectl get cronjob NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE hello */1 * * * * False 1 34s 46s
获取任务
[root@master-1 cronjob]# kubectl get jobs NAME COMPLETIONS DURATION AGE hello-1597072680 0/1 37s 37s pi 1/1 2m38s 15m
获取job
[root@master-1 job]# pods=$(kubectl get pods --selector=job-name=hello-1597072680 --output=jsonpath={.items..metadata.name})
[root@master-1 cronjob]# echo $pods
hello-1597072680-rc7hx
获取结果
[root@master-1 cronjob]# kubectl logs $pods Mon Aug 10 15:19:27 UTC 2020 Hello from the Kubernetes cluster
通过界面查看任务
定时任务输出的结果
删除Cron Job
[root@master-1 cronjob]# kubectl delete -f cronjob.yaml cronjob.batch "hello" deleted11.6 服务发现 11.6.1 Service
此Service不能直译,在kubernetes中为了更好的定位每一个或者每组POD (Label 标签),才出现了Service的概念。
因为我们知道POD 的IP地址是在每次重启或者是容器重新部署之后是有变化的。而且容器的IP地址是无法固定的,所有需要Service来定位POD。
11.6.1.1 案例一: 定义服务的Service通过节点的Nodeport 端口访问应用
[root@master-1 java]# cat provider-passport-service.yaml
apiVersion: v1
kind: Service
metadata:
name: passport-svc #Service 名 称
spec:
type: NodePort
ports:
- port: 8081 #Service 端口类型
targetPort: 8081 #容器端口
protocol: TCP #端口协议
selector: #根据 Label 选择
app: passport
11.6.2 Service 网络代理模式
用户通过Service访问服务的时候, 实际是通过node节点上kube-proxy访问pod 服务,那么Kube-Proxy有以下的工作模式:
- Iptables(默认模式),
- IPVS模式,
- userspace
在 Kubernetes v1.2 中,kube-proxy 的 iptables 模式成为默认设置。 Kubernetes v1.8添加了 ipvs 代理模式。
Iptables模式
- Node节点客户端直接访问ServiceIP,Linux根据Iptables协议栈规则策略匹配。
- ServiceIP根据标签直接访问Backend Pod。
IPVS 代理模式
IPVS是LVS一个组件,提供高性能、高可靠性的四层负载均衡器。IPVS 是IP Virtual Server的简写。
- IPVS构建在netfilter上,作为Linux 内核的一部分,从传输层实现了负载均衡。
- IPVS 能直接转发 基于Services的TCP 和UDP到真实服务器。
- IPVS能直接构建一个VIPs 并通过负载均衡算法,把请求转发到backend Pod。
IPVS支持的负载均衡算法:
- rr: 轮询
- lc: 最小连接数
- dh: 目的地址hash
- sh: 源地址hash
- sed: 最短期望延迟
- nq: 无须队列等待
注意:
- 要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前使 IPVS Linux 在节点上可用。
- 当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。
安装ipvsadm、conntrack
[root@master-1 java]# yum -y install ipvsadm conntrack-tools
加载ipvs模块
[root@master-1 java]# cat > /etc/sysconfig/modules/ipvs.modules <查看内核模块加载
[root@master-1 java]# cat >>/etc/sysctl.conf <生效
[root@master-1 ipvs]# sysctl -p net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1修改kube-proxy 配置文件
增加配置
[root@node-1 ~]# cat /etc/kubernetes/cfg/kube-proxy --masquerade-all=true #确保反向流量通过 --feature-gates=SupportIPVSProxyMode=true #打开支持 ipvs 模式 --proxy-mode=ipvs # kube-proxy 最后配置 --ipvs-scheduler=rr #明确代理模式为 ipvs选择调度方式为轮询调度
[root@node-1 ~]# cat /etc/kubernetes/cfg/kube-proxy KUBE_PROXY_OPTS="--logtostderr=true --v=4 --metrics-bind-address=0.0.0.0 --hostname-override=192.168.91.146 --masquerade-all=true --feature-gates=SupportIPVSProxyMode=true --proxy-mode=ipvs --ipvs-scheduler=rr --cluster-cidr=10.0.0.0/24 --kubeconfig=/etc/kubernetes/cfg/kube-proxy.kubeconfig"查看转发列表与IP
[root@node-1 ~]# ipvsadm -L -n | grep 8080 TCP 10.0.0.136:8080 rr -> 172.17.25.2:8080 Masq 1 0 0 -> 172.17.67.9:8080 Masq 1 0 0 TCP 10.0.0.220:8080 rr -> 172.17.25.7:8080 Masq 1 0 0查看 IP
[root@node-1 ~]# ip a | grep 136 inet 10.0.0.136/32 brd 10.0.0.136 scope global kube-ipvs011.6.2.2案例二: 通过IPVS 访问服务获取节点的pod地址
[root@master-1 ~]# kubectl get pod -A -o wide | grep 146 default demo-app-57756548d8-sltsg 1/1 Running 1 3d9h 172.17.25.7 192.168.91.146获取146节点的svc地址
[root@master-1 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demo-app ClusterIP 10.0.0.2208080/TCP 3d9h 访问146节点的SVC
dnstools# curl 10.0.0.220:8080 Hello! My name is demo-app-57756548d8-sltsg. I have served 202 requests so far.注意: 如果发现有nodeport 类型的端口在被修改完成了ipvs 模式的节点上,需要使用 iptables -F 清空iptables 表, 或者是直接在机器上使用curl访问.
11.6.3 Service服务类型11.6.4 Service 端口类型
- ClusterIP:通过集群的内部IP暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
- NodePort:通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
- LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
11.6.5 访问Service方式
- port: service的的端口
- targetport: pod也就是容器的端口
- nodeport: 容器所在宿主机的端口(实质上也是通过service暴露给了宿主机)
Service 的虚拟IP 是由Kubernetes 虚拟出来的内部网络,外部是无法寻址到的。但是有些 服务又需要被外部访问到,例如web 前端。这时候就需要添加一层网络转发,即外网到内网的转发。
Kubernetes 提供了NodePort、LoadBalancer、Ingress 三种方式访问Service。
访问方式图解:
11.7 DNS
- NodePort, Kubernetes会在每一个Node上暴露出一个端口:NodePort,外部网络可以通过[NodeIP]:[NodePort]访问到后端的Service。
- LoadBalancer,在NodePort基础上,Kubernetes可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发。该模式需要底层云平台(例如GCE)支持。
- Ingress,是一种HTTP方式的路由转发机制,由Ingress Controller 和HTTP 代理服务器组合而成。Ingress Controller 实时监控Kubernetes API,实时更新HTTP 代理服务器的转发规则。HTTP 代理服务器有GCE Load-Balancer、HaProxy、Nginx 等开源方案。
- 本质上是反向代理。
DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组DNS记录。 如果整个集群的 DNS 一直被启用,那么所有的Pod 应该能够自对Service 进行名称解析。
例如,有一个名称为 “my-service” 的 Service,它在 Kubernetes 集群中名为 “myns” 的 Namespace 中,为 “my-service.my-ns” 创建了一条 DNS 记录。 在名称为 “myns” 的 Namespace中的Pod应该能够简单地通过名称查询找到 “my-service”。
11.7.1 案例一: 通过Service名称访问服务获取Service名称
[root@master-1 job]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demo-app ClusterIP 10.0.0.2208080/TCP 3d11h kubernetes ClusterIP 10.0.0.1 443/TCP 9d 访问服务
服务访问的正确格式: SERVICE_NAME.NS
[root@master-1 job]# kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools dnstools# curl demo-app.default:8080 Hello! My name is demo-app-57756548d8-sltsg. I have served 2279 requests so far.注意:Service 在没有修改的情况下,是不会修改的; 而cluster ip 在每次重建Service的时 候,会修改的。所以建议使用service name 连接内部服务。这也是为什么需要安装DNS的 原因。
11.8 存储- SecretSecret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。
Secret有三种类型:
11.8.1 案例一: 导入Docker Registry认证信息
- Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
- Opaque:base64编码格式的Secret,用来存储密码、密钥等;
- kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息。
在Kubernetes中需要导入Docker私有镜像仓库的登录信息,才能从私有仓库拉取镜像,
登录信息的存储使用Secret加密存储。
- 创建 secret 密钥
#创建 secret (注意解析 docker-server (hosts)) [root@master-1 ~]# kubectl create secret docker-registry registry-secret --docker-server=reg.abc.com --docker-username=user --docker-password=Aa123456 --docker-email=user@abc.com secret/registry-secret created
- 下载密钥
[root@master-1 ~]# kubectl get secret registry-secret -o yaml apiVersion: v1 data: .dockerconfigjson: eyJhdXRocyI6eyJyZWcuYWJjLmNvbSI6eyJ1c2VybmFtZSI6InVzZXIiLCJwYXNzd29yZCI6IkFhMTIzNDU2IiwiZW1haWwiOiJ1c2VyQGFiYy5jb20iLCJhdXRoIjoiZFhObGNqcEJZVEV5TXpRMU5nPT0ifX19 kind: Secret metadata: creationTimestamp: "2020-08-11T00:55:20Z" name: registry-secret namespace: default resourceVersion: "142965" selflink: /api/v1/namespaces/default/secrets/registry-secret uid: bf406ed7-a8de-41d7-ab2a-1e1791023162 type: kubernetes.io/dockerconfigjson
- 修改为需要导入的格式apiVersion: v1
kind: Secret metadata: name: regis-secre namespace: default data: .dockerconfigjson: eyJhdXRocyI6eyJyZWcuYWJjLmNvbSI6eyJ1c2VybmFtZSI6InVzZXIiLCJwYXNzd29yZCI6IkFhMTIzNDU2IiwiZW 1haWwiOiJ1c2VyQGFiYy5jb20iLCJhdXRoIjoiZFhObGNqcEJZVEV5TXpRMU5nPT0ifX19 type: kubernetes.io/dockerconfigjson
- kubectl create -f registry-secret.yaml
[root@master-1 ~]# cat registry-secret.yaml apiVersion: v1 kind: Secret metadata: name: regsecret namespace: default data: .dockerconfigjson:eyJhdXRocyI6eyJyZXBvLmhvc3RzY2MuY29tIjp7InVzZXJuYW1lIjoidXNlciIsInBhc3N3b3JkIjoiQWExMjM0NTY3OCIsImVtYWlsIjoidXNlckBhYmMuY29tIiwiYX11.9 基于角色的访问控制- RBAC基于角色(Role)的访问控制(RBAC)是一种基于企业中用户的角色来调节控制对计算 机或网络资源的访问方法。
11.9.1 RABC 可操作资源列表
- RBAC 使用 rbac.authorization.k8s.io API Group 来实现授权决策,允许 管理员通过 Kubernetes API 动态配置策略.
- 启用 RBAC,需要在 apiserver 配置文件中添加参数–authorizationmode=RBAC
11.9.2 资源列表可操作的权限列表
- Pods: 容器
- ConfigMaps: 配置
- Deployments: 容器控制器
- Nodes: 节点
- Secrets: 凭证
- Namespaces: 命名空间
Create、get、delete、list、update、edit、watch、exec
资源列表与权限关系:
11.9.3 RBAC中的其他对象11.9.3.1 授权角色绑定图解
- Rule:规则,规则是一组属于不同 API Group 资源上的一组操作的集合;
- Role 和 ClusterRole:角色和集群角色,这两个对象都包含上面的 Rules 元素,
- 二者的区别在于,
- 在 Role中,定义的规则只适用于单个命名空间,也就是和 namespace 关联的,
- 而 ClusterRole 是集群范围内的,因此定义的规则不受命名空间的约束。
- Subject:主题,对应在集群中尝试操作的对象,集群中定义了3种类型的主题资源:
- User Account:用户,这是有外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用 KeyStone或者 Goolge 帐号,甚至一个用户名和密码的文件列表也可以。对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理;
- Group:组,这是用来关联多个账户的,集群中有一些默认创建的组,比如clusteradmin;
- Service Account:服务帐号,通过Kubernetes API来管理的一些用户帐号,和namespace进行关联的,适用于集群内部运行的应用程序,需要通过API来完成权限认证,所以在集群内部进行权限操作,都需要使用到 ServiceAccount.
- RoleBinding 和 ClusterRoleBinding:角色绑定和集群角色绑定,简单来说就是把声明的 Subject 和我们的 Role 进行绑定的过程(给某个用户绑定上操作的权限),
- 二者的区别也是作用范围的区别:
- RoleBinding 只会影响到当前 namespace 下面的资源操作权限,
- 而 ClusterRoleBinding 会影响到所有的 namespace。
Service Account 集群的内部的鉴权.
11.9.4 案例一:创建登录Dashboard的用户创建登录dashboard的用户, 并且只能操作kube-system这个命名空间下面的 pods 和 deployments,所以需要创建ServiceAccount对象.
创建SA对象
[root@master-1 ~]# kubectl create sa demo-sa -n kube-system serviceaccount/demo-sa created创建角色kube-role
[root@master-1 ~]# cat kube-sa-role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kube-sa-role namespace: kube-system rules: - apiGroups: [""] #找不到资源 pods 对应的 apiGroup resources: ["pods"] #可以操作的资源 verbs: ["get", "watch", "list"] #对资源可以操作的列表 - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]常用的apiGroups列表查阅: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/
[root@master-1 ~]# cat kube-sa-rolebinding.yaml kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: kube-sa-rolebinding namespace: kube-system subjects: - kind: ServiceAccount name: demo-sa namespace: kube-system roleRef: kind: Role name: kube-sa-role apiGroup: rbac.authorization.k8s.ioServiceAccount 会生成一个Secret对象和它进行映射,这个Secret里面包含一个token,如果dashboard也时属于kube-system, 则这个token 可以用来登录到dashboard
[root@master-1 rabc]# kubectl apply -f kube-sa-role.yaml role.rbac.authorization.k8s.io/kube-sa-role created [root@master-1 rabc]# kubectl apply -f kube-sa-rolebinding.yaml rolebinding.rbac.authorization.k8s.io/kube-sa-rolebinding created获取token
[root@master-1 rabc]# kubectl get secret -n kube-system |grep demo-sa demo-sa-token-njvtq kubernetes.io/service-account-token 3 2m41s获取base64
[root@master-1 rabc]# kubectl get secret demo-sa-token-njvtq -o jsonpath={.data.token} -n kube-system |base64 -d eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZW1vLXNhLXRva2VuLW5qdnRxIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlbW8tc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5YmI2ZTFiMi1iMWU5LTRhZjUtYmMyYy02ODNkNjc2YmQ1ODMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVtby1zYSJ9.MCgiXFjxbYEC2HqtBJsKpS-5EWCmw2kULsOZqIYLwxFXpR8rAPzpjzU5WuIDNCguebxOXK_3VnIY-5kLI5TlvyImvM8KEOZkn2JpmJp3EgPzOzypIoqADDCO9rxRTTzGhxS0O1oskuGJu2IZaIGZhrk6GdJ-dc1Mc94wOaqaLHDQXLbZSJmSQvFliDRxYvJZ4fVxztICAUjnTvUMrXgf6RT6nqR6ZFt7m46gLBoxrOiOVHJzBFmqlIXYqk2l-vwaufTS_Vw5oKcEXNItl3g9SydG5Ezp1fb14mnN2YnM_XsCJxRzSOU2H_GPEe-3sgiBbfzdh1HrhBAORUCSqIxT5g登录dashbosh,输入上面生成的token
输入kube-system 命名空间
11.9.5 案例二:创建一个不受限制的SA账号, 用于集群内部的认证创建SA
[root@master-1 job]# cat super-sa.yaml apiVersion: v1 kind: ServiceAccount metadata: name: super-sa namespace: kube-system创建账号
[root@master-1 rabc]# kubectl apply -f super-sa.yaml serviceaccount/super-sa created创建ClusterRole (控制权限)
- 使用的cluster-admin这个对象,这是Kubernetes集群内置的 ClusterRole 对象, 无需创建。
查看cluster-admin 定义的权限
- 所有的资源不受限制, 相当于超级管理员
[root@master-1 rabc]# kubectl get clusterrole cluster-admin -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2020-08-06T07:05:39Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: cluster-admin resourceVersion: "39" selflink: /apis/rbac.authorization.k8s.io/v1/clusterroles/cluster-admin uid: 8a74bf28-5875-4c66-bcfb-a49dce6d1aa4 rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*'创建角色绑定
- RoleBinding 与 ClusterRoleBinding, 最大的不同就是, RoleBingding 受限制于NS, ClusterRoleBinding反 之.
[root@master-1 job]# cat super-sa-ClusterRoleBinding.yaml kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: super-sa-clusterrolebinding subjects: - kind: ServiceAccount name: super-sa namespace: kube-system roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io[root@master-1 rabc]# kubectl apply -f super-sa.yaml serviceaccount/super-sa unchanged [root@master-1 rabc]# kubectl apply -f super-sa-ClusterRoleBinding.yaml clusterrolebinding.rbac.authorization.k8s.io/super-sa-clusterrolebinding created获取base64编码与案例一中相同
[root@master-1 ~]# kubectl get secret -n kube-system super-sa-token-wqjz6 kubernetes.io/service-account-token 3 71s获取token
[root@master-1 rabc]# kubectl get secret super-sa-token-wqjz6 -o jsonpath={.data.token} -n kube-system | base64 -d eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJzdXBlci1zYS10b2tlbi13cWp6NiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzdXBlci1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjI1ZTAzY2QxLTY3N2EtNDAyYy04ZGIzLTVmYjE0NjFkYjA0ZCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTpzdXBlci1zYSJ9.cvBz0uv717Z6OKw3S_ahFxrtF_5CdG-KKOwoQIm7YSZsdKwk0Fovxgf-cKaFILFOb1uKHsbU7Sk2e3VUJx0fdI4ugv6jo53Bi7WO6HPVRoCSxhEoYffzb8GFcRZ0sObPcHqvv35nb572Ll8B-krd3aJ_uUmsPp4QH6LsakXVeQFkAQ-MJBzvX_KcisBqTp87dnvmZJMLbUhsZea0UexGvbwUMR2NLQNelhjJRPfyhlk5TLOpVfycN59BkXtcoD8Ayd8EHWW9T6Dpa1ZXWN-wjJOwl_RT6c1GPARyjOydGIVCAW7sWQAZR-NQmxuWonHyQu-qLjW8e1HhMvn_GE6b3A使用上面生成的token 登录系统
11.9.6 案例三: RBAC之Yaml授权文件讲解[root@master-1 job]# cat prometheus-rabc.yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: prometheus-rbac subjects: - kind: ServiceAccount name: prometheus-k8s namespace: monitoring roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io11.9.7 案例四: 实际操作授权命令操作kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous解释
11.10 Yaml 文件详解 11.10.0 Yaml 是什么?
- 集群角色绑定用户system:anonymous, 拥有cluster-admin的权限, 集群角色名称为 system:anonymous
Yaml 是一种用来写配置文件的语言。结构上它有两种可选的类型:Lists 和 Maps。
11.10.1 YAML语法规则
- List 用 -(破折号)来定义每一项,
- Map 则是一个 key:value 的键值对来表示。
11.10.2 Yaml结构类型图解
- 大小写敏感;
- 使用缩进表示层级关系;
- 缩进时不允许使用Tal键,只允许使用空格;
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;
- "#"表示注释,从这个字符一直到行尾,都会被解析器忽略;
- “—”" 为可选的分隔符;
在Kubernetes中,Yaml支持两种结构类型即可:Lists、Maps
注
11.10.3 Kubernetes
- Yaml 转 Properties (https://www.toyaml.com/index.html)
- Yaml 转 Json (http://nodeca.github.io/js-yaml/)
通过Yaml创建资源 如果需要通过yaml 文件创建Kubernetes 对象,需要配置如下的字段:
11.10.4 案例一: Kubernetes pod编排文件讲解
- apiVersion: 创建该对象所使用的 Kubernetes API 的版本
- kind: 想要创建的对象的类型
- metadata: 帮助识别对象唯一性的数据,包括一个 name 字符串、UID 和可选的 namespace
Pod在程序中运行的必须的编排文件
apiVersion: v1 #指定 api 版本,此值必须在 kubectl apiversion 中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数据/属性 name: test-pod #资源的名字,在同一个 namespace 中必须唯一 labels: #设定资源的标签 k8s-app: apache version: v1 annotations: #自定义注解列表 - name: String #自定义注解名字 spec: #specification of the resource content 指定该资源的内容 restartPolicy: Always #表明该容器一直运行,默认 k8s 的策略,在此容器退出后,会立即创建一个相同的容器 nodeSelector: #节点选择,先给主机打标签 kubectl label nodes kube-node1 zone=node1 zone: node1 containers: - name: test-pod #容器的名字 image: 10.192.21.18:5000/test/chat:latest #容器使用的镜像地址 imagePullPolicy: Never # Kubernetes 拉取镜像策略 command: ['sh'] #启动容器的运行命令,将覆盖容器中的 Entrypoint,对应 Dockefile 中的 ENTRYPOINT args: ["$(str)"] #启动容器的命令参数,对应 Dockerfile 中 CMD 参数 env: #指定容器中的环境变量 - name: str #变量的名字 value: "/etc/run.sh" #变量的值 resources: #资源管理 requests: #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行 cpu: 0.1 #CPU 资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为 0.001 核(1m) memory: 32Mi #内存使用量 limits: #资源限制 cpu: 0.5 memory: 1000Mi ports: - containerPort: 80 #容器开发对外的端口 name: httpd #名称 protocol: TCP livenessProbe: #pod 内容器健康检查的设置 httpGet: #通过 httpget 检查健康,返回 200-399 之间,则认为容器正常 path: / #URI 地址 port: 80 scheme: HTTP initialDelaySeconds: 180 #表明第一次检测在容器启动后多长时间后开始 timeoutSeconds: 5 #检测的超时时间 periodSeconds: 15 #检查间隔时间 #也可以用这种方法 #exec: 执行命令的方法进行监测,如果其退出码不为 0,则认为容器正常 # command: # - cat # - /tmp/health #也可以用这种方法 #tcpSocket: //通过 tcpSocket 检查健康 # port: number lifecycle: #生命周期管理 postStart: #容器运行之前运行的任务 exec: command: - 'sh' - 'yum upgrade -y' preStop:#容器关闭之前运行的任务 exec: command: ['service httpd stop'] volumeMounts: #挂载持久存储卷 - name: volume #挂载设备的名字,与 volumes[*].name 需要对应 mountPath: /data #挂载到容器的某个路径下 readOnly: True volumes: #定义一组挂载设备 - name: volume #定义一个挂载设备的名字 #meptyDir: {} hostPath: path: /opt #挂载设备类型为 hostPath,路径为宿主机下的/opt,这里设备类型支持很多种 #nfs11.10.5 案例二: Kubernetes deployment运行apiVersion: apps/v1 # 1.9.0 之前的版本使用 apps/v1beta2,可通过命令 kubectl api-versions 查看 kind: Deployment #指定创建资源的角色/类型 metadata: #资源的元数据/属性 name: web-server #资源的名字,在同一个 namespace 中必须唯一 spec: replicas: 2 #pod 副本数量 selector: #定义标签选择器 matchLabels: app: web-server #符合目标的 pod 的标签 template: # Deployment 扩容 pod 的时候根据此模板 metadata: labels: #Pod 的 label app: web-server #pod 副本的标签,selector 根据此标签选择 pod 副本 spec: #指定该资源的内容 containers: #pod 内容器定义的部分 - name: nginx #容器的名字 image: nginx:1.12.1 #容器的镜像地址 ports: - containerPort: 80 #容器暴露的端口[root@master ~]# kubectl create -f nginx.yaml11.10.6 案例三: Kubernetes Services 运行[root@master ~]# cat nginx-svc.yaml apiVersion: v1 kind: Service metadata: name: nginx-service #service 名称 spec: selector: app: web-server #匹配 service 选择器标签的 pod ports: - protocol: TCP port: 80 #service 端口 targetPort: 80 #pod端口11.11 ConfigMapConfigMap 允许您将配置文件与属性文件分离,以使容器化的应用程序具有可移植性。
- Kubernetes 空间都可以使用;
- 可以作为变量或者路径文件使用;
- Pod支持自动更新内容;
获取系统中的ConfigMap
[root@master-1 configmap]# kubectl get configmap NAME DATA AGE traefik-config 1 4d11h11.11.1 案例一: 将ConfigMap中的所有键值对配置为容器环境变量创建一个包含多个键值对的 ConfigMap。
[root@master-1 configmap]# cat configmap-multikeys.yaml apiVersion: v1 kind: ConfigMap metadata: name: special-config namespace: default data: SPECIAL_LEVEL: L1 SPECIAL_TYPE: Nginx创建ConfigMap
[root@master-1 configmap]# kubectl apply -f configmap-multikeys.yaml configmap/special-config created查看ConfigMap
[root@master-1 configmap]# kubectl get configmap/special-config -n default NAME DATA AGE special-config 2 31s查看详细内容
[root@master-1 configmap]# kubectl describe configmap special-config Name: special-config Namespace: default Labels:Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"SPECIAL_LEVEL":"L1","SPECIAL_TYPE":"Nginx"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"special-co... Data ==== SPECIAL_LEVEL: ---- L1 SPECIAL_TYPE: ---- Nginx Events: 创建容器引用ConfigMap
[root@master-1 configmap]# cat pod-configmap.yaml apiVersion: v1 kind: Pod metadata: name: pod-test-configmap spec: containers: - name: pod-test-configmap image: busybox command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] env: - name: SPECIAL_LEVEL_KEY valueFrom: configMapKeyRef: name: special-config key: SPECIAL_LEVEL - name: SPECIAL_TYPE_KEY valueFrom: configMapKeyRef: name: special-config key: SPECIAL_TYPE restartPolicy: Never创建pod
[root@master-1 configmap]# kubectl apply -f pod-configmap.yaml pod/pod-test-configmap created查看pod日志
[root@master-1 configmap]# kubectl log pod-test-configmap log is DEPRECATED and will be removed in a future version. Use logs instead. L1 Nginx11.11.2 案例二: 将 ConfigMap 数据添加到容器中的特定路径Nginx pod 文件
[root@master-1 configmap]# cat nginx.yaml apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx-configmap replicas: 1 template: metadata: labels: app: nginx-configmap spec: containers: - name: nginx-configmap image: nginx volumeMounts: - name: config-volume mountPath: /mnt/ ports: - containerPort: 80 volumes: - name: config-volume configMap: name: special-config items: - key: SPECIAL_LEVEL path: keys启动
[root@master-1 configmap]# kubectl apply -f nginx.yaml deployment.apps/nginx-deployment created [root@master-1 configmap]# kubectl get pod | grep nginx-deployment nginx-deployment-69fd86756f-f6bhw 1/1 Running 0 115s查看容器内容
[root@master-1 configmap]# kubectl exec -it nginx-deployment-69fd86756f-f6bhw bash root@nginx-deployment-69fd86756f-f6bhw:/# cd /mnt root@nginx-deployment-69fd86756f-f6bhw:/mnt# ls keys root@nginx-deployment-69fd86756f-f6bhw:/mnt# cat keys L1root修改ConfigMap 内容(验证pod自动更新)
- 修改内容
[root@master-1 configmap]# cat configmap-multikeys.yaml apiVersion: v1 kind: ConfigMap metadata: name: special-config namespace: default data: SPECIAL_LEVEL: L111 SPECIAL_TYPE: Nginx应用新配置
[root@master-1 configmap]# kubectl apply -f configmap-multikeys.yaml configmap/special-config configured [root@master-1 configmap]# kubectl describe configmap special-config Name: special-config Namespace: default Labels:Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"SPECIAL_LEVEL":"L111","SPECIAL_TYPE":"Nginx"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"special-... Data ==== SPECIAL_LEVEL: ---- L111 SPECIAL_TYPE: ---- Nginx Events: 查看容器是否可以自动更新
- 需要等待1分钟(默认)
[root@master-1 configmap]# kubectl exec -it nginx-deployment-69fd86756f-f6bhw -- cat /mnt/keys L11111.11.3 案例三: 将ConfigMap中的所有键值对配置为容器环境变量定义配置文件
- kustomize 应用配置管理
[root@master-1 redis]# cat kustomization.yaml configMapGenerator: - name: redis-master-config files: - redis-config resources: - redis-pod.yaml定义redis配置文件
[root@master-1 redis]# cat redis-config maxmemory 2mb maxmemory-policy allkeys-lru定义redis pod 文件
[root@master-1 redis]# cat redis-pod.yaml apiVersion: v1 kind: Pod metadata: name: redis spec: hostNetwork: true containers: - name: redis image: redis:5.0.4 command: - redis-server - "/redis-master/redis.conf" env: - name: MASTER value: "true" ports: - containerPort: 6379 resources: limits: cpu: "0.1" volumeMounts: - mountPath: /redis-master-data name: data - mountPath: /redis-master name: config volumes: - name: data emptyDir: {} - name: config configMap: name: redis-master-config items: - key: redis-config path: redis.conf由于ingress章节中创建了redis-tcp的pod,6379端口被占用。需要删除该pod
创建redis
[root@master-1 redis]# ll total 12 -rw-r--r-- 1 root root 120 Aug 11 10:33 kustomization.yaml -rw-r--r-- 1 root root 43 Aug 11 10:29 redis-config -rw-r--r-- 1 root root 652 Aug 11 10:31 redis-pod.yaml [root@master-1 redis]# kubectl apply -k . configmap/redis-master-config-k66gtchdm4 unchanged pod/redis created获取redis节点地址
[root@master-1 redis]# kubectl get pods -o wide | grep redis redis 1/1 Running 0 6m10s 192.168.91.21 192.168.91.21连接访问Redis
[root@master-2 ~]# redis-cli -h 192.168.91.21 -p 6379 192.168.91.21:6379> ConFIG GET maxmemory 1) "maxmemory" 2) "2097152" #字节 192.168.91.21:6379> ConFIG GET maxmemory-policy 1) "maxmemory-policy" 2) "allkeys-lru"



