Kubernetes的基础知识 〜Docker for Mac实践指南〜

简而言之

参考的亲手实践

以下是两个网页的链接:

1. https://www.nic.ad.jp/ja/materials/iw/2018/proceedings/h2/h2-takara-3.pdf
2. https://www.nic.ad.jp/ja/materials/iw/2018/proceedings/h2/h2-takara-4.pdf

Kubernetes 是什么?

Kubernetes是一种用于自动化操作Linux容器的开源软件(OSS),也被称为”k8s”或”kube”。
在日本,它的发音为”クーバネテス”或”クーベネティス”。
通过使用Kubernetes,您可以自动化应用程序的部署和扩展等操作。换句话说,它可以将运行Linux容器的主机集群化。

中文中要求身份、職業等信息的列表。

我将整理常见的术语以备查阅。
您无须记住这里的所有内容,当在实践中遇到不熟悉的术语时,请参考此处。

Kubernetes 的组成要素

    • ポッド(Pod)

 

    • ポッドは複数のコンテナから構成されます。ポッド単位でコンテナが起動・破棄されます。また、ポッドは一時的な存在であるため再起動はありません。各ポッドには一意の仮想NICが割り当てられます。また、同じポッド内のコンテナ同士はIPアドレスを共有し、localhost で通信できます。

 

    • ノード(Node)

 

    • Dockerコンテナを実行するサーバのことです。複数のポッドを持ちます。

 

    • マスターノード(Master Node)

 

    • 各ノードの管理を行うノードのことです。

 

    • クラスター(Cluster)

 

    • コンテナやネットワークの設定などをクラスタリングしたものです。

 

    • ネームスペース(Namespace)

 

    • ネームスペースをつけてクラスターを仮想化できるものです。あらかじめ「default」「docker」「kube-public」などのネームスペースが用意されています。例えば、WEBサーバ群、DBサーバ群、などのような分け方が想定できます。

 

    • コンテキスト(Context)

 

    • Kubernetes の環境を分けるための定義です。 クラスター、ネームスペース、ユーザーをグループ化したものです。

 

    • サービス(Service)

 

    ポッドに対してクラスタ外からアクセスするためにはサービスを定義する必要があります。サービスにはクラスタの代表となるIPを指定します。

为了控制上述要素的出现

    • コントローラー

 

    • ポッドを制御するためのオブジェクトです。コントローラーには様々な種類があり、特性によって使い分けます。

 

    • デプロイメント(Deployment)

 

    • 最も良く使われるコントローラーがデプロイメントです。良くあるWEBサーバなどの用途ではこちらを使います。ポッド数をスケールしたり、ロールバックをしたり、求められる基本的な動作をします。

 

    • Service

 

    • サービスを定義します。

 

    • ConfigMap

 

    • コンテナで使用される設定を定義します。

 

    • Secret

 

    • コンテナで使用される秘匿情報を定義します。

 

    • Volume

 

    • コンテナに割り当てるストレージを定義します。

 

    • Job

 

    • ジョブを定義します。

 

    • CronJob

 

    定期的に実行されるジョブを定義します。

其他术语

    • マニフェスト

 

    Kubernetes の構成を定義するための形式(yamlファイル)のことです。

要在 Mac 上使用 Kubernetes

在 Mac 上使用 Kubernetes 有以下的方法。每个方法都有优点和缺点。

    • Docker for Mac の Kubernetes を使う

既に Docker for Mac がインストールされている場合は最速の方法です。
Docker for Mac 自体が重いという話があり、パフォーマンスが懸念されます。
また、Kubernetes の構成に限りがあるらしいです。

Minikube を使う

自動で Vagrant の仮想環境をたて、Kubernetes を実行してくれます。
より完全に近い Kubernetes 環境を再現してくれるらしいです。

Docker for Mac 版实践指导

总结

如果您已经安装了 Docker for Mac,则使用 Docker for Mac 的 Kubernetes 是更快速的选择。

Kubernetes 提供了一个可以在图形界面上查看容器状态的仪表盘功能。
让我们在观察状态的同时理解更深入一些。

前提 tí)

    OSX が Docker for Mac 18.06 以上に対応していること

安装

请按照以下参考文档安装Docker for Mac:
https://docs.docker.com/docker-for-mac/install/

启用Kubernetes

打开Docker菜单,点击“偏好设置”。
从显示的设置菜单中选择“Kubernetes”,即可进入如下界面。

点击启用Kubernetes、默认情况下将Docker堆叠部署到Kubernetes、显示系统容器(高级)这三个选项,然后点击”应用并重启”。在菜单栏中会出现”Kubernetes正在运行”的项目,稍等片刻确认变为绿色。

接下来,在终端中将上下文切换到”docker-for-desktop”。

$ kubectl config use-context docker-for-desktop
Switched to context "docker-for-desktop".

我们来观察一下上下文的状态。
我们可以确认它已经成为指定的上下文了。

