K8S基础 - 03Pod入门
一、 Pod概念
1.1 每个Pod内都有一个根容器: pause容器
1.2 Pod存在的意义
- 创建容器使用docker, 一个docker容器对于一个应用程序,一个容器一个进程
- Pod是多进程设计的,运行多个应用程序
- 为了亲密性的应用: 两个应用之间进行交互; 网络之间调用; 两个应用需要频繁调用
1.3 Pod 内部共享
- 容器之间默认是相互隔离的,依赖于 Namespace 和 CGroup 机制
- 共享网络: 通过Pause容器, 把其他业务容器 加入到Pause容器里,让所有业务容器在同一命名空间中,实现网络共享
- 共享存储: 引入数据卷概念Volume,使用数据卷进行持久化存储
二、命令创建Pod
2.1 kubectl run 创建Pod
[root@k8s-node31 ~]# kubectl run nginx-deploy --image=nginx:1.20.0-alpine --port=80 --replicas=1 --dry-run=true
Flag --replicas has been deprecated, has no effect and will be removed in the future.
W1005 10:17:03.359048 112699 helpers.go:567] --dry-run=true is deprecated (boolean value) and can be replaced with --dry-run=client.
pod/nginx-deploy created (dry run)
[root@k8s-node31 ~]# kubectl run nginx-deploy --image=nginx:1.20.0-alpine --port=80 --dry-run=client
pod/nginx-deploy created (dry run)
[root@k8s-node31 ~]# kubectl run nginx-deploy --image=nginx:1.20.0-alpine --port=80
pod/nginx-deploy created
[root@k8s-node31 ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 1 1 1 2d1h
2.2 kubectl expose 暴露端口
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name]
[--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]
[root@k8s-node31 ~]# kubectl expose pod nginx-deploy --name=nginx-svc --port=80 --target-port=80 --protocol=TCP
service/nginx-svc exposed
[root@k8s-node31 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 115d
nginx-svc ClusterIP 10.108.204.249 <none> 80/TCP 8s
[root@k8s-node31 ~]# curl 10.108.204.249
[root@k8s-node31 ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 19d
[root@k8s-node31 ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-f9fd979d6-679dg 1/1 Running 4 19d
coredns-f9fd979d6-j74z9 1/1 Running 5 19d
[root@k8s-node31 ~]# kubectl exec -it nginx-deploy -- /bin/sh
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local bearpx.com
options ndots:5
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19d
svc-nginx NodePort 10.107.97.86 <none> 80:30088/TCP 2d23h
2.3 测试服务访问: 宿主机、Pod
[root@k8s-master ~]# yum install bind-utils
[root@k8s-master ~]# dig -t A svc-nginx.default.svc.cluster.local @10.96.0.10
; <<>> DiG 9.11.26-RedHat-9.11.26-4.el8_4 <<>> -t A svc-nginx.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45483
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 3db51b9f60c4708e (echoed)
;; QUESTION SECTION:
;svc-nginx.default.svc.cluster.local. IN A
;; ANSWER SECTION:
svc-nginx.default.svc.cluster.local. 30 IN A 10.107.97.86
;; Query time: 2 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 六 10月 23 10:27:16 CST 2021
;; MSG SIZE rcvd: 127
[root@k8s-master ~]# kubectl run client --image=busybox --replicas=1 -it --restart=Never
/ # wget -O - -q http://svc-nginx:80/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
三、YAML文件创建Pod
3.1 命令创建的局限
# 使用kubectl run 只能创建一个Pod
[root@k8s-master ~]# kubectl run mynginx --image=sun2010wg/my-nginx:v1 --replicas=3
Flag --replicas has been deprecated, has no effect and will be removed in the future.
pod/mynginx created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mynginx 1/1 Running 0 12s
[root@k8s-master ~]# kubectl delete pod mynginx
pod "mynginx" deleted
# 获取yaml文件 [root@k8s-master ~]# kubectl create deployment web --image=nginx -o yaml --dry-run=client > my1.yml [root@k8s-master ~]# kubectl get deployment nginx -o=yaml > my2.yml
3.2 自主式Pod资源
资源的清单格式:
apiVersion(group/version), kind, metadata(name, namespace, labels,annotations,...),spec, status(只读)
[root@k8s-master ~]# kubectl explain pod KIND: Pod VERSION: v1 FIELDS: apiVersion <string> kind <string> metadata <Object> spec <Object> status <Object>
镜像拉取策略IfNotPresent
- IfNotPresent: 默认值, 镜像在宿主机上不存在时才会拉取
- Always: 每次创建Pod都会重新拉取镜像
- Never: Pod永远不会主动拉取镜像
[root@k8s-master pod-k8s]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: demo
tier: frontend
spec:
containers:
- name: mynginx
image: sun2010wg/my-nginx:v1
imagePullPolicy: IfNotPresent ### Always, Never, IfNotPresent
restartPolicy: Always
容器重启策略restartPolicy:
- Always: 当容器终止退出后,总是重启容器, 默认策略
- OnFailure: 当容器异常退出(退出状态码非0)时, 才会重启容器
- Never: 当容器终止退出, 不会重启容器
使用command和args 修改镜像中的默认应用
[root@k8s-master pod-k8s]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: demo
tier: frontend
spec:
containers:
- name: mynginx
image: sun2010wg/my-nginx:v1
- name: busybox
image: busybox
# command: ["/bin/sh", "-c" "sleep 3600"]
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
3.3 Pod控制器
[root@k8s-master pod-k8s]# cat dep-mynginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mynginx-app
spec:
replicas: 2
selector:
matchLabels:
app: mynginx
template:
metadata:
labels:
app: mynginx
spec:
containers:
- name: mynginx
image: sun2010wg/my-nginx:v1
imagePullPolicy: Never
ports:
- containerPort: 80
[root@k8s-master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
mynginx-app 2/2 2 2 10m
[root@k8s-master pod-k8s]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
mynginx-app-bddc44777-fx6gj 1/1 Running 1 2d10h app=mynginx,pod-template-hash=bddc44777
mynginx-app-bddc44777-p9lkh 1/1 Running 1 2d10h app=mynginx,pod-template-hash=bddc44777
3.4 使用Service暴露端口
[root@k8s-master pod-k8s]# cat svc-mynginx.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-mynginx
spec:
type: NodePort
selector:
app: mynginx
ports:
- name: http
nodePort: 30089
port: 80
targetPort: 80
[root@k8s-master ~]# kubectl apply -f svc-mynginx.yaml
service/svc-mynginx created
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
svc-mynginx NodePort 10.109.228.159 <none> 80:30089/TCP 10s
使用Service IP地址访问
/ # wget -O - -q 10.109.228.159/hostname.html
mynginx-app-cbc4dcd5d-79lvd
/ # wget -O - -q 10.109.228.159/hostname.html
mynginx-app-cbc4dcd5d-9dbb5
/ # wget -O - -q 10.109.228.159/hostname.html
mynginx-app-cbc4dcd5d-79lvd
/ # wget -O - -q 10.109.228.159/hostname.html
mynginx-app-cbc4dcd5d-79lvd
/ # wget -O - -q 10.109.228.159/hostname.html
mynginx-app-cbc4dcd5d-79lvd
/ # wget -O - -q 10.109.228.159/hostname.html
mynginx-app-cbc4dcd5d-9dbb5
使用Service 名称访问
/ # wget -O - -q svc-mynginx/hostname.html
mynginx-app-cbc4dcd5d-79lvd
/ #
/ # wget -O - -q svc-mynginx/hostname.html
mynginx-app-cbc4dcd5d-9dbb5
/ # while true; do wget -O - -q svc-mynginx/hostname.html; sleep 1; done
mynginx-app-cbc4dcd5d-79lvd
mynginx-app-cbc4dcd5d-9dbb5
mynginx-app-cbc4dcd5d-9dbb5
mynginx-app-cbc4dcd5d-79lvd
mynginx-app-cbc4dcd5d-9dbb5
mynginx-app-cbc4dcd5d-9dbb5
mynginx-app-cbc4dcd5d-9dbb5
[root@k8s-master pod-k8s]# kubectl edit svc svc-mynginx
Edit cancelled, no changes made.
四、Pod管理
4.1 扩展Pod数量
[root@k8s-master ~]# kubectl scale --replicas=3 deployment mynginx-app
deployment.apps/mynginx-app scaled
[root@k8s-master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
mynginx-app 3/3 3 3 17m
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mynginx-app-cbc4dcd5d-79lvd 1/1 Running 0 17m
mynginx-app-cbc4dcd5d-9dbb5 1/1 Running 0 17m
mynginx-app-cbc4dcd5d-l6flg 1/1 Running 0 25s
/ # while true; do wget -O - -q svc-mynginx/hostname.html; sleep 1; done
mynginx-app-cbc4dcd5d-l6flg
mynginx-app-cbc4dcd5d-79lvd
mynginx-app-cbc4dcd5d-9dbb5
mynginx-app-cbc4dcd5d-l6flg
4.2 更新容器的镜像
[root@k8s-master ~]# kubectl set image deployment mynginx-app mynginx=sun2010wg/my-nginx:v2
deployment.apps/mynginx-app image updated
[root@k8s-master ~]# kubectl edit deploy mynginx-app
Edit cancelled, no changes made.
[root@k8s-master ~]# kubectl set image deployment mynginx-app mynginx=sun2010wg/my-nginx:v1
deployment.apps/mynginx-app image updated
### 查看滚动更新进度
[root@k8s-master ~]# kubectl rollout status deployment mynginx-app
Waiting for deployment "mynginx-app" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "mynginx-app" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "mynginx-app" rollout to finish: 2 old replicas are pending termination...
Waiting for deployment "mynginx-app" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "mynginx-app" rollout to finish: 1 old replicas are pending termination...
deployment "mynginx-app" successfully rolled out
每次更新都是生成新的Pod
/ # while true; do wget -O - -q svc-mynginx/hostname.html; sleep 1; done
mynginx-app-bddc44777-jvcrt
mynginx-app-bddc44777-c2msr
mynginx-app-bddc44777-lzgjr
### 回滚到上一次配置
[root@k8s-master ~]# kubectl rollout undo deployment mynginx-app
deployment.apps/mynginx-app rolled back
/ # while true; do wget -O - -q svc-mynginx/hostname.html; sleep 1; done
mynginx-app-cbc4dcd5d-b276w
mynginx-app-cbc4dcd5d-r8q8p
mynginx-app-cbc4dcd5d-f8cwz
4.3 更新Service配置
可以访问集群中的任意节点IP:30088
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
nodePort: 30088
port: 80
targetPort: 80
[root@k8s-master pod-k8s]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx NodePort 10.107.97.86 <none> 80:30088/TCP 2d23h
4.4 Pod中多个容器
[root@k8s-master pod-k8s]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo ### Pod名称
namespace: default
labels:
app: demo
tier: frontend
spec:
containers:
- name: mynginx ### 容器名称
image: sun2010wg/my-nginx:v1
- name: busybox
image: busybox
# command: ["/bin/sh", "-c" "sleep 3600"]
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
[root@k8s-master ~]# curl 10.244.3.10/hostname.html
pod-demo
[root@k8s-master ~]# kubectl logs pod-demo mynginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/10/23 06:36:31 [notice] 1#1: using the "epoll" event method
2021/10/23 06:36:31 [notice] 1#1: nginx/1.20.0
2021/10/23 06:36:31 [notice] 1#1: built by gcc 10.2.1 20201203 (Alpine 10.2.1_pre1)
2021/10/23 06:36:31 [notice] 1#1: OS: Linux 4.18.0-193.28.1.el8_2.x86_64
2021/10/23 06:36:31 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/10/23 06:36:31 [notice] 1#1: start worker processes
2021/10/23 06:36:31 [notice] 1#1: start worker process 23
2021/10/23 06:36:31 [notice] 1#1: start worker process 24
10.244.0.0 - - [23/Oct/2021:06:37:10 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.1" "-"
10.244.0.0 - - [23/Oct/2021:06:37:16 +0000] "GET /hostname.html HTTP/1.1" 200 9 "-" "curl/7.61.1" "-"
Pod内的多个容器共享网络,文件系统独立
[root@k8s-master ~]# kubectl exec -it pod-demo -c mynginx -- /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP
link/ether ae:22:0d:cd:c1:b7 brd ff:ff:ff:ff:ff:ff
inet 10.244.3.10/24 brd 10.244.3.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ls
bin docker-entrypoint.sh lib opt run sys var
dev etc media proc sbin tmp
docker-entrypoint.d home mnt root srv usr
/ # exit
[root@k8s-master ~]# kubectl exec -it pod-demo -c busybox -- /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue
link/ether ae:22:0d:cd:c1:b7 brd ff:ff:ff:ff:ff:ff
inet 10.244.3.10/24 brd 10.244.3.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
~ # cd /
/ # ls
bin dev etc home proc root sys tmp usr var
/ # mkdir /data
/ # exit
4.5 删除Pod
[root@k8s-master ~]# kubectl delete -f pod-demo.yaml
pod "pod-demo" deleted
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Terminating 0 4m30s
五、标签
- key=value
- key: 字母、数字、_(下划线)、-(中划线)
- value:可以为空,只能以字母或数字开头及结尾,中间可使用
5.1 查看标签,筛选Pod
[root@k8s-master ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS client 1/1 Running 0 4h38m run=client # 默认标记 mynginx-app-bddc44777-fx6gj 1/1 Running 0 3h28m app=mynginx,pod-template-hash=bddc44777 mynginx2 1/1 Running 0 3h38m run=mynginx2 nginx-app-c6744f88d-bc6k2 1/1 Running 1 16h app=nginx,pod-template-hash=c6744f88d
[root@k8s-master ~]# kubectl get pods -L app # 显示app的值 NAME READY STATUS RESTARTS AGE APP client 1/1 Running 0 4h38m mynginx-app-bddc44777-fx6gj 1/1 Running 0 3h29m mynginx mynginx2 1/1 Running 0 3h39m nginx-app-c6744f88d-bc6k2 1/1 Running 1 16h nginx # 标签中有key为app的Pod [root@k8s-master ~]# kubectl get pods -l app NAME READY STATUS RESTARTS AGE mynginx-app-bddc44777-fx6gj 1/1 Running 0 3h29m nginx-app-c6744f88d-bc6k2 1/1 Running 1 16h [root@k8s-master ~]# kubectl get pods -l app --show-labels NAME READY STATUS RESTARTS AGE LABELS mynginx-app-bddc44777-fx6gj 1/1 Running 0 3h30m app=mynginx,pod-template-hash=bddc44777 nginx-app-c6744f88d-bc6k2 1/1 Running 1 16h app=nginx,pod-template-hash=c6744f88d
5.2 给Pod添加Label
[root@k8s-master ~]# kubectl label pods pod-demo release=canary
pod/pod-demo labeled
[root@k8s-master ~]# kubectl label pods pod-demo release=stable --overwrite
pod/pod-demo labeled
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 85s app=demo,release=stable,tier=frontend
5.3 查询符合多个标签的Pod
[root@k8s-master ~]# kubectl get pods -L app,run
NAME READY STATUS RESTARTS AGE APP RUN
client 1/1 Running 0 4h40m client
mynginx-app-bddc44777-fx6gj 1/1 Running 0 3h30m mynginx
mynginx2 1/1 Running 0 3h40m mynginx2
nginx-app-c6744f88d-bc6k2 1/1 Running 1 16h nginx
[root@k8s-master ~]# kubectl get pods -l release, app # 不能带空格
error: name cannot be provided when a selector is specified
[root@k8s-master ~]# kubectl get pods -l release,app
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 4m19s
5.4 标签选择器
- 等值关系: =, ==, !=
- 集合关系:
- KEY in (value1, value2,...) KEY notin (value1, value2,...)
- KEY !KEY
- 许多资源支持内嵌字段定义其使用的标签选择器: matchLabels
- matchExpressions: 基于给定的表达式来定义使用标签选择器。 {key:"KEY", operator:"OPERATOR",values:[VAL1,VAL2,...]}
- 操作符: In, NotIn: Values字段的值必须为非空列表; Exists, NotExists: values字段的值必须为非空列表
[root@k8s-master ~]# kubectl get pods -l release=stable,app=mynginx
No resources found in default namespace.
[root@k8s-master ~]# kubectl get pods -l release=stable,app=demo
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 4m43s
[root@k8s-master ~]# kubectl get pods -l "release in (stable, beta)"
[root@k8s-master ~]# kubectl get pods -l "release notin (alpha, beta)"
5.5 节点选择标签
[root@k8s-master ~]# kubectl label nodes k8s-node33.bearpx.com disktype=ssd
node/k8s-node33.bearpx.com labeled
[root@k8s-master pod-k8s]# cat pod-ssd.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-ssd
namespace: default
labels:
app: ssd
annotations:
kunking.com/created-by: cluster admin
spec:
containers:
- name: mynginx
image: sun2010wg/my-nginx:v1
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
nodeSelector:
disktype: ssd
[root@k8s-master ~]# kubectl apply -f pod-ssd.yaml
pod/pod-ssd created
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-ssd 1/1 Running 0 24s 10.244.2.13 k8s-node33.bearpx.com <none> <none>
5.6 annotations
与labels不同的地方在于, 它不能用于挑选资源对象, 仅用于为对象提供"元数据"。
[root@k8s-master ~]# kubectl describe pod pod-ssd
Name: pod-ssd
Namespace: default
Priority: 0
Node: k8s-node33.bearpx.com/192.168.6.33
Start Time: Sat, 23 Oct 2021 15:28:20 +0800
Labels: app=ssd
Annotations: kunking.com/created-by: cluster admin
Status: Running
IP: 10.244.2.15