全栈工程师开发手册 (作者:栾鹏)
架构系列文章 <https://blog.csdn.net/luanpeng825485697/article/details/83830968>

首先我们需要在本地docker中调试运行一遍,再发布到k8s上去。

如果需要在本地部署k8s环境,可以使用mimnikube,参考:
https://blog.csdn.net/luanpeng825485697/article/details/80862581
<https://blog.csdn.net/luanpeng825485697/article/details/80862581>

<>拉取公用镜像

如果在docker拉取公用镜像,例如拉取redis和mysql
拉取mysql和redis镜像 docker pull mysql docker pull redis
<>将本地应用制作成镜像

将应用制作成docker镜像,需要我们编写dockerfile文件.

可以参考https://blog.csdn.net/luanpeng825485697/article/details/80921390

编写好dockerfile以后,我们将应用制作成镜像
docker build -t images_name -f dockerfilepath .
上面这句话images_name是自己指定的镜像的名称
dockerfilepath是dockerfile文件的相对路径,最后面的.是当前目录.在dacokerfile文件中就是以最后的这个.代表的路径作为上下文路径的

<>运行公用镜像

还是以redis和mysql为例
docker run -p 3306:3306 --name mysql_container -v $PWD/conf:/etc/mysql/conf.d
-v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d
mysql docker run -p 6379:6379 --name redis_container -v $PWD/data:/data -d
redis redis-server --appendonly yes
上面的语句直接运行镜像,通过命令设置了端口号,容器名称,设置了挂载和部分参数设置.

其中我们也可以看出,对于数据库镜像,我们要将容器的数据文件挂载成本地的.这样容器重启后数据也还在本地.

<>运行自定义镜像

根据构建的镜像启动容器
docker run --name container_name -p 8881:8881 -d image_name # 容器名 镜像名 映射端口
这样就能按照镜像来启动容器了. 命令中端口映射前面是主机端口,后面是容器环境的端口.
只有绑定了才能将主机端口的信息送达到容器的端口,容器才能从自己的端口处得到信息.

当然也可以启动,停止,删除容器
docker ps -a 查看容器 docker stop container_id 停止容器,但是不删除 docker start contain_id
启动停止的容器 docker rm contain_id 删除容器

这个需要注意的是在docker中,容器启动后,再关闭容器中的内容是会保存的,所以启动一个已经关闭的容器,会在上一次运行以后的结果下再运行.但是这些结果不会保存到镜像中,如果我们将容器删了,再重新根据镜像启动容器,那会是一个原始的容器.

而在k8s中,容器一但关闭,就彻底删除,不可能保留上一次的结果.

<>进入容器进行调试

上面我们已经学习了一种启动模型
docker run --name container_name -p 8881:8881 -d image_name # 容器名 镜像名 映射端口
启动-d表示后台运行的意思.
当然也可以以交互的方式启动容器
docker run --name container_name -p 8881:8881 -it image_name /bin/bash
这种启动方式,启动后就自动进入容器内部命令行,不过这种启动方式,在退出容器后会,容器会自动关闭.

所以建议还是以-d后台启动的形式启动容器,然后我们再进入正在运行的容器中
docker ps -a 查看所有的容器 docker exec -it container_id /bin/bash   根据容器id进入容器
这样就可以进入一个正在运行的容器,做相关修改

<>容器内部修改

容器内部是一个非常简单的环境,所以不会像我们的电脑包含很多工具。

容器应用配置文件问题

比如最简单的vim都没有,所以你会发现很多命令没法用了。我们想编辑文件,可能就需要安装一下vim
apt-get update apt-get install vim
但是只要安装了就会增大容器的大小,而且安装的内容并不经常运行,所以我们也可以经本地的文件修改,复制到容器中
docker cp xxx.txt container_id:/xxx/xxx/xxxx
不过这种方法也过于繁琐,所以最好的办法还是通过主机和容器建共享目录。在本机上和容器中使用同一个共享文件。

