容器編排系統之Kubectl工具的基礎使用

1874發表於2020-12-13

  前文我們瞭解了k8s的架構和基本的工作過程以及測試環境的k8s叢集部署,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/14126750.html;今天我們主要來了解下k8s命令列工具kubectl的基礎操作;

  kubectl簡介

  kubectl是k8s官方提供的工具,它是一款命令列工具,我們可以使用它來部署k8s叢集,管理k8s叢集上的資源;kubectl這個工具有很多子命令,每個子命令都有不同的功能,比如建立資源我們可以使用create或apply子命令來實現;不同的是在k8s上建立資源的方式有兩種,一種是陳述式介面,一種是宣告式介面;所謂宣告式介面就是把我們要建立的資源,通過寫成一個配置檔案,然後使用apply子命令應用指定的配置檔案的方式;陳述式介面是指我們要在命令列告訴k8s怎麼去建立資源,比如建立pod控制器,使用什麼映象,副本數量等等;通常我們使用create子命令來陳述建立一個資源;當然create子命令也可以指定一個資源清單的方式來建立資源;兩者不同的是apply可以多次執行,如果發現對應清單有變化就應用變化部分,沒變化就不應用;而create不能多次執行;

  kubectl工具使用的語法

kubectl [flags] [options]

  提示:flages是用來指定子命令,options是對應子命令的選項;

  檢視kubectl工具的使用幫助

[root@master01 ~]# kubectl --help
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 or Replication Controller
  autoscale     Auto-scale a Deployment, ReplicaSet, or ReplicationController

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
  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
  debug         Create debugging sessions for troubleshooting workloads and nodes

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
  replace       Replace a resource by filename or stdin
  wait          Experimental: Wait for a specific condition on one or many resources.
  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@master01 ~]# 

  檢視子命令幫助

[root@master01 ~]# kubectl create --help
Create a resource from a file or from stdin.

 JSON and YAML formats are accepted.

Examples:
  # Create a pod using the data in pod.json.
  kubectl create -f ./pod.json
  
  # Create a pod based on the JSON passed into stdin.
  cat pod.json | kubectl create -f -
  
  # Edit the data in docker-registry.yaml in JSON then create the resource using the edited data.
  kubectl create -f docker-registry.yaml --edit -o json

Available Commands:
  clusterrole         Create a ClusterRole.
  clusterrolebinding  Create a ClusterRoleBinding for a particular ClusterRole
  configmap           Create a configmap from a local file, directory or literal value
  cronjob             Create a cronjob with the specified name.
  deployment          Create a deployment with the specified name.
  ingress             Create an ingress with the specified name.
  job                 Create a job with the specified name.
  namespace           Create a namespace with the specified name
  poddisruptionbudget Create a pod disruption budget with the specified name.
  priorityclass       Create a priorityclass with the specified name.
  quota               Create a quota with the specified name.
  role                Create a role with single rule.
  rolebinding         Create a RoleBinding for a particular Role or ClusterRole
  secret              Create a secret using specified subcommand
  service             Create a service using specified subcommand.
  serviceaccount      Create a service account with the specified name

Options:
      --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or
map key is missing in the template. Only applies to golang and jsonpath output formats.
      --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the
object that would be sent, without sending it. If server strategy, submit server-side request
without persisting the resource.
      --edit=false: Edit the API resource before creating
      --field-manager='kubectl-create': Name of the manager used to track field ownership.
  -f, --filename=[]: Filename, directory, or URL to files to use to create the resource
  -k, --kustomize='': Process the kustomization directory. This flag can't be used together with -f
or -R.
  -o, --output='': Output format. One of:
json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
      --raw='': Raw URI to POST to the server.  Uses the transport specified by the kubeconfig file.
      --record=false: Record current kubectl command in the resource annotation. If set to false, do
not record the command. If set to true, record the command. If not set, default to updating the
existing annotation value only if one already exists.
  -R, --recursive=false: Process the directory used in -f, --filename recursively. Useful when you
want to manage related manifests organized within the same directory.
      --save-config=false: If true, the configuration of current object will be saved in its
annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to
perform kubectl apply on this object in the future.
  -l, --selector='': Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l
key1=value1,key2=value2)
      --template='': Template string or path to template file to use when -o=go-template,
