k8s的Pod内容器互相访问——容器内使用python操作同Pod的mysql容器

目录

一、容器外部访问容器内部服务

1. 使用hostNetwork参数(容器内部服务与宿主机同一网段)

2. 使用hostPort参数(将容器内端口暴露出来)

3. 使用NodePort参数

4. 使用LoadBalancer参数

二、容器内部服务访问外部服务

1. 使用hostNetwork参数(Pod与宿主机在同一网段)

2. 使用endpoints组件

三、同Pod中容器访问——以ubuntu16.04+mysql+redis为例


序言

研究k8s断断续续都好几个月了,因为没有项目实战,纯网上学习一直对容器之间互相通信不知道怎么弄,一直也很郁闷,今天在总结之前的学习成果时候,网上查着之前都看过很多遍的文档,突然就想通了,赶紧跟着示例重新实践了一番,至此容器间通信的基础操作告一段落。

很奇怪,当你没想通一件事情时候,怎么在网上找都找不到方案,怎么看网上的教程都无从下手;但是一旦想通了那个点,再看网上遍地文档都在告诉你应该怎么做怎么做,或许这就是不到一定的时候,对同一个东西看到的层面不同,理解不同吧。所以读书温故而知新是很有道理的。 ^ _*  。

 

K8s容器之间互相访问方式总结

容器之间互相通信或者访问

同一个pod: 直接localhost:+端口

同一个节点,不同pod:给pod做service,通过服务发现的方式访问(service端口方式设为nodePort或者targetPort)。访问方式:nodePort:+端口

不同节点的容器访问:需要网络(隧道,路由)overlay(vxlan),openswitch,flannel等类似路由器。

一、容器外部访问容器内部服务

1. 使用hostNetwork参数(容器内部服务与宿主机同一网段)

特点:当Pod调度到哪个节点就使用哪个节点的IP地址,客户端使用IP地址访问容器里面的服务。一个node只能启动一个pod端口,端口不能冲突

以启动nginx容器为例,yaml文件写法以及操作如下:

[root@k8s01 yaml]# cat end-nginx.yaml   
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx1  
  labels:  
    app: web  
spec:  
 hostNetwork: true  
 containers:  
  - name: ng-web  
    image: nginx:latest  
    imagePullPolicy: Never 

操作:

[root@k8s01 yaml]# kubectl apply -f end-nginx.yaml  
pod/nginx1 created  
[root@k8s01 yaml]# kubectl  get pods -o wide  
NAME               READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES  
nginx1                1/1     Running   0          72s   192.168.54.129   k8s02   <none>           <none>  
[root@k8s01 yaml]# curl -I http://192.168.54.129     --直接访问Pod的IP地址   
HTTP/1.1 200 OK  
Server: nginx/1.17.5  
Date: Wed, 27 Nov 2019 07:52:02 GMT  
Content-Type: text/html  
Content-Length: 612  
Last-Modified: Tue, 22 Oct 2019 14:30:00 GMT  
Connection: keep-alive  
ETag: "5daf1268-264"  
Accept-Ranges: bytes  
[root@k8s01 yaml]#  

2. 使用hostPort参数(将容器内端口暴露出来)

特点:Pod调度到哪个节点就用哪个节点的IP址访问, 端口可以随机指定。生产环境pod必须与宿机绑定才可使用

以启动nginx容器为例,yaml文件写法以及操作如下:

[root@k8s01 yaml]# cat end-nginx2.yaml   
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx2  
  labels:  
    app: web  
spec:  
 containers:  
  - name: ng-web2  
    image: nginx:latest  
    imagePullPolicy: Never  
    ports:  
    - name: http  
      containerPort: 80     #--容器端口  
      hostPort: 80     #--暴露端口  
      protocol: TCP  

操作:

[root@k8s01 yaml]# kubectl apply -f  end-nginx2.yaml  
pod/nginx2 created  
[root@k8s01 yaml]# kubectl  get pods  -o wide  
NAME           READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES  
nginx2               1/1     Running   0          4m31s   10.244.1.67   k8s02   <none>           <none>  
  
[root@k8s01 yaml]# curl  -I http://192.168.54.129      #--Pod在哪个宿主机就用哪个IP地址   
HTTP/1.1 200 OK  
Server: nginx/1.17.5  
Date: Wed, 27 Nov 2019 08:15:24 GMT  
Content-Type: text/html  
Content-Length: 612  
Last-Modified: Tue, 22 Oct 2019 14:30:00 GMT  
Connection: keep-alive  
ETag: "5daf1268-264"  
Accept-Ranges: bytes  
[root@k8s01 yaml]#  

3. 使用NodePort参数

特 点:使用node节点的IP加端口可以访问Pod服务,master节点IP不可以访问。端口范围30000-32767。

