环境准备
已经搭建好集群环境的四台虚拟机:
- 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 --