mysql上k8s_通过搭建MySQL掌握k8s(Kubernetes)重要概念(上):网络与持久卷

上一篇"通过实例快速掌握k8s(Kubernetes)核心概念"讲解了k8s的核心概念,有了核心概念整个骨架就完整了,应付无状态程序已经够了,但还不够丰满。应用程序分成两种,无状态和有状态的。一般的前段和后端程序都是无状态的,而数据库是有状态的,他需要把数据存储起来,这样即使断电,数据也不会丢失。要创建有状态的程序,还需要引入另外一些k8s概念。它们虽然不是核心,但也很重要,共有三个,持久卷,网络和参数配置。掌握了这些之后,基本概念就已经做到了全覆盖,k8s就已经入门了。我们通过搭建MySQL来熟悉这些k8s概念。容器本身是无状态的,一旦出现问题它会被随时销毁,它存储的数据也就丢失了。MySQL需要一个能保存数据的持久层,在容器被销毁之后仍然存在,k8s叫它持久卷。

创建和验证MySQL镜像:

在k8s上安装MySQL之前,先用Docker验证一下MySQL镜像:

docker run --name test-mysql -p 3306:33060 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

“root”是根(root)用户的password,这里是在创建MySQL容器时指定“root”用户的password。“test-MySQL”是容器的名字。“mysql:5.7”用的是docker库里的“MySQL”5.7版本。这次没有用最新的8.0版,因为新版跟以前的客户端不兼容,需要修改很多东西。所用的镜像是全版的Linux,因而文件比较大,有400M。

容器建好了之后,键入“docker logs test-mysql”,查看日志。

...

2019-10-03T06:18:50.439784Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.17' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.

2019-10-03T06:18:50.446543Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060

查看容器状态。

vagrant@ubuntu-xenial:~$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

3b9c50420f5b mysql:latest "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 3306/tcp, 33060/tcp test-mysql

为了验证MySQL,需要在虚机上安装MySQL客户端。

sudo apt-get -y -f install mysql-client

完成之后,键入“docker inspect test-mysql”找到容器IP地址, 下面显示"172.17.0.2"是容器IP地址。

vagrant@ubuntu-xenial:~$ docker inspect test-mysql

...

"Gateway": "172.17.0.1",

"IPAddress": "172.17.0.2",

"IPPrefixLen": 16,

"IPv6Gateway": "",

...

键入“mysql -h 172.17.0.2 -P 3306 --protocol=tcp -u root -p”登录到MySQL,"172.17.0.2"是MySQL的IP地址,“3306”是MySQL端口,是在创建镜像时设定的对外开放的端口,“root”是用户名,“-p”是password的参数选项。敲入命令后,系统要求输入password,输入后,显示已成功连接到MySQL。

vagrant@ubuntu-xenial:~$ mysql -h 172.17.0.2 -P 3306 --protocol=tcp -u root -p

...

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 3

Server version: 5.7.27 MySQL Community Server (GPL)

...

在k8s上安装MySQL

在k8s上安装MySQL分成三个部分,创建部署文件,创建服务文件和安装测试。

部署(Deployment)文件

下面是部署配置文件。在上一篇文章中已经详细讲解了文件格式,所有的k8s的配置文件格式都是相同的。“template”之上是部署配置,从“template”向下是Pod配置。从“containers”开始是Pod里面的容器配置。“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: 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

服务(Service)文件

下面是服务配置文件,这个与上一篇讲的配置基本相同,这里就不解释了。

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

安装测试:

有了配置文件后,下面就开始创建MySQL。在创建时要按照顺序,依次进行,先从最底层的对象开始创建。

创建部署和服务:

kubectl apply -f mysql-deployment

kubectl apply -f mysql-service.yaml

查看服务:

vagrant@ubuntu-xenial:~$ kubectl get service

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kubernetes ClusterIP 10.96.0.1 443/TCP 3h42m

mysql-service NodePort 10.102.253.32 3306:30306/TCP 3h21m

“mysql-service”的端口(PORT(S))有两个,“3306”是k8s内部端口,“30306”是外部端口。由于“NodePort”已经打开了对外端口,这时就可以在虚拟机上通过“30306”端口访问MySQL。

vagrant@ubuntu-xenial:~$ 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 6

Server version: 5.7.27 MySQL Community Server (GPL)

