以下内容仅作为测试,为了说明各个对象之间的关系,采用的kubectl run...,生产环境不建议使用;
1. 创建控制器(deployment)并在其下挂载Pod.
Usage:
kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...] [options]
~]$ kubectl run nginx --image=nginx:1.14-alpine --port=80 --replicas=1
nginx: 控制器名称
--image: 指定Pod中的容器要基于哪个镜像运行
--port: Pod中容器的端口
--relicas: 副本数(当副本数没有达到定义的数量时,比如删除了某个副本,那么控制器会补全)
查询Pod是否成功启动
~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-7689897d8d-t76qv 1/1 Running 0 100m
#查询控制器deployment
~]$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 1/1 1 1 4h26m
#删除Pod查看是否会自动补全副本
~]$ kubectl delete pod nginx-deploy-7689897d8d-t76qv
# 查看Pod,发现名字已经改变了,是个新的Pod
~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-7689897d8d-t82wq 1/1 Running 0 100m
# 查看Pod的详细信息
~]$ kubectl describe pod nginx-deploy-7689897d8d-t82wq
....
2. CoeDns相关说明
当在任何一个节点上运行了一个Pod之后,则集群中的任意一个节点都可直接访问此Pod的IP地址或此Pod注册的Service的地址或主机名;
[node2]操作(单独访问Pod的IP地址) ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-7689897d8d-t82wq 1/1 Running 0 111m 10.244.2.7 node2 <none> <none> ~]$ curl 10.244.2.7
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Tue, 09 Jun 2020 08:09:19 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 10 Apr 2019 01:08:42 GMT
Connection: keep-alive
ETag: "5cad421a-264"
Accept-Ranges: bytes
将deployment发布到Service
Usage:
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]
~]$ kubectl expose deployment nginx --port=80 --target-port=80 --protocol=TCP --type=ClusterIP
注释:
deployment: 发布出去的类型,这里要发布deployment类型的控制器
nginx: 控制器的名称
port: service的端口
target-port: 后端Pod的端口
protocol: 使用的协议
type: 默认为ClusterIP,还有NodePort, LoadBalancer, ExternalName
~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.99.43.205 <none> 80/TCP 109m
# 查看Service的详细信息
~]$ kubectl describe svc nginx
Name: nginx
Namespace: default
Labels: run=nginx-deploy
Annotations: <none>
Selector: run=nginx-deploy
Type: ClusterIP
IP: 10.99.43.205
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.7:80
Session Affinity: None
Events: <none>
问:为什么要访问Service的IP地址,不访问Pod的呢?
答:因为Pod是有生命周期的,且IP地址及主机名都不是固定的,但Service的地址和主机名,不人为删除Service后重建的话,默认是不会更改的,Service只是服务器上一个ipvs或IPtables规则.
~]$ curl -I 10.99.43.205
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Tue, 09 Jun 2020 08:25:11 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 10 Apr 2019 01:08:42 GMT
Connection: keep-alive
ETag: "5cad421a-264"
Accept-Ranges: bytes
# 启动一个客户端容器,试着访问Service的名称(nginx),发现也是可以的,因为Pod中的/etc/resolv.conf中默认记录了CoreDns的地址,一个Service可能是提供给Pod使用的,Pod中默认拥有CoreDns的记录,所以可以直接访问名称;
~]$ kubectl run client image=busybox -it -- /bin/sh
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5
/ # wget -O - -q nginx
....
<title>Welcome to nginx!</title>
....
修改service的发布类型为NodePort
NodePort: 可将Service的端口映射到宿主机的端口,使外界可直接访问;
~]$ kubectl edit svc nginx ..... spec: ..... # 默认创建的时候为ClusterIP类型,可这样动态修改,亦或创建时通过"type=NodePort"指定(区分大小写.) type: NodePort .....
~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
nginx ClusterIP 10.99.43.205 <none> 80:31381/TCP 18h
#注释:
80:是Service的端口.
31381: 是Service映射到宿主机的端口.
访问验证,在网页端输入http://IP(宿主机IP):31381,即可访问Service下的deployment下的Pod程序;
3. 动态调整Pod副本数量、及灰度升级、回滚.
Usage:
kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME) [options]
# 增加副本数量至3个.
~]$ kubectl scale --replicas=3 deployment nginx
~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-84cd4b7f95-95h74 1/1 Running 0 80m
nginx-84cd4b7f95-nwpt4 1/1 Running 0 80m
nginx-84cd4b7f95-t7pzf 1/1 Running 0 80m
# 降低副本数量至2个.
~]$ kubectl scale --replicas=2 deployment nginx
NAME READY STATUS RESTARTS AGE
nginx-84cd4b7f95-95h74 1/1 Running 0 80m
nginx-84cd4b7f95-t7pzf 1/1 Running 0 80m
# 灰度升级.
Usage:
kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N [options]
# 变更镜像
~]$ kubectl set image deployment nginx nginx-deploy=nginx:latest
deployment: 控制器的类型
nginx: 控制器的名称
nginx-deploy: Pod中容器的名称,使用"kubectl describe pod Pod名"就可查询到
nginx:latest: 要变更的镜像,默认从DockerHub上获取
# 回滚
Usage:
kubectl rollout SUBCOMMAND [options]
~]$ kubectl rollout undo deployment nginx
总结:
1. Pod是注册到Service之上的,当Pod作为客户端访问另外的Pod时,不使用对方的IP地址,使用Service的名称或地址;
2. 控制器控制着Pod的副本数量,监控着Pod的状态,当副本不够用时,及时补全,当过多时,及时剔除;
3. CoreDns也是有Service的;