$ kubectl config get-contexts
CURRENT   NAME                 CLUSTER          AUTHINFO         NAMESPACE
          docker-desktop       docker-desktop   docker-desktop
*         docker-for-desktop   docker-desktop   docker-desktop 

您可以通过输入以下命令来确认群集、上下文等当前的状态。

$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://kubernetes.docker.internal:6443
  name: docker-desktop
contexts:
- context:
    cluster: docker-desktop
    user: docker-desktop
  name: docker-desktop
- context:
    cluster: docker-desktop
    user: docker-desktop
  name: docker-for-desktop
current-context: docker-for-desktop
kind: Config
preferences: {}
users:
- name: docker-desktop
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

如果您有兴趣,您可以使用以下命令来确认Docker镜像的生成状态,容器是否已启动以及Kubernetes的Pods是否已创建。

$ docker images
$ docker ps -a
$ kubectl get pods --all-namespaces

启用仪表盘。

如果启用仪表板,您可以使用图形用户界面查看像上面的命令中确认的 Kubernetes 状态。
有关仪表板的详细信息,请参阅以下链接:
https://github.com/kubernetes/dashboard

首先,请使用以下命令将仪表板启用。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc6/aio/deploy/recommended.yaml

接下来,启动仪表盘。

$ kubectl proxy
Starting to serve on 127.0.0.1:8001

站起来后,尝试从以下链接访问仪表板。
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

然后会显示认证界面。

需要令牌,所以我们在终端中搜索令牌。
首先查找以”default-token”为开头的密钥,然后进一步确认其详细信息。然后令牌将被显示出来。

$ kubectl -n kube-system get secret | grep default-token
default-token-h5snm                              kubernetes.io/service-account-token   3      3d22h

$ kubectl -n kube-system describe secret default-token-h5snm
Name:         default-token-h5snm
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 9e7e6f74-a435-4f90-83a1-cbca37953aa5

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlc...

在先前的认证界面中输入令牌,并登录。
如果显示如下界面,则表示成功。

执行”Hello World”

通常,構建Kubernetes集群需要编写清单文件,但由于我们想要先快速尝试一下,我们将执行Hello World命令来观察情况。请执行以下命令。

$ kubectl run hello-world --image=hello-world -it --restart=Never

起来后,我会从刚才的仪表板上看一下。
现在有一个名为hello-world的Pod,它带有”default”命名空间,只有一个节点,所以我们使用”docker-desktop”。
点击可以查看更多详细信息。

如果从终端进行确认,可以使用以下命令查看。

$ kubectl get pod
NAME          READY   STATUS      RESTARTS   AGE
hello-world   0/1     Completed   0          15m

$ kubectl describe pod
Name:         hello-world
Namespace:    default
Priority:     0
Node:         docker-desktop/192.168.65.3
Start Time:   Mon, 30 Mar 2020 18:11:16 +0900
Labels:       run=hello-world
Annotations:  <none>
Status:       Succeeded
IP:           10.1.0.12
...

就算只是随便看了一眼播放列表和仪表盘,我还是会把这个播放列表删除掉。

$ kubectl delete pod hello-world

写出宣言书

接下来,让我们来描述一下清单(Manifest)。
我们将使用手把手教学的存储库进行确认。
https://github.com/larable/grpc-go-handson-for-mac

以以下方式克隆存储库。

git clone git@github.com:larable/grpc-go-handson-for-mac.git

以下是《宣言》的基本要素。

apiVersion: v1 # APIのバージョン
kind: Pod # APIの種別
metadata:
  name: test # オブジェクト名
spec: # オブジェクトの仕様
  containers:
  - name: ubuntu
    image: ubuntu:18.04

在理解了这一点之后,我们希望着手编写部署清单,但是这次我们将使用先前提到的仓库中以下的清单:k8s/dev-bgg-deployment.yaml。

这份宣言也是基于先前的基本结构进行描述的。对于新加入的项目,附有注释。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bgg-deployment
spec:
  replicas: 1 # レプリカ数
  selector:
    matchLabels:
      app: backend
  template: # ポッドを生成する際のテンプレート
    metadata:
      labels:
        app: backend # デプロイメントのポッドと対応づける
    spec:
      containers:
        - image: boilerplate-grpc-go
          imagePullPolicy: IfNotPresent # ローカルになければ Docker Hub から pull する
          securityContext:
            capabilities:
              add:
                - SYS_PTRACE
          name: bgg-container
          env:
            - name: GRPC_PORT
              value: "50051"
          ports:
            - containerPort: 50051
            - containerPort: 40000
          readinessProbe:
            exec:
              command: ["/bin/grpc_health_probe", "-addr=:50051"]
            initialDelaySeconds: 1
            timeoutSeconds: 1
          livenessProbe:
            exec:
              command: ["/bin/grpc_health_probe", "-addr=:50051"]
            initialDelaySeconds: 1
            timeoutSeconds: 1
          resources:
            limits:
              cpu: 100m
              memory: 32Mi
            requests:
              cpu: 100m
              memory: 32Mi