...

mysql>

这时本地虚机已经与k8s联通了,下一步就可以在宿主机( 笔记本)上用图形客户端来访问MySQL了。我是在Vagrant里设定了私有网络,设定的虚机IP地址是 "192.168.50.4”,就用这个地址和30306端口来访问MySQL。

56bb5fc31e09b2762e4b3975bd60661b.png

网络:

这里的网络有两层含义,一层是k8s网络,就是让k8s内部服务之间可以互相访问,并且从k8s集群外部可以访问它内部的服务。另一层是宿主机(笔记本)和虚机之间的网路,就是在宿主机上可以访问虚机。这两层都通了之后,就可以在宿主机直接访问k8s集群里面的MySQL。

k8s网络:

k8s的网络也有两层含义,一个是集群内部的,k8s有内部DNS,可以通过服务名进行寻址。另一个是从集群外部访问集群内部服务,一共有四种方式,详情请见“Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?”

LoadBalancer:Load Balancer不是由K8s来管理的。k8s通过Load Balancer把外部请求转发给内部服务。这种方法要求有Load Balancer,一般云环境里会提供,但自己的本地环境就没有了。不过Minikube提供了一个程序可以模拟Load Balancer。你只要键入“minikube tunnel ”,它就会模拟Load Balancer,对请求进行转发。只不过当你在使用“Load Balancer”时(在Minikube环境里),每次运行服务时产生的IP和端口是随机的,不能控制,使用起来不太方便,但在正式环境里就没有这个问题。

下面是服务信息,“EXTERNAL-IP”是"pending",说明外部网络不通。

$ kubectl get service

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kubernetes ClusterIP 10.96.0.1 443/TCP 31d

nginx-service LoadBalancer 10.104.228.212 80:31999/TCP 45h

下面是在运行“minikube tunnel ”(在另一个窗口运行)之后的服务信息,“EXTERNAL-IP”是 “10.104.228.212”。这时Minikube的LoadBalancer已经起作用了,现在就可以通过IP地址从外部访问k8s内部的服务了,“80”是k8s内部端口,“31999”是k8s对外端口。

$ kubectl get service

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kubernetes ClusterIP 10.96.0.1 443/TCP 31d

nginx-service LoadBalancer 10.104.228.212 10.104.228.212 80:31999/TCP 45h

这是一种比较好的方式,但不能控制它的IP地址和端口,因此我暂时没有采用它。

NodePort:这种方法可以在每个Node上开放一个对外端口,每一个指向这个端口的请求都被转发给一个服务。它的好处是你可以指定一个固定的端口(端口的取值范围只能是30000–32767),这样我在笔记本上访问MySQL时就不用更换端口了。 如果你不指定,系统会随机分配一个。它的缺点是每个端口只能有一个服务,而且端口取值受限制,因此不适合生产环境。但在Windows环境,由于我用Vagrant固定了虚机的IP地址,这个问题就不存在了。因此它是最好的选择。

ClusterIP: 这个只能在k8s集群内部寻址。

Ingress: 这是推荐的方法,一般在生产环境中使用。Load balancer的问题是每一个服务都要有一个Load balancer,服务多了之后会很麻烦,这时就会用Ingress,它的缺点是配置起来比较复杂。Minikube自带了一个基于Nginx的Ingress控制器,只需运行“minikube addons enable ingress”,就行了。但Ingress的设置较复杂,因此这里没有用它。

虚拟机网络:

这里讲的是宿主机(笔记本)和虚机之间的互相访问,主要是从宿主机访问虚机。我用的是Vagrant, 因此要在Vagran的配置文件(Vagrantfile)里进行配置。它有两种方法:

端口转发:它可以把笔记本上特定端口的请求转发到虚机的指定端口,还是比较方便的。只是如果事先不知道是哪个端口,或端口是变化的,就比较麻烦。Vagrant的配置命令:“config.vm.network "forwarded_port", guest: 3306, host: 3306, auto_correct: true”

私有网络:这是一种很灵活的方式。可以给宿主机和虚机各自设定一个固定的IP地址,这样可以双向互访。任何端口都没有问题,唯一的缺点就是你要事先确定IP地址。详情请参见“Vagrant reverse port forwarding?”。Vagrant的配置命令:“config.vm.network "private_network", ip: "192.168.50.4”

