目录
Yaml语法解析
Pod
pod是如何被创建的
1.创建一个pod
2.创建一个多容器pod
进入容器
3.配置节点标签
4.Pod容器的交互
4.1创建pod,并做本地解析
4.2pod共享进程
4.3pod共享宿主机namespace
5.钩子函数lifecycle
基础指令
# 查看对应资源: 状态
$ kubectl get <SOURCE_NAME> -n <NAMESPACE> -o wide# 查看对应资源: 事件信息
$ kubectl describe <SOURCE_NAME> <SOURCE_NAME_RANDOM_ID> -n <NAMESPACE># 查看pod资源: 日志
$ kubectl logs -f <SOURCE_NAME_RANDOM_ID> [CONTINER_NAME] -n <NAMESPACE># 创建资源: 根据资源清单
$ kubectl apply[or create] -f <SOURCE_FILENAME>.yaml# 删除资源: 根据资源清单
$ kubectl delete -f <SOURCE_FILENAME>.yaml# 修改资源: 根据反射出的etcd中的配置内容, 生产中不允许该项操作, 且命令禁止
$ kubectl edit <SOURCE_NAME> <SOURCE_NAME_RANDOM_ID> -n <NAMESPACE>
Yaml语法解析
YAML是一个类似 XML、JSON 的标记性语言。它强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义比较简单,号称"一种人性化的数据格式语言"。
YAML的语法比较简单,主要有下面几个:
1、大小写敏感
2、使用缩进表示层级关系
3、缩进不允许使用tab,只允许空格( 低版本限制 )
4、缩进的空格数不重要,只要相同层级的元素左对齐即可
5、'#'表示注释YAML支持以下几种数据类型:
1、纯量:单个的、不可再分的值
2、对象:键值对的集合,又称为映射(mapping)/ 哈希(hash) / 字典(dictionary)
3、数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)补充说明:
1、书写yaml切记: 后面要加一个空格
2、如果需要将多段yaml配置放在一个文件中,中间要使用---分隔
创建命名空间
vim test.yaml
apiVersion: v1
kind: Namespace
metadata:
name: aren
kubectl apply -f test.yaml
# 如果通过命令行创建
$ kubectl create namespace webserver
# 删除名称空间[注意,这将删除名称空间下的所有资源]
$ kubectl delete namespace webserver
Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元; Pod 中会启动一个或一组紧密相关的业务容器, 各个业务容器相当于Pod 中的各个进程, 此时就可以将Pod 作为虚拟机看待; 在创建 Pod 时会启动一个init容器, 用来初始化存储和网络, 其余的业务容器都将在init容器启动后启动, 业务容器共享init容器的存储和网络; Pod 只是一个逻辑单元, 并不是真实存在的“主机”, 这种类比主机的概念可以更好的符合现有互联网中几乎所有的虚拟化设计; 像之前运行在虚拟机中的 nginx、mysql、php均可以使用对应的镜像运行出对应的容器在Pod中, 来类比虚拟机中运行这三者;
对于 Pod 而言, 在运行的过程中, k8s为了控制其生命周期的状态, 增加了容器探测指针、资源限额、期望状态保持、多容器结合、安全策略设定、控制器受管、故障处理策略 等; Pod在平时是不能够被单独创建的, 而是需要使用控制器对其创建, 这样可以时刻保持Pod的期望状态;
在Kubernetes中所有的资源均可通过命令行参数或者资源清单[yaml/json]的方式进行创建和修改, 但由于Kubernetes属于声明式资源控制集群, 故大多管理Kubernetes集群的方式采用资源配置清单; 资源配置清单可以很好的追溯资源的原型和详细的配置, 且配合版本控制能够完成更好的溯源、回滚、发布等操作; 所以课程中所有的资源创建和修改都会采用资源配置清单的方式, 除部分命令行操作以外;
pod是如何被创建的
-
step1: kubectl 向 k8s api server 发起一个create pod 请求
-
step2: k8s api server接收到pod创建请求后,不会去直接创建pod;而是生成一个包含创建信息的yaml。
-
step3: apiserver 将刚才的yaml信息写入etcd数据库。
-
step4: scheduler 查看 k8s api,判断:pod.spec.Node == null,若为null,表示这个Pod请求是新来的,需要创建;因此先进行调度计算,找到最适合的node。并更新数据库
-
step5: node节点上的Kubelet通过监听数据库更新,发现有新的任务与自己的node编号匹配,则进行任务创建
1.创建一个pod
创建pod模板
kubectl run [pod名称] --image=mysql --namespace=aren --port=3306 --dry-run -o yaml
[root@kube-master kubernetes]# vim mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
namespace: aren
labels:
name: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- name: MYSQL_DATABASE
value: "test"
2.创建一个多容器pod
[root@kube-master kubernetes]# vim test.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: aren
labels:
name: nginx
spec:
restartPolicy: OnFailure
containers:
- name: centos
imagePullPolicy: IfNotPresent
image: 10.36.192.206:8088/library/centos:7.9.2009
command: ["tail","-f","/dev/null"]
- name: nginx
imagePullPolicy: IfNotPresent
image: 10.36.192.206:8088/library/nginx:1.20.2
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
# nodeName: kube-node1
nodeSelector:
kubernetes.io/hostname: kube-node2
kubectl apply -f test.yaml
# 字段解析
restartPolicy:
pod 重启策略,可选参数有:
1、Always:Pod中的容器无论如何停止都会自动重启
2、OnFailure: Pod中的容器非正常停止会自动重启
3、Never: Pod中的容器无论怎样都不会自动重启imagePullPolicy:
镜像拉取策略,可选参数有:
1、Always:总是重新拉取
2、IfNotPresent:默认,如果本地有,则不拉取
3、Never:只是用本地镜像,从不拉取nodeSelector:
节点选择器:可以指定node的标签,查看标签指令:nodeSelector:
kubernetes.io/hostname: kube-node2
nodeName:
节点名称: 可以指定node的名称进行调度
$ kubectl get node --show-labels
进入容器
-n 指定命名空间 -c 指定pod中的容器
[root@kube-master ~]# kubectl exec -it -n aren nginx -c centos /bin/bash
3.配置节点标签
添加标签
kubectl label nodes node3 name=value
删除标签
kubectl label nodes node3 name-
[root@kube-master ~]# kubectl label nodes kube-node1 type=cpus
可以通过 nodeSelector:(节点选择器:可以指定node的标签,查看标签指令:)
nodeSelector:
type=cpus
4.Pod容器的交互
4.1创建pod,并做本地解析
[root@kube-master ~]# vim host-alias.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: centos
name: centos
namespace: default
spec:
containers:
- image: 10.36.192.206:8088/library/centos:7.9.2009
name: centos
command:
- "tail"
- "-f"
- "/dev/null"
hostAliases:
- ip: "192.168.134.166"
hostnames:
- "kube-node1"
- ip: "192.168.134.163"
hostnames:
- "kube-node2"
# kubectl apply -f host-alisa.yaml
# 字段解析
command:
启动容器时执行的指令,类似于docker run -it 镜像 tail -f /dev/null
hostAliases:
在容器中的/etc/hosts文件中配置本地解析
进入容器可以看到
4.2pod共享进程
shareProcessNamespace: true #共享进程名称空间
[root@kube-master ~]# vim pod.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
namespace: aren
spec:
shareProcessNamespace: true
containers:
- name: test-web
image: 10.36.192.206:8088/library/nginx:1.20.2
ports:
- containerPort: 80
- name: busybox
image: 10.36.192.206:8088/library/busybox
stdin: true
tty: true
# kubectl apply -f pod.yaml
1. 定义了 shareProcessNamespace=true
表示这个 Pod 里的容器要共享进程(PID Namespace)如果是false则为不共享。
2. 定义了两个容器:
一个 nginx 容器
一个开启了 tty 和 stdin 的 busybos 容器在 Pod 的 YAML 文件里声明开启它们俩,等同于设置了 docker run 里的 -it(-i 即 stdin,-t 即 tty)参数。此 Pod 被创建后,就可以使用 shell 容器的 tty 跟这个容器进行交互了。
可以在busybbox中看到nginx的进程
4.3pod共享宿主机namespace
定义了共享宿主机的 Network、IPC 和 PID Namespace。这样,此 Pod 里的所有容器,会直接使用宿主机的网络、直接与宿主机进行 IPC 通信、看到宿主机里正在运行的所有进程。
hostNetwork: true #共享宿主机网络 有端口可以直接访问宿主机ip
hostIPC: true #共享ipc通信
hostPID: true #共享宿主机的pid
[root@kube-master ~]# vim pod1.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
spec:
hostNetwork: true
hostIPC: true
hostPID: true
containers:
- name: test-web
image: 10.36.192.206:8088/library/nginx:1.20.2
ports:
- containerPort: 80
- name: busybox
image: 10.36.192.206:8088/library/busybox
stdin: true
tty: true
# kubectl apply -f pod1.yaml
查看详信息 ,发现与kube-node1共享
5.钩子函数lifecycle
kubernetes 在主容器启动之后和删除之前提供了两个钩子函数:
post start:容器创建之后执行,如果失败会重启容器
pre stop:容器删除之前执行,执行完成之后容器将成功删除,在其完成之前会阻塞删除容器的操作
钩子函数的三种使用方式:
第一种 exec 执行指令
lifecycle: postStart: exec: command: - cat - /etc/hosts
第二种 在容器中请求端口
lifecycle: postStart: tcpSocket: port: 8080
第三种 向容器发起http请求
lifecycle: postStart: httpGet: path: / # URI地址 port: 80 # 端口号 host: 192.168.96.10 # 主机地址 scheme: HTTP
实例
[root@kube-master ~]# vim lifecycle.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-lifecycle
namespace: default
labels:
app: nginx
spec:
containers:
- name: nginx-lifecycle
image: nginx:1.16.1
ports:
- containerPort: 80
protocol: TCP
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo '<h1>this is a nginx-lifecycle test page</h1>' > /usr/share/nginx/html/index.html"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'stop nginx 30 ' > /usr/share/nginx/html/index.html; sleep 30"]
# kubectl apply -f lifecycle.yaml
查看
[root@kube-master kubernetes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-lifecycle 1/1 Running 0 10s 10.244.9.98 kube-node1 <none> <none>
[root@kube-master kubernetes]# curl 10.244.9.98
<h1>this is a nginx-lifecycle test page</h1>
#删除pod
[root@kube-master kubernetes]#kubectl delete pod nginx-lifecycle -n default
[root@kube-master ~]# curl 10.244.9.98
stop nginx 30