1.什么是pod?
Pod是可以创建和管理Kubernetes计算的最小可部署单元,一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker),多个容器间共享IPC、Network和UTC namespace。
Pod是可以创建和管理Kubernetes计算的最小可部署单元,
一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。pod也可以理解为是花生壳,一个pod中好几个花生豆(container),也可能一个pod中一个container,里面的container共享pod内的IP、Network和ns(namespace)等资源,这样就存在容器的多个副本不能直接放在一个pod里的问题,必须靠端口不同来区分一个pod中的不同容器。所有功能都是通过api接口实现。
扩展
默认情况下,master的令牌会在24小时后过期,如果要在当前令牌过期后将节点加入到集群中,可以通过在控制平面节点上运行以下命令来创建新令牌:
kubeadm token create #创建新令牌
kubeadm token list # 查看令牌
k8s命令:kubectl 自动补全功能
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
2.pod中常用的命令
之前为我们已经搭建好k8s集群,其中server1是仓库,server2是master,server3,4是master的worker
(1) 使用命令查看k8s服务
集群提供的IP地址只可以在集群内部访问
外网无法访问
查看flannel环境,可以看到mater主机是0网段
server3是1网段
server4是2网段
(2)部署Deployment、扩容、更新、回滚
创建两个副本
删除一个pod,发现又重新出现了一个pod,但是后面的代码变了,这是因为Deployment控制器的机制,他发现副本数量不足2时,他会自动创建,补足两个副本。
kubectl delete deployment nginx
//彻底删除
kubectl expose deployment demo --port=80 --target-port=80,此时pod客户端可以通过service的名称或ip访问后端的两个Pod,设定可供集群外部访问的虚拟IP
访问此虚拟IP,发现其具有负载均衡式的落在了两个后端上
kubectl describe svc demo 可以详细的看到demo这个服务的虚拟ip和两个后端
[root@server2 ~]# kubectl describe svc demo
Name: demo
Namespace: default
Labels: app=demo
Annotations: <none>
Selector: app=demo
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.104.35.85 ###虚拟IP
IPs: 10.104.35.85
Port: <unset> 80/TCP ###端口
TargetPort: 80/TCP
Endpoints: 10.244.1.4:80,10.244.2.4:80 ##两个后端
Session Affinity: None
Events: <none>
[root@server2 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-546cc8ddd-56992 1/1 Running 0 11m 10.244.1.4 server3 <none> <none>
demo-546cc8ddd-9wsmb 1/1 Running 0 9m30s 10.244.2.4 server4 <none> <none>
使用kubectl get svc 更改类型NodePort,随机分配端口,内部所有节点都能访问,可以实现负载均衡。
NodePort: 在ClusterIP基础上为Service在每台机器上绑定一个端口,这样
就可以通过 NodeIP:NodePort 来访问该服务
Pod扩容与缩容
扩容
用svc可以看到此时集群有6个后端服务
测试一下负载均衡
同理,缩容也很简单,多余的副本会被回收(缩容时,最新创建pod的会被最先删除)
更新镜像版本
镜像从myapp:v1更新为myapp:v2
更新前后两者变化(第一张图为更新前,第二张图为更新后)
可以看到更新后的v2是7bd47bddfc这个,开启的副本数量是2。可以看到5b4fc8bb88的信息也保存着,但是开启的副本数量是0,问什么还要保存他的信息呢?这是因为回滚时的需要。
[root@server2 ~]# kubectl rollout history deployment demo ## 查看历史版本
deployment.apps/demo
REVISION CHANGE-CAUSE
1 <none>
2 <none>
[root@server2 ~]# kubectl rollout undo deployment demo --to-revision=1 ## 回滚版本
deployment.apps/demo rolled back
[root@server2 ~]# curl 10.104.35.85
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
3、资源清单介绍
在k8s中,一般使用yaml格式的文件来创建我们期望产生的pod,该yaml文件称为资源清单,可以减少命令行的使用,减少错误,可重复性好,可以规范化部署,因此备受喜爱
4、资源清单实现
编写myapp.yaml 文件
[root@server2 ~]# cat myapp.yaml
apiVersion: v1 ## 指明api资源属于哪个群组和版本,同一个组可以有多个版本
kind: Pod ## 标记创建的资源类型,k8s主要支持以下资源类别(Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob)
metadata: ## 元数据
name: myapp ## 对象名称
spec: ## 定义目标资源的期望状态
containers:
- name: myapp ##容器名字
image: myapp:v1 ##指定镜像
用myapp.yaml 文件创建pod
修改myapp.yaml 文件
[root@server2 ~]# cat myapp.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp
image: myapp:v2
imagePullPolicy: IfNotPresent ## 优先在已有镜像的服务端创建,不再重复拉取镜像,节省资源
ports: # 定容器所在主机需要监听的端口号,会写到iptables策略中
- containerPort: 80
hostPort: 80 # 利用NAT把物理机的80端口影射到容器的80端口
拉起pod后,节点分配到了server3上,查看iptables
继续修改
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
hostNetwork: true ## 直接将物理机的端口给容器用
containers:
- name: myapp
image: myapp:v2
imagePullPolicy: IfNotPresent
# ports:
# - containerPort: 80
# hostPort: 80
### server3对应172.25.10.3
[root@server3 flannel]# netstat -antlupe | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 478019 11179/nginx: master
##查看端口
再次修改
[root@server2 ~]# cat myapp.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
hostNetwork: true
containers:
- name: myapp
image: myapp:v2
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "100m" ##对CPU和内存的最低限制
memory: "50Mi"
limits:
cpu: "200m" ##对CPU和内存的最高限制
memory: "100Mi"
kubectl describe pod myapp ##查看信息
默认容器副本退出后会自动重启always,这里可以使用never参数设置不重启。退出后,该节点显示已完成,且不会自动重启
设置指定后端起动
[root@server2 ~]# cat myapp.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
nodeName: server4 ## 将server4作为后端启动
hostNetwork: true
containers:
- name: myapp
image: myapp:v2
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "200m"
memory: "100Mi"
容器内启动两个镜像
[root@server2 ~]# cat myapp.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
nodeName: server4
hostNetwork: true
containers:
- name: myapp
image: myapp:v2
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "200m"
memory: "100Mi"
- name: demo
image: busybox:latest
imagePullPolicy: IfNotPresent
stdin: true
tty: true
查看标签
[root@server2 ~]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
server2 Ready control-plane,master 9h v1.21.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server2,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
server3 Ready <none> 8h v1.21.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server3,kubernetes.io/os=linux
server4 Ready <none> 8h v1.21.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server4,kubernetes.io/os=linux
[root@server2 ~]# cat myapp.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
nodeName: server4
hostNetwork: true
containers:
- name: myapp
image: myapp:v2
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "200m"
memory: "100Mi"
nodeSelector:
kubernetes.io/hostname: server4 ##标签指定server4节点
[root@server2 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp 1/1 Running 0 3m13s 172.25.10.4 server4 <none> <none>