k8s,作為目前最流行的容器編排中間件,大家應該都聽說過,很多公司也都在用,但基本都是運維在管理k8s,開發人員一般涉及不到,開發人員只需要寫業務代碼,然后運維人員負責制作鏡像,然后用k8s拉取鏡像,啟動容器,對外提供服務,這一套,現在都是自動化的,但是我覺著作為業務研發,也應該要清楚這一套流程的實現機制,這樣在出問題的時候,可以多一些排查的思路,而不是只能干等著運維同事排查。
接下來,我就以一個python項目的啟動過程舉例,來看一下一個python項目是如何在k8s中部署起來的。
(1)、第一步,編寫python的業務代碼
(2)、第二步,使用預先寫好的Dockerfile文件制作docker鏡像,鏡像中會包含執行python文件的命令定義
(3)、第三步,將docker鏡像推到本地的鏡像倉庫,比如:docker提供的registry或者VMvare提供的harbor,后者是對registry的擴展,添加了很多企業級功能,目前大部分企業一般都用后者來管理鏡像
(4)、第四步,編寫k8s的的yaml文件,yaml文件中會指定從企業的鏡像倉庫拉取鏡像,然后以此創建pod,對外提供服務
以上就是將一個python項目容器化啟動的流程,下面我們具體操作一下。
先看一下目錄
文章目錄
- 1、編寫python的業務代碼
- 2、編寫Dockerfile文件,制作docker鏡像
- 2.1、編寫Dockerfile文件
- 2.2、制作docker鏡像
- 3、將docker鏡像推送到本地registry鏡像倉庫
- 3.1、啟動一個帶認證功能的registry
- 3.1.1、創建加密的用戶名和密碼文件
- 3.1.2、啟動帶認證功能的registry
- 3.1.3、驗證認證功能
- 3.2、推送docker鏡像
- 4、編寫k8s的yaml文件
- 4.1、創建kubenetes secret
- 4.2、編寫yaml文件
- 5、根據yaml文件,創建pod
1、編寫python的業務代碼
這部分業務代碼,參考了極客時間的<深入剖析kubernetes>專欄課。
這段python代碼很簡單,就是從環境變量里讀取NAME的值,打印在hello后面,如果獲取不到,就將world打印在hello后面。
from flask import Flask
import socket
import osapp = Flask(__name__)@app.route('/')
def hello():html = "<h3>Hello {name}!</h3>" \"<b>Hostname:</b> {hostname}<br/>"return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())if __name__ == "__main__":app.run(host='0.0.0.0', port=80)
代碼里,引用了flask框架來發布web服務,我們使用requirements.txt來聲明我們引用的包,requirements.txt文件在python代碼的同級目錄下。
app.py requirements.txt
2、編寫Dockerfile文件,制作docker鏡像
2.1、編寫Dockerfile文件
這個Dockerfile文件,也是參考極客時間的<深入剖析kubernetes>專欄課,每一行代碼都是一個Dockerfile的命令原語。這些原語具體的含義,都做了注釋
# 使用官方提供的Python開發鏡像作為基礎鏡像,我們制作出來的鏡像,就會包含python的基礎開發環境
FROM python:2.7-slim# 將工作目錄切換為/app,類似于一個cd /app命令
WORKDIR /app# 將當前目錄下的所有內容復制到/app下
ADD . /app# 使用pip命令安裝這個python應用所需要的依賴
RUN pip install --trusted-host pypi.python.org -r requirements.txt# 允許外界訪問容器的80端口
EXPOSE 80# 設置環境變量
ENV NAME=World# 設置容器進程為:python app.py,即:這個Python應用的啟動命令
CMD ["python", "app.py"]
2.2、制作docker鏡像
docker build -t py_container .
-t意思是給這個鏡像起一個名字,創建成功的話,使用docker image ls可以查看我們創建的這個鏡像
3、將docker鏡像推送到本地registry鏡像倉庫
3.1、啟動一個帶認證功能的registry
3.1.1、創建加密的用戶名和密碼文件
# 安裝工具,Ubuntu系統
apt-get install -y apache2-utils# 創建認證文件(用戶:admin,密碼:123456)
mkdir -p /opt/registry/auth
htpasswd -Bbn admin 123456 > /opt/registry/auth/htpasswd
3.1.2、啟動帶認證功能的registry
docker run -d -p 5000:5000 \--name registry \-v /opt/registry/auth:/auth \-e "REGISTRY_AUTH=htpasswd" \-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \-v /opt/registry/data:/var/lib/registry \--restart always \registry:2
3.1.3、驗證認證功能
我們訪問一下我們此前推送到registry的鏡像列表
root@1121-67dff6765fc00 # curl http://localhost:5000/v2/_catalog
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}
可以看到,認證失敗。此時我們加上此前設置的用戶名密碼,就可以訪問registry成功
root@1121-67dff6765fc00 # curl -u admin:123456 http://localhost:5000/v2/_catalog
{"repositories":["py-container"]}
3.2、推送docker鏡像
#將我們此前制作的鏡像打上一個tag
docker tag cf756704a3dc localhost:5000/py-container:0.0.1
#將打好tag的鏡像推送到倉庫
docker push localhost:5000/py-container:0.0.1
4、編寫k8s的yaml文件
4.1、創建kubenetes secret
我們需要將這個regcred配置到yaml中,然后kubenetes就可以訪問到需要認證才可以訪問的本地registry
kubectl create secret docker-registry regcred \--docker-server=localhost:5000 \--docker-username=admin \--docker-password=123456
4.2、編寫yaml文件
這個yaml文件很簡單,就是創建了一個名為py-container-deployment的deployment,這個deployment管理了2個pod,pod的鏡像從本地registry中拉取。yaml文件的末尾,我們增加了imagePullSecrets來引用此前創建的kubenetes secret,以此可以訪問需要加密訪問的registry
apiVersion: apps/v1
kind: Deployment
metadata:name: py-container-deployment
spec:selector:matchLabels:app: py-containerreplicas: 1template:metadata:labels:app: py-containerspec:containers:- name: py-podimage: localhost:5000/py-container:0.0.1ports:- containerPort: 80imagePullSecrets:- name: regcred
5、根據yaml文件,創建pod
kubectl create -f py_pod.yaml
查看pod的啟動情況
如果要刪除這個deployment管理的pod,我們可以通過以下命令刪除
kubectl delete deployment py-container-deployment