kubectl explain pod #查看pod字段说明
kubectl explain pod.apiVersion #查看pod.apiVersion字段说明
kubectl explain pod.spec #查看pod.spec字段说明
kubectl explain pod.spec.containers #查看pod.spec.containers字段说明
cat > pod.yml <
kubectl get deployment
kubectl delete deployment --all #删除所有default命名空间的deployment
kubectl get pod
kubectl delete pod --all #删除所有default命名空间的pod
kubectl get svc
kubectl delete svc nginx-deployment #删除default命名空间的nginx-deployment
定义一个init-pod.yml,其中有两个initc,和manc。
cat > init-pod.yml < myservice.yml < mydb.yml <
使用httpGet,检测是否存在index1.html,当访问/index1.html返回200时,READY状态将被标记为1/1。
cat > readness.yml <index1.html
exit
#此时查看pod,READY是 1/1。
kubectl get pod
容器启动时,创建一个文件/tmp/live,等待60秒后删除。livenessProbe,检测/tmp/live是否存在,如果不存在表示容器提供服务异常,容器会重启。创建下面pod最终效果是,隔60秒后,服务会重启。
cat > liveness.yml <
效果如下:
[root@k8s-master01 install-k8s]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
liveness-exec-pod 1/1 Running 0 53s
liveness-exec-pod 1/1 Running 1 118s
liveness-exec-pod 1/1 Running 2 3m36s
liveness-exec-pod 1/1 Running 3 5m16s
httpget的方式监测/index.html,当手动删除/index.html后,会重建pod。
cat > liveness-httpget.yml <
最终效果:
[root@k8s-master01 install-k8s]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
liveness-httpget-pod 1/1 Running 0 14s
liveness-httpget-pod 1/1 Running 1 89s
创建一个pod,暴露80端口,在livenessProbe中,使用TCPSocket监测8110,他会一直重启。
cat > liveness-tcp.yml <
最终效果:
[root@k8s-master01 install-k8s]# kubectl get pod -w
probe-tcp 1/1 Running 0 1s
probe-tcp 1/1 Running 1 29s
probe-tcp 1/1 Running 2 58s
probe-tcp 1/1 Running 3 88s
probe-tcp 1/1 Running 4 119s
probe-tcp 0/1 CrashLoopBackOff 4 2m29s
probe-tcp 1/1 Running 5 3m14s
probe-tcp 0/1 CrashLoopBackOff 5 3m39s
创建一个pod,httpget监测index.html是否存在,如果存在容器启动完成。启动后,httpget监测index.html是否存在,如果存在表示存活。
cat > readness-liveness-httpget.yml <
容器启动时,打印一句日志。容器退出时打印一句日志。
cat > start-stop.yml < /usr/share/message"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStop handler > /usr/share/message"]
EOF
kubectl create -f start-stop.yml
cat > rs.yml <
操作效果:
[root@k8s-master01]# kubectl apply -f rs.yml #创建rs
replicaset.extensions/frontend created
[root@k8s-master01 controller-study]# kubectl get rs #查看rs
NAME DESIRED CURRENT READY AGE
frontend 3 3 3 17s
[root@k8s-master01]# kubectl get pod --show-labels #查看pod,并查看labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-rjrsw 1/1 Running 0 73s tier=frontend
frontend-vlqwv 1/1 Running 0 73s tier=frontend
frontend-wfcmw 1/1 Running 0 73s tier=frontend
[root@k8s-master01]# kubectl label pod frontend-vlqwv tier=frontend1 --overwrite=True #修改其中的一个pod的label
pod/frontend-vlqwv labeled
[root@k8s-master01]# kubectl get pod --show-labels #再查看时,会多出一个pod,因为label修改过之后,label的数量不够3了,就会再创建一个
NAME READY STATUS RESTARTS AGE LABELS
frontend-rjrsw 1/1 Running 0 2m2s tier=frontend
frontend-tv7n8 1/1 Running 0 6s tier=frontend
frontend-vlqwv 1/1 Running 0 2m2s tier=frontend1
frontend-wfcmw 1/1 Running 0 2m2s tier=frontend
[root@k8s-master01]# kubectl delete rs --all #删除所有rs
replicaset.extensions "frontend" deleted
[root@k8s-master01]# kubectl get pod --show-labels #再查看pod时,会看到上句只删除了tier=frontend的pod,tier=frontend1的pod并没有删除
NAME READY STATUS RESTARTS AGE LABELS
frontend-vlqwv 1/1 Running 0 2m44s tier=frontend1
创建deployment,deployment会创建rs,利用rs维护pod。
cat > deployment.yml <
假如您创建了一个有5个 niginx:1.7.9 replica的 Deployment,但是当还只有3个 nginx:1.7.9 的 replica 创建出来的时候您就开始更新含有5个 nginx:1.9.1 replica 的 Deployment。在这种情况下,Deployment 会立即杀掉已创建的3个 nginx:1.7.9 的 Pod,并开始创建 nginx:1.9.1 的 Pod。它不会等到所有的5个 nginx:1.7.9 的Pod 都创建完成后才开始改变航道
可以通过设置 .spec.revisonHistoryLimit 项来指定 deployment 最多保留多少 revision 历史记录。默认的会保留所有的 revision;如果将该项设置为0,Deployment 就不允许回退了
daemonset会维护每个节点有且只有一个pod。
cat > daemonset.yml <
操作如下:
[root@k8s-master01]# kubectl get pod -o wide #查看pod,在node01,node02上都有一个pod
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deamonset-example-chwrs 1/1 Running 0 18s 10.244.2.54 k8s-node02
deamonset-example-zz6nr 1/1 Running 0 18s 10.244.1.54 k8s-node01
[root@k8s-master01]# kubectl delete pod deamonset-example-chwrs #删除一个pod
pod "deamonset-example-chwrs" deleted
[root@k8s-master01]# kubectl get pod -o wide #再查看时,还是显示 node01,node02上都有一个pod
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deamonset-example-kmptk 1/1 Running 0 2s 10.244.2.55 k8s-node02
deamonset-example-zz6nr 1/1 Running 0 2m14s 10.244.1.54 k8s-node01
通过job管理pod。
例子实现功能:使用perl镜像构建,计算pi的后2000位
cat > job.yml <
周期性执行任务。cronjob会创建job,通过job管理pod。
例子实现功能:每一分钟创建一个新的job,打印一句时间日志。
cat > cronjob.yml
先部署一个deployment,然后再通过svc代理。
svc通过label匹配pod,然后再实现代理。
cat > svc-deployment.yml < svc.yml <
操作如下:
[root@k8s-master01 service]# kubectl get svc #查看svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 2d19h
myapp ClusterIP 10.99.87.110 80/TCP 26s
[root@k8s-master01 service]# ipvsadm -Ln #查看ipvs代理,可以看到有10.99.87.110的代理
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.96.0.1:443 rr
-> 192.168.183.10:6443 Masq 1 3 0
TCP 10.96.0.10:53 rr
-> 10.244.0.14:53 Masq 1 0 0
-> 10.244.0.15:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 10.244.0.14:9153 Masq 1 0 0
-> 10.244.0.15:9153 Masq 1 0 0
TCP 10.99.87.110:80 rr
-> 10.244.1.60:80 Masq 1 0 0
-> 10.244.1.61:80 Masq 1 0 0
-> 10.244.2.62:80 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 10.244.0.14:53 Masq 1 0 0
-> 10.244.0.15:53 Masq 1 0 0
[root@k8s-master01 service]# curl 10.99.87.110 #访问ipvs的地址,可以轮询访问到服务
Hello MyApp | Version: v2 | Pod Name
[root@k8s-master01 service]# curl 10.99.87.110/hostname.html
myapp-deploy-6cc7c66999-4nmz7
[root@k8s-master01 service]# curl 10.99.87.110/hostname.html
myapp-deploy-6cc7c66999-mv68q
[root@k8s-master01 service]# curl 10.99.87.110/hostname.html
myapp-deploy-6cc7c66999-gvxmr
无头服务会代理所有的pod。
svc创建成功之后,会将路由写到coredns里面。命名规则:当前服务名称.命名空间名称.集群名称。默认命名空间名称是:default,默认集群名称为svc.cluster.local.。
cat > svc-headless.yml <
操作效果:
[root@k8s-master01 service]# kubectl get pod -n kube-system -o wide|grep coredns #查看coredns的IP
coredns-5c98db65d4-m84ww 1/1 Running 3 2d20h 10.244.0.15 k8s-master01
coredns-5c98db65d4-mtlqz 1/1 Running 3 2d20h 10.244.0.14 k8s-master01
[root@k8s-master01 service]# dig -t A myapp-headless.default.svc.cluster.local. @10.244.0.14 |grep myapp-headless #通过coredns解析,得到当前所有的pod
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> -t A myapp-headless.default.svc.cluster.local. @10.244.0.14
;myapp-headless.default.svc.cluster.local. IN A
myapp-headless.default.svc.cluster.local. 30 IN A 10.244.1.61
myapp-headless.default.svc.cluster.local. 30 IN A 10.244.1.60
myapp-headless.default.svc.cluster.local. 30 IN A 10.244.2.62
通过NodePort方式发布服务,会再每个节点上暴露一个>30000的随机端口,此时,可以在k8s容器之外访问。
cat > svc-nodeport.yml
最终效果:
[root@k8s-master01 service]# kubectl get svc #查看svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 2d20h
myapp NodePort 10.99.87.110 80:31768/TCP 79m
[root@k8s-master01 service]# ipvsadm -Ln #查看ipvs的录用规则,可以看到192.168.183.10:31768被路由到了10.244.1.60:80、10.244.1.61:80、10.244.2.62:80
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.17.0.1:31768 rr
-> 10.244.1.60:80 Masq 1 0 0
-> 10.244.1.61:80 Masq 1 0 0
-> 10.244.2.62:80 Masq 1 0 0
TCP 192.168.183.10:31768 rr
-> 10.244.1.60:80 Masq 1 0 0
-> 10.244.1.61:80 Masq 1 0 1
-> 10.244.2.62:80 Masq 1 0 1
[root@k8s-master01 service]# netstat -nap|grep :31768 #查看主机暴露的端口31768
tcp6 0 0 :::31768 :::* LISTEN 79184/kube-proxy
此时可以通过下面任意一个地址访问到pod。
http://192.168.183.10:31768
http://192.168.183.20:31768
http://192.168.183.21:31768
ExternalName 可以实现dns导向,即dns层代理。
cat > svc-extrnalname.yml <
最终效果:
[root@k8s-master01 service]# kubectl get svc #查看svc,可以看到my-service-1解析到了hub.hdj.com
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 2d22h
my-service-1 ExternalName hub.hdj.com 6s
[root@k8s-master01 service]# dig -t A my-service-1.default.svc.cluster.local. @10.244.0.14 |grep my-service-1 #根据coredns解析my-service-1,可以得到hub.hdj.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> -t A my-service-1.default.svc.cluster.local. @10.244.0.14
;my-service-1.default.svc.cluster.local. IN A
my-service-1.default.svc.cluster.local. 5 IN CNAME hub.hdj.com.
ingress-nginx地址:https://kubernetes.github.io/ingress-nginx/
由于kubernetes svc只提供了4层代理。如需要实现7层代理,需使用ingress-nginx来扩展。
下载 https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml。
其中用到的镜像:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0 我们直接pull不到,需要将yaml中的quay.io改为中国科技大的镜像:quay.mirrors.ustc.edu.cn 即可。也可以下载好镜像,将镜像上传至每个节点,再导入。我这儿采用第二种方式。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/provider/baremetal/service-nodeport.yaml
tar -zxf ingree.contro.tar.gz
docker load -i ingree.contro.tar
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml
k8s中存储有ConfigMap 、secret、volume、persistent volume、
ConfigMap 一般用来存储配置文件。
mkdir dir
cd dir
cat > game.properties < ui.properties <
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
kubectl describe cm special-config
cat > env/env.yml < apply -f env/pod-env.yml <
表现效果
[root@k8s-master01 configmap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 9s
[root@k8s-master01 configmap]# kubectl log dapi-test-pod #查看日志
log is DEPRECATED and will be removed in a future version. Use logs instead.
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=dapi-test-pod
HOME=/root
PKG_RELEASE=1~buster
SPECIAL_TYPE_KEY=charm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_VERSION=1.17.8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
NJS_VERSION=0.3.8
KUBERNETES_PORT_443_TCP_PROTO=tcp
SPECIAL_LEVEL_KEY=very
log_level=INFO
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
cat > pod-command-env.yml <
最终效果
kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-commond-pod 0/1 Completed 0 6s
dapi-test-pod 0/1 Completed 0 13m
[root@k8s-master01 env]# kubectl log dapi-test-commond-pod
log is DEPRECATED and will be removed in a future version. Use logs instead.
very charm INFO
创建一个pod,将名为special-config的ConfigMap,注册到containers的volumes中起名为config-volume,然后将config-volume挂载到test-container的/etc/config目录中。此时可以在/etc/config目录中看到special-config的configmap。
cat > pod-volumes.yml <
表现效果:
[root@k8s-master01 env]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-volume-pod 0/1 Completed 0 4s
[root@k8s-master01 env]# kubectl logs dapi-test-volume-pod
very
[root@k8s-master01 env]# kubectl exec dapi-test-volume-pod -it -- /bin/bash
root@dapi-test-volume-pod:/# cd /etc/config
root@dapi-test-volume-pod:/etc/config# ls
special.how special.type
root@dapi-test-volume-pod:/etc/config# cat special.how
very
root@dapi-test-volume-pod:/etc/config# cat special.type
charm
cat > hot-update.yml <
kubernetes提供的加密存储密码的方式。
创建一个secret,用户名是admin,密码是:1f2d1e2e67df。采用Opaque类型加密,所以使用base64方式对明文加密。
cat > secrets.yml <
将secret挂载到/etc/mysecret目录中。
cat > pod-secret-volume.yml <
操作效果:
[root@k8s-master01 secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
seret-test 1/1 Running 0 7s
[root@k8s-master01 secret]# kubectl exec seret-test -it -- /bin/sh #进入容器,可以看到/etc/mysecrst目录有password、username,查看时,直接看到明文。
# cd /etc/mysecret
# ls
password username
# cat password
1f2d1e2e67df
# cat username
admin
cat > env-secret.yml <
最终效果:
[root@k8s-master01 secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-deployment-5974888d48-dtmhk 1/1 Running 0 9s
pod-deployment-5974888d48-tsldz 1/1 Running 0 9s
[root@k8s-master01 secret]# kubectl exec pod-deployment-5974888d48-tsldz -it -- /bin/sh #进入容器,查看环境变量,可以得到明文的值
# echo $TEST_USER
admin
# echo $TEST_PASSWORD
1f2d1e2e67df
在kubernetes中,访问docker私有仓库时,需要让kubernetes存在docker仓库认证。
在hub.hdj.com上创建一个私有仓库,privatelib。
给私有仓库中推一个镜像。
docker tag wangyanglinux/myapp:v2 hub.hdj.com/privatelib/wangyanglinux:v2 #标记tag
docker push hub.hdj.com/privatelib/wangyanglinux:v2 #推到私有仓库中
docker logout hub.hdj.com #退出docker在hub.hdj.com的登录
docker pull hub.hdj.com/privatelib/wangyanglinux:v2 #此时拉取镜像时,需要登录
创建 docker registry 认证的 secret
kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
操作效果:
[root@k8s-master01 secret]# kubectl create secret docker-registry myregistrykey --docker-server=hub.hdj.com --docker-username=admin --docker-password=Harbor12345 [email protected]
secret/myregistrykey created
创建pod,
cat > privatelib-pod.yml <
多容器之间文件共享,文件长期保持。
kubernetes支持的卷类型:
awsElasticBlockStore azureDisk azureFile cephfs csi downwardAPI emptyDir
fc flocker gcePersistentDisk gitRepo glusterfs hostPath iscsi local nfs
persistentVolumeClaim projected portworxVolume quobyte rbd scaleIO secret
storageos vsphereVolume
每次pod重建的时候会重置emptyDir为空目录。但是pod崩溃不会丢失emptyDir的数据。
挂载一个emptyDir的volume,将这个volume挂载到两个container中,在test-container1中的挂载目录是:/cache/c1,在test-container2中的挂载目录是:/cache/c2。
cat > emptyDir.yml <
操作效果:
进入test-container1中/cache/c1目录下,写一个date >> index.html
kubectl exec test-pd -c test-container1 -it -- /bin/sh
# cd /cache/c1
# date >> index.html
# cat index.html
Tue Feb 11 23:33:17 UTC 2020
进入test-container2中/cache/c2目录下,查看index.html,可以看到刚才在test-container1中写入的时间。再写一个date >> index.html
[root@k8s-master01 ~]# kubectl exec test-pd -c test-container2 -it -- /bin/sh
/ # cd /cache/c2
# cat index.html
Tue Feb 11 23:33:17 UTC 2020
/cache/c2 # date >> index.html
/cache/c2 # cat index.html
Tue Feb 11 23:33:17 UTC 2020
Tue Feb 11 23:34:27 UTC 2020
再进入test-container1中/cache/c1目录下,查看index.html,可以看到刚才在test-container2中写入的时间。
kubectl exec test-pd -c test-container1 -it -- /bin/sh
# cd /cache/c1
# cat index.html
Tue Feb 11 23:33:17 UTC 2020
Tue Feb 11 23:34:27 UTC 2020
hostPath 将主机节点的文件系统中的文件或目录挂载到集群中。
hostPath 卷的 type有下面一些。
值 | 行为 |
---|---|
空字符串(默认)用于向后兼容,这意味着在挂载 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate | 如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为 0755,与 Kubelet 具有相同的组和所有权。 |
Directory | 给定的路径下必须存在目录 |
FileOrCreate | 如果在给定的路径上没有任何东西存在,那么会根据需要创建一个空文件,权限设置为 0644,与 Kubelet 具有相同的组和所有权。 |
File | 给定的路径下必须存在文件 |
Socket | 给定的路径下必须存在 UNIX 套接字 |
CharDevice | 给定的路径下必须存在字符设备 |
BlockDevice | 给定的路径下必须存在块设备 |
将/data目录挂载到pod中
cat > hostPath.yml <
表现效果:
进入pod中的test-pd目录,写一个date>>index.html
[root@k8s-master01 volumes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-pd 1/1 Running 0 13s 10.244.1.75 k8s-node01
[root@k8s-master01 volumes]# kubectl exec test-pd -it -- /bin/sh
# cd test-pd
# date>>index.html
# cat index.html
Wed Feb 12 01:01:28 UTC 2020
在k8s-node01中的/data目录下,查看index.html ,可以看到在容器中写入的内容,再写入date >> index.html
[root@k8s-node01 data]# cat index.html
Wed Feb 12 01:01:28 UTC 2020
[root@k8s-node01 data]# date >> index.html
[root@k8s-node01 data]# cat index.html
Wed Feb 12 01:01:28 UTC 2020
2020年 02月 12日 星期三 09:01:47 CST
再进入pod中的test-pd目录,查看index.html,可以看到在k8s-node01中写入的内容
[root@k8s-master01 volumes]# kubectl exec test-pd -it -- /bin/sh
# cd test-pd
# cat index.html
Wed Feb 12 01:01:28 UTC 2020
2020年 02月 12日 星期三 09:01:47 CST
PersistentVolume(pv):持久化卷,可以挂载外部的存储服务,如nfs等。
PersistentVolumeClaim(PVC):持久化卷引用,对持久化卷的匹配等。
PersistentVolume 可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个PV 的访问模式都将被设置为该卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能以只读方式导出到服务器上。每个 PV 都有一套自己的用来描述特定功能的访问模式
在命令行中,访问模式缩写为:
Retain(保留)——手动回收
Recycle(回收)——基本擦除( rm -rf /thevolume/* )
Delete(删除)——关联的存储资产(例如 AWS EBS、GCE PD、Azure Disk 和 OpenStack Cinder 卷)将被删除
当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略
下面试下一个nfs通过PV挂载至kubernetes中,再通过pvc挂载至pod中。
安装nfs:
yum install -y nfs-common nfs-utils rpcbind
mkdir /nfsdata
mkdir /nfsdata/nfs{1..3}
ls /nfsdata/
chmod 777 -R /nfsdata/
cat > /etc/exports <>1.html
umount /test/nfs1
rm -rf /test/nfs1
mount -t nfs 192.168.183.100:/nfsdata/nfs1 /test/nfs1 #测试nfs2
cd /test/nfs2
echo 1>>1.html
umount /test/nfs2
rm -rf /test/nfs2
mount -t nfs 192.168.183.100:/nfsdata/nfs1 /test/nfs1 #测试nfs3
cd /test/nfs3
echo 1>>1.html
umount /test/nfs3
rm -rf /test/nfs3
创建三个PV:
cat > pv.yml <
创建PVC:
cat > pvc.yml <
最终效果:
[root@k8s-master01 volumes]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 5d4h
nginx ClusterIP None 80/TCP 80m
[root@k8s-master01 volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfspv1 10Gi RWO Retain Bound default/www-web-2 nfs 89m
nfspv2 5Gi RWO Retain Bound default/www-web-1 nfs 89m
nfspv3 2Gi RWO Retain Bound default/www-web-0 nfs 89m
[root@k8s-master01 volumes]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound nfspv3 2Gi RWO nfs 77m
www-web-1 Bound nfspv2 5Gi RWO nfs 76m
www-web-2 Bound nfspv1 10Gi RWO nfs 76m
[root@k8s-master01 volumes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-0 1/1 Running 0 78m 10.244.2.77 k8s-node02
web-1 1/1 Running 0 77m 10.244.1.76 k8s-node01
web-2 1/1 Running 0 77m 10.244.2.78 k8s-node02
在nfs服务的/nfsdata中写入index.html。
echo "1111111111">>/nfsdata/nfs2/index.html
echo "22222222">>/nfsdata/nfs2/index.html
echo "33333333">>/nfsdata/nfs3/index.html
chown 777 -R /nfsdata
然后访问各个pod暴露的服务,可以得到在nfs服务器中写的内容
[root@k8s-master01 volumes]# curl 10.244.1.76
22222222
[root@k8s-master01 volumes]# curl 10.244.2.77
33333333
[root@k8s-master01 volumes]# curl 10.244.2.78
1111111111
删除一个pod web-0,再次查看pod,可以看到web-0被重建了,再访问web-0,可以得到与之前一样的内容。
[root@k8s-master01 volumes]# kubectl delete pod web-0
pod "web-0" deleted
[root@k8s-master01 volumes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-0 1/1 Running 0 17s 10.244.2.79 k8s-node02
web-1 1/1 Running 0 84m 10.244.1.76 k8s-node01
web-2 1/1 Running 0 84m 10.244.2.78 k8s-node02
[root@k8s-master01 volumes]# curl 10.244.2.79
33333333
创建一个pod,使用$(podname).(headless server name)访问StatefulSet 的pod
cat > test-pd.yml <
进入这个pod,ping web-1,可以看到,可以ping通。
[root@k8s-master01 volumes]# kubectl exec test-pd -it -- /bin/sh #进入这个pod
/ # ping web-1.nginx
PING web-1.nginx (10.244.1.76): 56 data bytes
64 bytes from 10.244.1.76: seq=0 ttl=64 time=0.214 ms
64 bytes from 10.244.1.76: seq=1 ttl=64 time=0.066 ms
删除web-1,查看pod,可以看到web-1已经重建了地址也变了,然后再ping web-1,发现可以ping通。
[root@k8s-master01 volumes]# kubectl delete pod web-1 #删除web-1
pod "web-1" deleted
[root@k8s-master01 volumes]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-pd 1/1 Running 0 8m16s 10.244.1.80 k8s-node01
web-0 1/1 Running 0 88m 10.244.2.79 k8s-node02
web-1 1/1 Running 0 11s 10.244.1.81 k8s-node01
web-2 1/1 Running 0 172m 10.244.2.78 k8s-node02
[root@k8s-master01 volumes]# kubectl exec test-pd -it -- /bin/sh
/ # ping web-1.nginx
PING web-1.nginx (10.244.1.81): 56 data bytes
64 bytes from 10.244.1.81: seq=0 ttl=64 time=0.064 ms
64 bytes from 10.244.1.81: seq=1 ttl=64 time=0.077 ms
通过coredns解析$(servicename).$(namespace).svc.cluster.local。可以得到StatefulSet 的三个地址。
[root@k8s-master01 volumes]# kubectl get pod -n kube-system -o wide|grep coredns #查看coredns地址
coredns-5c98db65d4-m84ww 1/1 Running 7 5d6h 10.244.0.15 k8s-master01
coredns-5c98db65d4-mtlqz 1/1 Running 7 5d6h 10.244.0.14 k8s-master01
[root@k8s-master01 volumes]# dig -t A nginx.default.svc.cluster.local. @10.244.0.14 |grep nginx #通过coredns解析 StatefulSet 的无头服务地址
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> -t A nginx.default.svc.cluster.local. @10.244.0.14
;nginx.default.svc.cluster.local. IN A
nginx.default.svc.cluster.local. 21 IN A 10.244.2.79
nginx.default.svc.cluster.local. 21 IN A 10.244.2.78
nginx.default.svc.cluster.local. 21 IN A 10.244.1.81
[root@k8s-master01 volumes]# kubectl delete -f pvc.yml
service "nginx" deleted
statefulset.apps "web" deleted
[root@k8s-master01 volumes]# kubectl get pod
No resources found.
[root@k8s-master01 volumes]# kubectl get statefulset
No resources found.
[root@k8s-master01 volumes]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 5d6h
[root@k8s-master01 volumes]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound nfspv3 2Gi RWO nfs 3h17m
www-web-1 Bound nfspv2 5Gi RWO nfs 3h16m
www-web-2 Bound nfspv1 10Gi RWO nfs 3h16m
[root@k8s-master01 volumes]# kubectl delete pvc --all
persistentvolumeclaim "www-web-0" deleted
persistentvolumeclaim "www-web-1" deleted
persistentvolumeclaim "www-web-2" deleted
[root@k8s-master01 volumes]# kubectl get pvc
No resources found.
[root@k8s-master01 volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfspv1 10Gi RWO Retain Released default/www-web-2 nfs 3h30m
nfspv2 5Gi RWO Retain Released default/www-web-1 nfs 3h30m
nfspv3 2Gi RWO Retain Released default/www-web-0 nfs 3h30m
[root@k8s-master01 volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfspv1 10Gi RWO Retain Released default/www-web-2 nfs 3h30m
nfspv2 5Gi RWO Retain Released default/www-web-1 nfs 3h30m
nfspv3 2Gi RWO Retain Released default/www-web-0 nfs 3h30m
[root@k8s-master01 volumes]# kubectl get pv nfspv1 -o yaml
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"name":"nfspv1"},"spec":{"accessModes":["ReadWriteOnce"],"capacity":{"storage":"10Gi"},"nfs":{"path":"/nfsdata/nfs1","server":"192.168.183.200"},"persistentVolumeReclaimPolicy":"Retain","storageClassName":"nfs"}}
pv.kubernetes.io/bound-by-controller: "yes"
creationTimestamp: "2020-02-12T09:59:11Z"
finalizers:
- kubernetes.io/pv-protection
name: nfspv1
resourceVersion: "351310"
selfLink: /api/v1/persistentvolumes/nfspv1
uid: 0f3aa860-190a-4bfd-835e-0f7258f7f718
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 10Gi
claimRef:
apiVersion: v1
kind: PersistentVolumeClaim
name: www-web-2
namespace: default
resourceVersion: "333994"
uid: ef02c9a5-1fb4-45f8-b874-9d68e286dfdb
nfs:
path: /nfsdata/nfs1
server: 192.168.183.200
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
volumeMode: Filesystem
status:
phase: Released
[root@k8s-master01 volumes]# kubectl edit pv nfspv1 #修改nfspv1 ,删除claimRef属性,及其子属性
persistentvolume/nfspv1 edited
[root@k8s-master01 volumes]# kubectl get pv #此时可以看到nfspv1状态为Available
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfspv1 10Gi RWO Retain Available nfs 3h33m
nfspv2 5Gi RWO Retain Released default/www-web-1 nfs 3h33m
nfspv3 2Gi RWO Retain Released default/www-web-0 nfs 3h33m
其余两个pv同样方式修改,删除claimRef属性及其子属性,最终效果。
[root@k8s-master01 volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfspv1 10Gi RWO Retain Available nfs 3h39m
nfspv2 5Gi RWO Retain Available nfs 3h39m
nfspv3 2Gi RWO Retain Available nfs 3h39m