应用初始化问题

有些应用第一次运行是需要初始化的,比如mysql,我们要创建数据库,这些数据库和数据表创建以后会保存到共享文件中。

比如下面是一个初始化mysql的命令
docker exec进入正在运行的mysql容器 配置mysql 初始化设置mysql数据库 mysql -u root -p 密码123456
创建数据库 create database database_name 然后运行本地初始化脚本 或者直接 use database_name; create
table table_name(face_id varchar(64),age int,gender tinyint, handle_time int,
vip tinyint,face_group char(64),face_info char(64),save_path char(64) not null,
reg_path char(64));
下面就可以在本机模拟客户端进行调试运行,查看每个容器的运行,查看配置文件该怎么写。以便放在k8s上能正常运行。

当我们成功在docker中成功跑通了我们的所有应用,并修正了所有的问题后,build了最近的镜像。下面我们来在k8s上运行应用

<>将本地docker镜像上传到服务器docker镜像中

我们需要先将本地docker镜像save到本地压缩文件
docker save -o image_name.tar image_name
再通过其他方式上传到服务器,比如ssh的scp方式
scp image_name.tar xxx@192.168.1.11:/home/xxx/
然后登录服务器,在服务器的docker中加载镜像压缩文件
docker load -i image_name.tar
这样本地的docker中的镜像就到了服务器的docker镜像中,下面需要将docker中的镜像推送到服务器私有仓库的镜像中

<>在服务器的docker中创建私有仓库

这一步操作是管理员做的事情。我们需要先在docker中创建私有仓库,再将k8s指定到docker的私有仓库。这样k8s才能使用私有仓库

1.master主机的docker先从公有仓库下载registry 镜像
docker pull registry
2.master主机的docker启动镜像
docker run -d -p 5000:5000 --restart=always --privileged --name
registry-container -v /root/docker/my_registry:/var/lib/registry registry
添加挂载使得本地/root/docker/my_registry用来存放私有仓库的镜像,这样容器重启镜像也不会删除。

3.master主机上修改每个结点的docker配置文件,用来将docker绑定到私有仓库


网络上有些教程,修改/etc/sysconfig/docker这个配置文件。但是这些教程对应的docker版本比较老,所以不要使用这些教程。新版本的docker使用下面的命令
vi /lib/systemd/system/docker.service 添加或修改 ExecStart=/usr/bin/dockerd -H
fd:// --insecure-registry=192.168.42.58:5000
如果不配置上面的情况会出现https错误

重启docker
systemctl daemon-reload systemctl restart docker service docker stop
关闭docker服务 service docker start 启动docker服务
上面的教程是使docker能正常拉取私有仓库镜像


我们平时基本把镜像部署在k8s中,所以k8s绑定docker私有仓库镜像也需要对k8s进行设置,以避免https错误,当然如果你的版本正确,是不会出现https错误,那样也就不需要修改配置文件。

根据k8s文件版本不同,也需要修改k8s的配置文件kube-apiserver文件,也是要添加
--insecure-registry=192.168.42.58:5000
不过每种格式的书写格式可能不同。

如果是minikube也可以设置insecure-registry。根据版本不同包含向量两种写法
minikube start --insecure-registry=192.168.42.58:5000 但是如果你已经‘minikube
start’过,那必须先: minikube delete 或者 minikube start --insecure-registry
"192.168.42.58:5000" 我的版本比较新,这种成功的
如果你觉的在服务器上搭建私有仓库麻烦,你可以在docker-hub上申请私有仓库,那样就不需要修改配置文件了。

<>为私有仓库配置登录账号密码

