书籍来源:《CKA/CKAD应试指南:从Docker到Kubernetes完全攻略》
一边学习一边整理老师的课程内容及实验笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:CKA备考实验 | 汇总_热爱编程的通信人的博客-CSDN博客
有的应用是多个pod联合使用的,比如使用wordpress + mysql搭建个人博客。
wordpress要连接到mysql的pod,拓扑图如图12-4所示。
wordpress需要连接到mysql才能正常工作,但是前面讲过,最好不要直接去访问pod的IP,因为pod不稳定,通过deployment创建出来的pod的IP又是会改变的。所以我们有必要为mysql的pod创建一个mysql的svc,只要不删除重建svc,则svc的IP是不会变的。
此时wordpress的pod需要连接mysql的svc的时候,mysql的svc会把请求转发给mysql pod。这样wordpress的pod就可以访问到mysql的pod了。那么wordpress的pod如何知道mysql svc的IP的呢?这里就涉及了服务的发现。
环境准备
如图12-4中,先创建出来一个mysql的pod,然后创建出来mysql的svc,在创建wordpress的pod的时候,让wordpress的pod连接到mysql的svc。
步骤1:先开始创建mysql的pod,对应的yaml文件如下。
##########实操验证##########
[root@vms10 svc]# cat pod-mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
name: mysql
spec:
containers:
- image: hub.c.163.com/library/mysql:latest
imagePullPolicy: IfNotPresent
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: redhat
- name: MYSQL_USER
value: tom
- name: MYSQL_PASSWORD
value: redhat
- name: MYSQL_DATABASE
value: blog
ports:
- containerPort: 3306
name: mysql
[root@vms10 svc]#
注意看这里mysql里设置的各个变量,把mysql的root密码设置为redhat,创建一个普通用户tom,且密码被设置为redhat,然后创建了一个数据库blog。
步骤2:创建mysql的pod。
##########实操验证##########
[root@vms10 svc]# kubectl apply -f pod-mysql.yaml
pod/mysql created
[root@vms10 svc]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql 1/1 Running 0 4s
[root@vms10 svc]#
此时mysql这个pod已经正常运行了。
步骤3:为mysql的pod创建svc,名字为dbsvc。
##########实操验证##########
[root@vms10 svc]# kubectl expose pod mysql --name=dbsvc --port=3306
service/dbsvc exposed
[root@vms10 svc]#
步骤4:下面创建wordpress的pod,对应的yaml文件如下。
##########实操验证##########
[root@vms10 svc]# cat pod-wordpress.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress
labels:
name: wordpress
spec:
containers:
- image: hub.c.163.com/library/wordpress:latest
imagePullPolicy: IfNotPresent
name: wordpress
env:
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: redhat
- name: WORDPRESS_DB_NAME
value: blog
- name: WORDPRESS_DB_HOST
value: 10.107.128.125
ports:
- containerPort: 80
name: wordpress
[root@vms10 svc]#
这里wordpress使用root用户连接到mysql,密码是redhat,使用的数据库为blog。那么连接mysql的IP是多少呢?在上面yaml文件里变量WORDPRESS_DB_HOST对应的值必须要填写mysql的IP,那么该填写什么呢?(此处用x.x.x.x替代了。)
通过直接访问clusterip的方式访问
每个svc都有自己的clusterIP,如果svc不删除重建的话,这个clusterIP就不会发生改变。如果通过clusterip的方式访问的话,此处需要首先查询出mysql svc对应的IP。
步骤1:获取mysql的svc的IP。
##########实操验证##########
[root@vms10 svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dbsvc ClusterIP 10.107.128.125 <none> 3306/TCP 2m24s
[root@vms10 svc]#
这里对应的地址是10.111.176.72,所以在pod-wordpress.yaml里,WORDPRESS_DB_HOST所对应的IP应该填写10.111.176.72。
步骤2:修改wordpress的yaml文件pod-wordpress.yaml里的WORDPRESS_DB_HOST部分,内容如下。
- name: WORDPRESS_DB_HOST
value: 10.111.176.72
步骤3:创建wordpress的pod。
##########实操验证##########
[root@vms10 svc]# kubectl apply -f pod-wordpress.yaml
pod/wordpress created
[root@vms10 svc]#
步骤4:查看pod运行状况。
##########实操验证##########
[root@vms10 svc]# kubectl get pods -o wide --no-headers
mysql 1/1 Running 2 21m 10.244.81.81 vms11.rhce.cc <none> <none>
wordpress 1/1 Running 0 2m48s 10.244.81.82 vms11.rhce.cc <none> <none>
[root@vms10 svc]#
此时通过wordpress的pod的IP地址10.244.81.101,就可以访问到wordpress了(注意,这个IP只能是master或者worker才能访问)。
步骤5:在master里的Firefox(master里需安装FireFox,在ssh客户端执行命令firefox &可远程打开master上Firefox浏览器)地址栏输入10.244.81.101,选择“简体中文”,单击“继续”按钮,如图12-5所示,在欢迎界面并没有让我们连接数据库,说明wordpress已经自动连接到mysql上了,如图12-6所示。
通过变量的方式
在同一个命名空间里,假设已经先存在了A服务,则在创建B pod的时候,B pod里会自动地学习到和A服务相关的一些变量,标记服务IP和端口的格式如下。
A服务名_SERVICE_HOST
A服务名_SERVICE_PORT
注意:这里服务名要换成大写。
在B pod的yaml文件里要引用关于A服务的变量时,用$(变量名)。
比如刚才已经创建了mysql的pod和mysql的服务dbsvc,然后又创建了wodpress的pod,进入wordpress的pod里查看相关变量,如下所示。
##########实操验证##########
[root@vms10 svc]# kubectl exec wordpress -it -- bash
root@wordpress:/var/www/html# env | grep DBSVC
DBSVC_PORT_3306_TCP_ADDR=10.100.82.197
DBSVC_SERVICE_PORT=3306
DBSVC_PORT_3306_TCP_PORT=3306
DBSVC_PORT_3306_TCP=tcp://10.100.82.197:3306
DBSVC_SERVICE_HOST=10.100.82.197
DBSVC_PORT=tcp://10.100.82.197:3306
DBSVC_PORT_3306_TCP_PROTO=tcp
root@wordpress:/var/www/html#
root@wordpress:/var/www/html# exit
exit
[root@vms10 svc]#
因为mysql的svc是在wordpress的pod之前创建的,可以看到,wordpress的pod里以变量的方式自动学习到了mysql svc的信息。因为mysql的svc的名字是dbsvc,所以这里识别出来的变量是DBSVC_SERVICE_HOST和DBSVC_SERVICE_PORT。
所以wordpress pod的yaml文件里,可以直接使用变量的方式来获取dbsvc的IP(DBSVC_SERVICE_HOST这个变量显示的就是dbsvc的IP)。
步骤1:删除wordpress的pod。
##########实操验证##########
[root@vms10 svc]# kubectl delete pod wordpress --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "wordpress" force deleted
[root@vms10 svc]#
步骤2:修改wordpress pod的yaml文件,把WORDPRESS_DB_HOST的值改成:
##########实操验证##########
[root@vms10 svc]# cat pod-wordpress.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress
labels:
name: wordpress
spec:
containers:
- image: hub.c.163.com/library/wordpress:latest
imagePullPolicy: IfNotPresent
name: wordpress
env:
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: redhat
- name: WORDPRESS_DB_NAME
value: blog
- name: WORDPRESS_DB_HOST
value: $(DBSVC_SERVICE_HOST)
ports:
- containerPort: 80
name: wordpress
[root@vms10 svc]#
注意:这里引用变量使用的是$() ,而不是${} ; value和name是对齐的。
步骤3:创建wordpress的pod。
##########实操验证##########
[root@vms10 svc]# kubectl apply -f pod-wordpress.yaml
pod/wordpress created
[root@vms10 svc]# kubectl get pods -o wide --no-headers
mysql 1/1 Running 2 25m 10.244.81.81 vms11.rhce.cc <none> <none>
wordpress 1/1 Running 0 11s 10.244.81.83 vms11.rhce.cc <none> <none>
[root@vms10 svc]#
此时wordpress的pod正常运行,pod的IP为10.244.81.102,通过这个地址查看下是否能正常访问到wordpress。
步骤4:在master的Firefox地址栏输入10.244.81.102,如图12-7和图12-8所示。
可以看到,现在跳过了数据库的设置,说明wordpress已经自动连接到数据库了。
通过变量的方式发现服务,有两个缺点。
(1)必须要在同一命名空间里。
(2)创建服务的时候,必须要有先后顺序。
步骤5:删除wordpress这个pod。
##########实操验证##########
[root@vms10 svc]# kubectl delete pod wordpress
pod "wordpress" deleted
[root@vms10 svc]#
通过DNS的方式
在kubernetes安装完毕之后,在kube-system命名空间里有一个coredns的deployment,它创建了2个副本的pod。
##########实操验证##########
[root@vms10 svc]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-7cc8dd57d9-7x22j 1/1 Running 2 29d
calico-node-jgj2s 1/1 Running 8 33d
calico-node-mds69 1/1 Running 12 33d
calico-node-wvhsg 1/1 Running 5 33d
coredns-545d6fc579-hhnsl 1/1 Running 1 31m
coredns-545d6fc579-hkzm5 1/1 Running 1 31m
etcd-vms10.rhce.cc 1/1 Running 5 33d
kube-apiserver-vms10.rhce.cc 1/1 Running 2 8d
kube-controller-manager-vms10.rhce.cc 1/1 Running 6 29d
kube-proxy-5f6vr 1/1 Running 3 33d
kube-proxy-tcjt6 1/1 Running 3 33d
kube-proxy-xw7j5 1/1 Running 3 33d
kube-scheduler-vms10.rhce.cc 1/1 Running 6 29d
metrics-server-bcfb98c76-qmpg8 1/1 Running 1 5d20h
[root@vms10 svc]#
这个deployment有一个名字叫作kube-dns的service。
##########实操验证##########
[root@vms10 svc]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 33d
metrics-server ClusterIP 10.100.73.39 <none> 443/TCP 5d20h
[root@vms10 svc]#
这样通过访问kube-dns这个service就能访问到coredns这些pod了。
在整个kubernetes集群里,不管在哪个命名空间,只要创建了服务,都会自动到CoreDNS里去注册,这样CoreDNS会知道每个服务及IP地址的对应关系,如图12-9所示。
在同一个命名空间里,其他pod可以直接通过服务名来访问到此服务。比如上图,过程就是pod2要访问svc1的时候,首先到coreDNS里问svc1的IP是多少,coreDNS查询出来之后告诉pod2,pod2就直接通过这个IP访问到svc1,表面上看就是pod2直接通过svc1这个名字就能访问了。
如同我们平时访问百度,在浏览器里输入http://www.baidu.com,回车一瞬间会通过dns把http://www.baidu.com解析成IP,但是我们却感觉好像直接通过主机名访问到百度似的。
比如刚才创建了一个dbsvc,它的IP是10.111.176.72。
##########实操验证##########
[root@vms10 svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dbsvc ClusterIP 10.100.82.197 <none> 3306/TCP 28m
[root@vms10 svc]#
创建一个临时容器,在里面直接通过服务名访问dbsvc。
##########实操验证##########
[root@vms10 svc]# kubectl run busybox --rm -it --image=busybox sh
If you don't see a command prompt, try pressing enter.
/ #
/ #
/ # ping dbsvc
PING dbsvc (10.100.82.197): 56 data bytes
^C
--- dbsvc ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
/ #
/ # exit
Session ended, resume using 'kubectl attach busybox -c busybox -i -t' command when the pod is running
pod "busybox" deleted
[root@vms10 svc]#
这里ping不通是正常的,因为svc并没有允许icmp通过,只允许特定端口的数据通过,但是可以看到这里已经把dbsvc解析到10.111.176.72了。
如果要访问其他命名空间里的服务,则需要在服务名后面指定命名空间,格式如下。
服务名.命名空间
所以在wordpress的yaml文件里指定WORDPRESS_DB_HOST具体值的时候,因为和mysql是在同一个命名空间,所以直接写上mysql svc的服务名即可。
步骤1:修改wordpress pod的yaml文件,把WORDPRESS_DB_HOST的值改成dvsvc。
##########实操验证##########
[root@vms10 svc]# cat pod-wordpress.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress
labels:
name: wordpress
spec:
containers:
- image: hub.c.163.com/library/wordpress:latest
imagePullPolicy: IfNotPresent
name: wordpress
env:
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: redhat
- name: WORDPRESS_DB_NAME
value: blog
- name: WORDPRESS_DB_HOST
value: dbsvc
ports:
- containerPort: 80
name: wordpress
[root@vms10 svc]#
这里直接指定的是mysql的svc的服务名。
步骤2:创建wordpress的pod。
##########实操验证##########
[root@vms10 svc]# kubectl apply -f pod-wordpress.yaml
pod/wordpress created
[root@vms10 svc]#
步骤3:查看wordpress pod的IP。
##########实操验证##########
[root@vms10 svc]# kubectl get pods -o wide --no-headers
mysql 1/1 Running 2 31m 10.244.81.81 vms11.rhce.cc <none> <none>
wordpress 1/1 Running 0 21s 10.244.81.85 vms11.rhce.cc <none> <none>
[root@vms10 svc]#
测试通过10.244.81.104是否能访问到wordpress。
步骤4:在master的Firefox地址栏输入10.244.81.104,如图12-10所示。
wordpress依然是可以访问的,说明wordpress pod已经正确地连接到mysql上了。