当配置私有网络时,需要在笔记本的VirtualBox上配置“Host-only Adapter”,如下图所示。

a4b46c911a796fb00324be68fd20b8d0.png

但这会造成在Vagrant启动Minikube时产生如下错误:“VBoxManage.exe: error: Failed to create the host-only adapter”。这是VirtualBox的一个Bug,你可以下载一个软件解决,详见这里. 这个软件已经是四年之前的了,开始还担心是否与现在的VirtualBox版本兼容,结果很好用,而且它是一个单独运行的软件,不会与现在的软件冲突。只要在启动虚机之前,用管理员身份运行这个补丁就行了。另外一个问题是,我原来使用的是5.x版的VirtualBox,上图中只能选“NAT”,不能选“Host-only Adapter”,升级到6.X之后才能选“Host-only Adapter”。但当虚机重新启动之后,它会自动变回“NAT”,不过私有网络还是可用。

创建持久卷(PersistentVolume):

k8s卷的概念包括卷和持久卷。

卷(volume):

卷是k8s的存储概念,它依附于Pod,不能单独存在。但它不是在容器层。因此如果容器被重新启动,卷仍然在。但如果Pod重新启动,卷就丢失了。如果一个Pod里有多个容器,那么这些容器共享Pod的卷。你可以把卷看成是一个目录,里面可以存储各种文件。k8s支持各种类型的卷,例如本地文件系统和各种云存储。

持久卷(PersistentVolume):

是对卷的一个封装,目的是为了更好地管理卷。它的生命周期不需要与Pod绑定,它可以独立于Pod存在。

持久卷申请(PersistentVolumeClaim):

是对持久卷资源的一个申请,你可以申请特定的存储容量的大小和访问模式,例如读写模式或只读模式。k8s会根据持久卷申请分配适合的持久卷,如果没有合适的,系统会自动创建一个。持久卷申请是对持久卷的一个抽象,就像编程里的接口(Interface),它可以有不同的具体实现(持久卷)。例如,阿里云和华为云支持的存储系统不同,它生成的持久卷也不相同。持久卷是与特定的存储实现绑定的。那你要把程序从阿里云移植到华为云,怎么保证配置文件的兼容性呢?你就用持久卷申请来做这个接口,它只规定存储容量大小和访问模式,而由阿里云和华为云自动生成各自云里满足这个接口需求的持久卷. 不过,它还有一个限制条件,那就是持久卷申请和持久卷的StorageClass需要匹配,这使它没有接口灵活。后面会详细讲解。

动态持久卷:

在这种情况下,你只需创建持久卷申请(不需要单独创建持久卷),然后把持久卷申请与部署绑定。系统会按照持久卷申请自动创建持久卷。下面是持久卷申请配置文件。其中“storage:1Gi”,是指申请的空间大小是1G。

持久卷申请配置文件:

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: mysql-pv-claim

labels:

app: mysql

spec:

accessModes:

- ReadWriteOnce

resources:

requests:

storage: 1Gi #持久卷的容量是 1 GB

```

**挂载持久卷申请的部署:**

下面是挂载了持久卷申请的部署配置文件。它通过把持久卷申请当做持久卷来使用,与Pod进行绑定。请阅读文件里有关持久卷的注释。

```shell

apiVersion: apps/v1

kind: Deployment

metadata:

name: mysql-deployment

spec:

selector:

matchLabels:

app: mysql

strategy:

type: Recreate

template:

metadata:

labels:

app: mysql

spec:

containers:

- image: 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

name: mysql

volumeMounts: # 挂载Pod上的卷到容器

- name: mysql-persistent-storage # Pod上卷的名字,与“volumes”名字匹配

mountPath: /var/lib/mysql # 挂载的Pod的目录

volumes: # 挂载持久卷到Pod

- name: mysql-persistent-storage # 持久卷名字, 与“volumMounts”名字匹配

persistentVolumeClaim:

claimName: mysql-pv-claim # 持久卷申请名字

这里只指定了Pod的挂载目录,并没有指定虚拟机(宿主机)的目录,后面会讲到如何找到虚拟机的目录(系统自动分配挂载目录)。

运行部署:

键入“kubectl apply -f mysql-volume.yaml”创建持久卷申请,在创建它的同时,系统自动创建持久卷。

查看持久卷申请

