k8s 部署应用

k8s 部署应用

目录

一. 部署一个应用
二. 扩容或缩容
三. 节点污点
四. Pod 调度策略
    1. request limits
    2. 节点标签选择器
    3. 节点亲和性
五. secret
    1. secret 创建方式
        a. 命令行创建
        b.编写 yaml
    2. secret资源的使用方式
        a. 添加到 Pod 的环境变量
        b. 以 volume 的形式挂载到 pod
六. ConfigMap
七. 存储编排
    1. 本地存储
        a. 创建 PV
        b.创建 PVC
        c. Pod 绑定 PVC
    2. NFS 存储
八. 服务发现与负载均衡

看完ubuntu 搭建 k8s 集群后我们搭建起了一个 k8s 集群,继续学习 k8s,本文讲述在k8s中部署应用的相关操作.

kubectl 是 k8s 集群管理控制器,使用kubectl api-resources可以显示服务器支持的 API 资源
接下来进行实战
一. 部署一个应用

deployment 是 Pod 之上的抽象,他可以定义一组 Pod 的副本数目,以及这个 Pod 的版本.一般大家用 Deployment 来做应用真正的管理,而 Pod 是组成 Deployment 最小的单元

kubectl create deployment web --image=nginx:1.14 --dry-run -o yaml > web.yaml

create deployment web 创建一个名为 web 的 deployment 资源
--dry-run 表示检查语法,但不实际执行
-o yaml 表示以 yaml 格式输出
> web.yaml 表示输出重定向到 web.yaml

web.yaml


apiVersion: apps/v1 # 版本号
kind: Deployment # 种类,还有 Pod 之类的
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1 # 副本数量
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:1.14 # 指定的镜像文件
name: nginx
resources: {}
status: {}

用下面的命令将配置 web.yaml 应用到 resource,
kubectl apply -f web.yaml
执行完毕后可以通过以下命令查看 Deployment 和 Pod
kubectl get deplyment,pods -o wide

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.extensions/web 1/1 1 1 34m nginx nginx:1.14 app=web

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/web-7c5c4cb946-zxf97 1/1 Running 0 8s 10.24.1.11 k8s-node1

可以到当前资源正在正常运行,
curl 10.24.1.11
如果有 nginx 的标准返回说明应用已经部署完毕
二. 扩容或缩容

k8s 扩容十分简单,只需要修改之前的 web.yaml 文件,将 replicas的值改为 10,然后再更新配置
kubectl replace -f web.yaml

也可以直接使用 scale 命令,一键指定副本数
kubectl scale deploy web --replicas=10
三. 节点污点

节点的属性:

NoSchedult: 一定不被调度,master 默认为此
PreferNodSchedult: 尽量不被调度
NoExecute: 不会调度,并且还会驱逐 Node 已有 Pod
none: 正常调度

查看当前节点污点值
kubectl describe node k8s-master | grep Taints
节点删除污点
kubectl taint node k8s-master node-role.kubernetes.io/master:NoSchedule-
节点设置污点
kubectl taint node k8s-master node-role.kubernetes.io/master=:NoSchedule
四. Pod 调度策略

Pod 的调度策略会影响 Pod 最终被调度到哪些节点上:

预选策略 必须全部满足,比如 node 是否正常,对 pod 依赖的存储卷是否能满足需求
优选策略 会根据启用的函数的得分相加得到评估
高级调度
    Toleration
    Taint
    label
    Affinity 分为软亲和性和硬亲和性
  1. request limits

继续在之前的环境上测试
先删除之前部署的资源
kubectl delete deployment web
然后修改web.yaml的containers字段

containers:
- image: nginx:1.14
name: nginx
resources:
requests:
memory: “3Gi”
limits:
memory: “4Gi”

最后应用
kubectl apply -f web.yaml
2. 节点标签选择器

删除 deployment
kubectl delete deployment web

给节点打标签
kubectl label node k8s-master test23_env=prod

修改web.yaml的containers字段

spec:
hostNetwork: true
containers:
- image: nginx:1.14
name: nginx
resources: {}
nodeSelector:
test123_env: prod

可以发现 Pod 都被调度到了 master 节点,并且节点的污点值的优先级高于标签

删除标签
kubectl label node k8s-master test123_env-
3. 节点亲和性

亲和性和节点选择器类似, 多了操作符:In NotIn Eists Gt Lt DoesNotExists,

软亲和性 preferreDuringSchedulingIgnoredDuringExecution 非必须满足
硬亲和性
requiredDuringSchedulingIgnoredDuringExecution 必须满足

spec:
containers:
- image: nginx:1.14
name: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: test123_env
operator: In
values:
- dev
- test
preferreDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
- matchExpressions:
- key: group
operator: In
values:
- ttttest

五. secret

secret 是包含少量敏感数据(例如密码,令牌或密钥)的对象.不然此类细心就可能会放入 Pod 或容器镜像中.使用 secret 意外着不需要将应用程序代码中包含机密数据.
secret 可以独立于使用它们的 Pod 创建,因此在创建,查看和编辑 Pod 的工作流程中暴露 secret 的风险较小.
Secret 可以通过三种方式于 Pod 一起使用:

作为挂载在一个或多个容器上的卷中的文件
作为容器的环境变量
在为 Pod拉取镜像时有 kubelet 执行
  1. secret 创建方式
    a. 命令行创建

创建名为secret1的 secret 资源

