序文
この記事では、「MySQLを構築してk8s(Kubernetes)の重要な概念をマスターする(パート1):ネットワークと永続ボリューム」について説明します。
元のブロガーはWindowsの仮想マシンであるVagrantのminikubeを使用しているため、macOSとは異なります。さらに、mysql:5.7ミラーをダウンロードする元のブロガーの方法はダウンロードできず、異なる構成ファイルになるため、この記事を利用できます。
ドッキングウィンドウのmysqlの:「から5.7画像引き参照ドッキングウィンドウは、MySQLの画像を引っ張ると遭遇した問題と解決策」
侵入。
準備オーケー
- mac OSシステムバージョン10.15.4、
- dockerデスクトップとk8sをインストールします。AlibabaCloudhttps://github.com/AliyunContainerService/k8s-for-docker-desktop/tree/v1.16.5を参照してください。
- dockerバージョン19.03.8、k8sバージョン
➜ kubectl version
Client Version: version.Info{
Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:26:26Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{
Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:18:29Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"linux/amd64"}
应用程序分成两种,无状态和有状态的。一般的前段和后端程序都是无状态的,而数据库是有状态的,他需要把数据存储起来,这样即使断电,数据也不会丢失。要创建有状态的程序,还需要引入另外一些k8s概念。它们虽然不是核心,但也很重要,共有三个,持久卷,网络和参数配置。掌握了这些之后,基本概念就已经做到了全覆盖,k8s就已经入门了。我们通过搭建MySQL来熟悉这些k8s概念。容器本身是无状态的,一旦出现问题它会被随时销毁,它存储的数据也就丢失了。MySQL需要一个能保存数据的持久层,在容器被销毁之后仍然存在,k8s叫它持久卷。
1.MySQLミラーを作成して確認します
国内のミラーdaocloud.io/libraryライブラリからダウンロードしてください。ダウンロード速度は感動的です。
docker pull daocloud.io/library/mysql:5.7
ダウンロードしたミラーを表示します。
docker images|grep mysql
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/library/mysql 5.7 718a6da099d8 2 weeks ago 448MB
mysqlミラー名のプレフィックスは忘れられないことに注意してください。忘れないと、エラーが報告されます。
フルネーム:daocloud.io/library/mysql:5.7
実行:
docker run --name test-mysql -p 3306:33060 -e MYSQL_ROOT_PASSWORD=root -d -it --net host daocloud.io/library/mysql:5.7
「root」はrootユーザーのパスワードです。これは、MySQLコンテナの作成時に指定した「root」ユーザーのパスワードです。「Test-MySQL」はコンテナの名前です。「Daocloud.io/library/mysql:5.7」は、daocloudミラーライブラリの「MySQL」バージョン5.7を使用します。今回は最新バージョン8.0を使用しませんでした。これは、新しいバージョンが以前のクライアントと互換性がなく、多くの変更が必要なためです。使用されるミラーはLinuxのフルバージョンであるため、ファイルは比較的大きく、400Mです。
コンテナが作成されたら、「dockerlogstest-mysql」と入力してログを表示します。「Dockerps」、コンテナのステータスを表示します。
docker ps -a|grep mysql
3b6ec96e49d0 daocloud.io/library/mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes test-mysql
dockerと入力し、mysqlにログインして以下を表示します。
docker exec -it 3b6ec96e49d0 bash
mysql -u root -p
パスワード「root」を入力して、通常のmysqlコンソールに入ります。操作が完了したら、2つの「exit」と入力してosのターミナルに戻ります。
2.MySQLをk8sにインストールします
k8sへのMySQLのインストールは、デプロイメントファイルの作成、サービスファイルの作成、およびインストールとテストの3つの部分に分かれています。
2.1デプロイメントファイル
以下は、デプロイメント構成ファイルです。ファイル形式については、前回の記事で詳しく説明しました。すべてのk8の構成ファイル形式は同じです。「テンプレート」の上には展開構成があり、「テンプレート」の下にはポッド構成があります。「コンテナ」から始まるのは、ポッド内のコンテナ構成です。「Env:」は環境変数です。ここでは、データベースのユーザー名とパスワードを環境変数で設定します。これについては後で詳しく説明します。MySQLのポートは「3306」です
apiVersion: apps/v1
kind: Deployment # 类型是部署
metadata:
name: mysql-deployment # 对象的名字
spec:
selector:
matchLabels:
app: mysql #用来绑定label是“mysql”的Pod
strategy:
type: Recreate
template: # 开始定义Pod
metadata:
labels:
app: mysql #Pod的Label,用来标识Pod
spec:
containers: # 开始定义Pod里面的容器
- image: daocloud.io/library/mysql:5.7 # image这块一定要写成daocloud的
name: mysql-con
imagePullPolicy: Never
env: # 定义环境变量
- name: MYSQL_ROOT_PASSWORD # 环境变量名
value: root # 环境变量值
- name: MYSQL_USER
value: dbuser
- name: MYSQL_PASSWORD
value: dbuser
args: ["--default-authentication-plugin=mysql_native_password"]
ports:
- containerPort: 3306 # mysql端口
name: mysql
2.2サービスファイル
以下は、サービス構成ファイルです。これは、基本的に前の記事の構成と同じであるため、ここでは説明しません。
apiVersion: v1
kind: Service
metadata:
name: mysql-service
labels:
app: mysql
spec:
type: NodePort
selector:
app: mysql
ports:
- protocol : TCP
nodePort: 30306
port: 3306
targetPort: 3306
2.3インストールテスト:
構成ファイルを使用して、MySQLの作成を開始しましょう。作成するときは、順序に従い、一番下のオブジェクトから順番に進める必要があります。
展開とサービスを作成します。
kubectl apply -f mysql-deployment.yaml
kubectl apply -f mysql-service.yaml
展開の表示:
kubectl get deployment
サービスの表示:
kubectl get service
「mysql-service」には2つのポート(PORT(S))があり、「3306」はk8sの内部ポート、「30306」は外部ポートです。「NodePort」が外部ポートを開いているので、osコンソールの「30306」ポートを介してMySQLにアクセスできます。
➜ test mysql -h localhost -P 30306 --protocol=tcp -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.31 MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
次のステップでは、グラフィカルクライアントを使用してMySQLにアクセスできます。ポート30306を使用してMySQLにアクセスします。
3.ネットワーク
ここでのネットワークには2つの意味があります。最初の層はk8sネットワークです。これにより、k8sの内部サービスが相互にアクセスでき、k8sクラスターの内部サービスにk8sクラスターの外部からアクセスできます。もう1つの層は、ホスト(ラップトップ)と仮想マシン間のネットワークです。つまり、ホスト上で仮想マシンにアクセスできます。これらの2つのレイヤーが接続されると、ホスト上のk8sクラスター内のMySQLに直接アクセスできます。
3.1 k8sネットワーク:
k8sのネットワークにも2つの意味があります。1つはクラスター内にあり、k8sには内部DNSがあり、サービス名でアドレス指定できます。もう1つは、クラスターの外部からクラスターの内部サービスにアクセスする方法です。合計4つの方法があります。詳細については、「Kubernetes NodePort vs LoadBalancer vs Ingress?いつ何を使用すればよいですか?」を参照してください。
3.1.1 LoadBalancer
3.1.2 NodePort:
このメソッドは、各ノードで外部ポートを開くことができ、このポートを指すすべての要求はサービスに転送されます。その利点は、固定ポートを指定できることです(ポートの値の範囲は30000〜32767のみです)。そのため、ラップトップでMySQLにアクセスするときにポートを変更する必要がありません。指定しない場合、システムはランダムに割り当てます。その欠点は、各ポートが1つのサービスしか持てず、ポート値が制限されているため、実稼働環境には適していないことです。
3.1.3 ClusterIP
これは、k8sクラスター内でのみ対処できます。
3.1.4入力
これは推奨される方法であり、一般的に実稼働環境で使用されます。ロードバランサーの問題点は、すべてのサービスにロードバランサーがあることです。サービスが増えると、非常に面倒になります。この時点で入力が使用されます。欠点は、構成が複雑になることです。MinikubeにはNginxベースのIngressコントローラーが付属しており、「minikubeアドオンで入力を有効にする」を実行するだけで機能します。ただし、Ingressの設定はより複雑なので、ここでは使用しません。
3.2仮想マシンネットワーク(省略)
4永続ボリュームを作成します(PersistentVolume)
k8sボリュームの概念には、ボリュームと永続ボリュームが含まれます。
4.0.1ボリューム:
ボリュームはk8sのストレージの概念であり、ポッドに接続されており、単独で存在することはできません。しかし、それはコンテナレベルではありません。したがって、コンテナを再起動しても、ボリュームはまだそこにあります。ただし、ポッドが再起動すると、ボリュームは失われます。ポッドに複数のコンテナがある場合、これらのコンテナはポッドのボリュームを共有します。ボリュームは、さまざまなファイルを保存できるディレクトリと考えることができます。k8sは、ローカルファイルシステムやさまざまなクラウドストレージなど、さまざまなタイプのボリュームをサポートします。
4.0.2 PersistentVolume:
これはボリュームのパッケージであり、目的はボリュームをより適切に管理することです。そのライフサイクルはポッドにバインドする必要はなく、ポッドとは独立して存在できます。
4.0.3永続ボリュームクレーム(PersistentVolumeClaim):
永続ボリュームリソースのアプリケーションです。特定のストレージ容量サイズと、読み取り/書き込みモードや読み取り専用モードなどのアクセスモードを申請できます。k8sは、永続ボリュームのアプリケーションに応じて適切な永続ボリュームを割り当てます。適切なボリュームがない場合、システムは自動的に作成します。永続ボリュームアプリケーションは、永続ボリュームを抽象化したものであり、プログラミングのインターフェイス(インターフェイス)と同様に、さまざまな特定の実装(永続ボリューム)を持つことができます。たとえば、AlibabaCloudとHuaweiCloudでサポートされているストレージシステムは異なり、生成される永続ボリュームも異なります。永続ボリュームは、特定のストレージ実装にバインドされています。プログラムをAlibabaCloudからHuaweiCloudに移行する場合、構成ファイルの互換性をどのように確認しますか?永続ボリュームアプリケーションを使用してこのインターフェイスを作成します。これは、ストレージ容量とアクセスモードのみを指定します。AlibabaCloudとHuawei Cloudは、それぞれのクラウドでこのインターフェイスの要件を満たす永続ボリュームを自動的に生成します。ただし、1つの制限もあります。つまり、永続ボリュームアプリケーションと永続ボリュームのStorageClassが一致する必要があるため、インターフェイスの柔軟性が不足します。これについては後で詳しく説明します。
4.0.4動的永続ボリューム:
この場合、永続ボリュームアプリケーションを作成するだけで(永続ボリュームを個別に作成する必要はありません)、永続ボリュームアプリケーションをデプロイメントにバインドするだけです。システムは、永続ボリュームアプリケーションに従って永続ボリュームを自動的に作成します。以下は、永続ボリュームアプリケーション構成ファイルです。その中で、「ストレージ:1Gi」は、要求されたスペースが1Gであることを意味します。
4.1永続ボリュームアプリケーション構成ファイル:
mysql-pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
4.2永続ボリュームをマウントするためのアプリケーションの展開:
以下は、永続ボリュームアプリケーションがマウントされたデプロイメント構成ファイルmysql-deployment-pvc.yamlです。永続ボリュームアプリケーションを永続ボリュームとして使用し、ポッドにバインドします。ファイル内の永続ボリュームに関する注記をお読みください。
apiVersion: apps/v1
kind: Deployment # 类型是部署
metadata:
name: mysql-deployment # 对象的名字
spec:
selector:
matchLabels:
app: mysql #用来绑定label是“mysql”的Pod
strategy:
type: Recreate
template: # 开始定义Pod
metadata:
labels:
app: mysql #Pod的Label,用来标识Pod
spec:
containers: # 开始定义Pod里面的容器
- image: daocloud.io/library/mysql:5.7
name: mysql-con
imagePullPolicy: Never
env: # 定义环境变量
- name: MYSQL_ROOT_PASSWORD # 环境变量名
value: root # 环境变量值
- name: MYSQL_USER
value: dbuser
- name: MYSQL_PASSWORD
value: dbuser
args: ["--default-authentication-plugin=mysql_native_password"]
ports:
- containerPort: 3306 # mysql端口
name: mysql
volumeMounts: #挂载Pod上的卷到容器
- name: mysql-persistent-storage #Pod上卷的名字,与“volumes”名字匹配
mountPath: /var/lib/mysql #挂载的Pod的目录
volumes: #挂载持久卷到Pod
- name: mysql-persistent-storage #持久卷名字,与“volumeMounts”名字匹配
persistentVolumeClaim:
claimName: mysql-pvc #持久卷申请名字
ここではポッドマウントディレクトリのみが指定されており、仮想マシン(ホスト)ディレクトリは指定されていません。仮想マシンディレクトリの検索方法(システムが自動的にマウントディレクトリを割り当てる)については、後で説明します。
4.3展開の実行:
「kubectlapply-f mysql-pvc.yaml」と入力して、永続ボリュームアプリケーションを作成します。作成すると、システムによって永続ボリュームが自動的に作成されます。
永続ボリュームアプリケーションを表示する
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pvc Pending manual 13s
- 現時点では、システムmysql-pvcのステータスが保留中であることがわかります。なぜですか。思ったように、システムが永続ボリュームpvを自動的に作成しなかったことがわかりました。自分で作成する必要があります。新しいファイルmysql-pv.yamlを作成し、次のように入力します。
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 1Gi # 大小1G
accessModes:
- ReadWriteOnce
hostPath:
path: "/tmp/kube" # 文件实际存放位置
「kubectlapply-f mysql-pv.yaml」と入力して永続ボリュームを作成し、両方が使用可能であることを確認します。
➜ test kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mysql-pv 1Gi RWO Retain Bound default/mysql-pvc manual 13s
➜ test kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pvc Bound mysql-pv 1Gi RWO manual 4m50s
永続ボリュームアプリケーションの詳細を表示する
kubectl describe pv mysql-pv
kubectl describe pvc mysql-pvc
新しいウィンドウを開いてMySQLディレクトリ情報を表示します
cd /tmp/kube
ls
4.4永続ボリュームのリサイクルモード:
永続ボリュームと永続ボリュームアプリケーションを削除すると、3つのリサイクルモードがあります。
保持:永続ボリュームアプリケーションが削除されても、永続ボリュームは残ります。永続ボリューム内のデータを手動で再利用できます。
削除(削除):永続ボリュームアプリケーションと永続ボリュームの両方が削除され、基になるストレージデータも削除されます。動的永続ボリュームを使用する場合、デフォルトのモードは削除です。もちろん、永続ボリュームの作成後に、永続ボリュームのリサイクルモードを変更できます。
リサイクル:この方法は推奨されなくなりました。代わりに保持を使用することをお勧めします。
4.5静的永続ボリューム:
動的永続ボリュームの問題の1つは、デフォルトのリサイクルモードが「削除」であるため、仮想マシンを再起動すると永続ボリュームが削除されることです。デプロイメントを再実行すると、k8sは新しいMySQLを作成するため、元のMySQLで新しく作成された情報は失われますが、これは表示したくありません。回復方法を手動で「保持」に変更することはできますが、元の永続ボリュームのデータを手動で回復する必要があります。
1つの解決策は、ホスト上に永続ボリュームを構築することです。これにより、問題が原因で仮想マシンが再起動されても、MySQLで新しく作成された情報が失われることはありません。クラウド上にある場合は専用のストレージレイヤーがあり、ローカルの場合はおおよそ3つの方法があります。
ローカル:ストレージをホストからk8sクラスターにマウントします。詳細については、「ボリューム」を参照してください
。HostPath:ストレージをホストからk8sクラスターにマウントしますが、単一ノード(ノード)のみをサポートするなど、多くの制限があります。 )、「ReadWriteOnce」モードのみをサポートします。詳細については、を参照してください:「kubernetesでボリュームとしてホストパス」
NFS:ネットワーク・ファイル・システム、これは最も柔軟ですが、NFSサーバーが必要です。詳細については、「Kubernetesボリュームガイド」を参照してください。
より単純な「ローカル」方式を選択しました。このように、永続ボリュームは個別に作成する必要があります。永続ボリュームアプリケーションを作成して、システムに永続ボリュームを自動的に作成させることはできません。
以下は、永続ボリュームと永続ボリュームアプリケーションを1つのファイルに書き込む「ローカル」モードを使用した構成ファイルです。「Local」メソッドを使用する場合は、「nodeAffinity」部分を設定する必要があります。「values:-minikube」の「Minikube」はk8sクラスターノードの名前であり、「Minikube」は「マスターノード」と「」の両方である1つのノードのみをサポートします。ワーカーノード」。
新しいファイルmysql-pv-pvc.yaml、永続ボリューム、および適用された構成ファイル:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-local
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: standard #持久卷存储类型,它需要与持久卷申请的类型相匹配
local:
path: /tmp/kube/mysql-local #宿主机的目录
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- docker-desktop # Node的名字
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim-local
labels:
app: mysql
spec:
accessModes:
- ReadWriteOnce
# storageClassName: # 这里的存储类型注释掉了
resources:
requests:
storage: 1Gi #1 GB
ノードの名前がわからない場合は、次のコマンドで表示できます。
kubectl get node
NAME STATUS ROLES AGE VERSION
docker-desktop Ready master 9d v1.16.6-beta.0
静的永続ボリュームに切り替えた後、永続ボリューム構成ファイルのみが変更されましたが、デプロイメントおよびサービス構成ファイルは変更されていません。永続ボリュームとデプロイメントを再実行します。成功後、仮想マシンを再起動しても、MySQLで新しく作成されたコンテンツは失われません。
ここでstorageClassNameの使用法に注意してください。k8sは、永続ボリュームと永続ボリュームアプリケーションのstorageClassNameが一致する必要があることを規定しています。一致すると、永続ボリュームが永続ボリュームアプリケーションに割り当てられます。ここでの永続ボリュームアプリケーションはstorageClassNameを指定しないため、システムはデフォルトのstorageClassを使用します。
デフォルトのstorageClassがインストールされているかどうかを確認します
kubectl get sc
NAME PROVISIONER AGE
hostpath (default) docker.io/hostpath 9d
デフォルトのstorageClassの詳細を表示する
kubectl describe sc
Name: hostpath
IsDefaultClass: Yes
Annotations: kubectl.kubernetes.io/last-applied-configuration={
"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{
"annotations":{
"storageclass.kubernetes.io/is-default-class":"true"},"name":"hostpath"},"provisioner":"docker.io/hostpath","reclaimPolicy":"Delete","volumeBindingMode":"Immediate"}
,storageclass.kubernetes.io/is-default-class=true
Provisioner: docker.io/hostpath
Parameters: <none>
AllowVolumeExpansion: <unset>
MountOptions: <none>
ReclaimPolicy: Delete
VolumeBindingMode: Immediate
Events: <none>
ここからわかるように、デフォルトのstorageClassがインストールされており、その名前は「hostpath」です。上記の永続ボリュームアプリケーションではstorageClassが指定されていないため、システムはデフォルトのstorageClassを使用してそれに一致し、上記の永続ボリュームのstorageClassNameは「hostpath」であり、一致させることができます。詳細については、「Kubernetesの動的プロビジョニングおよびストレージクラス」を参照してください。
5追記
5.1 k8s管理のバックグラウンドにログインして、作成したmysqlを表示できます
http:// localhost:8001 / api / v1 / namespaces / kubernetes-dashboard / services / https:kubernetes-dashboard:/ proxy /#/ override?namespace = default
作成した展開、ポッドとpv、pvcなどを表示します。
5.2同じ名前でPVまたはPVCを作成する
元のPVまたはPVCがまだ存在し、元のPVと同じ名前で新しいPVを作成すると、次のエラーが発生します
。persistentvolumeclaim“ mysql-pv-claim”が無効です:spec:forbidden:is immutableバインドされたクレームのresources.requestsを除いて作成した後
、元のPVまたはPVCを削除して、新しいものを作成する必要があります。
5.3完全な削除
kubectl delete service mysql-service
kubectl delete deployment mysql-deployment
kubectl delete pvc mysql-pvc
kubectl delete pv mysql-pv