Kubernetes简介手册

关于这篇文章

这是一个收集了有关Kubernetes(简称K8s)命令的备忘单。我们将重点整理K8s的基本命令kubectl的用法,同时通过实际操作一个简单的K8s集群来学习。

环境

作为运行k8s的环境

    • ローカルではminikube

 

    AWS EKS

有很多选择,为了简单起见,我们决定使用minikube来建立本地环境。
只要调整权限,EKS集群基本上可以以相同的方式使用。

准备好

请参考以下URL,安装 minikube:
(https://kubernetes.io/docs/tasks/tools/install-minikube/)

首先,启动minikube,并确认集群的IP。

$ minikube start
...
$ minikube ip
192.168.99.101

确认设置

让我们使用K8s的基本命令kubectl来查看信息。

查看全部设定

我认为,虽然在Minikube或EKS中这些设置是自动创建的,但如果了解其内容,当出现问题时会更容易处理,所以我会解释一下。

设定文件可以在 ~/.kube/config 中找到,但也可以通过 kubectl config view 命令查看。
从 kubectl config view 的结果中,我提取了有关 minikube 的信息。

- cluster:
    certificate-authority: /Users/zawawahoge/.minikube/ca.crt
    server: https://192.168.99.101:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube

在结构上,有一个名为minikube的cluster,并且有一个名为minikube的context引用它。
首先,在cluster中注册集群IP和认证密钥,然后context引用它。
刚才的集群IP也被写入到配置文件中。

接下来,让我们使用 kubectl 来确认关于连接的目标集群信息的上下文。
上下文是指 Kubernetes 为了方便连接多个集群而提供的关于集群和项目连接信息的内容。

详细来说,

    • name(コンテクストそのものの名前)

 

    • cluster(どのクラスタ設定を使うか)

 

    • user(どういうユーザとしてクラスタに接続するか)

 

    • authinfo

 

    namespace(名前空間)

是由…组成的。

查看当前设置的上下文列表

可以使用kubectl config get-contexts命令。

$ kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO   NAMESPACE
*         minikube   minikube   minikube

尽管Minikube的默认值有些平淡,但像EKS集群这样的情况下名称会更加复杂。

确认默认的上下文名称

$ kubectl config current-context
minikube

上下文是关于客户端试图通过kubectl连接到集群的信息,所以即使进行了修改,也不会在远程端反映出来。如果想要连接到不同的集群或命名空间,需要创建一个新的上下文或编辑现有的上下文。

创建新的背景信息

$ kubectl config set-context my-context
Context "my-context" created.

$ kubectl config get-contexts my-context
CURRENT   NAME         CLUSTER   AUTHINFO   NAMESPACE
          my-context

一个全新的环境被建立起来了。

编辑上下文

$ kubectl config set-context my-context --namespace new-namespace --cluster minikube
Context "my-context" modified.

$ kubectl config get-contexts my-context
CURRENT   NAME         CLUSTER    AUTHINFO   NAMESPACE
          my-context   minikube              new-namespace

更改默认上下文

$ kubectl config use-context my-context
Switched to context "my-context".

更改默认上下文的命名空间。

在实际应用中,虽然连接的集群是相同的,但可能会有需要更改命名空间的情况。这时候,只需要改写当前上下文的命名空间就可以了。

# 変更前のコンテクストの詳細
$ kubectl config get-contexts $(kubectl config current-context)
CURRENT   NAME         CLUSTER    AUTHINFO   NAMESPACE
*         my-context   minikube              new-namespace

$ kubectl config set-context --current --namespace new-new-namespace
Context "my-context" modified.

# 変更後のコンテクストの詳細
$ kubectl config get-contexts $(kubectl config current-context)
CURRENT   NAME         CLUSTER    AUTHINFO   NAMESPACE
*         my-context   minikube              new-new-namespace

设定背景细节

$ kubectl config view

# デフォルトのコンテクストの設定詳細
$ kubectl config view --minify

实际运行集群并观察结果。

前座時間有点长,但现在让我们实际运行minikube的集群吧。
我们将部署一个相当简单的集群,其中有三个由nginx镜像创建的容器。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

将默认上下文设置为minikube,以便准备好访问集群。

kubectl config use-context minikube
Switched to context "minikube".

部署集群

$ kubectl apply -f nginx-deploy.yaml

查看有关集群的信息列表

在k8s中,

    • Deployment

 

    • ReplicaSet

 

    • Pod

 

    Service

使用kubectl get命令,可以获取集群的信息。当使用all选项时,将输出上述四个选项的全部内容。

$ kubectl get all
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-56db997f77-6rvxq   1/1     Running   0          8m27s
pod/nginx-56db997f77-9w55k   1/1     Running   0          8m27s
pod/nginx-56db997f77-ptw9c   1/1     Running   0          8m27s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   13d

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   3/3     3            3           8m27s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-56db997f77   3         3         3       8m27s

如果只想查看部署情况时,可以将”all”替换为”deploy”。
添加”-o wide”选项可以增加输出的信息量。

$ kubectl get deploy
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   3/3     3            3           11m

$ kubectl get deploy -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
nginx   3/3     3            3           11m   nginx        nginx    app=nginx

查看詳細設定

使用-o yaml或-o json选项,可以查看更详细的信息。刚才应用的yaml文件写得非常简略,但是命令可以查看省略的默认值。

kubectl get deploy -o yaml的结果如下:

apiVersion: v1
items:
- apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    annotations:
      deployment.kubernetes.io/revision: "1"
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx","name":"nginx","ports":[{"containerPort":80}]}]}}}}
    creationTimestamp: "2019-05-11T17:51:32Z"
    generation: 1
    name: nginx
    namespace: default
    resourceVersion: "211356"
    selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx
    uid: 693dc4b4-7415-11e9-9b1f-0800273e0575
  spec:
    progressDeadlineSeconds: 600
    replicas: 3
    revisionHistoryLimit: 10
    selector:
      matchLabels:
        app: nginx
    strategy:
      rollingUpdate:
        maxSurge: 25%
        maxUnavailable: 25%
      type: RollingUpdate
    template:
      metadata:
        creationTimestamp: null
        labels:
          app: nginx
      spec:
        containers:
        - image: nginx
          imagePullPolicy: Always
          name: nginx
          ports:
          - containerPort: 80
            protocol: TCP
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
        dnsPolicy: ClusterFirst
        restartPolicy: Always
        schedulerName: default-scheduler
        securityContext: {}
        terminationGracePeriodSeconds: 30
  status:
    availableReplicas: 3
    conditions:
    - lastTransitionTime: "2019-05-11T17:54:24Z"
      lastUpdateTime: "2019-05-11T17:54:24Z"
      message: Deployment has minimum availability.
      reason: MinimumReplicasAvailable
      status: "True"
      type: Available
    - lastTransitionTime: "2019-05-11T17:51:32Z"
      lastUpdateTime: "2019-05-11T17:54:24Z"
      message: ReplicaSet "nginx-56db997f77" has successfully progressed.
      reason: NewReplicaSetAvailable
      status: "True"
      type: Progressing
    observedGeneration: 1
    readyReplicas: 3
    replicas: 3
    updatedReplicas: 3
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

我得到了相当详细的信息。

查看Pod列表

如果使用“-o wide”选项,显示的信息会增加。

$ kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
nginx-56db997f77-6rvxq   1/1     Running   0          22m   172.17.0.10   minikube   <none>           <none>
nginx-56db997f77-9w55k   1/1     Running   0          22m   172.17.0.9    minikube   <none>           <none>
nginx-56db997f77-ptw9c   1/1     Running   0          22m   172.17.0.8    minikube   <none>           <none>

寻找Pod名称的列表

使用awk命令可以轻松提取Pod名称列表。将显示第二行及以后的第一列。

# Pod名のリストを表示
$ kubectl get pods | awk 'NR>1{print $1}'
nginx-56db997f77-6rvxq
nginx-56db997f77-9w55k
nginx-56db997f77-ptw9c

# PodのIPのリストを表示
$ kubectl get pods -o wide | awk 'NR>1{print $6}'
172.17.0.9
172.17.0.8
172.17.0.4

获取具有特定标签的 Pod 列表

当使用-l选项指定标签时,只提取具有特定标签的POD。

$ kubectl get pods -l app=nginx
NAME                     READY   STATUS    RESTARTS   AGE
nginx-56db997f77-6rvxq   1/1     Running   2          36h
nginx-56db997f77-9w55k   1/1     Running   2          36h
nginx-56db997f77-ptw9c   1/1     Running   2          36h

访问集群内的容器

这三个Pod分别具有集群中的私有IP地址。
作为k8s的特点,同一集群中的Pod可以使用这个私有IP地址相互通信。
让我们实际验证一下。

为访问群集内部,创建临时的Pod。

我创建了一个只用于通过busybox执行wget命令的Pod,然后向IP地址为172.17.0.10的Pod发送请求,成功收到了index.html的响应。

$ kubectl run -i -t busybox --image=busybox --restart=Never
/ # wget 172.17.0.10:80
Connecting to 172.17.0.10:80 (172.17.0.10:80)
index.html           100% |****************************************************************************************|   612  0:00:00 ETA

/ # ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link  src 172.17.0.11
# このPodのプライベートIPは172.17.0.11

试着进入集装箱内

使用kubectl exec命令,可以实现与docker exec相同的功能,访问Pod中的容器。

$ kubectl exec -it nginx-56db997f77-6rvxq bash
root@nginx-56db997f77-6rvxq:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@nginx-56db997f77-6rvxq:/#

只要nginx日志是输出到标准输出的,我们可以使用kubectl logs命令来确认。

检查Pod的容器输出的日志

$ kubectl logs nginx-56db997f77-6rvxq
172.17.0.11 - - [11/May/2019:18:28:39 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-"

因为刚才发送HTTP请求的发送源busybox容器的IP地址是172.17.0.11,所以我知道日志已经正确保存了。

服务

使用负载均衡器将外部通信路由到Pod

我确认了三个nginx的Pod正常运行,但是从集群外面无法进行通信。有一种名为Load balancer的Service类型可以在外部通过指定的方式将通信路由到Pod上。

apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
spec:
  selector:
    app: nginx
  ports:
  - port: 80
  type: LoadBalancer

应用-f命令后,将创建一个新的Service。
我觉得你可能会担心该Service会不会正确地与Deployment和负载均衡器结合起来。
实际上,由于选择器与Deployment相匹配,所以Service能够找到对应的Deployment。

$ kubectl apply -f nginx-service.yaml
service/nginx-lb created

$ kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP        13d
nginx-lb     LoadBalancer   10.99.193.167   <pending>     80:32328/TCP   10s

由于在minikube上,此Service处于Pending状态,因此无法访问。
从0.31.0版本开始,minikube添加了一个名为minikube tunnel的功能,使用它可以实现访问。
参考资料:https://qiita.com/inajob/items/4025a1d1aa83721c453d

$ minikube tunnel
Status:
    machine: minikube
    pid: 45884
    route: 10.96.0.0/12 -> 192.168.99.101
    minikube: Running
    services: [nginx-lb]
    errors:
        minikube: no errors
        router: no errors
        loadbalancer emulator: no errors

再试一次,确实显示了EXTERNAL-IP。

$ kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1      <none>         443/TCP        13d
nginx-lb     LoadBalancer   10.109.96.98   10.109.96.98   80:32425/TCP   10m
$ curl 10.109.96.98
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
  ...(略)

请注意,在实际的 AWS 运营中,必须使用 EKS 服务可用的负载均衡器,这样才能从外部进行访问。

广告
将在 10 秒后关闭
bannerAds