环境准备
已经搭建好集群环境的四台虚拟机:
- k8s-master01:192.168.19.159
- k8s-node01:192.168.19.160
- k8s-node02:192.168.19.161
- harbo:192.168.19.170(hub.xixihaha.com)
具体搭建步骤可参考:
- 部署 k8s 集群:https://www.theboyaply.cn/archives/k8s-cluster-building
- 搭建 harbor 私有仓库:https://www.theboyaply.cn/archives/k8s-cluster-harbor
准备好集群环境之后,使用任一台虚拟机往 harbor 仓库推送一个 nginx 镜像,然后将本地的 nginx 镜像删除。后续会使用这个镜像作为演示镜像。
简单演示
kubectl run
- 创建并运行一个或多个容器镜像。
- 创建一个deployment 或job 来管理容器。
语法:
$ run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]
创建 deployment
我们使用 run
命令创建一个 deployment
:
kubectl run nginx-deployment --image=hub.xixihaha.com/library/mynginx:v1 --port=80 --replicas=1
nginx-deployment:创建的 deployment
的名称。
--image:容器运行的镜像,若被分配到的节点上没有该镜像,会自动拉取。
--port:暴露的端口,若该容器被 svc
代理,则 svc
需要使用这个端口进行映射。
--replicas:期望的副本数量。k8s 会自动维护该容器一直在这个数量。
查看 deployment 信息
kubectl get deployment
:
[root@k8s-master01 ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/1 1 0 8s
查看 ReplicaSet 信息
kubectl get rs
:
[root@k8s-master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5498966dd4 1 1 1 28s
结果中有一个名为 nginx-deployment-5498966dd4
的 ReplicaSet
。我们在 Pod 介绍 一节提到过,deployment
是需要结合 RS
使用的,让 RS
来管理 Pod
的生命周期。
查看 Pod 信息
kubectl get pod
:
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-5498966dd4-f4srr 1/1 Running 0 16s
kubectl get pod -o wide
查看更多信息:
[root@k8s-master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-5498966dd4-f4srr 1/1 Running 0 12m 10.244.2.2 k8s-node02 <none> <none>
可以看见,该 Pod
的 IP
为 10.244.2.2
,运行在 k8s-node02
节点上。
此时我们去 k8s-node02
节点上查看运行的容器:
[root@k8s-node02 ~]# docker ps -a | grep nginx
4c4560cb4a13 hub.xixihaha.com/library/mynginx "nginx -g 'daemon of…" 15 minutes ago Up 15 minutes k8s_nginx-deployment_nginx-deployment-5498966dd4-f4srr_default_37dead71-35f3-41fd-bc01-18dfcf076d62_0
dd815e3e06f6 k8s.gcr.io/pause:3.1 "/pause" 15 minutes ago Up 15 minutes k8s_POD_nginx-deployment-5498966dd4-f4srr_default_37dead71-35f3-41fd-bc01-18dfcf076d62_0
从显示的信息中发现确实是运行了一个 nginx 容器。
但是你会发现,除了 nginx 之外,还有一个 pause 容器,这个我们之前也提到过,每一个运行的 Pod 都会有一个名为 pause 的容器。pause 容器的作用是共享网络、数据卷等。
删除 Pod
kubectl delete pod
:
# 查看 Pod
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-5498966dd4-f4srr 1/1 Running 0 23m
# 删除 Pod
[root@k8s-master01 ~]# kubectl delete pod nginx-deployment-5498966dd4-f4srr
pod "nginx-deployment-5498966dd4-f4srr" deleted
# 查看 Pod
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-5498966dd4-vgrsd 1/1 Running 0 14s
因为我们在创建 deployment
的时候使用 --replicas=1
指定了 Pod 的期望值,因此在删除 Pod 之后,RS 又重新创建了一个 Pod。可以看到,上下两次查看的 Pod 名称是不一样的。
扩容 Pod 数量
kubectl scale
:
# --replicas=3,指定期望值。deployment/nginx-deployment,指定 deployment 的名称
[root@k8s-master01 ~]# kubectl scale --replicas=3 deployment/nginx-deployment
deployment.extensions/nginx-deployment scaled
# 查看 Pod
[root@k8s-master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-5498966dd4-9jsjl 1/1 Running 0 2m15s 10.244.2.4 k8s-node02 <none> <none>
nginx-deployment-5498966dd4-lch2c 1/1 Running 0 2m15s 10.244.1.2 k8s-node01 <none> <none>
nginx-deployment-5498966dd4-vgrsd 1/1 Running 0 7m51s 10.244.2.3 k8s-node02 <none> <none>
查看 Pod 信息发现 Pod 的副本数量已经是 3 个了,并且在 node02 节点上运行了两个,在 node01 节点上运行了一个。
查看 SVC 信息
kubectl get svc
:
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h12m
kubectl expose
kubectl expose
:
将资源暴露为新的Kubernetes Service。
指定 deployment、service、replicaset、replication controller 或 pod,并使用该资源的选择器作为指定端口上新服务的选择器。deployment 或 replicaset 只有当其选择器可转换为 service 支持的选择器时,即当选择器仅包含 matchLabels 组件时才会作为暴露新的 Service。
资源包括(不区分大小写):
pod(po),service(svc),replication controller(rc),deployment(deploy),replica set(rs)
语法:
$ expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]
创建 SVC
上面我们将 nginx-deployment
这个 Pod 扩容到了 3 个,那么我们现在创建一个 service(SVC)
来统一代理这些 Pod。
kubectl expose deployment nginx-deployment --port=3000 --target-port=80
--port:SVC
暴露的端口为3000。即 SVC
提供给外部调用的端口。
--target-port:映射的容器端口。即创建 deployment
时使用的 --port
参数指定的端口。
查看 SVC
kubectl get svc
:
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h18m
nginx-deployment ClusterIP 10.107.168.17 <none> 3000/TCP 16s
其中,nginx-deployment
就是我们创建的 SVC
,它的 IP
为 10.107.168.17
,端口为 3000
,意味着外部服务可以通过这个地址和端口访问 SVC
,然后 SVC
通过轮询转发到具体的 Pod
上面。
[root@k8s-master01 ~]# curl 10.107.168.17:3000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
......
......
因为 SVC
就是调用 lvs
模块去实现负载均衡的,所以我们可以查看 lvs
规则来查看 SVC
与 Pod
的 IP
代理关系:
[root@k8s-master01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
...
...
TCP 10.107.168.17:3000 rr
-> 10.244.1.2:80 Masq 1 0 0
-> 10.244.2.3:80 Masq 1 0 0
-> 10.244.2.4:80 Masq 1 0 0
...
...
可以看见,上面的 10.107.168.17:3000
代理的三个 IP
地址就是现有的三个 Pod
的 IP
地址。
修改 SVC TYPE 使其对外开放
目前外部服务(比如浏览器)使用这个 IP(10.107.168.17)
是无法访问到 SVC
的。我们可以通过修改 SVC的TYPE
来让 SVC
可以被外部服务访问。
我们通过 kubectl get svc
知道 nginx-deployment
的 TYPE
为 ClusterIP
:
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h34m
nginx-deployment ClusterIP 10.107.168.17 <none> 3000/TCP 16m
修改 SVC
的 TYPE
:
kubectl edit svc
:
# 编辑 svc
kubectl edit svc nginx-deployment
# 将其中的
spec:
type: ClusterIP
# 修改为
spec:
type: NodePort
再次查看 SVC
发现其 TYPE
已经变成了 NodePort
,同时在其 port
一栏的 3000 端口还被映射到了一个随机端口 30578
:
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h40m
nginx-deployment NodePort 10.107.168.17 <none> 3000:30578/TCP 22m
下面我们就可以使用集群中任一节点的 IP
地址加上这个随机端口(30578
)访问到 SVC
了,比如使用 k8s-master01
节点的 IP
进行访问:192.168.19.150:30578
-- end --