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/

 

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