1.k8s的基本指令
1.1 基础命令
1.# 查看对应资源: 状态
$ kubectl get <SOURCE_NAME> -n <NAMESPACE> -o wide
2.# 查看对应资源: 事件信息
$ kubectl describe <SOURCE_NAME> <SOURCE_NAME_RANDOM_ID> -n <NAMESPACE>
3.# 查看pod资源: 日志
$ kubectl logs -f <SOURCE_NAME_RANDOM_ID> [CONTINER_NAME] -n <NAMESPACE>
4.# 创建资源: 根据资源清单
$ kubectl apply[or create] -f <SOURCE_FILENAME>.yaml
5.# 删除资源: 根据资源清单
$ kubectl delete -f <SOURCE_FILENAME>.yaml
6.# 修改资源: 根据反射出的etcd中的配置内容, 生产中不允许该项操作, 且命令禁止
$ kubectl edit <SOURCE_NAME> <SOURCE_NAME_RANDOM_ID> -n <NAMESPACE>
1.2 命令实践
# 查看node状态
$ kubectl get node # -o wide 显示更加详细的信息
# 查看service对象
$ kubectl get svc
# 查看kube-system名称空间内的Pod
$ kubectl get pod -n kube-system
# 查看所有名称空间内的pod
$ kubectl get pod -A
# 查看集群信息
$ kubectl cluster-info
# 查看各组件信息
$ kubectl -s https://api-server:6443 get componentstatuses
# 查看各资源对象对应的api版本
$ kubectl explain pod
# 查看帮助信息
$ kubectl explain deployment
$ kubectl explain deployment.spec
$ kubectl explain deployment.spec.replicas
1.3 使用kubectl -s ( ) get componentstatuses 查看各组件信息时可能会报错,以下为解决办法
解决办法:
问题一解决
$ vim /etc/kubernetes/manifests/kube-scheduler.yaml
10 spec:
11 containers:
12 - command:
13 - kube-scheduler
14 - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
15 - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
16 - --bind-address=127.0.0.1
17 - --kubeconfig=/etc/kubernetes/scheduler.conf
18 - --leader-elect=true
19 - --port=0 # 将此行注释或删除
$ vim /etc/kubernetes/manifests/kube-controller-manager.yaml
10 spec:
11 containers:
12 - command:
13 - kube-controller-manager
14 - --allocate-node-cidrs=true
15 - --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
16 - --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
17 - --bind-address=127.0.0.1
18 - --client-ca-file=/etc/kubernetes/pki/ca.crt
19 - --cluster-cidr=10.244.0.0/16
20 - --cluster-name=kubernetes
21 - --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
22 - --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
23 - --controllers=*,bootstrapsigner,tokencleaner
24 - --kubeconfig=/etc/kubernetes/controller-manager.conf
25 - --port=0 # 将此行注释或删除
$ systemctl restart kubelet
重启截图如图:
2. 创建一个pod对象(包含多个镜像,指定命令空间)
2.1 测试yaml文件
#创建命名空间
apiVersion: v1 //可使用kubectl explain namespace查看api版本
kind: Namespace
metadata:
name: project //创建好的命名空间名称
#创建一个pod实现双镜像
---
apiVersion: v1
kind: Pod
metadata:
name: system1
namespace: project
labels:
name: myapp
spec:
containers:
- name: centos
image: centos:7 //创建第一个容器centos
imagePullPolicy: IfNotPresent //如果本地有,就不会向官网进行拉取
command: ["tail","-f","/dev/null"] //创建centos容器时,如果不夯住,容器起不来
- name: nginx //创建第二个容器nginx
image: nginx
imagePullPolicy: IfNotPresent
2.2 查看创建好的namespace信息,pod信息,以及描述信息
2.2.1 查看namespace信息
2.2.2 查看创建好的命名空间的pod信息 需要-n指定命名空间
2.2.3 查看描述信息(创建过程)
[root@master ~]# kubectl describe pod system -n project
2.2.4 查看pod的节点某一个容器的日志,需要使用-c 选择
3. 容器可选择的属性 )
"name": 容器名称
"image": 容器镜像
"command": 容器启动指令
"args": 指令参数
"workingDir": 工作目录
"ports": 容器端口
"env": 环境变量
"resource": 资源限制
"volumeMounts": 卷挂载
"livenessProbe": 存活探针
"readinessProbe": 就绪探针
"startupProbe": 启动探针
"livecycle": 钩子函数
"terminationMessagePath": 容器的异常终止消息的路径,默认在 /dev/termination-log
"imagePullPolicy": 镜像拉去策略
"securityContext": 安全上下文
"stdin": 给容器分配标准输入,类似docker run -i
"tty": 分配终端
4.imagePullPolicy和restartPolicy的三个参数分别代表什 么含义
restartPolicy(pod重启策略,可选参数有:)
1.Always: Pod中的容器无论如何停止都会自动重启.
2.Onfailure: Pod中的容器非正常停止都会自动重启.
3.Never: Pod中的容器无论怎么样都不会自动重启.
imagePullPolicy(镜像拉取策略,可选参数有:)
1.Always: 不管本地有没有,都会去重新拉取
2.IfNotPresent: 如果本地有就不会去拉取.
3.Never: 只用本地镜像,不会去拉取,本地没有就报错.
5.节点选择器
5.1 使用nodeName选择节点
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
name: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 3306
nodeName: node2
查看结果:
5.2 标签选择器(nodeSelector选择器)
5.2.1.查看标签,发现这三个标签后面内容不同,我们可以在此标签下指定node节点.
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
name: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 3306
#使用nodeselector指定节点
nodeSelector:
kubernetes.io/hostname: node2
运行结果查看:
5.2.2 给不同的节点添加标签:
如图可见俩个节点type类型不同,现在我们将mysql运行在node1上,type=cpu
yml文件:
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
name: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 3306
nodeSelector:
type: cpu
查看运行结果是否在node1节点上
#由图可知,实验完成.
6.Pod容器的交互
6.1创建Pod并做本地解析(相当于给容器内部做域名解析)
#命令行创建pod
[root@master kubernetes]# kubectl run test --image=nginx --namespace=default --dry-run -o yaml > test.yaml
1.编写test.yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: test
namespace: default
spec:
containers:
- image: centos:7
name: test
imagePullPolicy: IfNotPresent
command: ["tail","-f","/dev/null"]
hostAliases:
- ip: "192.168.75.120"
hostnames:
- "node1"
- "k8s-node1"
- ip: "192.168.75.130"
hostnames:
- "node2"
- "k8s-node12"
2.运行test.yaml文件
3.进入pod为test里面的容器test
[root@master kubernetes]# kubectl exec -it test -c test /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@test /]#
4.查看域名解析并且使用ping命令
由上图可知,容器内域名解析完成.
7.pod共享进程
7.1 编写pod yaml文件(在spec模块添加 shareProcessNamespace: true)
1.编写yaml文件
apiVersion: v1
kind: Pod
metadata:
name: shareprocess
spec:
shareProcessNamespace: true
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
2.运行,有下图可知:shareprocess运行在node服务器上
3.在node2服务器查看进程,由图可知进程已经共享
8.Pod共用宿主机
1.需要添加三个键值
hostNetwork: true #共享宿主机网络
hostIPC: true #共享ipc通信
hostPID: true #共享宿主机的pid
2. 编写yaml文件
[root@master kubernetes]# vim shareprocess.yaml
apiVersion: v1
kind: Pod
metadata:
name: shareprocess
spec:
hostNetwork: true #共享宿主机网络
hostPID: true #共享宿主机的pid
hostIPC: true #共享IPC通信
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
3.运行此文件
[root@master kubernetes]# kubectl apply -f shareprocess.yaml
pod/shareprocess created
[root@master kubernetes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
shareprocess 1/1 Running 0 17s 192.168.75.130 node2 <none> <none>
[root@master kubernetes]#
4.由上图可知我们的程序运行在了node2节点上,此时我们去node2节点上查看nginx端口是否共享,因为我们文件写的nginx的80端口,如果端口存在,我们去浏览器进行访问,查看是否可以成功.
5.由上图可知,端口已经共享到主机,此时去浏览器访问80端口,发现可以访问,实验成功.
9. 钩子函数lifecycle
9.1.postStart 和 preStop的使用
1.概念:
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
2.编写yaml文件
[root@master kubernetes]# vim shareprocess.yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
#启动容器之后执行的命令
lifecycle:
postStart:
exec:
command:
- /bin/bash
- -c #执行字符串中的指令
- "echo 'nginx-test lifecycle' > /usr/share/nginx/html/index.html "
#关闭容器后执行的命令
preStop:
exec:
command: ["/bin/bash","-c","echo '停止nginx30秒'> /usr/share/nginx/html/index.html","sleep 30"]
3.运行上述yaml文件
[root@master kubernetes]# kubectl apply -f shareprocess.yaml
pod/lifecycle created
[root@master kubernetes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
lifecycle 1/1 Running 0 20s 10.244.166.138 node1 <none> <none>
#此时,pod已经运行成功,我们去curl 10.244.166.138
[root@master kubernetes]# curl 10.244.166.138
nginx-test lifecycle
#发现nginx默认页面在容器启动之后已经被改了
9.2 在启动容器时请求某个端口,比如本地的80端口
1.编写yaml文件
[root@master kubernetes]# vim shareprocess.yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
httpGet:
path: / # URI地址
port: 80 # 端口号
host: 192.168.75.110 # 主机地址
scheme: HTTP
2.运行此yaml文件
[root@master kubernetes]# kubectl apply -f shareprocess.yaml
#查看描述信息:
[root@master kubernetes]# kubectl describe pod lifecycle
Normal Scheduled 12s default-scheduler Successfully assigned default/lifecycle to node1
Normal Pulling 11s kubelet Pulling image "nginx"
Normal Pulled 11s kubelet Successfully pulled image "nginx" in 609.620947ms
Normal Created 11s kubelet Created container nginx
Normal Started 11s kubelet Started container nginx
# 查看pod节点信息
[root@master kubernetes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
lifecycle 1/1 Running 0 71s 10.244.166.140 node1 <none> <none>
3.当我们修改启动容器后访问的端口时,比如改为90端口,并且修改ip,如果访问不到那么这个pod就起不来
[root@master kubernetes]# vim shareprocess.yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
httpGet:
path: / # URI地址
port: 90 # 端口号
host: 192.168.75.153 # 主机地址
scheme: HTTP
运行yaml文件,从描述信息发现起不来,因为访问不到这个ip,所以起不来
[root@master kubernetes]# kubectl describe pod lifecycle
9.3 容器探针
1. 以文件作文参考
[root@kub-k8s-master ~]# cd prome/
[root@kub-k8s-master prome]# vim test-liveness-exec.yaml
---
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: test-liveness-exec
spec:
containers:
- name: liveness
image: daocloud.io/library/nginx
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 50
livenessProbe: #探针,健康检查
exec: #类型
command: #命令
- cat
- /tmp/healthy
initialDelaySeconds: 5 #健康检查,在容器启动5s后开始执行
periodSeconds: 5 #每5s执行一次
#创建pod
[root@kub-k8s-master prome]# kubectl apply -f test-liveness-exec.yaml
pod/test-liveness-exec created
#查看Pod的状态
[root@kub-k8s-master prome]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-configmap 1/1 Running 0 16h
nginx-pod 1/1 Running 0 12h
test-liveness-exec 1/1 Running 0 75s
由于已经通过了健康检查,这个 Pod 就进入了 Running 状态。
然后30 s 之后,再查看一下 Pod 的 Events:
```
[root@kub-k8s-master prome]# kubectl describe pod test-liveness-exec
```
发现,这个 Pod 在 Events 报告了一个异常:
```
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Unhealthy 54s (x9 over 3m34s) kubelet, kub-k8s-node1 Liveness probe failed: cat: /tmp/healthy: No such file or directory
```
这个健康检查探查到 /tmp/healthy 已经不存在了,所以它报告容器是不健康的。那么接下来会发生什么呢?
再次查看一下这个 Pod 的状态:
```
[root@kub-k8s-master prome]# kubectl get pod test-liveness-exec
NAME READY STATUS RESTARTS AGE
test-liveness-exec 1/1 Running 4 5m19s
```
这时发现,Pod 并没有进入 Failed 状态,而是保持了 Running 状态。这是为什么呢?
> RESTARTS 字段从 0 到 1 的变化,就明白原因了:这个异常的容器已经被 Kubernetes 重启了。在这个过程中,Pod 保持 Running 状态不变。
> #注
> k8s 中并没有 Docker 的 Stop 语义。所以如果容器被探针检测到有问题,查看状态虽然看到的是 Restart,但实际却是重新创建了容器。
>
> 这个功能就是 Kubernetes 里的Pod 恢复机制,也叫 restartPolicy。它是 Pod 的 Spec 部分的一个标准字段(pod.spec.restartPolicy),默认值是 Always,即:任何时候这个容器发生了异常,它一定会被重新创建。
2.以某一个服务端口进行参考 http get方式探针
[root@kub-k8s-master prome]# vim liveness-httpget.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: daocloud.io/library/nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe: #探针,健康检查
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
#创建该pod
[root@kub-k8s-master prome]# kubectl create -f liveness-httpget.yaml
pod/liveness-httpget-pod created
#查看当前pod的状态
[root@kub-k8s-master prome]# kubectl describe pod liveness-httpget-pod
...
Liveness: http-get http://:http/index.html delay=1s timeout=1s period=3s #success=1 #failure=3
#登录容器
测试将容器内的index.html删除掉
[root@kub-k8s-master prome]# kubectl exec -it liveness-httpget-pod /bin/bash
root@liveness-httpget-pod:/# mv /usr/share/nginx/html/index.html index.html
root@liveness-httpget-pod:/# command terminated with exit code 137
可以看到,当把index.html移走后,这个容器立马就退出了。
#此时查看pod信息
[root@kub-k8s-master prome]# kubectl describe pod liveness-httpget-pod
...
Normal Killing 49s kubelet, kub-k8s-node2 Container liveness-exec-container failed liveness probe, will be restarted
Normal Pulled 49s kubelet, kub-k8s-node2 Container image "daocloud.io/library/nginx" already present on machine
...
#看输出,容器由于健康检查未通过,pod会被杀掉,并重新创建
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
lifecycle-demo 1/1 Running 1 34h
liveness-httpget-pod 1/1 Running 1 5m42s
#restarts 为 1
#重新登录容器,发现index.html又出现了,说明容器被重新构建
[root@kub-k8s-master prome]# kubectl exec -it liveness-httpget-pod /bin/bash
root@liveness-httpget-pod:/# cat /usr/share/nginx/html/index.html
#以上为pod所有实验.