如果想要控制registry的使用权限,使其只有在登录用户名和密码之后才能使用的话,还需要做额外的设置。如果只是调试那就不需要太多的控制,可以忽略这一步。
先创建存储账号密码的地方 mkdir /data/docker-registry-auth/
创建账号密码
docker run --entrypoint htpasswd registry:latest -Bbn username password >
/data/docker-registry-auth/htpasswd 例如 docker run --entrypoint htpasswd
registry:latest -Bbn luanpeng 123456 > /data/docker-registry-auth/htpasswd

上面这条命令是为luanpeng用户名生成密码为123456的一条用户信息,存在/data/docker-registry-auth/htpasswd文件里面,文件中存的密码是被加密过的。

此容器启动后会自动停止。

检查下htpasswd是否已经被创建:
$ cat /data/docker-registry-auth/htpasswd
luanpeng:$2y$05$WcUjExtIbG4w1.viDLYxQeo65dUzVeN80YWHwuIpWHTwDIjXRnJIS
使用带用户权限的registry时候,容器的启动命令就跟上面不一样了,将之前的容器停掉并删除,然后执行下面的命令:
docker run -d -p 5000:5000 --restart=always --name registry-container -v
/data/docker-registry-auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e
"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e
REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v
/root/docker/my_registry:/var/lib/registry registry:latest
上面的命令添加了配置文件的映射,又添加了镜像存储地方的映射

带有用户权限的registry启动以后,如果直接想查看仓库信息、pull或push都会出现权限报错,必须先登录
sudo docker login --username=luanpeng 192.168.42.58:5000 # 登录 docker pull
192.168.42.58:5000/images_name:latest
将镜像推送到带有访问权限的私有仓库也是一样
sudo docker login --username=yourusername 192.168.42.58:5000 $ sudo docker tag
[ImageId] 192.168.42.58:5000/images_name:[镜像版本号] $ sudo docker push
192.168.42.58:5000/images_name:[镜像版本号]
根据提示,输入用户名和密码即可。如果登录成功,会在/root/.docker/config.json文件中保存账户信息,这样就可以继续使用了。
上传以后可以查看
curl http://192.168.42.58:5000/v2/_catalog 查看私有仓库里面的镜像 curl
http://192.168.42.58:5000/v2/imagename/tags/list 查看私有仓库里面的镜像的版本
(下面是阿里云私有镜像)
sudo docker login --username=yourusername registry.cn-shenzhen.aliyuncs.com $
sudo docker tag [ImageId]
registry.cn-shenzhen.aliyuncs.com/haibincoder/centos:[镜像版本号] $ sudo docker push
registry.cn-shenzhen.aliyuncs.com/haibincoder/centos:[镜像版本号]
如果是minikube启动的单机效果可以不用设置账号密码。

直接使用
docker login localhost:5000 就可以登录了,账号密码就是电脑账号密码
为k8s集群创建Secret

启动私有仓库账号密码权限以后,k8s链接私有仓库就需要账号密码了。
kubectl delete secret your-registr-name 删除旧的或错的秘钥,当然也可以不删除 kubectl create
secret docker-registry lpsecret --docker-server=192.168.42.58:5000
--docker-username=luanpeng --docker-password=123456
--docker-email=825485697@qq.com -n kube-system
使用命令方式创建邮箱为必选参数,老版本可能不是必填项

注意: -n your-namespaces
为指定命名空间,需要自己先创建命名空间,(后面的教程包含创建命名空间)一般搭建k8s集群时,建议新建一个命名空间来隔离资源。

your-registr-name为你为保密字典定义的名称。为后面的yaml中就要填写这个秘钥的形成
spec: imagePullSecrets: - name: your_registr_name containers: - name:
your-container # 容器名称 image: 192.168.42.201:5000/your_images:1.0 # 基于的镜像名,
根据镜像创建容器
创建以后你就可以在k8s的dashboard中保密字典类目看到你创建的秘钥

如果没有dashboard可以通过下面的命令查看
kubectl get secret -n your-namespaces
在k8s中拉取私有仓库的镜像有时也会报错https错误,这个时候就需要修改k8s的配置文件