通过部署来启动Pod

在上述文件中尝试生成对象。
在此之前,需要确保本地已经创建了 Docker 镜像,否则会报错。请先启动。

$ # おまじない
$ export KUBECONTEXT=minikube
$ export IMAGE=boilerplate-grpc-go
$ sh build.sh

我会试着启动一下。

$ kubectl apply -f k8s/dev-bgg-deployment.yaml
deployment.apps/bgg-deployment created

我会检查部署和Pod的状态。

$ kubectl get deploy
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
bgg-deployment   1/1     1            1           74s

$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
bgg-deployment-85449c8b86-w4ltj   1/1     Running   0          79s

我确认了你已经站起来了。
顺便说一下,如果你想删除对象,可以使用以下命令。

$ kubectl delete -f k8s/dev-bgg-deployment.yaml

新增服务

Pod已经启动,但是目前无法从外部访问。
要访问,需要添加一个服务。
服务可以进行IP地址定义、DNS定义、负载均衡等操作。

服务也会在清单中进行描述。
那么,让我们用样本存储库下面的文件来尝试一下。
k8s/dev-bgg-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: bgg-headless-svc # 内部DNSへ登録する名前
spec:
  clusterIP: None
  ports:
    - name: headless
      port: 50051
      protocol: TCP
      targetPort: 50051
  selector:
    app: backend # デプロイメントのラベルを指定する

那我们来生成服务吧。

$ kubectl apply -f k8s/dev-bgg-service.yaml

当查看已启动的服务时,可以确认它以指定的端口启动。

$ kubectl get services
NAME               TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
bgg-headless-svc   ClusterIP   None         <none>        50051/TCP   8m28s
kubernetes         ClusterIP   10.96.0.1    <none>        443/TCP     8

让我们在此状态下查看仪表板。
您可以确认部署、Pod和副本集已被生成。

我会先删除到现在为止创建的东西。

$ kubectl delete -f k8s/dev-bgg-service.yaml
service "bgg-headless-svc" deleted

$ kubectl delete -f k8s/dev-bgg-deployment.yaml
deployment.apps "bgg-deployment" deleted

引入 skaffold

我已经理解了Kubernetes的基本操作。但是在本地开发中,如果经常需要更新环境,从创建Docker镜像到启动Kubernetes的步骤有些繁琐。而且,当想要启动多个服务时,情况会更加困难。这就是Skaffold的用武之地。
Skaffold可以将Docker构建到kubectl应用的整个过程进行流程化,使其变得简单易行。此外,它还具有监视文件并在更改时自动更新的功能。

首先,需要进行安装。

$ brew install skaffold

skaffold 的设置写在 skaffold.yaml 文件中。
这次我们将参考示例存储库中的 skaffold.yaml 进行尝试。

apiVersion: skaffold/v2alpha4
kind: Config
build:
  artifacts:
  - image: boilerplate-grpc-go
    custom:
      buildCommand: ./build.sh
      dependencies:
        paths:
          - main.go
          - service
          - go.mod
          - go.sum
          - build.sh
          - Dockerfile
  local:
    useDockerCLI: true
    useBuildkit: true
    concurrency: 1
profiles:
  - name: local
    activation:
      - kubeContext: minikube
    build:
      local:
        push: false
    deploy:
      kubectl:
        manifests:
          - k8s/dev-*.yaml
  - name: stg
    activation:
      - kubeContext: arn:aws:eks:us-west-2:113269943850:cluster/eks-sandbox
    build:
      artifacts:
        - image: 113269943850.dkr.ecr.us-west-2.amazonaws.com/boilerplate/grpc-go
    deploy:
      kubectl:
        manifests:
          - k8s/stg-*.yaml

我将尝试启动。
初次启动将需要一些时间。

$ kubectl config use-context minikube
$ skaffold dev

使用这个,我们确认启动成功了。
在 skaffold dev 命令中,它会监听应用程序的修改并执行构建和部署操作,但如果只想执行一次,可以运行以下命令。

$ skaffold run

已经完成了。

Minikube版本的实操教程

如果我有能力的话,我会把它写下来。

故障排除

docker 命令和 kubectl 命令没有返回响应。

如果无法收到Docker命令或kubectl命令的响应,或者出现超时的提示,就重新启动Docker Desktop。
在菜单栏中选择Docker并重新启动,若连这个都无法操作,就通过活动监视器等方式进行重新启动。

当kubectl apply命令无法生成对象时,以下是调查方法。

使用以下命令来查看对象的详细信息和日志,以找出原因。

$ # 詳細を確認
$ kubectl describe [オブジェクト名] [名前]
$ # ログを確認
$ kubectl logs [名前]

出现找不到Docker镜像的错误。

如果您在使用 kubectl apply 时希望使用本地的 Docker 镜像,但遇到了找不到的错误,请参考下列解决方法。

image pull policy を IfNotPresent (ローカルになければpull) にする
docker イメージのタグを latest にしない

广告
将在 10 秒后关闭
bannerAds