本随笔接前两两章,建立离master主节点和node01、node02、node03三个节点
kubectl子命令
master ~]# kubectl
kubectl controls the Kubernetes cluster manager. Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/ Basic Commands (Beginner): create Create a resource from a file or from stdin. //增 expose Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service run Run a particular image on the cluster set Set specific features on objects Basic Commands (Intermediate): explain Documentation of resources get Display one or many resources //查 edit Edit a resource on the server //改 delete Delete resources by filenames, stdin, resources and names, or by resources and label selector //删除 Deploy Commands: rollout Manage the rollout of a resource //滚动 scale Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job //手动改变应用程序的规模 autoscale Auto-scale a Deployment, ReplicaSet, or ReplicationController //自动改变,即创建HPA Cluster Management Commands: //集群管理 certificate Modify certificate resources. cluster-info Display cluster info //集群信息 top Display Resource (CPU/Memory/Storage) usage. cordon Mark node as unschedulable //标记一个节点不可被调用 uncordon Mark node as schedulable //标记节点可被调用 drain Drain node in preparation for maintenance taint Update the taints on one or more nodes //给节点增加污点,作用是控制是否被调用 Troubleshooting and Debugging Commands: describe Show details of a specific resource or group of resources //描述资源的详细信息,例如 master ~]# kubectl describe node node01 logs Print the logs for a container in a pod attach Attach to a running container exec Execute a command in a container port-forward Forward one or more local ports to a pod proxy Run a proxy to the Kubernetes API server cp Copy files and directories to and from containers. auth Inspect authorization Advanced Commands: diff Diff live version against would-be applied version apply Apply a configuration to a resource by filename or stdin patch Update field(s) of a resource using strategic merge patch replace Replace a resource by filename or stdin wait Experimental: Wait for a specific condition on one or many resources. convert Convert config files between different API versions kustomize Build a kustomization target from a directory or a remote url. Settings Commands: label Update the labels on a resource annotate Update the annotations on a resource completion Output shell completion code for the specified shell (bash or zsh) Other Commands: api-resources Print the supported API resources on the server api-versions Print the supported API versions on the server, in the form of "group/version" config Modify kubeconfig files plugin Provides utilities for interacting with plugins. version Print the client and server version information Usage: kubectl [flags] [options] Use "kubectl <command> --help" for more information about a given command. Use "kubectl options" for a list of global command-line options (applies to all commands).
描述一个资源的详细信息
[root@master ~]# kubectl describe node master Name: master Roles: master Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/arch=amd64 kubernetes.io/hostname=master kubernetes.io/os=linux node-role.kubernetes.io/master= Annotations: flannel.alpha.coreos.com/backend-data: {"VtepMAC":"2e:6c:70:78:ed:70"} flannel.alpha.coreos.com/backend-type: vxlan flannel.alpha.coreos.com/kube-subnet-manager: true flannel.alpha.coreos.com/public-ip: 192.168.184.141 kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock node.alpha.kubernetes.io/ttl: 0 volumes.kubernetes.io/controller-managed-attach-detach: true CreationTimestamp: Fri, 31 May 2019 20:34:59 +0800 Taints: node-role.kubernetes.io/master:NoSchedule //表示只要不是master的组件都不能调度到master上 Unschedulable: false Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- MemoryPressure False Mon, 03 Jun 2019 22:20:17 +0800 Fri, 31 May 2019 20:34:53 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Mon, 03 Jun 2019 22:20:17 +0800 Fri, 31 May 2019 20:34:53 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure PIDPressure False Mon, 03 Jun 2019 22:20:17 +0800 Fri, 31 May 2019 20:34:53 +0800 KubeletHasSufficientPID kubelet has sufficient PID available Ready True Mon, 03 Jun 2019 22:20:17 +0800 Mon, 03 Jun 2019 22:06:07 +0800 KubeletReady kubelet is posting ready status Addresses: InternalIP: 192.168.184.141 Hostname: master Capacity: cpu: 4 ephemeral-storage: 12786Mi hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 1867048Ki pods: 110 Allocatable: cpu: 4 ephemeral-storage: 12066383443 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 1764648Ki pods: 110 System Info: Machine ID: 45c658713b3b423387314d097b36aa61 System UUID: 7C8C4D56-7732-E896-C85E-040A2FCEF804 Boot ID: 474da659-6243-4a63-a5f9-2e436260b3d2 Kernel Version: 3.10.0-693.el7.x86_64 OS Image: CentOS Linux 7 (Core) Operating System: linux Architecture: amd64 Container Runtime Version: docker://18.9.6 Kubelet Version: v1.14.2 Kube-Proxy Version: v1.14.2 PodCIDR: 10.244.0.0/24 Non-terminated Pods: (8 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE --------- ---- ------------ ---------- --------------- ------------- --- kube-system coredns-fb8b8dccf-42b7j 100m (2%) 0 (0%) 70Mi (4%) 170Mi (9%) 3d1h kube-system coredns-fb8b8dccf-bjv95 100m (2%) 0 (0%) 70Mi (4%) 170Mi (9%) 3d1h kube-system etcd-master 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3d1h kube-system kube-apiserver-master 250m (6%) 0 (0%) 0 (0%) 0 (0%) 3d1h kube-system kube-controller-manager-master 200m (5%) 0 (0%) 0 (0%) 0 (0%) 3d1h kube-system kube-flannel-ds-amd64-w4jfh 100m (2%) 100m (2%) 50Mi (2%) 50Mi (2%) 2d18h kube-system kube-proxy-f88gd 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3d1h kube-system kube-scheduler-master 100m (2%) 0 (0%) 0 (0%) 0 (0%) 3d1h Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 850m (21%) 100m (2%) memory 190Mi (11%) 390Mi (22%) ephemeral-storage 0 (0%) 0 (0%) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Starting 14m kubelet, master Starting kubelet. Normal NodeHasSufficientMemory 14m kubelet, master Node master status is now: NodeHasSufficientMemory Normal NodeHasNoDiskPressure 14m kubelet, master Node master status is now: NodeHasNoDiskPressure Normal NodeHasSufficientPID 14m kubelet, master Node master status is now: NodeHasSufficientPID Normal NodeNotReady 14m kubelet, master Node master status is now: NodeNotReady Normal NodeAllocatableEnforced 14m kubelet, master Updated Node Allocatable limit across pods Normal NodeReady 14m kubelet, master Node master status is now: NodeReady
[root@master ~]# kubectl version //查看客户端和服务器端的版本 Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.2", GitCommit:"66049e3b21efe110454d67df4fa62b08ea79a19b", GitTreeState:"clean",
BuildDate:"2019-05-16T16:23:09Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.2", GitCommit:"66049e3b21efe110454d67df4fa62b08ea79a19b", GitTreeState:"clean",
BuildDate:"2019-05-16T16:14:56Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"linux/amd64"}
[root@master ~]# kubectl cluster-info //查看集群信息 Kubernetes master is running at https://192.168.184.141:6443 //向外输出的API Server地址 KubeDNS is running at https://192.168.184.141:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
//相当于CoreDNS,运行获取路径时,从集群外部访问的执行端口转发的代理的访问方式 To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
三个重要的附件:kube-proxy、CoreDNS、flannel
如何对k8s集群进行增删改查
[root@master ~]# kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1 --dry-run=true kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version.
Use kubectl run --generator=run-pod/v1 or kubectl create instead. deployment.apps/nginx-deploy created (dry run) //deployment.apps表示类别,在deployment控制器下控制的应用程序apps,叫nginx-deploy
[root@master ~]# kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1 kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. deployment.apps/nginx-deploy created
[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 1/1 1 1 88s
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-55d8d67cf-r45d4 1/1 Running 0 3m12s //nginx-deploy(名称)-55d8d67cf-r45d4(hash码)
[root@master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-55d8d67cf-r45d4 1/1 Running 0 5m26s 10.244.1.2 node03 <none> <none>
[root@node03 ~]# ifconfig cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 //创建的pod属于cni0桥 inet 10.244.1.1 netmask 255.255.255.0 broadcast 0.0.0.0 //这里是24为掩码,即10.244.1是网络地址,是整个大网10.244.0.0的子网,10.244.1.0/24专供node03上的pod使用 inet6 fe80::2865:d6ff:fec3:8c48 prefixlen 64 scopeid 0x20<link> ether 2a:65:d6:c3:8c:48 txqueuelen 1000 (Ethernet) RX packets 1 bytes 28 (28.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 648 (648.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 //创建的pod地址不属于docker0桥的 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:fa:b6:01:67 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.1.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::8cfe:edff:fe64:fa7 prefixlen 64 scopeid 0x20<link> ether 8e:fe:ed:64:0f:a7 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 8 overruns 0 carrier 0 collisions 0
[root@node02 ~]# ifconfig //没有cni0桥是因为这里还没有创建pod docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:0f:c0:cc:e7 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0。。。。 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.2.0 netmask 255.255.255.255 broadcast 0.0.0.0 //子网:10.244.2.0/24专供node02上的pod使用 inet6 fe80::80c1:b0ff:fe56:d03c prefixlen 64 scopeid 0x20<link> ether 82:c1:b0:56:d0:3c txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 8 overruns 0 carrier 0 collisions 0
[root@node01 ~]# ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:7d:52:0a:23 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.3.0 netmask 255.255.255.255 broadcast 0.0.0.0 //子网:10.244.3.0/24专供node01上的pod使用 inet6 fe80::909c:12ff:fe96:2258 prefixlen 64 scopeid 0x20<link> ether 92:9c:12:96:22:58 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 8 overruns 0 carrier 0 collisions 0
[root@node01 ~]# curl 10.244.1.2 //pod运行在node03上,但是在node01、master、node02上都是可以访问的 <!DOCTYPE html> //因为master、node01、node02和node03都处于同一网段中,但是pod的地址只能在k8s集群内部使用; <html> //pod的客户端分为两类:1、其他pod,2、集群外部的客户端 <head> <title>Welcome to nginx!</title> <style> 。。。。。。。
[root@master ~]# kubectl get pod //已存在的pod NAME READY STATUS RESTARTS AGE nginx-deploy-55d8d67cf-r45d4 1/1 Running 0 58m
[root@master ~]# kubectl delete pod nginx-deploy-55d8d67cf-r45d4 //删除pod pod "nginx-deploy-55d8d67cf-r45d4" deleted
[root@master ~]# kubectl get pod //删除后会立马创建新的pod,引文pod资源是控制器管理的,如果pod资源不够时,控制器会自动创建一个新的pod NAME READY STATUS RESTARTS AGE nginx-deploy-55d8d67cf-tfppt 0/1 ContainerCreating 0 6s
[root@master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-55d8d67cf-tfppt 1/1 Running 0 5m45s 10.244.2.2 node02 <none> <none>
//这次是创建在node02上,但是node02由于没有镜像,所以要先下载镜像
node02 ~]# ifconfig //上述将已经存在的pod删除后,又新建一个pod,这样就改变了pod的IP,但是服务仍然存在,所以以IP地址访问是不可以的,因此应该给pod一个固定端点, cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 //当客户端访问时,只需要访问它的固定端点,固定端点由service提供。 inet 10.244.2.1 netmask 255.255.255.0 broadcast 0.0.0.0 inet6 fe80::1cf7:fcff:fe37:bfd2 prefixlen 64 scopeid 0x20<link> ether 1e:f7:fc:37:bf:d2 txqueuelen 1000 (Ethernet) RX packets 1 bytes 28 (28.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 648 (648.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.2.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::80c1:b0ff:fe56:d03c prefixlen 64 scopeid 0x20<link> ether 82:c1:b0:56:d0:3c txqueuelen 0 (Ethernet) RX packets 6 bytes 1158 (1.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 506 (506.0 B) TX errors 0 dropped 8 overruns 0 carrier 0 collisions 0
master ~]# kubectl expose --help //expose暴漏的端口(创建或者代理) 是service_port
Usage: kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] //[--port=port]指service的端口
[--name=name] [--external-ip=external-ip-of-service] [--type=type] [options] //[--name=name]是service的名称,[--type=type]是service的类型
[--port=port]指服务的端口(service有自己的地址),[--target-port=number-or-name]目标端口是pod的端口
service是为pod提供一个固定访问端点,但这个端点不支持外部访问,只能在集群内部的节点上才能被访问,这种端点大多时候是被pod客户端访问的。pod客户端在访问
服务时,是可以基于service的名称来访问的(IP地址是动态生成的),但是pod客户端必须能解析这个service名称。解析时就需要依赖CoreDNS服务。
service只有一个servic IP,只能在集群内被各pod客户端访问,而不能突破集群边界,被集群外部的客户端访问
master ~]# kubectl expose deployment nginx-deploy --name=nginx --port=80 --target-port=80 --protocol=TCP
service/nginx exposed //nginx是服务名称,是nginx-deploy创建的pod资源
//deployment是控制器,将控制器相关的pod资源即nginx-deployment创建为一个服务,服务名是nginx。
[root@master ~]# kubectl get svc //svc是service的缩写,查看创建的服务 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d15h nginx ClusterIP 10.96.75.49 <none> 80/TCP 2m41s
service是为pod提供一个固定访问端点,但这个端点不支持外部访问,只能在集群内部的节点上才能被访问,这种端点大多时候是被pod客户端访问的。
pod客户端在访问服务时,是可以基于service的名称来访问的(IP地址是动态生成的),但是pod客户端必须能解析这个service名称。
解析时就需要依赖CoreDNS服务。CoreDNS地址是可以查询的,但一般并不会直接使用地址,而是使用CoreDNS的服务名称。
master ~]# kubectl get pods -n kube-system -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-fb8b8dccf-42b7j 1/1 Running 0 3d15h 10.244.0.2 master <none> <none> coredns-fb8b8dccf-bjv95 1/1 Running 0 3d15h 10.244.0.3 master <none> <none> etcd-master 1/1 Running 1 3d15h 192.168.184.141 master <none> <none> kube-apiserver-master 1/1 Running 1 3d15h 192.168.184.141 master <none> <none> kube-controller-manager-master 1/1 Running 4 3d15h 192.168.184.141 master <none> <none> kube-flannel-ds-amd64-4z7ht 1/1 Running 0 18h 192.168.184.144 node03 <none> <none> kube-flannel-ds-amd64-k4rxq 1/1 Running 0 18h 192.168.184.142 node01 <none> <none> kube-flannel-ds-amd64-w4jfh 1/1 Running 0 3d8h 192.168.184.141 master <none> <none> kube-flannel-ds-amd64-ztbm6 1/1 Running 2 2d21h 192.168.184.143 node02 <none> <none> kube-proxy-f88gd 1/1 Running 1 3d15h 192.168.184.141 master <none> <none> kube-proxy-kvd9x 1/1 Running 0 18h 192.168.184.144 node03 <none> <none> kube-proxy-qqhpx 1/1 Running 0 18h 192.168.184.142 node01 <none> <none> kube-proxy-zsnz5 1/1 Running 2 2d21h 192.168.184.143 node02 <none> <none> kube-scheduler-master 1/1 Running 3 3d15h 192.168.184.141 master <none> <none>
[root@master ~]# kubectl get svc -n kube-system //查看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 3d15h
为了演示效果CoreDNS解析效果,再启动一个pod作为客户端使用
[root@master ~]# kubectl run client --image=busybox --replicas=1 -it --restart=Never If you don't see a command prompt, try pressing enter. / # cat /etc/resolv.conf nameserver 10.96.0.10 //IP解析地址指向10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local //svc.cluster.local表示k8s集群的本地pod资源的特定后缀,default表示pod所属的名称空间的名字,
options ndots:5 / # //所以如果基于服务的名称进行解析时,一定要使用完整的服务名称。如果服务名称不完整,搜索域是不一样的
master ~]# yum install bind-utils
master ~]# dig -t A nginx.default.svc.cluster.local @10.96.0.10 //根据服务全名,通过CoreDNS服务将service的IP解析出来 ; <<>> DiG 9.9.4-RedHat-9.9.4-73.el7_6 <<>> -t A nginx.default.svc.cluster.local @10.96.0.10 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33271 ;; 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 ;; QUESTION SECTION: ;nginx.default.svc.cluster.local. IN A ;; ANSWER SECTION: nginx.default.svc.cluster.local. 5 IN A 10.96.75.49 //根据service服务(nginx)名称将service的IP解析出来 ;; Query time: 72 msec ;; SERVER: 10.96.0.10#53(10.96.0.10) ;; WHEN: Tue Jun 04 12:47:39 CST 2019 ;; MSG SIZE rcvd: 107
[root@master ~]# kubectl run client --image=busybox --replicas=1 -it --restart=Never If you don't see a command prompt, try pressing enter. / # cat /etc/resolv.conf nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5 / # wget nginx Connecting to nginx (10.96.75.49:80) //根据service名称解析出来service的IP index.html 100% |***********************************************************************************************| 612 0:00:00 ETA / # wget -O - -q http://nginx:80/ //此时这里的80端口被调度到pod的port上 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> </html>
下面将pod手动宕机,测试使用同一个service名称(nginx)是否还可以访问
[root@master ~]# kubectl get pods //查询pod的名称 NAME READY STATUS RESTARTS AGE client 1/1 Running 0 36m nginx-deploy-55d8d67cf-tfppt 1/1 Running 0 5h35m [root@master ~]# kubectl delete pods nginx-deploy-55d8d67cf-tfppt //删除pod pod "nginx-deploy-55d8d67cf-tfppt" deleted [root@master ~]# kubectl get pods 再次查看,控制器已经新建了一个pod NAME READY STATUS RESTARTS AGE client 1/1 Running 0 36m nginx-deploy-55d8d67cf-hlj9v 0/1 ContainerCreating 0 11s [root@master ~]# kubectl get pods //新建的pod已经运行 NAME READY STATUS RESTARTS AGE client 1/1 Running 0 37m nginx-deploy-55d8d67cf-hlj9v 1/1 Running 0 37s
/ # wget -O - -q http://nginx:80/ //再次使用service服务的名称进行访问nginx服务,还是可以访问的,这就是通过标签和标签选择器关联pod资源,而不是基于IP地址来选择的。
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</body>
master ~]# kubectl expose deployment nginx-deploy --name=nginx --port=80 --target-port=80 --protocol=TCP
上述实验说明了只要是nginx-deploy创建的pod,一律都纳入到服务的后端中去,这就是service可以为pod提供固定的访问端点。
service是iptables规则或者ipvs规则
[root@master ~]# kubectl get pods -o wide //目前服务运行在node01上,但是在其他节点(node02或node03)都是可以查看相关规则的 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES client 1/1 Running 0 6h12m 10.244.1.3 node03 <none> <none> nginx-deploy-55d8d67cf-hlj9v 1/1 Running 0 5h36m 10.244.3.2 node01 <none> <none>
[root@master ~]# kubectl get svc //主要关注的不是pod自身,而是svc,service生成后即nginx会生成iptables或ipvs规则,把所有访问10.96.75.49:80的都调度至 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE //nginx用标签选择器关联到的各pod后端。
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d22h
nginx ClusterIP 10.96.75.49 <none> 80/TCP 6h45m
如何查看标签选择器关联到哪些客户端?
[root@master ~]# kubectl describe svc nginx //下面显示的资源都是可以被改变的 Name: nginx Namespace: default Labels: run=nginx-deploy Annotations: <none> Selector: run=nginx-deploy //选择器选择那些所有拥有run标签,且值=nginx-deploy的pod资源 Type: ClusterIP IP: 10.96.75.49 //比如IP地址改变后,解析结果也会自动修改,这里的变化会立即CoreDNS的解析记录当中,如果把这个服务删除了,这个地址也是发生变化的 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 10.244.3.2:80 //如果pod资源被删除,这里会发生相应的变化 Session Affinity: None Events: <none>
[root@master ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS client 1/1 Running 0 7h4m run=client nginx-deploy-55d8d67cf-hlj9v 1/1 Running 0 6h27m pod-template-hash=55d8d67cf,run=nginx-deploy
//当此标签被删除时,再创建是依然要有此标签才能被选中,而不是根据IP地址被选中
首先使用kubectl run创建一个pod,比如这个pod运行的是nginx,此时nginx只能对集群内的节点提供访问功能,集群外的节点是无法访问的;所以就需要创建一个service,由service通过pod的标签关联pod,然后对集群外部提供服务。
以上就是service的意义
控制器是根据标签选择器来关联到pod资源上的
[root@master]# kubectl describe deployment nginx-deploy Name: nginx-deploy Namespace: default CreationTimestamp: Tue, 04 Jun 2019 06:32:12 +0800 Labels: run=nginx-deploy Annotations: deployment.kubernetes.io/revision: 1 Selector: run=nginx-deploy Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: run=nginx-deploy Containers: nginx-deploy: Image: nginx:1.14-alpine Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Progressing True NewReplicaSetAvailable Available True MinimumReplicasAvailable OldReplicaSets: <none> NewReplicaSet: nginx-deploy-55d8d67cf (1/1 replicas created) Events: <none>
一个创建好的deployment控制器的副本数量是可以动态修改的
[root@master ~]# kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=2 //创建新的控制器,副本是2
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/myapp created
[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE myapp 2/2 2 2 5m38s nginx-deploy 1/1 1 1 10d
[root@master ~]# kubectl get deployment -w //-w表示监控 NAME READY UP-TO-DATE AVAILABLE AGE myapp 2/2 2 2 95s nginx-deploy 1/1 1 1 10d
[root@master ~]# kubectl get pods -o wide //新创建的pod在不同的节点上,同时他们的网络也是不同的
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES client 0/1 Error 0 9d <none> node03 <none> <none> client1 0/1 Completed 0 9d 10.244.2.3 node02 <none> <none> myapp-5bc569c47d-24qfh 1/1 Running 0 7m29s 10.244.2.4 node02 <none> <none> myapp-5bc569c47d-7ql96 1/1 Running 0 7m29s 10.244.1.4 node03 <none> <none> nginx-deploy-55d8d67cf-hlj9v 1/1 Running 3 9d 10.244.3.5 node01 <none> <none>
[root@master ~]# kubectl run client2 --image=busybox --replicas=1 -it --restart=Never //应该为pod提供固定的访问端点,即service If you don't see a command prompt, try pressing enter. / # wget -O - -q 10.244.2.4 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> / # wget -O - -q 10.244.1.4 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> / # wget -O - -q 10.244.1.4/hostname.html myapp-5bc569c47d-7ql96 / # wget -O - -q 10.244.2.4/hostname.html myapp-5bc569c47d-24qfh
为pod创建固定访问端点
[root@master ~]# kubectl expose deployment myapp --name=myapp --port=80 service/myapp exposed [root@master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d myapp ClusterIP 10.96.152.130 <none> 80/TCP 7s nginx ClusterIP 10.96.75.49 <none> 80/TCP 9d
随机调度不同节点上的pod
/ # wget -O - -q myapp Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> / # wget -O - -q myapp/hostname.html myapp-5bc569c47d-7ql96 / # wget -O - -q myapp/hostname.html myapp-5bc569c47d-24qfh / # wget -O - -q myapp/hostname.html myapp-5bc569c47d-24qfh / # wget -O - -q myapp/hostname.html myapp-5bc569c47d-7ql96 / # wget -O - -q myapp/hostname.html myapp-5bc569c47d-24qfh / # wget -O - -q myapp/hostname.html myapp-5bc569c47d-7ql96 / # while true; do wget -O - -q myapp/hostname.html; sleep 1; done myapp-5bc569c47d-7ql96 myapp-5bc569c47d-24qfh myapp-5bc569c47d-24qfh myapp-5bc569c47d-7ql96 myapp-5bc569c47d-24qfh myapp-5bc569c47d-7ql96
pod是动态变动的,可以进行扩展或者缩小
master ~]# kubectl scale --help
Usage:
kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)
master ~]# kubectl scale --replicas=5 deployment myapp //将控制器myapp的副本数量增加到5 deployment.extensions/myapp scaled
[root@master ~]# kubectl get pods //查看副本是五个 NAME READY STATUS RESTARTS AGE client 0/1 Error 0 9d client1 0/1 Completed 0 9d client2 1/1 Running 0 65m myapp-5bc569c47d-24qfh 1/1 Running 0 75m myapp-5bc569c47d-7ql96 1/1 Running 0 75m myapp-5bc569c47d-bdpxf 1/1 Running 0 69s myapp-5bc569c47d-ftrgc 1/1 Running 0 69s myapp-5bc569c47d-qlk7f 0/1 Running 0 69s nginx-deploy-55d8d67cf-hlj9v 1/1 Running 3 9d
/ # while true; do wget -O - -q myapp/hostname.html; sleep 1; done //这里可以把5个pod都可以访问到 myapp-5bc569c47d-ftrgc myapp-5bc569c47d-24qfh myapp-5bc569c47d-ftrgc myapp-5bc569c47d-bdpxf myapp-5bc569c47d-qlk7f myapp-5bc569c47d-qlk7f myapp-5bc569c47d-7ql96 myapp-5bc569c47d-bdpxf myapp-5bc569c47d-qlk7f myapp-5bc569c47d-qlk7f myapp-5bc569c47d-7ql96
[root@master ~]# kubectl scale --replicas=3 deployment myapp //缩减pod副本数量
deployment.extensions/myapp scaled
[root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE client 0/1 Error 0 9d client1 0/1 Completed 0 9d client2 0/1 Error 0 78m client3 1/1 Running 0 2m46s myapp-5bc569c47d-24qfh 1/1 Running 0 88m myapp-5bc569c47d-7ql96 1/1 Running 0 88m myapp-5bc569c47d-bdpxf 1/1 Running 0 14m nginx-deploy-55d8d67cf-hlj9v 1/1 Running 3 9d
/ # while true; do wget -O - -q myapp/hostname.html; sleep 1; done //缩减后只调度剩下三个pod myapp-5bc569c47d-24qfh myapp-5bc569c47d-7ql96 myapp-5bc569c47d-7ql96 myapp-5bc569c47d-bdpxf myapp-5bc569c47d-24qfh myapp-5bc569c47d-bdpxf
下面将myapp滚动升级到V2版本
/ # while true; do wget -O - -q myapp; sleep 1; done Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
master ~]# kubectl set image --help
Usage:
kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N
[root@master ~]# kubectl get pods //首先查看升级哪些pod NAME READY STATUS RESTARTS AGE client 0/1 Error 0 9d client1 0/1 Completed 0 9d client2 0/1 Error 0 119m client3 1/1 Running 0 43m myapp-5bc569c47d-24qfh 1/1 Running 0 129m myapp-5bc569c47d-7ql96 1/1 Running 0 129m myapp-5bc569c47d-bdpxf 1/1 Running 0 55m nginx-deploy-55d8d67cf-hlj9v 1/1 Running 3 9d
master ~]# kubectl describe pods myapp-5bc569c47d-24qfh //可以显示升级容器的相关信息
Name: myapp-5bc569c47d-24qfh Namespace: default Priority: 0 PriorityClassName: <none> Node: node02/192.168.184.143 Start Time: Fri, 14 Jun 2019 09:28:42 +0800 Labels: pod-template-hash=5bc569c47d run=myapp Annotations: <none> Status: Running IP: 10.244.2.4 Controlled By: ReplicaSet/myapp-5bc569c47d Containers: //容器名称 myapp: Container ID: docker://698843132d3a70585e8065470f97ae1d74ece31ae04749c57b9e93a66fe99d91 Image: ikubernetes/myapp:v1 Image ID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513 Port: <none> Host Port: <none> State: Running Started: Fri, 14 Jun 2019 09:30:14 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-fckpp (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-fckpp: Type: Secret (a volume populated by a Secret) SecretName: default-token-fckpp Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: <none>
修改控制器下面对应的容器,并指明所要升级到的镜像版本
[root@master ~]# kubectl set image deployment myapp myapp=ikubernetes/myapp:v2
deployment.extensions/myapp image updated
[root@master ~]# kubectl rollout status deployment myapp //这里显示已经更新完成
deployment "myapp" successfully rolled out
此时控制器的版本已经升级到V2版本了
/ # while true; do wget -O - -q myapp; sleep 1; done Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
此时查看各pod的名称,已经发生了改变
[root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE client 0/1 Error 0 10d client1 0/1 Completed 0 9d client2 0/1 Error 0 3h45m client3 1/1 Running 0 149m myapp-86984b4c7c-24tmb 1/1 Running 0 97m myapp-86984b4c7c-clqhw 1/1 Running 0 96m myapp-86984b4c7c-crzfj 1/1 Running 0 97m nginx-deploy-55d8d67cf-hlj9v 1/1 Running 3 10d
升级故障可以做回滚
回滚有两种方法:
1、直接修改版本
master ~]# kubectl set image deployment myapp myapp=ikubernetes/myapp:v1
2、使用命令
master ~]# kubectl rollout --help
Examples: # Rollback to the previous deployment kubectl rollout undo deployment/abc # Check the rollout status of a daemonset kubectl rollout status daemonset/foo Available Commands: history View rollout history pause Mark the provided resource as paused resume Resume a paused resource status Show the status of the rollout undo Undo a previous rollout Usage: kubectl rollout SUBCOMMAND [options] Use "kubectl <command> --help" for more information about a given command. Use "kubectl options" for a list of global command-line options (applies to all commands).
master ~]# kubectl rollout undo --help //
Usage: //指明回滚到哪一个版本,如果不指明就回滚到上一个版本
kubectl rollout undo (TYPE NAME | TYPE/NAME) [flags] [options]
[root@master ~]# kubectl rollout undo deployment myapp deployment.extensions/myapp rolled back [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE client3 1/1 Running 0 157m myapp-5bc569c47d-5cdpw 1/1 Running 0 7s myapp-5bc569c47d-c4gr2 1/1 Running 0 11s myapp-5bc569c47d-njr5w 1/1 Running 0 9s //上述三个是运行回滚后的版本的pod myapp-86984b4c7c-24tmb 0/1 Terminating 0 105m //结束此前版本 nginx-deploy-55d8d67cf-hlj9v 1/1 Running 3 10d
/ # while true; do wget -O - -q myapp; sleep 1; done //此时已经运行的是V1版本了 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
如果想要在进群外部(比如浏览器)访问集群服务,该如何做?
可以将service类型修改为NodePort即可
master ~]# kubectl edit svc myapp
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: Service metadata: creationTimestamp: "2019-06-14T02:35:03Z" labels: run: myapp name: myapp namespace: default resourceVersion: "369638" selfLink: /api/v1/namespaces/default/services/myapp uid: 039652cc-8e4d-11e9-a017-000c29cef804 spec: clusterIP: 10.96.152.130 ports: - port: 80 protocol: TCP targetPort: 80 selector: run: myapp sessionAffinity: None type: ClusterIP --> 将ClusterIP 修改为NodePort status: loadBalancer: {}
修改成功后显示:service/myapp edited
[root@master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d myapp NodePort 10.96.152.130 <none> 80:30327/TCP 3h15m //30327是每一个节点的这个端口都可以访问myapp nginx ClusterIP 10.96.75.49 <none> 80/TCP 10d
每一个节点都可以访问
并且是负载均衡的