<>将本地docker镜像推送到私有仓库中

要想在k8s中拉取镜像,必须按照上面的教程,为k8s绑定私有仓库服务器,并配置私有仓库提供的账号密码。

对于有权限限制的docker私有仓库,我们要先使用docker login进行登录
sudo docker login --username=yourusername 192.168.42.58:5000 docker tag
image_name:latest 192.168.42.58:5000/image_name:latest #在docker镜像标记为私有仓库的镜像
docker push 192.168.42.58:5000/image_name:latest # 将本地镜像push到私有仓库
如果出现下面类似的错误,说明使用的是https,需要按上面的教程修改docker配置文件
v1 ping attempt failed with error: Get https://192.168.174.128:5000/v1/_ping:
http: server gave HTTP response to HTTPS client
如果tag错了,想要删除的话需要
关闭容器后 docker rmi 192.168.42.58:5000/image_name 先根据名称删除,删除tag docker rmi
1c8ea16890a8 再根据镜像id删除,删除镜像
查看仓库里面情况
curl http://192.168.42.58:5000/v2/_catalog 查看私有仓库里面的镜像 curl
http://192.168.42.58:5000/v2/imagename/tags/list 查看私有仓库里面的镜像的版本 curl
http://192.168.42.58:5000/v2/imagename/manifests/tag (镜像每一层的哈希值(digest))
推送到私有仓库以后,自定义镜像便有了镜像地址。在后面编写yaml文件时,需要使用私有仓库镜像的地址

若在将镜像推送到私有仓库时,有错误类似Get https://192.168.42.58:5000/v1/_ping:
<https://192.168.42.58:5000/v1/_ping:> http: server gave HTTP response to HTTPS
client

修改/etc/docker/daemon.json文件,写入:
{ "registry-mirrors": ["http://hub-mirror.c.163.com"] } {
"insecure-registries":["192.168.42.58:5000"] }
或者修改
vi /lib/systemd/system/docker.service 添加或修改 ExecStart=/usr/bin/dockerd -H
fd:// --insecure-registry=192.168.42.58:5000
或者修改

/etc/init/docker.conf,在其中增加--insecure-registry 192.168.112.136:5000



由于各个版本不一样,所以修改的地方就不一样

//重启docker

service docker restart

<>本地控制服务器k8s

k8s的控制是通过~/.kube/config文件来实现的。

所以我们只需要将服务器上/.kube/config的文件内容拷贝到本地pc机器上的
/.kube/config就可以通过kubectl来控制服务器上的k8s的资源了。

如果本地使用monikube调试,
/.kube/config文件必须删除以后,monikube才能重新创建config文件,不会自动修改config。所以如果我们当前想通过minikube调试,就将
/.kube/config文件删除,再启动minikube start,如果想控制远程服务器的k8s,就修改/.kube/config为远程服务器的
/.kube/config内容。

<>学习yaml文件语法

yaml文件的语法格式可以参考:
https://blog.csdn.net/luanpeng825485697/article/details/79478338
<https://blog.csdn.net/luanpeng825485697/article/details/79478338>

当然,如果你已经学过了或者你有现成的yaml文件demo可以直接跳过

<>在k8s上创建空间

创建文件create_namespace.yaml
apiVersion: v1 kind: Namespace metadata: name: luanpeng labels: name: luanpeng
在当前目录下运行
kubectl create -f create_namespace.yaml
就可以在kubectl链接的k8s上创建命名空间luanpeng这个空间了。以后设置资源都可以在这个空间中设置

<>创建服务

这里我们以创建service服务为例,分别以私有镜像和共有镜像为例。

<>使用公有镜像创建容器

使用公有镜像创建容器,比如我们使用官方最新版的mysql来创建服务。


如果我们创建的是共有镜像,我们就不需要前面介绍的那些build镜像,上传,加载等一系列操作。只需要编写yaml文件。系统会自动从官方拉取镜像。不过要保障官方有此版本的镜像文件。