vagrant@ubuntu-xenial:~/dockerimages/kubernetes/mysql$ kubectl get pvc

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

mysql-pv-claim Bound pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa 1Gi RWO standard 10m

查看持久卷申请详细信息

vagrant@ubuntu-xenial:/mnt$ kubectl describe pvc mysql-pv-claim

Name: mysql-pv-claim

Namespace: default

StorageClass: standard

Status: Bound

Volume: pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa

Labels: app=mysql

...

显示持久卷:

vagrant@ubuntu-xenial:/mnt$ kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa 1Gi RWO Delete Bound default/mysql-pv-claim standard 24h

键入“kubectl describe pv pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa”, 显示持久卷详细信息。从这里可以看出,虚拟机上的持久卷在如下位置:“Path: /tmp/hostpath-provisioner/pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa”。

vagrant@ubuntu-xenial:/mnt$ kubectl describe pv pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa

Name: pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa

Labels:

Annotations: hostPathProvisionerIdentity: 19948fdf-e67f-11e9-8fbd-026a5b40726f

pv.kubernetes.io/provisioned-by: k8s.io/minikube-hostpath

Finalizers: [kubernetes.io/pv-protection]

StorageClass: standard

Status: Bound

Claim: default/mysql-pv-claim

Reclaim Policy: Delete

Access Modes: RWO

VolumeMode: Filesystem

Capacity: 1Gi

Node Affinity:

Message:

Source:

Type: HostPath (bare host directory volume)

Path: /tmp/hostpath-provisioner/pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa

HostPathType:

Events:

查看MySQL目录信息:

vagrant@ubuntu-xenial:/tmp/hostpath-provisioner/pvc-ac6c88d5-ef5a-4a5c-b499-59715a2d60fa$ ls -al

total 188488

drwxrwxrwx 6 999 docker 4096 Oct 4 13:23 .

drwxr-xr-x 3 root root 4096 Oct 4 12:58 ..

-rw-r----- 1 999 docker 56 Oct 4 12:58 auto.cnf

-rw------- 1 999 docker 1679 Oct 4 12:59 ca-key.pem

-rw-r--r-- 1 999 docker 1107 Oct 4 12:59 ca.pem

-rw-r--r-- 1 999 docker 1107 Oct 4 12:59 client-cert.pem

-rw------- 1 999 docker 1679 Oct 4 12:59 client-key.pem

-rw-r----- 1 999 docker 668 Oct 4 13:21 ib_buffer_pool

-rw-r----- 1 999 docker 79691776 Oct 4 13:23 ibdata1

-rw-r----- 1 999 docker 50331648 Oct 4 13:23 ib_logfile0

-rw-r----- 1 999 docker 50331648 Oct 4 12:58 ib_logfile1

-rw-r----- 1 999 docker 12582912 Oct 4 13:24 ibtmp1

drwxr-x--- 2 999 docker 4096 Oct 4 12:58 mysql

drwxr-x--- 2 999 docker 4096 Oct 4 12:58 performance_schema

-rw------- 1 999 docker 1679 Oct 4 12:59 private_key.pem

-rw-r--r-- 1 999 docker 451 Oct 4 12:59 public_key.pem

-rw-r--r-- 1 999 docker 1107 Oct 4 12:59 server-cert.pem

-rw------- 1 999 docker 1675 Oct 4 12:59 server-key.pem

drwxr-x--- 2 999 docker 4096 Oct 4 13:18 service_config

drwxr-x--- 2 999 docker 12288 Oct 4 12:58 sys

持久卷的回收模式:

当持久卷和持久卷申请被删除后,它有三种回收模式。

保持(Retain):当持久卷申请被删除后,持久卷仍在。你可以手动回收持久卷里的数据。

** 删除(Delete)**:持久卷申请和持久卷都被删除,底层存储的数据也会被删除。当使用动态持久卷时,缺省的模式是Delete。当然,你可以在持久卷被创建之后修改它的回收模式。

** 回收(Recycle)**:这种方式已经不推荐使用了,建议用Retain代替。

静态持久卷:

动态持久卷的一个问题是它的缺省回收模式是“删除”,这样当虚机重新启动后,持久卷会被删除。当你重新运行部署时,k8s会创建一个新的MySQL,这样原来MySQL里的新建信息就会丢失,这是我们不愿意看到的。虽然你可以手动修改回收方式为“保持”,但还是要手动回收原来持久卷里的数据。

