YAML基础知识及搭建一台简洁版guestbook
一,前言
前面我们已经搭建过简易版k8s集群了,在此基础上可以搭建一个简洁版guestbook ,以便来学习k8s创建pod的整个过程。
二,在此之前,我们还需要学习一下YAML基础知识
YAML 基础
YAML
是专门用来写配置文件的语言,非常简洁和强大,远比JSON
格式方便。YAML
语言(发音 /ˈjæməl/)的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。
它的基本语法规则如下:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
#
表示注释,从这个字符一直到行尾,都会被解析器忽略。
在我们的kubernetes
中,你只需要两种结构类型就行了:
- Lists
- Maps
也就是说,你可能会遇到Lists的Maps和Maps的Lists,等等。不过不用担心,你只要掌握了这两种结构也就可以了,其他更加复杂的我们暂不讨论。
Maps
首先我们来看看Maps
,我们都知道Map
是字典,就是一个key:value的键值对,Maps
可以让我们更加方便的去书写配置信息,例如:
---
apiVersion: v1
kind: Pod
第一行的---
是分隔符,是可选的,在单一文件中,可用连续三个连字号---
区分多个文件。这里我们可以看到,我们有两个键:kind 和 apiVersion,他们对应的值分别是:v1和Pod。上面的 YAML 文件转换成 JSON 格式的话,你肯定就容易明白了:
{ "apiVersion": "v1", "kind": "pod" }
我们在创建一个相对复杂一点的 YAML 文件,创建一个 KEY 对应的值不是字符串而是一个 Maps:
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web
上面的 YAML 文件,metadata 这个 KEY 对应的值就是一个Maps
了,而且嵌套的 labels 这个 KEY 的值又是一个Map,你可以根据你自己的情况进行多层嵌套。
上面我们也提到了 YAML 文件的语法规则,YAML 处理器是根据行缩进来知道内容之间的嗯关联性的。比如我们上面的 YAML 文件,我用了两个空格作为缩进,空格的数量并不重要,但是你得保持一致,并且至少要求一个空格(什么意思?就是你别一会缩进两个空格,一会缩进4个空格)。我们可以看到 name 和 labels 是相同级别的缩进,所以 YAML 处理器就知道了他们属于同一个 MAP,而 app 是 labels 的值是因为 app 的缩进更大。
注意:在 YAML 文件中绝对不要使用 tab 键。
同样的,我们可以将上面的 YAML 文件转换成 JSON 文件:
{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "kube100-site", "labels": { "app": "web" } } }
或许你对上面的 JSON 文件更熟悉,但是你不得不承认 YAML 文件的语义化程度更高吧?
Lists
Lists
就是列表,说白了就是数组,在 YAML 文件中我们可以这样定义:
args - Cat - Dog - Fish
你可以有任何数量的项在列表中,每个项的定义以破折号(-
)开头的,与父元素直接可以缩进一个空格。对应的 JSON 格式如下:
{ "args": [ 'Cat', 'Dog', 'Fish' ] }
当然,list 的子项也可以是 Maps,Maps 的子项也可以是list如下所示:
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: flaskapp-demo image: jcdemo/flaskapp ports: - containerPort: 5000
比如这个 YAML 文件,我们定义了一个叫 containers 的 List 对象,每个子项都由 name、image、ports 组成,每个 ports 都有一个 key 为 containerPort 的 Map 组成,同样的,我们可以转成如下 JSON 格式文件:
{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "kube100-site", "labels": { "app": web" } }, "spec": { "containers": [{ "name": "front-end", "image": "nginx", "ports": [{ "containerPort": "80" }] }, { "name": "flaskapp-demo", "image": "jcdemo/flaskapp", "ports": [{ "containerPort": "5000" }] }] } }
是不是觉得用 JSON 格式的话文件明显比 YAML 文件更复杂了呢?
三,创建pod
使用 YAML 创建 Pod
现在我们已经对 YAML 文件有了大概的了解了,我相信你应该没有之前那么懵逼了吧?我们还是来使用 YAML 文件来创建一个 Deployment 。
#创建pod的过程,都在master上进行操作。
#如下是需要用到的YAML文件
1,redis-master-deployment.yaml配置文件
1 [root@master guestbook]# cat redis-master-deployment.yaml 2 apiVersion: extensions/v1beta1 3 kind: Deployment 4 metadata: 5 name: redis-master 6 spec: 7 replicas: 1 8 template: 9 metadata: 10 labels: 11 app: redis 12 role: master 13 tier: backend 14 spec: 15 containers: 16 - name: master 17 # image: redis 18 image: 192.168.200.10/redis/redis:master 19 resources: 20 requests: 21 cpu: 100m 22 memory: 100Mi 23 ports: 24 - containerPort: 6379
#注意,配置文件中 image此处使用的我本地harbor上的image,你也可以直接写注释行的image:redis 。即可从外网下载redis镜像,此过程pod启动较慢,需要耐心等待。
#下文中出现的任何image均可被替换为自己的本地的image
2,redis-master-service.yaml配置文件
1 [root@master guestbook]# cat redis-master-service.yaml 2 apiVersion: v1 3 kind: Service 4 metadata: 5 name: redis-master 6 labels: 7 app: redis 8 role: master 9 tier: backend 10 spec: 11 ports: 12 # the port that this service should serve on 13 - port: 6379 14 targetPort: 6379 15 selector: 16 app: redis 17 role: master 18 tier: backend
3,redis-slave-deployment.yaml
1 [root@master guestbook]# cat redis-slave-deployment.yaml 2 apiVersion: extensions/v1beta1 3 kind: Deployment 4 metadata: 5 name: redis-slave 6 spec: 7 replicas: 2 8 template: 9 metadata: 10 labels: 11 app: redis 12 role: slave 13 tier: backend 14 spec: 15 containers: 16 - name: slave 17 image: 192.168.200.10/redis/redis:slave 18 19 resources: 20 requests: 21 cpu: 100m 22 memory: 100Mi 23 env: 24 - name: GET_HOSTS_FROM 25 value: env 26 ports: 27 - containerPort: 6379
#注 此处image可以替换为:image: kubeguide/guestbook-redis-slave
4,redis-slave-service.yaml配置文件
1 [root@master guestbook]# cat redis-slave-service.yaml 2 apiVersion: v1 3 kind: Service 4 metadata: 5 name: redis-slave 6 labels: 7 app: redis 8 role: slave 9 tier: backend 10 spec: 11 ports: 12 # the port that this service should serve on 13 - port: 6379 14 selector: 15 app: redis 16 role: slave 17 tier: backend
5,frontend-deployment.yaml配置文件
1 [root@master guestbook]# cat frontend-deployment.yaml 2 apiVersion: extensions/v1beta1 3 kind: Deployment 4 metadata: 5 name: frontend 6 spec: 7 replicas: 3 8 template: 9 metadata: 10 labels: 11 app: guestbook 12 tier: frontend 13 spec: 14 containers: 15 - name: php-redis 16 image: kubeguide/guestbook-php-frontend 17 resources: 18 requests: 19 cpu: 100m 20 memory: 100Mi 21 env: 22 - name: GET_HOSTS_FROM 23 value: env 24 ports: 25 - containerPort: 80
6,frontend-service.yaml配置文件
1 [root@master guestbook]# cat frontend-service.yaml 2 apiVersion: v1 3 kind: Service 4 metadata: 5 name: frontend 6 labels: 7 app: guestbook 8 tier: frontend 9 spec: 10 type: NodePort 11 ports: 12 # the port that this service should serve on 13 - port: 80 14 nodePort: 30001 15 selector: 16 app: guestbook 17 tier: frontend
四,启动pod
1,启动redis master
使用deployment确保只有一个pod在运行(当某个节点down了,deploy会在另一个健康的node启动redis master),但可能会有数据丢失。
[root@master guestbook]# kubectl create -f redis-master-deployment.yaml deployment "redis-master" created
2,启动master service
一个kubernetes service会对一个或多个container进行负载均衡,这是通过我们上面redis-master中定义的labels元数据实现的,值得注意的是,在redis中只有一个master,但是我们依然为它创建一个service,这是因为这样我们就能使用一个elastic IP来路由到具体某一个master。
kubernetes集群中的service是通过container中的环境变量实现服务发现的,service基于pod label实现container的负载均衡。
在第一步中创建的pod包含了一个label“name=redis-master”,service的selector字段决定了service将流量转发给哪个pod,port和targetPort信息定义了service proxy运行在什么端口。
[root@master guestbook]# kubectl create -f redis-master-service.yaml service "redis-master" created #查看创建的service [root@master guestbook]# kubectl get service NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend 10.254.206.198 <nodes> 80:30001/TCP 5d kubernetes 10.254.0.1 <none> 443/TCP 8d nginx 10.254.178.122 <pending> 8088:32488/TCP 4d redis-master 10.254.90.116 <none> 6379/TCP 5d redis-slave 10.254.248.244 <none> 6379/TCP 5d
3,同样的方式创建其他pod,如果出现是吧,可打开/var/log/message/下进行查看。
4,在master上查看创建的pod详细信息
1 #查看service信息 2 [root@master guestbook]# kubectl get service 3 NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE 4 frontend 10.254.206.198 <nodes> 80:30001/TCP 5d 5 kubernetes 10.254.0.1 <none> 443/TCP 8d 6 nginx 10.254.178.122 <pending> 8088:32488/TCP 4d 7 redis-master 10.254.90.116 <none> 6379/TCP 5d 8 redis-slave 10.254.248.244 <none> 6379/TCP 5d 9 10 11 [root@master guestbook]# kubectl get service --all-namespaces 12 NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE 13 default frontend 10.254.206.198 <nodes> 80:30001/TCP 5d 14 default kubernetes 10.254.0.1 <none> 443/TCP 8d 15 default nginx 10.254.178.122 <pending> 8088:32488/TCP 4d 16 default redis-master 10.254.90.116 <none> 6379/TCP 5d 17 default redis-slave 10.254.248.244 <none> 6379/TCP 5d 18 kube-system kubernetes-dashboard 10.254.22.70 <nodes> 80:30912/TCP 4d 19 20 #查看pod信息 21 [root@master guestbook]# kubectl get pods --all-namespaces -o wide 22 NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE 23 default frontend-1308123497-bvpkx 1/1 Running 0 5d 10.255.98.3 192.168.20.75 24 default frontend-1308123497-lg52q 1/1 Running 0 5d 10.255.39.4 192.168.20.76 25 default frontend-1308123497-z67ct 1/1 Running 0 5d 10.255.34.2 192.168.20.74 26 default nginx-1151984195-19ms4 1/1 Running 0 4d 10.255.34.4 192.168.20.74 27 default redis-master-1610630896-zmv8f 1/1 Running 0 5d 10.255.39.2 192.168.20.76 28 default redis-slave-2804703596-bg8k5 1/1 Running 0 5d 10.255.39.3 192.168.20.76 29 default redis-slave-2804703596-m2s6n 1/1 Running 0 5d 10.255.98.2 192.168.20.75 30 kube-system kubernetes-dashboard-1924705696-x47dd 1/1 Running 0 4d 10.255.34.3 192.168.20.74 31 32 33 [root@master guestbook]# kubectl get deployments 34 NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 35 frontend 3 3 3 3 5d 36 nginx 1 1 1 1 4d 37 redis-master 1 1 1 1 5d 38 redis-slave 2 2 2 2 5d 39 40 [root@master guestbook]# kubectl get deployments --all-namespaces 41 NAMESPACE NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 42 default frontend 3 3 3 3 5d 43 default nginx 1 1 1 1 4d 44 default redis-master 1 1 1 1 5d 45 default redis-slave 2 2 2 2 5d 46 kube-system kubernetes-dashboard 1 1 1 1 4d 47 [root@master guestbook]#
5,可以通过任意node节点来访问
http://192.168.20.74:30001/
五,总结
由此可见,访问任意工作节点都可以,可以得出,此处可以使用VIP来实现HA。
在创建pod过程中,如果出现问题都可以通过/var/log/message 日志动态查看。