创建mysql.yaml文件
--- --- apiVersion: v1 kind: Service metadata: name: mysql-service namespace:
luanpeng labels: app: mysql-service spec: type: NodePort ports: - port: 3306
targetPort: 3306 protocol: TCP name: http selector: app: mysql-deployment ---
apiVersion: apps/v1 kind: Deployment metadata: name: mysql-deployment
namespace: luanpeng spec: selector: matchLabels: app: mysql-pod replicas: 1
template: metadata: labels: app: mysql-pod spec: nodeName: node1 #
使用nodeName可以指定运行节点 volumes: - name: mysql-data hostPath: path: /mysql/data -
name: mysql-log hostPath: path: /mysql/log - name: mysql-conf hostPath: path:
/mysql/conf containers: - name: mysql-container image: mysql:5.6 #
最新版本的不能进行划分数据卷 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD
value: introcks volumeMounts: - name: mysql-data mountPath: /var/lib/mysql -
name: mysql-log mountPath: /logs - name: mysql-conf mountPath: /etc/mysql/conf.d

上面的yaml文件中,我们创建了一个mysql服务,服务下包含一个deployment,deployment下包含一个pod,一个pod下面启动一个container

使用kubectl创建镜像
kubectl create -f mysql.yaml
启动以后我们可以在k8s的dashboard中查看运行情况,如果报错,我们可以先关闭服务,然后根据提示解决问题
kubectl delete -f mysql.yaml
启动mysql的容器后,

我们进入容器
kubectl get pods -n luanpeng # 查看指定空间下的pod kubectl exec
mysql-deployment-db9bc9f9c-5cdpq -it -n luanpeng /bin/bash # 进入指定容器
对数据库进行初始化
初始化设置mysql数据库 mysql -u root -p 密码xxxxx 创建数据库 create database yourdatabase;
然后运行本地初始化脚本 或者直接 use yourdatabase; create table yourtable(face_id
varchar(64),age int,gender tinyint, handle_time int, vip tinyint,face_group
char(64),face_info char(64),save_path char(64) not null, reg_path char(64));
desc yourtable; 查看表结构
这样就完成了创建,由于使用了共享卷,所以pod重启以后数据库结构信息仍然存在

<>使用私有仓库拉取镜像创建容器

对于公司内部的项目, 我们不可能使用公有开放的镜像仓库, 一般情况可能会花钱买 docker私仓服务, 或者说自己在服务器上搭建自己的私仓, 但不管怎样,
我们如何让k8s能够拉取私有仓库的镜像

自己的服务器创建私有仓库


如果在自己服务器上创建私有仓库。则直接在yaml中输入192.168.xx.xx:5000/imagesname:1.0这种镜像地址,然后输入拉取秘钥就可以拉取成功。
.... spec: imagePullSecrets: - name: registry-key containers: - name:
your-container # 容器名称 image: 192.168.42.201:5000/your-images:1.0 # 基于的镜像名,
根据镜像创建容器 .....
使用阿里云提供的私有仓库

1、登录docker镜像仓库

这里以阿里云docker镜像仓库为例
docker login --username=yin32167@aliyun.com registry.cn-hangzhou.aliyuncs.com
之后输入密码就可以了, 这个时候我们可以在配置文件中查看登录情况
cat ~/.docker/config.json
这个时候我们虽然可以通过docker pull命令拉取镜像, 但无法通过k8s创建pod方式拉取

2、生成密钥secret
kubectl create secret docker-registry regsecret
--docker-server=registry.cn-hangzhou.aliyuncs.com
--docker-username=yin32167@aliyun.com --docker-password=xxxxxx
--docker-email=yin32167@aliyun.com 其中: regsecret: 指定密钥的键名称, 可自行定义
--docker-server: 指定docker仓库地址 --docker-username: 指定docker仓库账号
--docker-password: 指定docker仓库密码 --docker-email: 指定邮件地址(选填)
可以看到当前除了默认的密钥, 还有我们刚才生成的. 另外要注意的是, 该密钥只能在对应namespace使用, 也就是这里的default,
如果需要用到其他namespace, 比如说test, 就需要在生成的时候指定参数 -n test