一个解决办法是把持久卷建在宿主机上,这样即使虚机出了问题被重新启动,MySQL里的新建信息依然不会丢失。如果是在云上,就会有专门的的存储层,如果是本地,大致有三种方式:

Local:把存储从宿主机挂载到k8s集群上. 详情请参见:"Volumes".

HostPath:也是把存储从宿主机挂载到k8s集群上,但它有许多限制,例如只支持单节点(Node),而且只支持“ReadWriteOnce”模式。详情请参见: "hostPath as volume in kubernetes".

NFS:网络文件系统,这种是最灵活的,但需要安装NFS服务器。详情请参见:"Kubernetes Volumes Guide".

我选择了比较简单的“Local”方式。在这种方式下,必须单独创建持久卷,不能 只创建持久卷申请而让系统自动创建持久卷。

下面是使用“Local”方式的配置文件,它把持久卷和持久卷申请写在了一个文件里。当用“Local”方式时,需要设置“nodeAffinity”部分,其中“values:- minikube” 的“Minikube”是k8s集群Node的名字,“Minikube”只支持一个Node,既是“Master Node”,又是“Worker Node”。

持久卷和申请的配置文件:

apiVersion: v1

kind: PersistentVolume

metadata:

name: mysql-pv

spec:

capacity:

storage: 1Gi

volumeMode: Filesystem

accessModes:

- ReadWriteOnce

storageClassName: standard #持久卷存储类型,它需要与持久卷申请的类型相匹配

local:

path: /home/vagrant/database/mysql #宿主机的目录

nodeAffinity:

required:

nodeSelectorTerms:

- matchExpressions:

- key: kubernetes.io/hostname

operator: In

values:

- minikube # Node的名字

---

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: mysql-pv-claim

labels:

app: mysql

spec:

accessModes:

- ReadWriteOnce

# storageClassName: # 这里的存储类型注释掉了

resources:

requests:

storage: 1Gi #1 GB

如果不知道Node名字,可用如下命令查看:

vagrant@ubuntu-xenial:/$ kubectl get node

NAME STATUS ROLES AGE VERSION

minikube Ready master 6d3h v1.15.2

改用静态持久卷之后,只有持久卷配置文件发生了变化,部署和服务的配置文件没有变。重新运行持久卷和部署,成功之后,即使重启虚拟机,MySQL里面的新建内容也没有丢失。

注意这里storageClassName的用法。k8s规定持久卷和持久卷申请的storageClassName必须匹配,这时才会把持久卷分配给持久卷申请。我们这里的持久卷申请没有指定storageClassName,这时系统会使用缺省的storageClass。

查看是否安装了缺省的storageClass

vagrant@ubuntu-xenial:/$ kubectl get sc

NAME PROVISIONER AGE

standard (default) k8s.io/minikube-hostpath 6d3h

vagrant@ubuntu-xenial:/$

查看缺省的storageClass详细信息

vagrant@ubuntu-xenial:/$ kubectl describe sc

Name: standard

IsDefaultClass: Yes

Annotations: storageclass.kubernetes.io/is-default-class=true

Provisioner: k8s.io/minikube-hostpath

Parameters:

AllowVolumeExpansion:

MountOptions:

ReclaimPolicy: Delete

VolumeBindingMode: Immediate

Events:

从这里可以看出,Minikube安装了缺省的storageClass,它的名字是“standard”。上面的持久卷申请里没有指定storageClass,因此系统使用缺省的storageClass与之匹配,而上面的持久卷的storageClassName是“standard”,正好能配上。详情请见“Dynamic Provisioning and Storage Classes in Kubernetes”

踩过的坑:

使用Hyper-V还是VirtualBox

Hyper-V和VirtualBox是不兼容的,只能选一个(当然你可以在这两者之间切换,但太麻烦了)。我在Windows上装了VirtualBox,运行正常。进入Vagrant之后,安装了“ubuntu”版的Linux。这时,当你启动Minikube时,可以键入“minikube start --vm-driver=virtualbox”,但系统显示“This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory”。我按照网上的建议去修改BIOS的“VT-X/AMD-v”,但我的BIOS就没有这个选项。其他的方法也都试过了,没有一个成功的。但因为已经装了VirtualBox,就不能用Hyper-V了。就只能用另外一个方法,使用命令“minikube start --vm-driver=none”。幸好这个方法工作得很好。