以启动nginx容器为例,yaml文件写法以及操作如下:

[root@k8s01 yaml]# cat end-nginx3.yaml    
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx3  
  labels:  
    app: web  
spec:  
 containers:  
  - name: ng-web3  
    image: nginx:latest  
    imagePullPolicy: Never  
    ports:  
      - containerPort: 80  
---  
kind: Service  
apiVersion: v1  
metadata:  
  name: ng-service  
spec:  
  type: NodePort  
  ports:  
    - name: http  
      port: 80  
      nodePort: 31000  
  selector:     #--后端Pod标签  
    app: web

操作:

[root@k8s01 yaml]# kubectl apply -f  end-nginx3.yaml  
pod/nginx3 created  
service/ng-service created  
[root@k8s01 yaml]# kubectl  get pods -o wide  
NAME      READY   STATUS    RESTARTS   AGE   IP       NODE    NOMINATED NODE   READINESS GATES  
nginx3         1/1     Running   0          63s   10.244.1.77   k8s02   <none>           <none>  
[root@k8s01 yaml]# kubectl  get svc -o wide  
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR  
ng-service   NodePort    10.102.52.148   <none>        80:31000/TCP   66s   app=web  
  
[root@k8s01 yaml]# curl  -I http://192.168.54.129:31000      --使用node节点IP地址访问,master节点IP访问不了。   
HTTP/1.1 200 OK  
Server: nginx/1.17.5  
Date: Wed, 27 Nov 2019 08:47:33 GMT  
Content-Type: text/html  
Content-Length: 612  
Last-Modified: Tue, 22 Oct 2019 14:30:00 GMT  
Connection: keep-alive  
ETag: "5daf1268-264"  
Accept-Ranges: bytes  
[root@k8s01 yaml]#  

4. 使用LoadBalancer参数

特点:必须使用云服务商提供一个VIP地址,只能node节点的IP地址可以访问,master地址不能访问。

以nginx服务为例,操作如下:

[root@k8s01 yaml]# cat end-nginx4.yaml   
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx4  
  labels:  
    app: web  
spec:  
 containers:  
  - name: ng-web4  
    image: nginx:latest  
    imagePullPolicy: Never  
    ports:  
      - containerPort: 80  
---  
kind: Service  
apiVersion: v1  
metadata:  
  name: ng-lb  
spec:  
  type: LoadBalancer  
  ports:  
    - name: http  
      port: 80  
  selector:  
    app: web  
status:                           #--如果有vip就要写,没有就不用写。  
  loadBalancer:  
    ingress:  
    - ip: 192.168.54.131

操作:

[root@k8s01 yaml]# kubectl apply -f  end-nginx4.yaml  
pod/nginx4 created  
service/ng-lb created  
[root@k8s01 yaml]# kubectl  get pods -o wide  
NAME          READY   STATUS    RESTARTS   AGE    IP        NODE    NOMINATED NODE   READINESS GATES  
nginx4            1/1     Running   0          4m6s   10.244.1.80   k8s02   <none>           <none>  
[root@k8s01 yaml]# kubectl  get svc -o wide  
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE     SELECTOR  
ng-lb        LoadBalancer   10.99.49.195    <pending>     80:30183/TCP   4m10s   app=web     --没有VIP地址  
  
[root@k8s01 yaml]# curl  -I http://192.168.54.129:30183  
HTTP/1.1 200 OK  
Server: nginx/1.17.5  
Date: Wed, 27 Nov 2019 09:11:01 GMT  
Content-Type: text/html  
Content-Length: 612  
Last-Modified: Tue, 22 Oct 2019 14:30:00 GMT  
Connection: keep-alive  
ETag: "5daf1268-264"  
Accept-Ranges: bytes  
[root@k8s01 yaml]#  
 

二、容器内部服务访问外部服务

1. 使用hostNetwork参数(Pod与宿主机在同一网段)

以nginx容器内访问外部mysql为例,操作如下:

[root@k8s01 yaml]# cat mysql.yaml   
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx5  
  labels:  
    app: mysql  
spec:  
  hostNetwork: true  
  containers:  
  - name: db-mysql  
    image: nginx:latest  
    imagePullPolicy: Never

操作:

[root@k8s01 yaml]# kubectl  apply -f mysql.yaml  
pod/nginx5 created  
[root@k8s01 yaml]# kubectl exec -it nginx5 /bin/bash  
root@nginx5:/# apt-get update            --更新创建   
root@nginx5:/# apt-get install mysql*     --安装mysql包  
root@nginx5:/# mysql -h 192.168.54.130 -u repl -p123456    --登陆mysql数据库  
Welcome to the MariaDB monitor.  Commands end with ; or \g.  
Your MySQL connection id is 16  
Server version: 5.7.27 MySQL Community Server (GPL)  
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.  
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.  
MySQL [(none)]> show databases;  
+--------------------+  
| Database           |  
+--------------------+  
| information_schema |  
| mysql              |  
| performance_schema |  
| sys                |  
| wuhan              |  
+--------------------+  
5 rows in set (0.001 sec)  
MySQL [(none)]>  
 