echo -n ‘admin’ > ./username
echo -n ‘123456789’ > ./password
kubectl create secret generic secret1 --from-file=./username --from-file=./password

b.编写 yaml

首先获取 user 和 password 的 base64 编码

echo -n ‘admin’ | base64
echo -n ‘123456789’ | base64

然后编写 yaml 文件

vim secret.yaml

apiVersion: v1
kind: Secret
metadata:
name: secret2
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU2Nzg5

最后使用secret.yaml文件创建
kubectl apply -f secret.yaml

查看指定的 secret 资源信息
kubectl describe secret secret1

查看所有 secret 资源信息
kubectl get secret

查看指定 secret 资源的内容

kubectl get secret secret2 -o jsonpath=‘{.data}’

输出 map[password:MTIzNDU2Nzg5 username:YWRtaW4=]%

echo -n “MTIzNDU2Nzg5” | base64 --decode # 解码

删除创建的 secret 资源
kubectl delete secret secret1
2. secret资源的使用方式
a. 添加到 Pod 的环境变量
b. 以 volume 的形式挂载到 pod
六. ConfigMap

ConfigMap 和 secret 类似但是不需要加密

vim redis.map

redis.ip=127.0.0.1
redis.port=6379
redis.password=123456

执行下面的命令创建一个名为redis-config的 ConfigMap
kubectl create configmap redis-config --from-file=redis.map
七. 存储编排

自动挂载所选存储系统,包括本地存储,网络存储系统.

PV: PersistentVolume, 持久化卷, PV 是存储的抽象,为了使本地磁盘与网络磁盘提供一致的服务.
PVC: PersistentVolumnClaim, 持久化卷声明, PVC 是 PV 的使用者,当底层存储变化了,只需要修改 PV,而不用修改 Pod
  1. 本地存储
    a. 创建 PV

创建一个 PV.yaml 声明的本地存储路径为/data/hostpath

vim PV.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: /data/hostpath

创建 PV 资源
kubectl apply -f PV.yaml
查看已有的 PV 资源
kubectl get pv

这个 pv 的状态为Available,说明还没有被 PVC 绑定,
⚠️注意这里声明的 hostPath 所有节点都有
b.创建 PVC

vim PVC.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi

创建 PVC 资源
kubectl apply -f PVC.yaml
查看
kubectl get pv,pvc
可以发现 pv 的状态变为了 Bound,表示这个 pv已经被绑定,PVC 是由 k8s 查找满足我们声明要求的 PV,然后由它来绑定的.
c. Pod 绑定 PVC

修改之前的 web.yaml的Containers字段

containers:
- image: nginx:1.14
name: nginx
volumeMounts:
- name: myresource
mountPath: /usr/share/nginx/html
volumes:
- name: myresource
persistentVolumeClaim:
claimName: my-pvc

⚠️注意在Pod 所在的 node 的/data/hostpath目录下创建 index.html,不然本地路径替换了原有的路径,里面内容为空.
将 web.yaml中的replica设置为多个后, PV 虽然只有一个.但是与 Pod 的概念类似,与它绑定的 Pod 有 N 个副本,PV就有 N 个副本,且PV 的副本之间的内容可以不一致

我尝试使用 hostNetwork: true,发现这样使得一台 node 只能启动一个 Pod.所以使用 StatefulSet+PV+hostNetwork 就可以部署类似挖矿的程序,

root @ k8s-master in ~ [10:07:19]

$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-84fc5964b5-27hfv 1/1 Running 1 9m35s 192.168.1.21 k8s-master
web-84fc5964b5-j8w24 0/1 CrashLoopBackOff 5 4m51s 192.168.1.21 k8s-master
web-84fc5964b5-n8lzh 1/1 Running 0 9m34s 192.168.1.8 k8s-node1

root @ k8s-master in ~ [10:07:27]

$ curl 192.168.1.21
master hello world

root @ k8s-master in ~ [10:07:34]

$ curl 192.168.1.8
node1 hello world

  1. NFS 存储

    安装 NFS 服务器

安装nfs

yum install -y nfs-utils

创建共享目录

mkdir -p /data/nfs

配置共享目录

cat > /etc/exports <<EOF
/data/nfs *(rw,no_root_squash)
EOF

启动nfs服务

systemctl start nfs

查看服务是否启动成功

ps aux | grep nfs

修改 PV.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
labels:
type: remote
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs: # 声明nfs存储
path: /data/nfs
server: 192.168.108.100

apply 所有

八. 服务发现与负载均衡

扩容后有很多 Pod,访问每个 Pod 的方式都是不同的,如何均匀的访问每一个 Pod(负载均衡),并且当扩容或者缩容的时候能够动态的将Pod添加或者剔除出负载均衡的范围(服务发现).

service 类型介绍(http://dockone.io/article/4884)

k8s 中的 Service用来提供这个服务,service 有 3 种类型

ClusterIp, 集群内部访问(默认)
NodePort: 集群外部访问(包含 ClusterIp)
LoadBalancer: 暴露服务到 internet 的标准方式
Ingress: 它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。

kubectl expose deployment web --port=8080 --target-port=80 --type=NodePort --dry-run -o yaml > service.yaml

expose deployment web 将类型为 deployment 的 web公开为新的k8s服务,
--port: 指定集群内部访问的端口
--target-port: 指定容器本身的端口
--type 表明这个 service 的类型

apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
ports:

  • port: 8080
    protocol: TCP
    targetPort: 80
    selector:
    app: web
    type: NodePort
    status:
    loadBalancer: {}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值