当用“minikube start --vm-driver=virtualbox”时,你是先建了虚拟机,再在虚拟机上运行Minikube。当用“minikube start --vm-driver=none”时,是直接在宿主机上运行Minikube。但由于我的Windows版本不能直接支持k8s,我已经在Windows上装了Linux虚机,并用Vagrant进行管理。如果用“minikube start --vm-driver=virtualbox”,就是在Linux虚机上又装了一个虚机。现在用“minikube start --vm-driver=none”,表面上看是在宿主机上运行,实际上已经运行在Windows的Linux虚机上了。

登录k8s集群

当用“minikube start --vm-driver=none”启动Minikube时,不能用“minikube ssh”登录k8s集群,因为这时已经没有虚机了,是直接安装在宿主机上,因此不需要“minikube ssh”。但你可以登录到Pod上,可用如下命令:" kubectl exec -ti mysql-deployment-56c9cf5857-fffth -- /bin/bash"。其中“mysql-deployment-56c9cf5857-fffth”是Pod名字。

创建重名PV或PVC

当原来的PV或PVC还在,而你又创建了一个新的PV, 并与原来的重名,则会得到如下错误:The persistentvolumeclaim "mysql-pv-claim" is invalid: spec: forbidden: is immutable after creation except resources.requests for bound claims. 这时,你需要将原来的PV或PVC删掉,再重新创建新的。

索引:

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python简单笔记

Remarks:python中注意缩进(Tab键或者4个空格) print(输出) 格式:print(values) 字符串、数字、变量等都可以输出: 实例: print(1)->1 print(11)->2 a …

【Alpha阶段】第一次Scrum Meeting

PS:因为安装android的SDK插件出现问题,在eclipse和android studio中安装都不成功,项目不能运行,且一直在下载一些插件,安装了3天都没有成功,按照网上的解决办法进行解决都没有成功,导致项目不能…

581. Shortest Unsorted Continuous Subarray连续数组中的递增异常情况

[抄题]: Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. You need to find the shortest suc…

python三阶魔方_三阶魔方自动求解及动态可视化matlab代码

