常见的企业环境中,容器化部署一般需要支持 golang、nodejs、python、java、php 等常见的开发语言。
本文探讨了一种将运行环境(Runtime)和代码(或编译后的二进制文件)分离的容器镜像打包的方式。
代码容器镜像结构为:
- 第一层基础镜像: busybox 或 alpine
- 第二层项目的第三方依赖库: pip 库 (python项目), npm库(nodejs项目) 第三方依赖jar包(java springboot项目) php项目的vendor
- 第三层:项目源代码或编译后的二进制
- 第四层: 项目的启动脚本,默认配置文件,其他杂项
代码容器镜像有如下功能:
- 把代码发布为 docker image
- 根据代码结构进行了分层,有利的减小了增量包的大小
- 代码容器本身不需要能运行代码,也不提供代码的运行环境
如何运行和发布项目?
将运行环境容器镜像和代码容器镜像共同组合起来,可利用 docker-compose 的容器挂载 和 kubernets init-container 技术进行发布。
方案的优点:
- 代码容器镜像只有源代码(php,python)或者编译后的二进制(golang,nodejs,java)
- 代码容器镜像不需要把代码运行起来,整个镜像的大小比常规的方式大大减小
- 运行环境容器镜像打安全补丁或进行升级时,不需要对已有的任何代码容器进行任何更改
show me the code
namespace: golang
depolyment: advert-stat
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: advert-stat
labels:
app: advert-stat
environment: prod
namespace: golang
annotations:
app.kubernetes.io/name: advert-stat
spec:
minReadySeconds: 0
progressDeadlineSeconds: 300
replicas: 3
revisionHistoryLimit: 20
selector:
matchExpressions:
- {key: release, operator: In, values: [stable,canary]}
- {key: app, operator: In, values: [advert-stat]}
template:
metadata:
name: advert-stat
labels:
app: advert-stat
release: stable
annotations:
cmhash: 83464a5373bc73779c39fd8b6a60c14c948e8a47
deletionGracePeriodSeconds: 6
spec:
imagePullSecrets:
- name: secret-private-registry
initContainers:
- name: init-pkg
image: repo.domain.com/golang/advert-stat:v1.0.07-20191025T163618
imagePullPolicy: Always
command: ['sh', '-c', "cp -rf /opt/* /app/ "]
volumeMounts:
- mountPath: /app
name: app-dir
- name: init-conf
image: repo.domain.com/config/golang-config
imagePullPolicy: Always
command: ['sh', '-c', "cp -rf /opt/advert-stat/* /app/ "]
volumeMounts:
- mountPath: /app
name: app-dir
containers:
- name: advert-stat
image: repo.domain.com/image/base:19.11
imagePullPolicy: Always
env:
- name: SYS_ID
value: advert-stat
- name: EXTRA_OPTS
value: ""
- name: RUN_AS
value: "nobody:nobody"
resources:
requests:
memory: '512Mi'
limits:
cpu: '500m'
memory: '512Mi'
livenessProbe:
tcpSocket:
port: 8080
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Connection
value: keep-alive
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 5
volumeMounts:
- mountPath: /app
name: app-dir
volumes:
- name: app-dir
emptyDir: {}
dnsConfig:
options:
- name: timeout
value: "5"
- name: attempts
value: "3"
- name: rotate
dnsPolicy: ClusterFirstWithHostNet
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: advert-stat
namespace: golang
spec:
selector:
app: advert-stat
release: stable
ports:
- name: svc-port
protocol: TCP
port: 80
targetPort: 8080
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 600
type: ClusterIP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: advert-stat-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
namespace: golang
spec:
rules:
- host: advert-stat.domain.com
http:
paths:
- path: /
backend:
serviceName: advert-stat
servicePort: 80
网友评论