云原生学习笔记

本文最后更新于:2022年12月10日 下午

概述:

记录云原生项目部署中的一些事项,从k8s部署到镜像打包推送(使用docker)

docker

常用指令

运行在虚拟机ubuntu20.04上

1
2
3
4
5
6
# 构建容器镜像,.表示在当前文件夹内,需要先有一个dockerfile
docker build -t getting-started .

# docker run运行docker,-d在后台运行,-p 80:6379,将主机的端口80映射到容器中的端口80
# --name给容命名
docker run -d -p 80:6379 --name redis redis:lastest

更新源码后,需要先删除旧容器,再启动新容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 获取容器的 ID 
docker ps

# 使用docker stop命令停止容器。
# 用docker ps查询的ip更换<the-container-id>
docker stop <the-container-id>

# 容器停止后,使用docker rm命令将其删除
docker rm <the-container-id>

# 将停止和删除命令合并,通过force指令
docker rm -f <the-container-id>

# 启动更新后的容器
docker run -dp 3000:3000 getting-started

使用卷实现持久化数据,更换容器后被存储的数据不会改变

1
2
3
4
5
6
7
# 使用docker volume create命令创建卷
docker volume create todo-db

# 再次停止并删除应用程序容器docker rm -f <id>,因为它仍在运行而不使用持久

# 启动 todo 应用程序容器,添加-v标志以指定卷安装,使用命名卷并将其挂载到/etc/todos,捕获在该路径创建的所有文件
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started

docker compose使用

1
2
3
4
5
# 检查是否安装上
docker compose version

# 启动应用程序栈,-d在后台运行所有内容
docker compose up -d

安装与使用镜像

1. 找镜像。

docker hub找所需的镜像,找不同版本可以点击tag查找所需版本

1
2
3
4
5
6
7
8
9
10
11
12
# 下载最新版本
docker pull nginx

docker pull nginx:1.20.1

# 查看所有镜像
docker images

# 删除镜像
docker rmi 镜像名:版本号/镜像id

docker rm 镜像

2. 启动容器

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用的OPTIONS
# OPTIONS:开机自启
--restart-always
# OPTIONS:端口映射,主机到镜像
-p 88:80

# 查看正在运行的容器
docker ps
# 查看所有
docker ps -a
# 删除停止的容器
docker rm 容器id/名称

3. 进入容器修改内容

1
2
# 进入容器内部
docker exec -it 容器id /bin/bash

4. 提交改变

1
2
3
4
5
# 总命令,,打包成一个镜像,细节使用--help查看
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

# 常用形式
docker commit -a "作者" -m "提交变化" 容器id 自定义名称

5. 远程使用

  • 打包成一个压缩包tar后传输给另一个机器,另一个机器再解压运行即可
    1
    2
    3
    4
    5
    # 打包成一个压缩包tar后传输
    docker save -o 自定义名称 镜像

    # 对压缩包解压运行即可
    docker load -i 上一步定义的名称
  • 推送到远程仓库,需要先docker login登录,并且dockerhub上有自己的仓库(docker logout登出)
    1
    2
    docker tag <local-image:tagname> <new-repo:tagname>
    docker push <new-repo:tagname>

6. 将数据挂载到外部

1
2
3
4
5
6
7
8
9
docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro --restart=always -d nginx
# --name some-nginx 定义名称
# -v /some/content:/usr/share/nginx/html:ro 将/usr/share/nginx/html与主机/some/content目录挂载,且为只读模式
# -d 后台运行
# --restart=always 开机自启

docker run --name my-nginx \
-v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro
-d nginx

挂载一个redis

1
2
3
4
5
6
7
8
docker run -v /data/redis/redis.conf:/etc/redis/redis.conf \
-v /data/redis/data:/data \
-d --name myredis \
-p 6379:6379 \
redis:latest redis-server /etc/redis/redis.conf
# 指令解释
# -v 进行挂载,将本地/data/redis/redis.conf与容器/etc/redis/redis.conf相挂载
# redis-server /etc/redis/redis.conf 启动自定义配置文件,指定配置文件必须是容器内的

7. 杂项

1
2
3
4
5
# 查看日志
docker logs 容器id

# 把容器指定位置的东西复制出来,将命令返回来是将外部复制到容器内
docker cp 容器id:文件绝对路径 外部路径