-o=go-template-file. The template format is golang templates
[http://golang.org/pkg/text/template/#pkg-overview].
      --validate=true: If true, use a schema to validate the input before sending it
      --windows-line-endings=false: Only relevant if --edit=true. Defaults to the line ending native
to your platform.

Usage:
  kubectl create -f FILENAME [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@master01 ~]# 

  提示:create是用來建立一個資源,在k8s上資源有很多型別,使用不同的子命令表示建立不同型別的資源,當然建立不同型別的資源對應的選項也有所不同;

  檢視建立控制器deploy的幫助

[root@master01 ~]# kubectl create deploy --help
Create a deployment with the specified name.

Aliases:
deployment, deploy

Examples:
  # Create a deployment named my-dep that runs the busybox image.
  kubectl create deployment my-dep --image=busybox
  
  # Create a deployment with command
  kubectl create deployment my-dep --image=busybox -- date
  
  # Create a deployment named my-dep that runs the nginx image with 3 replicas.
  kubectl create deployment my-dep --image=nginx --replicas=3
  
  # Create a deployment named my-dep that runs the busybox image and expose port 5701.
  kubectl create deployment my-dep --image=busybox --port=5701

Options:
      --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or
map key is missing in the template. Only applies to golang and jsonpath output formats.
      --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the
object that would be sent, without sending it. If server strategy, submit server-side request
without persisting the resource.
      --field-manager='kubectl-create': Name of the manager used to track field ownership.
      --image=[]: Image names to run.
  -o, --output='': Output format. One of:
json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
      --port=-1: The port that this container exposes.
  -r, --replicas=1: Number of replicas to create. Default is 1.
      --save-config=false: If true, the configuration of current object will be saved in its
annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to
perform kubectl apply on this object in the future.
      --template='': Template string or path to template file to use when -o=go-template,
-o=go-template-file. The template format is golang templates
[http://golang.org/pkg/text/template/#pkg-overview].
      --validate=true: If true, use a schema to validate the input before sending it

Usage:
  kubectl create deployment NAME --image=image -- [COMMAND] [args...] [options]

Use "kubectl options" for a list of global command-line options (applies to all commands).
[root@master01 ~]# 

  提示:deploy是pod控制器,建立pod控制器需要指定對應控制器要使用那個映象來執行pod,其次要指定pod裡執行容器的副本數量,預設不指定就表示預設副本為1;

  示例:建立一個nginx pod控制器,指定使用nginx:1.14-alpine映象來執行pod

[root@master01 ~]# kubectl create deploy ngx-dep --image=nginx:1.14-alpine 
deployment.apps/ngx-dep created
[root@master01 ~]# 

  檢視pod建立情況

[root@master01 ~]# kubectl get pod 
NAME                        READY   STATUS    RESTARTS   AGE
nginx-dep-8967df55d-j8zp7   1/1     Running   0          71m
ngx-dep-5c8d96d457-62qd6    1/1     Running   0          33s
[root@master01 ~]# 

  提示:在k8s上資源有兩種級別,第一種是叢集級別,第二種是名稱空間級別;所謂名稱空間就是把資源用邏輯的方式隔離的機制;在同一名稱空間資源的名稱不能相同;預設不指定名稱空間,都是default名稱空間;

  檢視長格式pod資訊

[root@master01 ~]# kubectl get pod -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP           NODE             NOMINATED NODE   READINESS GATES
nginx-dep-8967df55d-j8zp7   1/1     Running   0          74m     10.244.2.2   node02.k8s.org   <none>           <none>
ngx-dep-5c8d96d457-62qd6    1/1     Running   0          3m47s   10.244.1.2   node01.k8s.org   <none>           <none>
[root@master01 ~]# 

  提示:-o用於指定輸出格式,常用的有3個值,wide表示顯示長格式資訊,這種現實方式能夠列出對應資源執行在那個node上,ip地址是多少等等資訊;yaml表示輸出yaml格式的,json表示輸出為json配置檔案的方式;

  建立名稱空間

[root@master01 ~]# kubectl create namespace testing
namespace/testing created
[root@master01 ~]# kubectl create namespace prod
namespace/prod created
[root@master01 ~]# kubectl create namespace develop
namespace/develop created
[root@master01 ~]# 

  檢視名稱空間

[root@master01 ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   132m
develop           Active   31s
kube-node-lease   Active   132m
kube-public       Active   132m
kube-system       Active   132m
prod              Active   41s
testing           Active   57s
[root@master01 ~]# 

  提示:在k8s中資源型別是有簡寫格式,比如namespace可以簡寫為ns,service可以簡寫為svc;

  刪除名稱空間

[root@master01 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   134m
develop           Active   2m1s
kube-node-lease   Active   134m
kube-public       Active   134m
kube-system       Active   134m
prod              Active   2m11s
testing           Active   2m27s
[root@master01 ~]# kubectl delete ns testing
namespace "testing" deleted
[root@master01 ~]# kubectl get ns           
NAME              STATUS   AGE
default           Active   134m
develop           Active   2m26s
kube-node-lease   Active   134m
kube-public       Active   134m
kube-system       Active   134m
prod              Active   2m36s
[root@master01 ~]# 

  提示:除了以上方式刪除資源,我們也可以使用資源型別/資源名稱的方式來指定資源;用空白字元隔開資源型別和名稱的方式只能一次刪除一個資源,而用斜線隔開的可以一次刪除多個資源;

  刪除develop、prod名稱空間

[root@master01 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   136m
develop           Active   4m20s
kube-node-lease   Active   136m
kube-public       Active   136m
kube-system       Active   136m
prod              Active   4m30s
[root@master01 ~]# kubectl delete ns/develop ns/prod
namespace "develop" deleted
namespace "prod" deleted
[root@master01 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   137m
kube-node-lease   Active   137m
kube-public       Active   137m
kube-system       Active   137m
[root@master01 ~]# 

  刪除pod

[root@master01 ~]# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
nginx-dep-8967df55d-j8zp7   1/1     Running   0          85m
ngx-dep-5c8d96d457-62qd6    1/1     Running   0          14m
[root@master01 ~]# kubectl delete pod nginx-dep-8967df55d-j8zp7
pod "nginx-dep-8967df55d-j8zp7" deleted
[root@master01 ~]# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
nginx-dep-8967df55d-8fl27   1/1     Running   0          50s
ngx-dep-5c8d96d457-62qd6    1/1     Running   0          15m
[root@master01 ~]# 

  提示:可以看到我們刪除pod以後,再次檢視,pod又重新建立起來了;其原因是我們使用pod控制器建立的pod它有自愈功能;我們知道在k8s上控制器的 作用就是負責建立和監控對應資源狀態是否符合我們定義的狀態,如果不符合它就會試著重啟或重建的方式讓其對應資源和我們定義的資源狀態保持一致;上述命令我們刪除了pod,但對應控制器發現對應pod被刪除了,它就會試著重新新建一個pod,讓其始終保持和我們期望的狀態保持一致;

  檢視deploy控制器

[root@master01 ~]# kubectl get deploy 
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
nginx-dep   1/1     1            1           94m
ngx-dep     1/1     1            1           23m
[root@master01 ~]# kubectl get deploy -o wide
NAME        READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
nginx-dep   1/1     1            1           94m   nginx        nginx:1.14-alpine   app=nginx-dep
ngx-dep     1/1     1            1           23m   nginx        nginx:1.14-alpine   app=ngx-dep
[root@master01 ~]# 

  刪除控制器

[root@master01 ~]# kubectl get deploy -o wide
NAME        READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
nginx-dep   1/1     1            1           95m   nginx        nginx:1.14-alpine   app=nginx-dep
ngx-dep     1/1     1            1           24m   nginx        nginx:1.14-alpine   app=ngx-dep
[root@master01 ~]# kubectl delete deploy nginx-dep
deployment.apps "nginx-dep" deleted
[root@master01 ~]# kubectl get deploy -o wide     
NAME      READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
ngx-dep   1/1     1            1           24m   nginx        nginx:1.14-alpine   app=ngx-dep
[root@master01 ~]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
ngx-dep-5c8d96d457-62qd6   1/1     Running   0          24m
[root@master01 ~]# 

  提示:刪除控制器它會連同控制器所建立的資源一併刪除;

  建立service

  在k8s中,service資源是用來訪問pod資源而存在的;我們知道刪除一個pod資源後,由於控制的原因,它會重新建立一個pod,那麼新建的pod怎麼讓外部訪問到呢?如果直接訪問podip,那麼每次訪問我們都需要檢視對應的podip才會訪問到對應的pod,很顯然這種不是我們想要的方式;對於service資源來說,它可以幫助我們自動的關聯對應的pod,從而實現我們只需要訪問對應service就可以訪問到pod;通常service的ip地址不會怎麼改變,或者變更沒有pod變更的快,service的作用就是幫助我們關聯對應名稱的pod,從而實現我們訪問serviceip就可以反代到對應的pod上;對於建立service來說,它有幾種型別;第一種clusterip,這種service能夠實現訪問service的ip地址+pod監聽埠就能訪問到對應pod,可以在k8s叢集任意節點訪問serviceip+podport從而訪問到對應pod;第二種是nodeport型別,這種service可以實現把外部任何主機訪問節點k8s任何一個節點的ip地址+一個固定埠就能訪問到pod;

  示例:建立clusterip型別的service,並關聯ngx-dep控制器

[root@master01 ~]# kubectl create service clusterip ngx-dep --tcp=80
service/ngx-dep created
[root@master01 ~]#

  提示:關聯pod只需要將service的名稱和對應控制器的名稱寫成一樣即可;

  檢視ngx-dep service詳細資訊

[root@master01 ~]# kubectl describe svc/ngx-dep   
Name:              ngx-dep
Namespace:         default
Labels:            app=ngx-dep
Annotations:       <none>
Selector:          app=ngx-dep
Type:              ClusterIP
IP Families:       <none>
IP:                10.101.104.228
IPs:               10.101.104.228
Port:              80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.2:80
Session Affinity:  None
Events:            <none>
[root@master01 ~]# 

  提示:可以看到ngx-dep service的ip地址為10.101.104.228;對應關聯的後端pod的地址為10.244.1.2:80

  訪問servcieip看看是否能夠訪問到對應pod?

[root@master01 ~]# curl  10.101.104.228
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master01 ~]# 

  在node01上訪問serviceip看看是否能夠訪問到對應pod呢?

[root@node01 ~]#  curl  10.101.104.228
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@node01 ~]# 

  提示:這個service地址只能在k8s叢集節點上訪問,外部其他主機不能夠正常訪問到;

  測試:刪除pod,看看對應service中endpoint關聯的地址是否會變成對應pod的地址呢?

[root@master01 ~]# kubectl get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
ngx-dep-5c8d96d457-62qd6   1/1     Running   0          57m   10.244.1.2   node01.k8s.org   <none>           <none>
[root@master01 ~]# kubectl delete pod ngx-dep-5c8d96d457-62qd6
pod "ngx-dep-5c8d96d457-62qd6" deleted
[root@master01 ~]# kubectl get pod -o wide                    
NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
ngx-dep-5c8d96d457-w6nss   1/1     Running   0          19s   10.244.2.3   node02.k8s.org   <none>           <none>
[root@master01 ~]# kubectl describe svc/ngx-dep
Name:              ngx-dep
Namespace:         default
Labels:            app=ngx-dep
Annotations:       <none>
Selector:          app=ngx-dep
Type:              ClusterIP
IP Families:       <none>
IP:                10.101.104.228
IPs:               10.101.104.228
Port:              80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.3:80
Session Affinity:  None
Events:            <none>
[root@master01 ~]# 

  提示:可以看到刪除了pod以後,新建的pod地址變為了10.244.2.3,對應service中endpoint關聯的地址也變為了對應pod的ip地址;

  訪問service看看是否能夠訪問到pod呢?

[root@master01 ~]# kubectl describe svc/ngx-dep
Name:              ngx-dep
Namespace:         default
Labels:            app=ngx-dep
Annotations:       <none>
Selector:          app=ngx-dep
Type:              ClusterIP
IP Families:       <none>
IP:                10.101.104.228
IPs:               10.101.104.228
Port:              80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.3:80
Session Affinity:  None
Events:            <none>
[root@master01 ~]# 
[root@master01 ~]# curl  10.101.104.228
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master01 ~]# 

  提示:之所以我們在k8s節點上訪問serviceip能夠訪問到對應pod,原因是我們在建立service時,其實就是在k8s所有節點上生成iptables規則或ipvs規則;

  刪除service

[root@master01 ~]# kubectl delete svc/ngx-dep
service "ngx-dep" deleted
[root@master01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   3h24m
[root@master01 ~]#

  建立nodeport型別的service

[root@master01 ~]#  kubectl create svc nodeport  ngx-dep --tcp=80
service/ngx-dep created
[root@master01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        3h24m
ngx-dep      NodePort    10.107.14.221   <none>        80:30492/TCP   11s
[root@master01 ~]# kubectl describe svc/ngx-dep
Name:                     ngx-dep
Namespace:                default
Labels:                   app=ngx-dep
Annotations:              <none>
Selector:                 app=ngx-dep
Type:                     NodePort
IP Families:              <none>
IP:                       10.107.14.221
IPs:                      10.107.14.221
Port:                     80  80/TCP
TargetPort:               80/TCP
NodePort:                 80  30492/TCP
Endpoints:                10.244.2.3:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
[root@master01 ~]# 

  提示:可以看到現在建立nodeport型別的service後,對應port不再是80:80而變成了80:30492,後面的30492這個埠不是pod埠,它是k8s叢集節點所監聽的一個固定埠;現在我們直接訪問k8s叢集任意一個節點的30492埠,就能訪問到對應的pod;

[root@docker_registry ~]# curl 192.168.0.41:30492
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@docker_registry ~]# curl 192.168.0.44:30492
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@docker_registry ~]# 

  提示:可以看到我們用其他主機訪問對應k8s任意節點的30492埠都能訪問到對應的pod;

  使用名稱訪問service

  我知道當k8s中的pod刪除以後,重新被建立以後可以使用訪問serviceip地址來實現訪問對應pod,那麼問題來了,假如service被刪除又重建以後,我們怎麼來訪問對應pod呢?使用serviceip我們要先檢視serviceip地址,很顯然這個問題又回到了pod刪除怎麼訪問對應pod;在k8s上除了執行的有幾個核心的pod以外,還有一個dns,名叫kube-dns,這個pod主要用來解析對應的名稱到對應服務ip,它可以實現服務的動態註冊;所謂服務動態註冊是指在對應的服務發生以後,它能夠及時的將變化結果反映到對應的解析記錄上,使得我們訪問對應服務不被服務變得而受影響;

  檢視kube-dns的地址

[root@master01 ~]# kubectl get svc -n 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   3h45m
[root@master01 ~]# 

  修改maser端節點dns伺服器為kube-dns的地址

[root@master01 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search k8s.org
nameserver 10.96.0.10
[root@master01 ~]# 

  訪問服務名稱看看是否能夠訪問到對應服務呢?

[root@master01 ~]# curl ngx-dep          
curl: (6) Could not resolve host: ngx-dep; Unknown error
[root@master01 ~]# 

  提示:這裡顯示不能解析ngx-dep,原因是本機的搜尋域為k8s.org;我們在初始化master時沒有指定--service-dns-domain的值為k8s.org,所以預設搜尋域為cluster.local;所以我們訪問時需要指定絕對名稱

  使用完全絕對名稱訪問服務

[root@master01 ~]# curl ngx-dep.default.svc.cluster.local.
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master01 ~]# 

  提示:有了這個絕對的名稱以後,我們在刪除有重建service就可以直接使用名稱訪問服務即可;

  驗證:刪除ngx-dep服務,再重新建ngx-dep服務,看看使用名稱能夠訪問到對應的服務?

[root@master01 ~]# kubectl get svc/ngx-dep
NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
ngx-dep   NodePort   10.107.14.221   <none>        80:30492/TCP   33m
[root@master01 ~]# kubectl delete svc/ngx-dep
service "ngx-dep" deleted
[root@master01 ~]# kubectl create svc clusterip ngx-dep --tcp=80:80
service/ngx-dep created
[root@master01 ~]# kubectl get svc/ngx-dep                              
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
ngx-dep   ClusterIP   10.106.196.39   <none>        80/TCP    6s
[root@master01 ~]# curl ngx-dep.default.svc.cluster.local               
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master01 ~]# 

  提示:可以看到新建的ngx-dep和以前的服務ip地址不一樣,但我們可以通過訪問同一名稱訪問到對應的pod;

  pod動態擴充套件

  新建pod控制器

[root@master01 ~]# kubectl create deploy myapp-dep --image=ikubernetes/myapp:v1
deployment.apps/myapp-dep created
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
myapp-dep-5bc4d8cc74-zcrwz   1/1     Running   0          10s
ngx-dep-5c8d96d457-w6nss     1/1     Running   0          60m
[root@master01 ~]# 

  新建myapp-dep服務

[root@master01 ~]# kubectl create svc clusterip myapp-dep --tcp=80:80
service/myapp-dep created
[root@master01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   4h3m
myapp-dep    ClusterIP   10.96.196.189   <none>        80/TCP    7s
ngx-dep      ClusterIP   10.106.196.39   <none>        80/TCP    5m16s
[root@master01 ~]# kubectl describe svc/myapp-dep
Name:              myapp-dep
Namespace:         default
Labels:            app=myapp-dep
Annotations:       <none>
Selector:          app=myapp-dep
Type:              ClusterIP
IP Families:       <none>
IP:                10.96.196.189
IPs:               10.96.196.189
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.3:80
Session Affinity:  None
Events:            <none>
[root@master01 ~]# 

  擴充套件pod

[root@master01 ~]# kubectl get deploy 
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
myapp-dep   1/1     1            1           4m16s
ngx-dep     1/1     1            1           122m
[root@master01 ~]# kubectl scale --replicas=5 deploy/myapp-dep
deployment.apps/myapp-dep scaled
[root@master01 ~]# kubectl get pod
NAME                         READY   STATUS              RESTARTS   AGE
myapp-dep-5bc4d8cc74-fpfvj   1/1     Running             0          7s
myapp-dep-5bc4d8cc74-gqhh5   0/1     ContainerCreating   0          7s
myapp-dep-5bc4d8cc74-j827z   0/1     ContainerCreating   0          7s
myapp-dep-5bc4d8cc74-s5ftj   0/1     ContainerCreating   0          7s
myapp-dep-5bc4d8cc74-zcrwz   1/1     Running             0          5m17s
ngx-dep-5c8d96d457-w6nss     1/1     Running             0          65m
[root@master01 ~]#

  提示:可以看到現在myapp-dep執行的pod變成了5個;

  縮減pod

[root@master01 ~]# kubectl scale --replicas=3 deploy/myapp-dep
deployment.apps/myapp-dep scaled
[root@master01 ~]# kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP           NODE             NOMINATED NODE   READINESS GATES
myapp-dep-5bc4d8cc74-cvkbc   1/1     Running   0          76s     10.244.1.5   node01.k8s.org   <none>           <none>
myapp-dep-5bc4d8cc74-gmt7w   1/1     Running   0          76s     10.244.3.5   node03.k8s.org   <none>           <none>
myapp-dep-5bc4d8cc74-gqhh5   1/1     Running   0          6m54s   10.244.2.4   node02.k8s.org   <none>           <none>
ngx-dep-5c8d96d457-w6nss     1/1     Running   0          72m     10.244.2.3   node02.k8s.org   <none>           <none>
[root@master01 ~]# 

  提示:動態擴縮減pod數量只需要把對應的replicas數量進行修改即可;預設不指定就是為1;

  現在再次檢視service對應的endpoint地址是否是上述三個地址呢?

[root@master01 ~]# kubectl describe svc/myapp-dep
Name:              myapp-dep
Namespace:         default
Labels:            app=myapp-dep
Annotations:       <none>
Selector:          app=myapp-dep
Type:              ClusterIP
IP Families:       <none>
IP:                10.96.196.189
IPs:               10.96.196.189
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.5:80,10.244.2.4:80,10.244.3.5:80
Session Affinity:  None
Events:            <none>
[root@master01 ~]# 

  提示:可以看到對應service後端endpoint地址已經關聯到以上3個pod地址;這也意味著我們訪問service,它會把我們的請求排程到對應的pod上進行響應,具體會這麼排程呢?

  訪問myapp-dep服務

[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-gmt7w
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-gmt7w
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-gqhh5
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-cvkbc
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-gmt7w
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-gmt7w
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-cvkbc
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-gqhh5
[root@master01 ~]# curl myapp-dep.default.svc.cluster.local/hostname.html
myapp-dep-5bc4d8cc74-gqhh5
[root@master01 ~]# 

  提示:的確service能夠排程請求,從上面訪問結果看,service排程是隨機排程,沒有什麼規律;

  以上就是k8s叢集環境中使用kubectl命令列工具來操作k8s上的名稱空間,控制器,服務相關演示和說明;從上面的演示可以知道,在k8s上所有的操作都在master端進行,因為master端有證書,預設情況k8s的aipserver會雙向認證,所謂雙向認證是指,不僅客戶端要驗證服務端證書,同時服務端也要驗證客戶端證書;在k8s上的所有操作都要先和apiserver打交道;其次建立pod控制器,只要控制器不被刪除,裡面定義的pod它就會一直處於我們期望的數量和狀態存在,即便我們手動刪除pod它也會自動重建;對於service來說,在k8s上建立service,從本質上講就是建立iptables或ipvs規則;不同型別的service訪問途徑略有不同,clusterip型別的service只能在k8s節點上實現訪問,nodeport型別的service可以實現從外部主機訪問k8s節點ip+對應建立service自動生成的固定埠就可以訪問到對應服務;除此之外,在k8s上我們可以通過kubectl scale來對pod控制器做動態擴縮減pod數量;如果一個service後端對應多個pod時,service還能起到排程的作用;

相關文章