三阶魔方自动求解及动态可视化matlab代码思路与步骤三阶魔方有6个面,每个面有333\times333小块,用一个6336\times3\times3633的矩阵来保存魔方的状态;定义412种魔方旋转行为:整体旋转(左右上下共4种方式AaCc),侧面(6个…

Qt 常用类——QStandardItemModel

转载:落叶知秋时 类QabstractItemModel,QabstractListModel,QAbstractTableModel不保存数据,用户需要从这些类派生出子类,并在子类中定义某种数据结构来保存数据。 与此不同,类QStandardItemModel负责保存数…

ad19原理图标注_AD19中原理图的模板如何进行编辑?

我们在进行原理图设计的时候,有时候不想去用软件自带默认的模板,想要用自己设计的模板,就涉及到我们的模板怎么去编辑的呢?我们应该如何去编辑原理图自己设计的模板?操作步骤是怎么的呢?我们今天就以AD19为…

mysql+秘密_mysql不被人知的秘密

http://blog.csdn.net/yueguanghaidao/article/details/69333872011先建立两张表。1.student表2.grade表一:mysql的复制技术1.表与数据的复制->>实现表结构和数据的同步create table desttable select * from srctable;(desttable:目标表,srctable…

mysql一个表几亿数据_如何在mysql 造1亿条记录的大容量数据表?

背景及目标:现有数据1000w单表,为压力测试准备1亿条数据。步骤:1.将1000w条记录,除id外都导入到多个文件中://DELIMITERDROP PROCEDURE if EXISTS createManyTable;create PROCEDURE createManyTable()BEGINDECLARE i …

windows键盘在mac上怎么识别_Mac电脑怎么使用pc键盘?

苹果电脑一般需要使用配套的mac键盘,毕竟按键和普通pc键盘不一样。但是总会遇到一些情况,比如配套的mac键盘坏了,而刚好有一个pc键盘,那么这时候苹果电脑要怎么用pc键盘呢?这边小编跟大家介绍mac电脑连接pc键盘以及设置…

LOJ#6002. 「网络流 24 题」最小路径覆盖

模板。 1 #include<iostream>2 #include<cstring>3 #include<cstdio>4 //#include<time.h>5 //#include<complex>6 //#include<set>7 //#include<queue>8 #include<algorithm>9 #include<stdlib.h>10 using namespace s…

zabbix mysql设置中文乱码_解决zabbix监控因php问题导致图形界面中文乱码方法

解决因编译php中添加了-enable-gd-jis-conv选项导致Zabbix监控系统图形界面中文乱码问题现象&#xff1a;php编译参数&#xff1a;说明&#xff1a;如果PHP编译时启用–enable-gd-jis-conv选项的话&#xff0c;那么非ASCII字符(例如汉字、拼音、希腊文和箭头) 会被当成EUC-JP编…

熟悉常用的HDFS操作

一、Hadoop提供的Shell命令完成相同任务&#xff1a; 在本地Linux文件系统的“/home/hadoop/”目录下创建一个文件txt&#xff0c;里面可以随意输入一些单词.在本地查看文件位置&#xff08;ls&#xff09;在本地显示文件内容使用命令把本地文件系统中的“txt”上传到HDFS中的当…

mysql 低端_mysql入门

相关了解(重点内容从标题一开始)目前主流数据库有:sqlserver, mysql, Qracle, SQLite, Access, MS SQL Server等, 我主要说的是mysql;以下几点需要记住!!!SQL包括了所有对数据库的操作, 主要由4个部分组1. 数据库定义语言(DDL): 用于定义和管理数据库对象, 包括数据库, 基本表,…

阿里云服务器由于被检测到对外攻击,已阻断该服务器对其它服务器端口的访问...

问题&#xff1a; (系统&#xff1a;CentOS 7.2 ) 前几天在阿里云服务器安装了Redis, 刚开始没有设置redis密码, 后台阿里云发送多次邮件提示如下&#xff1a; 经过几次波折才发现并彻底解决了问题&#xff1a; 原因&#xff1a; 估计是因为 Redis服务开启时没有设置密码 &…

批量找注入 python3+sqlmap结合

注入一直都是用sqlmap 导致本来就不怎么精通的手工注入现在就忘的一干二净 想实战练习 却一时又找不到有注入的网站 于是便有了这篇文章 想找个批量获取域名链接的工具 但都是只是获取域名而已 都没获取后面的参数 于是自己写了个只获取bing前10页的结果 输入q 结束循环…

golang 反射

参考&#xff1a;|--http://blog.51cto.com/speakingbaicai/1707637 |--https://studygolang.com/articles/6324 反射是在golang程序运行时检查变量所具有类型的一种机制。由于反射可以得出关于变量结构的数据&#xff08;即“关于数据的数据”&#xff09;&#xff0c;所以这也…

java硬件编程_关于JAVA并发编程你需要知道的——硬件篇

无论程序语言如何千变万化&#xff0c;他们都深深地根植于目前的计算机体系结构。左图是intel CPU的三级高速缓存设计&#xff0c;由于高速缓存对程序员基本不可见&#xff0c;因此可以抽象为右图。缓存的设计首先还是先谈谈左图。L1-cache分为两部分&#xff0c;i-cache存储指…

net Core做一个webApi的简单实例

用NetCore 和Dapper 和mySql做一个简单的实例&#xff0c; 一准备工作 1&#xff1a;VS2017windos系统&#xff0c;也可以用其他的操作系统和工具 2&#xff1a;一台Cenetos的虚拟机或者虚拟机 二&#xff1a;开始 1&#xff1a;用微软官方的netCore的ToDo项目改造&#xff0c;…

java 文件输出流_Java 文件输出流

Java IO教程 - Java文件输出流创建输出流要写入文件&#xff0c;我们需要创建一个FileOutputStream类的对象&#xff0c;它将表示输出流。// Create a file output streamString destFile "test.txt";FileOutputStream fos new FileOutputStream(destFile);当写入文…

MySQL5.7参数log_timestamps

最近测试MySQL 5.7.21 Community Server这个版本的MySQL数据库时&#xff0c;发现其错误日志的时间跟系统当前时间不一致&#xff0c;后面检查发现日期时间格式都是UTC时间&#xff0c;查了一下相关资料&#xff0c;原来在MySQL 5.7.2 之后日志文件里面的时间戳从默认的本地系…