在docker运行期间操作防火墙需要重启docker
systemctl restart docker

打包并使用镜像

编写Dockerfile,示例如下

1
2
3
4
5
FROM docker pull openjdk:8-jdk-slim
LABEL maintainer=yedeng
COPY target/*.jar /app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

在当前目录下开始打包(必须要有docker环境),打包结束后可以使用docker images查看

1
2
3
docker build -t java-demo:v1.0 .
# -t java-demo:v1.0 表示命名
# . 表示在当前目录下,用于COPY中的路径

设置主机名
hostnamectl set-hostname 自定义名称

kubernetes

部分概念类似于docker,但k8s具有自愈、负载均衡等自动调整的能力

常用指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 验证集群节点状态
kubectl get nodes

# 获取各pod的ip
kubectl get pod -owide

# 查看对pod的描述
kubectl describe pod <pod-name>
kubectl describe pod -n <namespace> <pod-name>

# 应用yaml文件
kubectl apply -f <calico.yaml>

# 取消对yaml文件应用
kubectl delete -f <ingress.yaml>

# 查看集群信息
kubectl cluster-info

可视化工具dashboard

dashboard

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml

安装与使用

安装教程

安装步骤
部署中遇到/proc/sys/net/ipv4/ip_forward为0的问题
解决方法

部署网络组件calico时,应使用获取对应版本(部署使用1.20.9版本)的calico.yaml
curl https://docs.projectcalico.org/v3.20/manifests/calico.yaml -O

部署metrics之后使用kubectl top nodes显示服务不可获取
参考资料

devops中使用apache下载,改为阿里云镜像
在ks-devops-agent配置文件修改MavenSetting

1
2
3
4
5
6
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirrors>

部署

部署:(Deployment)
有状态副本集:中间件(StatefulSet)
守护进程集:(DaemonSet)日志收集

Deployment

通过deployment部署的应用,只有删除deployment才能删除pod(直接删除pod将重启pod)
具有多副本、扩缩容、自愈、故障转移、滚动更新、版本回退能力
命令行部署kubectl create deployment <mytomcat> --image=<tomcat:8.5.68>
查看部署kubectl get deploy

yaml配置部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-dep
name: my-dep
spec:
replicas: 3
selector:
matchLabels:
app: my-dep
template:
metadata:
labels:
app: my-dep
spec:
containers:
- image: nginx
name: nginx

命名空间

获取命名空间kubectl get ns

命令行创建

1
2
kubectl create ns hello
kubectl delete ns hello

通过yaml文件

1
2
3
4
apiVersion: v1
kind: Namespace
metadata:
name: hello

Pod

命令行创建,与docker类似kubectl run mynginx --image=nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看default名称空间的Pod
kubectl get pod
# 描述
kubectl describe pod <pod-name>
# 删除
kubectl delete pod <pod-name> -n <namespace>
# 查看Pod的运行日志
kubectl logs <pod-name>

# 打印更完善的信息
kubectl get pod -owide
# 每个Pod,k8s都会分配一个ip(仅限集群内),使用Pod的ip+pod里面运行容器的端口
curl 192.168.169.136

# 集群中的任意一个机器以及任意的应用都能通过Pod分配的ip来访问这个Pod

访问pod的bash,也可以使用dashboard选择’执行’访问

1
kubectl exec -it <pod-name> -- /bin/bash

通过yaml创建

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
labels:
run: mynginx
name: mynginx
namespace: default
spec:
containers:
- image: nginx
name: mynginx

一个pod两个容器(两个image),一个pod有一个内部ip,多个容器共用这个ip,通过不同的端口区分

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Pod
metadata:
labels:
run: myapp
name: myapp
spec:
containers:
- image: nginx
name: nginx
- image: tomcat:8.5.68
name: tomcat

Service

仅限集群内部访问
获取所有暴露的服务kubectl get service
删除某个servicekubectl delete service <service-name>

选择一次部署,统一部署pod使用的ip(任意)(在集群内的机器上可以通过该方法访问)
也可以在容器内部,使用域名访问,域名为:服务名.命名空间.svc(在机器上无法使用域名访问)

1
2
3
4
5
# 暴露my-dep部署内容,--port是集群内部开放的端口,在集群内使用serviceip:8000即可负载均衡的访问,--target-port是(部署pod的)目标端口,type缺省为ClusterIP
kubectl expose deployment <my-dep> --port=8000 --target-port=80 --type=ClusterIP

#使用标签检索Pod
kubectl get pod -l app=my-dep

暴露服务有两种方式ClusterIP和NodeIP

ClusterIP

NodePort

集群外部可访问

nodeport在每个集群都会开放一个端口,开放的端口范围在30000-32767,可访问任意一台机器的ip:对应端口

1
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort

通过yaml文件暴露端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
labels:
app: my-dep
name: my-dep
spec:
ports:
- port: 8000
protocol: TCP
targetPort: 80
selector:
app: my-dep
type: NodePort

Ingress

相当于网关层
查看规则kubectl get ingress可简写为kubectl get ing
修改规则kubectl edit ing <name>

配置通过域名访问服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-host-bar
spec:
ingressClassName: nginx
rules:
- host: "hello.atguigu.com"
http:
paths:
- pathType: Prefix # 以"hello.atguigu.com"作为前缀的所有请求发给hello-server服务(即hello.atguigu.com/的所有请求)
path: "/"
backend:
service:
name: hello-server
port:
number: 8000

存储持久化

NFS

一个文件系统
实现k8s主从节点共享
在k8s的主节点运行

1
2
3
4
5
6
7
8
9
10
#nfs主节点,将/ngs/data作为共享文件夹暴露
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

mkdir -p /nfs/data
# 启用rpc远程绑定
systemctl enable rpcbind --now
# 启动nfs服务器
systemctl enable nfs-server --now
#配置生效
exportfs -r

删除部署之后,文件系统内的东西不会自动清理

将部署中的/usr/share/nginx/html路径下内容挂载到/nfs/data/nginx-pv(nfs路径,需要装好nfs文件系统)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-pv-demo
name: nginx-pv-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pv-demo
template:
metadata:
labels:
app: nginx-pv-demo
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
server: 172.31.0.4
path: /nfs/data/nginx-pv

PV&PVC

PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格
二者配合使用,能够为应用分配指定大小空间;当pod删除时,其对应的存储空间也会删除

静态供应创建好PV池,申请时在内部选择
查看创建的pv池kubectl get pv
创建PV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# capacity.storage限定大小10M,
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01-100m
spec:
capacity:
storage: 100M
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/01
server: 10.0.4.17
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02-3gi
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/02
server: 10.0.4.17
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv03-5gi
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/03
server: 10.0.4.17

PVC相当于申请书,用于申请空间
动态供应申请时自动创建PV

ConfigMap

配置统一管理

将redis.conf文件制作为configmap

1
kubectl create cm redis-conf --from-file=redis.conf

以上指令等价于一下yaml

1
2
3
4
5
6
7
8
apiVersion: v1
data: #data是所有真正的数据,key:默认是文件名 value:配置文件的内容
redis.conf: |
appendonly yes
kind: ConfigMap
metadata:
name: redis-conf #定义配置名
namespace: default

在部署redis时使用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
command:
- redis-server
- "/redis-master/redis.conf" #指的是redis容器内部的位置
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /data # /data中的内容以data形式挂载,对应volume中name为data的挂载方式
name: data
- mountPath: /redis-master # 挂载路径,名为config
name: config
volumes:
- name: data
emptyDir: {}
- name: config # 配置名为config的挂载方式
configMap:
name: redis-conf # 名为redis-conf的配置集
items: # 获取data中的对应项目
- key: redis.conf # 取出key值放在path(redis内部的)下
path: redis.conf

Secret

用于保存敏感信息

查看kubectl get secret

1
2
3
4
kubectl create secret docker-registry leifengyang-docker \
--docker-username=leifengyang \
--docker-password=Lfy123456 \
--docker-email=534096094@qq.com

使用保存的secret下载镜像yaml

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: private-nginx
spec:
containers:
- name: private-nginx
image: leifengyang/guignginx:v1.0
imagePullSecrets:
- name: leifengyang-docker

云原生学习笔记
https://danmoliuhen.github.io./2022/09/26/云原生学习笔记/
作者
CaiYe
发布于
2022年9月26日
许可协议