目錄
1. 使用hostNetwork參數(容器內部服務與宿主機同一網段)
1. 使用hostNetwork參數(Pod與宿主機在同一網段)
三、同Pod中容器訪問——以ubuntu16.04+mysql+redis爲例
序言
研究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/