2. 使用endpoints组件

以nginx容器内访问外部mysql为例,操作如下:

[root@k8s01 yaml]# cat endpoint.yaml  
apiVersion: v1  
kind: Endpoints  
metadata:  
  name: mysql-test  
  namespace: default  
subsets:  
  - addresses:  
    - ip: 192.168.54.130   # --指定宿机主mysql服务器  
    ports:  
      - port: 3306      #--指定端口  
---  
apiVersion: v1  
kind: Service  
metadata:  
  name: mysql-test    #--service后端指向endpoints地址  
  labels:  
    app: abc  
spec:  
  ports:  
    - port: 3306  
---  
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx6       #--启动一个容器,测试连接mysql  
  labels:  
    app: db  
spec:  
 containers:  
  - name: mysql-test  
    image: nginx:latest  
    imagePullPolicy: Never  

操作:

[root@k8s01 yaml]# kubectl  apply -f endpoint.yaml  
endpoints/mysql-test created  
service/mysql-test created  
pod/nginx6 created  
[root@k8s01 yaml]# kubectl get pods -o wide  
NAME         READY   STATUS    RESTARTS   AGE   IP          NODE    NOMINATED NODE   READINESS GATES  
nginx6                    1/1     Running   0          12s   10.244.1.85   k8s02   <none>           <none>  
[root@k8s01 yaml]# kubectl get svc -o wide  
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE   SELECTOR  
mysql-test   ClusterIP   10.98.57.89     <none>        3306/TCP   16s   <none>  
[root@k8s01 yaml]# kubectl get endpoints -o wide  
NAME         ENDPOINTS                       AGE  
mysql-test   192.168.54.130:3306             21s  
[root@k8s01 yaml]# kubectl exec -it nginx6 /bin/bash  
root@ nginx6:/# mysql -h mysql-test -u repl -p123456    --使用endpoints名字(映射到service,service映射到192.168.54.130)  
Welcome to the MariaDB monitor.  Commands end with ; or \g.  
Your MySQL connection id is 19  
Server version: 5.7.27 MySQL Community Server (GPL)  
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.  
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.  
MySQL [(none)]> show databases;  
+--------------------+  
| Database           |  
+--------------------+  
| information_schema |  
| mysql              |  
| performance_schema |  
| sys                |  
| wuhan              |  
+--------------------+  
5 rows in set (0.001 sec)  
MySQL [(none)]>  

三、同Pod中容器访问——以ubuntu16.04+mysql+redis为例

描述:建立一个pod,里面包含三个容器,分别是ubuntu16.04,mysql,redis

目的:在Ubuntu16.04系统中通过python操作mysql和redis容器

yaml文件:

$ cat c2c-test.yaml
apiVersion: v1  
kind: Pod  
metadata:  
 name: c2c-test  
spec:   
 containers:  
 - name: myos  
   image: ubuntu:16.04 
   tty: true  
 - name: myredis  
   image: redis  
   ports:  
   - containerPort: 6379  
 - name: mysql  
   image: mysql  
   ports:  
   - containerPort: 3306  
   env:  
   - name: MYSQL_ROOT_PASSWORD  
     value: "root"  
 

启动服务后,进入ubuntu16.04容器进行redis或者mysql的操作

$ kubectl apply -f c2c-test.yaml
$ kubectl exec -it c2c-test -c myos bash
 

当在myos容器里想访问redis或者mysql时,因为是在同一个容器中,所以共用一个ip地址,可以用localhost+port直接访问,在实际项目中我们会经常使用python操作redis和mysql, 以mysql为例,新建一个测试python文件。python提前安装好所需包:pip install pymysql,  pip install  cryptography

$ vi mysqltest.py  
import pymysql  
db = pymysql.connect(host='localhost',  user='root', passwd='root',db='lmh') #这里host是'localhost'就是我们mysql容器的连接地址
cursor = db.cursor()  
cursor.execute("CREATE TABLE test (id int PRIMARY KEY, name varchar(20));") 
data = cursor.fetchone()  
print ("Database version : %s " % data)  
db.close() 

注意此时python文件执行的结果是在mysql中database:lmh中新建一个test的表格 。

现在可以通过进入mysql容器,查看test的表格已经创建成功。对于redis同样操作,所以我们就实现了pod内容器之间的互连。

$ kubectl exec -it c2c-test -c mysql bash

 

参考:http://blog.itpub.net/25854343/viewspace-2665927/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章