3、 yml文件加入密钥参数
containers: - name: channel image:
registry-internal.cn-hangzhou.aliyuncs.com/yin32167/channel:dev-1.0 ports: -
containerPort: 8114 imagePullSecrets: - name: regsecret
其中imagePullSecrets是声明拉取镜像时需要指定密钥, regsecret 必须和上面生成密钥的键名一致,
另外检查一下pod和密钥是否在同一个namespace, 之后k8s便可以拉取镜像

<>配置文件

配置文件一般我们包含在应用中,而入股打包成镜像以后,配置文件就不能再修改了,所以我们有集中方式来实现配置文件。

1、设置挂载,我们可以将配置文件的目录挂载成主机地址或网络地址。


在第一次创建pod时,不要让pod包含任何启动命令,然后进入pod,里面的配置文件是空的,因为容器中配置文件的目录,其实是主机的目录,而这个目录可能都不存在。在容器中,进入配置文件目录,添加配置文件,或修改配置文件。当然也可以通过kubectl
cp直接复制到容器指定目录下。这样容器的配置文件目录下就有了配置文件,其实这个配置文件是存储在服务器主机或者网络上的(因为这个目录是通过挂载添加到容器的)。然后删除这个服务(或者pod),重新创建一个服务(pod),这个pod是带有启动命令的。并且也添加了挂载。这个pod启动后就能正常读取配置文件了。

2、通过k8s的configmap实现。

configmap是k8s环境下的配置文件。跟secret一样。通过命令创建存储在k8s中。pod可以绑定configmap来读取配置。

通过命令行创建configmap
kubectl create configmap lykops-config
--from-file=db_config_file=database.conf --from-file=ver.conf
--from-literal=username=test --from-literal=hostname=localhost

–from-file表示来自文件,直接把文件内容写入configmap中,可以为目录也可以为文件,如果是文件的话,可以使用db_config_file=database.conf来修改key值
–from-literal表示使用键值对配置

通过yaml文件创建configmap
kubectl delete -f lykops-config.yaml cat << EOF > lykops-config.yaml kind:
ConfigMap apiVersion: v1 metadata: name: lykops-config namespace: default
labels: software: apache project: lykops app: configmap version: v1 data: PWD:
/ user: lykops mysql.config : |- username: lykops host: localhost port: 3306
EOF kubectl create -f lykops-config.yaml
ata就是配置变量:
PWD和user两行就是两个环境变量属性
mysql.config : |-就是配置文件,下面的内容是配置文件mysql.config内容

使用ConfigMap

两种方式让pod使用,第一种是环境变量或参数,第二种是文件挂载。
cat << EOF > lykops-cm-pod.yaml apiVersion: v1 kind: Pod metadata: name:
lykops-cm-pod labels: project: lykops app: lykops-cm version: v1 spec:
containers: - name: lykops-cm-pod image: web:apache command: ['sh',/etc/run.sh]
env: - name: SPECIAL_USER valueFrom: configMapKeyRef: name: lykops-config key:
username resources: requests: cpu: 0.01 memory: 8Mi limits: cpu: 0.1 memory:
16Mi volumeMounts: - name: config-volume mountPath: /data/ volumes: - name:
config-volume configMap: name: lykops-config EOF kubectl create -f
lykops-cm-pod.yaml

当ConfigMap以数据卷的形式挂载进Pod时,更新ConfigMap(或删掉重建ConfigMap),Pod内挂载的配置信息会热更新,但使用环境变量方式加载到pod,则不会自动更新。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信