kubernetes实践录 - 使用Baget部署一个私有Nuget仓库
Reference:
书接上回 kubernetes实践录 - 在ubuntu上搭建k8s集群. 本回将在上次安装好的kubernetes集群上部署一个Baget
应用. 其实就是通过部署Baget
来学习下kubernetes
里面的一些基本的概念, 包括Node
, Pod
Deployment
Service
Ingress
.
本文只是记录自己实践过程, 若有错误或不当之处, 敬请指正或讨论.
Node
节点(Node)是kubernetes集群中的一台物理服务器或虚拟机, 节点大致可以分为主节点(master)和其他节点. 主节点主要负责提供一系列管理接口方便对集群进行管理. 而其他节点一般会被调度执行工作负载, 通常来说pod
就是跑在这些其他节点上的. 当然你也可以让主节点运行指定的pod, 这是可以通过配置实现的, 通常本地开发时可能会这么做, 此时主节点就相当于被污染了(tainted
).
Pod和Deployment
如果我们要在kubernetes中运行我们自己的应用, 那么首先我们就需要构建pod. 一个pod中可以包含一个或多个(通常是一个)容器(container).
pod是kubernetes中最小的调度单元, 当pod启动或停止时, pod中的容器会跟着一起启动或停止.
pod这个名字的由来: 大家应该都知道, Docker的图标上是一只鲸鱼, pod之意其实就是一群鲸鱼.
那Deployment和Pod有什么关系呢? 通过Deployment我们可以构建出一个Pod, 配置pod中的容器和容器使用的硬件资源等.
比如我们要部署一个Baget应用, 那么我们需要先创建baget-deployment.yaml
文件, 这个文件中定义了一个Deployment资源, 然后执行kubectl apply -f baget-deployment.yaml
, kubernetes就会帮我们创建好pod了, 可以通过kubectl get pods --all-namespaces
查看当前kubernetes集群中正在运行的pod.
点击查看 baget-deployment.yaml 文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: baget
namespace: baget
labels:
app: baget
spec:
selector:
matchLabels:
app: baget
replicas: 1
strategy:
rollingUpdate:
maxUnavailable: 1
maxSurge: 2
type: RollingUpdate
template:
metadata:
labels:
app: baget
spec:
containers:
- name: baget
image: loicsharma/baget:latest
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
livenessProbe:
httpGet:
path: /v3/index.json
port: 80
initialDelaySeconds: 30
timeoutSeconds: 30
successThreshold: 1
failureThreshold: 3
periodSeconds: 30
envFrom:
- configMapRef:
name: baget-config
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- name: baget-data
mountPath: /var/baget
volumes:
- name: baget-data
hostPath:
path: /laplus/data/baget
restartPolicy: Always
这是一个yaml格式的配置文件, 顶层包括了apiVersion
kind
metadata
spec
这几个对象. 几乎每个kubernetes配置文件都会有apiVersion
kind
metadata
这几个东西;
apiVersion
用来用来说明这个配置文件适用的kubernetes api;
apiVersion: apps/v1
kind
表示这个资源的类型, 这里是Deployment
;
kind: Deployment
metadata
表示的是资源的元数据, 通常有name
和labels
这两个属性, 我这里还多定义了一个namespace.
metadata:
name: baget
namespace: baget
labels:
app: baget
重点看下.spec.template.spec
这段
spec:
containers:
- name: baget
image: loicsharma/baget:latest
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
livenessProbe:
httpGet:
path: /v3/index.json
port: 80
initialDelaySeconds: 30
timeoutSeconds: 30
successThreshold: 1
failureThreshold: 3
periodSeconds: 30
envFrom:
- configMapRef:
name: baget-config
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- name: baget-data
mountPath: /var/baget
volumes:
- name: baget-data
hostPath:
path: /laplus/data/baget
这段中我们定义了容器的镜像, 容器可以调度的硬件资源的限制, 容器的健康检查, 环境变量, 磁盘挂载等内容.
最后执行kubectl apply -f baget-deployment.yaml
让kubernetes创建我们定义的资源, 执行 kubectl get pods -n baget
可以列出baget
名称空间下的所有pod
NAME READY STATUS RESTARTS AGE
baget-5576d6fc79-n8k2s 1/1 Running 0 20h
用Service在集群内部转发请求到指定的pod
有了pod之后, 经过容器化的应用就可以在pod中运行了. 下面我们要通过Service在集群内部暴露pod中的应用.
一个Service相当于集群内部的负载均衡器, 创建Service后, kubernetes中的其他pod就可以通过http://baget/v3/index.json
访问到刚刚创建的叫Baget
的pod了.
apiVersion: v1
kind: Service
metadata:
name: baget
namespace: baget
labels:
app: baget
spec:
type: ClusterIP
selector:
app: baget
ports:
- port: 80
targetPort: 80
protocol: TCP
上面的Service配置清单中的.spec.type
指明了服务的类型, 除了这个用的ClusterIP
, 另外还有LoadBalancer
,NodePort
等; 如果用NodePort
的话, 那么可以直接将应用暴露到集群外, 也就是说可以直接使用宿主机ip + nodePort端口访问到应用了, 比如我这里就可以用http://192.168.124.66:<NodePort-Port>/v3/index.json
访问到部署的Baget应用.
用Ingress负载均衡外部的请求
Ingress可以理解为kubernetes中的外部负载均衡器和一个反向代理服务器. 它通常被部署在集群的边缘节点上, 负责处理来自kubernetes集群外部的请求, 把请求转发给指定的Service等服务.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: baget
namespace: baget
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- "baget.inner.laplus.com"
rules:
- host: "baget.inner.laplus.com"
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: baget
port:
number: 80
执行 kubectl apply -f baget-ingress.yaml
部署上面的配置清单后, 本地解析baget.inner.laplus.com
这个域名到安装了nginx-ingress
的边缘服务器ip
192.168.124.66 baget.inner.laplus.com
然后用浏览器访问https://baget.inner.laplus.com
就可以访问到Baget的首页啦.
小结
理解了Pod
Development
Service
Ingress
的相关概念后, 要在kubernetes上部署一个容器化的web应用其实还是挺容易的.
遇到一些坑的地方主要是因为防火墙端口没有全部开放的问题, 按照 https://www.cnblogs.com/laggage/p/install-kubernetes-on-ubuntu.html#%E9%98%B2%E7%81%AB%E5%A2%99 里面的配置好防火墙开放端口就行了.