Kubernetes使用ConfigMap配置应用程序(二)

上一篇学习了通过args方式还是env方式都是将配置应用,配置参数硬编码在POD配置文件中,实际应用部署的过程中,我们希望配置参数和POD配置能够解藕,今天我们就看一下如何用ConfigMap配置应用。

创建一个ConfigMap

  • 使用命令行创建
1
kubectl create configmap fortune-configmap --from-literal=sleep-interval=60

创建成功以后可以通过kubectl命令查询configmap的配置。

kubectl get configmap fortune-configmap -o yaml 查询结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
data:
sleep-interval: "60"
kind: ConfigMap
metadata:
creationTimestamp: "2020-09-29T12:29:40Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:sleep-interval: {}
manager: kubectl-create
operation: Update
time: "2020-09-29T12:29:40Z"
name: fortune-configmap
namespace: default
resourceVersion: "2434"
selfLink: /api/v1/namespaces/default/configmaps/fortune-configmap
uid: a6562e65-1431-47b1-b153-e4c270561a2c
  • 使用yaml文件创建

上述查询到信息将metadata中只保留名称就可以创建一个简单的ConfigMap配置文件,使用如下命令即可通过文件创建ConfigMap kubectl create -f fortune-congfigmap.yaml

在POD文件中使用CongfigMap配置应用

  • 使用环境变量配置应用 修改POD配置文件,使用ConfigMap配置env参数
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
43
44
45
apiVersion: v1
kind: Pod
metadata:
name: fortune-env
labels:
app: fortune-env
spec:
containers:
- name: html-gen
image: 172.17.0.1:5000/fortune:env
env:
- name: INTERVAL
valueFrom:
configMapKeyRef:
name: fortune-configmap
key: sleep-interval
volumeMounts:
- name: html
mountPath: /var/htdocs
- name: log
mountPath: /var/log/fortune
- name: web-server
image: 172.17.0.1:500/nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
- name: log-server
image: 172.17.0.1:5000/nginx:log
volumeMounts:
- name: log
mountPath: /usr/share/nginx/log
readOnly: true
ports:
- containerPort: 8080
protocol: TCP
volumes:
- name: html
emptyDir: {}
- name: log
emptyDir: {}

重新创建PODkubectl create -f fortune-pod-env.yaml, 此时再查询fortune每个60秒更新一次。实际应用部署时,也可以修改ConfigMap的配置,当新新建POD时会使用新的ConfigMap值。

  • 使用参数配置应用

和使用环境变量配置POD类似,修改POD配置文件,使用ConfigMap配置args参数

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
43
44
45
46
apiVersion: v1
kind: Pod
metadata:
name: fortune-args
labels:
app: fortune-args
spec:
containers:
- name: html-gen
image: 172.17.0.1:5000/fortune:args
env:
- name: INTERVAL
valueFrom:
configMapKeyRef:
name: fortune-configmap
key: sleep-interval
args: [$(INTERVAL)]
volumeMounts:
- name: html
mountPath: /var/htdocs
- name: log
mountPath: /var/log/fortune
- name: web-server
image: 172.17.0.1:500/nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
- name: log-server
image: 172.17.0.1:5000/nginx:log
volumeMounts:
- name: log
mountPath: /usr/share/nginx/log
readOnly: true
ports:
- containerPort: 8080
protocol: TCP
volumes:
- name: html
emptyDir: {}
- name: log
emptyDir: {}

创建PODkubectl create -f fortune-pod-args.yaml, 此时查询fortune每个60秒更新一次。

此时,如果删除旧的ConfigMap,重新配置一个新的ConfigMap,再同时删除frotune-env pod和fortune-args pod并重新新建POD时会使用新的ConfigMap值。

ConfigMap可以配置的资源

从文件、文件夹和字符创建的ConfigMap

Kubernetes使用ConfigMap配置应用程序(一)

传统的应用程序在部署时往往需要通过命令行参数、环境变量、配置文件等方式配置应用程序。Kubernetes应用程序可以通过ConfigMap和Secret来配置应用程序。ConfigMap和Secret的区别主要是Secret用于敏感数据配置,数据在Kubernetes中是加密存储的。

选择ConfigMap和Secret的原则比较简单:

  • 非敏感数据则使用ConfigMap配置;
  • 敏感数据使用Secret配置;
  • 如果既有敏感数据又有非敏感数据则使用Secret配置。

ConfigMap和Secret使用方式类似,这里主要描述ConfigMap的使用方式。

这次还是以fortune应用程序为例,通过ConfigMap向fortune传递参数调整程序刷新的时间间隔。首先我看一下不借助ConfigMap我们如何通过命令参数和环境变量配置应用。

1.使用命令参数配置应用

修改fortune镜像,增加间隔参数

  • 修改fortuneloop.sh,增加间隔参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#! /bin/bash
trap "exit" SIGINT
INTERVAL=$1

mkdir /var/htdocs
mkdir /var/fortune

echo Configured to generate new fortune every $INTERVAL seconds.

while :
do
echo $(date) writing fortune to /var/htdocs/index.html >> /var/log/fortune/$(date +%Y-%m-%d).log
/usr/games/fortune > /var/htdocs/index.html

sleep $INTERVAL
done
  • 修改Dockerfile增加默认参数
1
2
3
4
5
6
FROM ubuntu:latest
RUN apt update ; apt install -y fortune
ADD fortuneloop.sh /bin/fortuneloop.sh

ENTRYPOINT ["/bin/fortuneloop.sh"]
CMD ["10"]

重新制作镜像:docker build -t 172.17.0.1:5000/fortune:args .,并推送本地镜像仓库

  • 本地运行镜像测试
1
2
docker run --name fortune-args -it 172.17.0.1:5000/fortune:args 15
Configured to generate new fortune every 15 seconds.

在POD中使用args覆盖容器参数

  • 修改POD配置文件
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
apiVersion: v1
kind: Pod
metadata:
name: fortune
labels:
app: fortune
spec:
containers:
- name: html-gen
image: 172.17.0.1:5000/fortune:args
args: ["30"]
volumeMounts:
- name: html
mountPath: /var/htdocs
- name: log
mountPath: /var/log/fortune
- name: web-server
image: 172.17.0.1:500/nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
- name: log-server
image: 172.17.0.1:5000/nginx:log
volumeMounts:
- name: log
mountPath: /usr/share/nginx/log
readOnly: true
ports:
- containerPort: 8080
protocol: TCP
volumes:
- name: html
emptyDir: {}
- name: log
emptyDir: {}

这样重新创建POD即可看到应用参数更新成"30"秒。

2.使用环境变量配置应用

修改fortune镜像,增加间隔环境变量

  • 修改fortuneloop.sh,使用INTERVAL代替默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /bin/bash
trap "exit" SIGINT
mkdir /var/htdocs
mkdir /var/fortune

echo Configured to generate new fortune every $INTERVAL seconds.

while :
do
echo $(date) writing fortune to /var/htdocs/index.html >> /var/log/fortune/$(date +%Y-%m-%d).log
/usr/games/fortune > /var/htdocs/index.html

sleep $INTERVAL
done
  • 修改Dockerfile增加默认参数
1
2
3
4
5
FROM ubuntu:latest
RUN apt update ; apt install -y fortune
ADD fortuneloop.sh /bin/fortuneloop.sh

ENTRYPOINT ["/bin/fortuneloop.sh"]

重新制作镜像:docker build -t 172.17.0.1:5000/fortune:env .,并推送本地镜像仓库

在POD中使用env覆盖容器参数

  • 修改POD配置文件
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
apiVersion: v1
kind: Pod
metadata:
name: fortune
labels:
app: fortune
spec:
containers:
- name: html-gen
image: 172.17.0.1:5000/fortune:env
env:
- name: INTERVAL
value: "45"
volumeMounts:
- name: html
mountPath: /var/htdocs
- name: log
mountPath: /var/log/fortune
- name: web-server
image: 172.17.0.1:500/nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
- name: log-server
image: 172.17.0.1:5000/nginx:log
volumeMounts:
- name: log
mountPath: /usr/share/nginx/log
readOnly: true
ports:
- containerPort: 8080
protocol: TCP
volumes:
- name: html
emptyDir: {}
- name: log
emptyDir: {}

这样重新创建POD即可看到应用参数更新成"45"秒。

上述两种方式,无论时通过args方式还是env方式都是将配置参数硬编码在POD配置文件中。实际应用部署的过程中,我们希望配置参数和POD配置能够解藕,这个就需要用到Kubernetes提供的ConfigMap来实现。

修改docker hub上的官方镜像

之前一直有个疑问,如果要在同一个Kubernetes的POD中部署两个系统镜像的容器,两个容器岂不是会有资源(网络端口号,文件等)冲突。在尝试在Kubernetes挂载不同的存储时就遇到同一个nginx镜像部署在同一个POD中,第二个POD始终失败的问题,查看日志也提示尝试多次终止了容器。猜测应该是在同一个POD中端口冲突导致第二个容器启动失败,于是修改官方nginx镜像的端口号成功在一个POD中启动了两个nginx容器。

具体操作如下:

从dokcer hub官方下载nginx:alpine镜像

docker pull nginx:alpine

查看镜像中的默认配置

1
2
docker run -it --name nginx  nginx:alpine /bin/sh
cat /etc/nginx/nginx.conf

修改官方镜像

  • 根据官方镜像修改端口号及默认目录
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
43
44
45
46
47
48
49
50
51
52
53
user  nginx;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

server {
listen 8080;
listen [::]:8080;
server_name localhost;

#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;

location / {
root /usr/share/nginx/log;
# index index.html index.htm;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

}
  • 新的dockerfile
1
2
3
4
FROM nginx:alpine
RUN mkdir -p /usr/share/nginx/log
ADD index.html /usr/share/nginx/log/index.html
COPY nginx.conf /etc/nginx/nginx.conf
  • 构建新的镜像

docker build -t nginx:log .

本地测试成功以后就可以推送到自己的镜像仓库了:)。

Kubernetes挂载存储

示例说明

为演示在Kubernetes挂载存储以下面为例:

  • fortune进程 利用fortune游戏每10秒钟更新一次html文档;并将更新过程钟写入日志。

  • web-server进程 使用nginx作为web服务器向外提供服务,客户展示fortune生成的html文件。

  • log-server进程 使用nginx作为服务器向外提供服务,可以查询fortune日志。

分别将上述进程部署到不同的容器中,容器间通过挂载emptyDir卷共享信息。

测试代码

  • fortune程序
1
2
3
4
5
6
7
8
9
10
11
12
#! /bin/bash
trap "exit" SIGINT
mkdir /var/htdocs
mkdir /var/fortune

while :
do
echo $(date) writing fortune to /var/htdocs/index.html >> /var/log/fortune/$(date +%Y-%m-%d).log
/usr/games/fortune > /var/htdocs/index.html

sleep 10
done

每10秒钟生成一次html文件,并记录生成日志

  • fortune的dockerfile
1
2
3
4
5
FROM ubuntu:latest
RUN apt update ; apt install -y fortune
ADD fortuneloop.sh /bin/fortuneloop.sh

ENTRYPOINT /bin/fortuneloop.sh
  • 将三个示例容器部署到一个POD中
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
apiVersion: v1
kind: Pod
metadata:
name: fortune
labels:
app: fortune
spec:
containers:
- name: html-gen
image: 172.17.0.1:5000/fortune
volumeMounts:
- name: html
mountPath: /var/htdocs
- name: log
mountPath: /var/log/fortune
- name: web-server
image: 172.17.0.1:500/nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
- name: log-server
image: 172.17.0.1:5000/nginx:log
volumeMounts:
- name: log
mountPath: /usr/share/nginx/log
readOnly: true
ports:
- containerPort: 8080
protocol: TCP
volumes:
- name: html
emptyDir: {}
- name: log
emptyDir: {}

nginx:log源于nginx:alpine镜像,只是将nginx默认80端口修改成8080端口,将默认的html root目录修改成/usr/share/nginx/log目录,具体修改方法下次在详细讲。

  • 建立一个NodePort类型的Service对外提供web服务
1
2
3
4
5
6
7
8
9
10
11
12
13
kind: Service
apiVersion: v1
metadata:
name: fortune-web-nodeport
spec:
selector:
app: fortune
type: NodePort
ports:
- port: 8088
targetPort: 80
nodePort: 30157

注意selector实际是按照POD中容器标签进行选择的,因此该信息必须和POD中设置的标签保持一致; targetPort和容器端口一致,nginx:alpine默认端口是80端口

  • 建立一个NodePort类型的Service对外提供log服务
1
2
3
4
5
6
7
8
9
10
11
12
kind: Service
apiVersion: v1
metadata:
name: fortune-log-nodeport
spec:
selector:
app: fortune
type: NodePort
ports:
- port: 8090
targetPort: 8080
nodePort: 30159

注意selector实际是按照POD中容器标签进行选择的,因此该信息必须和POD中设置的标签保持一致; targetPort和容器端口一致,nginx:log默认端口是8080端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: fortune-ingress
spec:
rules:
- host: fortune-web.local.com
http:
paths:
- path: /
backend:
serviceName: fortune-web-nodeport
servicePort: 8088
- host: fortune-log.local.com
http:
paths:
- path: /
backend:
serviceName: fortune-log-nodeport
servicePort: 8090

通过Ingress对外提供访问策略,分别根据不同的域名选择到不同的服务中。 新版本的Kubernetes提供了新的网络策略接口,在后续文章中详细测试。

  • 配置域名和IP地址

在minikube中创建ingress后可以通过:kubectl get ingress 查询ingress信息,该信息中包含了域名和IP地址的对应信息,在/etc/hosts中配置该信息即可在本机通过域名访问服务。

测试结果

  • 查询资源信息

  • 修改hosts文件

  • 访问web和log服务

Kubernetes将服务暴露给外部方式

kubernets集群内部的服务可以直接环境变量、内部DNS等方式被发现,并在集群内部提供服务。如何将Kubernetes的服务暴露给外部客户端呢? Kubernetes提供以下集中方式将服务暴露给开外部客户端:

通过NodePort暴露服务

顾名思义,将服务类型设置成NodePort方式,Kubernetes会在集群每个节点上打开一个端口,将该端口的流量转发到服务的POD。

通过负载均衡器暴露

负载均衡方式实际是NodePort方式的增强,将服务类型设置成LoadBalancer方式实际是通过云基础架构提供的负载均衡器,将流量转发到集群内部的NodePort上。

通过Ingress暴露

Ingress是Kubernetes一种资源,通过类似LoadBalancer类似的能力,区别在于每个LoadBalancer都需要一个独立的公网IP,而Ingress只需要一个公网IP即可根据规则将流量转发到对应的服务。

Kubernetes发现服务

Kubernetes发现服务

由于Kubernetes的POD的生命是短暂的,可以随时被创建和销毁,不能通过指定IP和端口号被客户端发现。另外,对于水平伸缩的POD,由多个POD提供服务,客户端也无需关心由那个POD提供服务,也就无需关心POD的部署位置。

通过引入服务(Service)提供稳定外部访问机制。

我们可以为服务创建多个端口。例如:一个servcie可以有80和443端口,通过80和443端口将外部访问转发到POD的8080和8443端口。

  • 服务发现
    • 通过环境变量发现服务 服务的创建早于POD,POD创建时k8s会通过环境变量发现服务;

    • 通过DNS发现服务 k8s集群提供了一个kube-dns POD,所有的POD都使用DNS(通过修改POD的/etc/resolv.conf文件实现)。

    • 通过FQPN发现服务

使用minikube部署本地镜像

启用本地镜像Hub

  • 使用如下命令启动本地镜像仓库

    sudo docker run -d -p 5000:5000 --restart=always --name registry registry

  • 查询是否启用成功

    curl -X GET 172.17.0.1:5000/v2/_catalog

    因为当前没有Push任何镜像到本地镜像仓库,查询结果是空。

Push镜像到local Hub

  • 为本地镜像打一个tag

    docker tag kubia 172.17.0.1:5000/kubia

  • 向本地镜像仓库推送镜像

    docker push 172.17.0.1:5000/kubia

  • 再次查询本地镜像仓库

    curl -X GET 172.17.0.1:5000/v2/_catalog

    返回: {"repositories":["kubia"]}

添加本地镜像到配置文件

sudo vim /etc/docker/daemon.json

加入如下信息:

1
2
3
4
5
6
7
8
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
],
"insecure-registries":["172.17.0.1:5000"] //增加本地镜像地址
}

这里的配置需要注意:172.17.0.1:5000,需要和tag镜像信息保持一致; 重启docker服务是配置生效: systemctl restart docker

新建一个minikube集群

minikube start --driver=docker --insecure-registry="172.17.0.1:5000" --registry-mirror="https://hub-mirror.c.163.com"

这里的本地ip地址必须和上述配置的一致。 由于docker pull镜像默认使用的https协议,因此需要明确告诉docker服务和minikube使用http协议(insecure-registry)

从local registry运行一个docker应用

  • 运行docker应用

    kubectl run kubia --image=172.17.0.1:5000/kubia --port 3000

    系统会返回:pod/kubia created

    docker run是运行一个rs,而不是delploy一个应用,无需要指定部署文件

  • 查询POD信息

    kubectl get pods,系统会返回pod运行状态,如果有异常可以使用 kubectl describe pod kubia 查询详细信息。

    1
    2
    NAME    READY   STATUS    RESTARTS   AGE
    kubia 1/1 Running 0 16s

  • 创建服务对象 此时虽然已经集群内部部署成功,应用仍然无法从集群外部访问,此时需要通过服务开放接口

    sudo kubectl expose pod kubia --name kubia-http --type=LoadBalancer

    由于minikube不支持LoaderBalancer类型,使用默认的type类型也可以。

  • 列出服务

    kubectl get services 系统返回服务信息:

    1
    2
    3
    NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    Kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13m
    kubia-http LoadBalancer 10.99.35.111 <pending> 3000:31902/TCP 97s
    此时查询到服务仍然未分配外部IP,minikube可以使用 minikube service kubia-http访问的服务的IP和端口。

    1
    2
    3
    4
    5
    6
    |-----------|------------|-------------|---------------------------|
    | NAMESPACE | NAME | TARGET PORT | URL |
    |-----------|------------|-------------|---------------------------|
    | default | kubia-http | 3000 | http://192.168.3.15:31902 |
    |-----------|------------|-------------|---------------------------|

    使用http://192.168.3.15:31902即可访问服务。

pod,service和rc之间的关系

镜像推送部署和应用部署流程

完成第一个docker应用程序

本文参考《Kubernetes in action》中的案例,部署一个node.js应用。在vscode中搭建node.js开发环境请自行百度。

创建应用程序

1
2
3
4
5
6
7
8
var http=require('http');

http.createServer(function(req,res){
res.writeHead(200,{'Content-Type':'text/plain'});
res.end('hello node.js');
}).listen(3000,'0.0.0.0',function(){
console.log('Server running at http://localhost:3000');
});

使用 node app.js启动应用程序,使用curl localhost:3000即可验证应用部署是否成功。

编写Dockerfile

1
2
3
FROM node:12
ADD app.js /app.js
ENTRYPOINT [ "node", "app.js" ]
> 注意: > 1. dockerfile 和app.js 在同一目录下 > 2. node版本号最好根据当期开发环境中版本保存一致,具体版本号使用node -v查询

制作镜像

在dockerfile目录下执行命令:sudo docker build -t kubia .

运行程序

sudo docker run --name kubia-container -p 3000:3000 -d kubia

验证应用

在浏览器中访问http://docker-ip:3000,浏览器显示hello node.js。docker ip可以通过ifconfig/ipconfig 命令查询

在Windwos 10 WSL2中安装Docker

最近在学习kubernets,正在阅读《Kubernetes in action》一书,为了感性化的理解书中内容决定同步在办公PC上安装书中涉及到工具和代码,今天先完成在win 10 WSL2中安装Docker。首先在win 10 WSL2中安装Docker想法是基于微软宣称的WSL2内核是真正的Linux内核,也就想当然的认为WSL2中的Ubuntu 20.04和在PC上直接安装是一致的,结果在安装过程中遇到各种小插曲。

打开硬件虚拟化支持

在BIOS中设置Intel虚拟化支持,进入到Virtualization选项中,设置Intel Virtual Technology为enable。重启以后即可在windows任务管理器-〉性能面板中查询虚拟化已开启。

升级WSL-〉WSL2

  • 升级win10到支持WLS2版本,Version 2004, Build 19041 or higher;

  • 设置WSL版本 在cmd中输入如下命令:wsl --set-default-version 2,将wsl版本设置为WSL2。

  • 安全ubuntu 20.04 在windows store中搜索ubuntu 20.04,安装ubuntu 20.04版本;安装完成后启动ubuntu 20.04系统提示

详细配置参考:https://docs.microsoft.com/en-us/windows/wsl/

安装Docker

  • 安装windows 10版本的Docker 不要直接使用系统apt的命令安装docker.io;建议下载windows 10的Docker版本,设置启动WSL即可。
  • 检查Docker安装是否成功 使用:sudo docker version查询docker版本: ### 如果显示如下信息则说明server端没有启动或者连接失败:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Client:
    Version: 19.03.12-ce
    API version: 1.40
    Go version: go1.14.4
    Git commit: 48a66213fe
    Built: Wed Jul 1 17:05:50 2020
    OS/Arch: linux/amd64
    Experimental: false
    Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.40/version": dial unix /var/run/docker.sock: connect: permission denied

  • 解决方案:
    • 使用sudo docker version查询,如果仍然显示失败;
    • 检查server是否启动

如果显示如下信息则说明启动成功:

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
Client:
Version: 19.03.12-ce
API version: 1.40
Go version: go1.14.4
Git commit: 48a66213fe
Built: Wed Jul 1 17:05:50 2020
OS/Arch: linux/amd64
Experimental: false

Server:
Engine:
Version: 19.03.12-ce
API version: 1.40 (minimum version 1.12)
Go version: go1.14.4
Git commit: 48a66213fe
Built: Wed Jul 1 17:05:26 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.3.4.m
GitCommit: d76c121f76a5fc8a462dc64594aea72fe18e1178.m
runc:
Version: 1.0.0-rc91
GitCommit: 24a3cf88a7ae5f4995f6750654c0e2ca61ef4bb2
docker-init:
Version: 0.18.0
GitCommit: fec3683

## 配置Docker

配置国内源

在Windows中配置国内源 配置Dokcer国内源时需要打开(图形化的)Docker Desktop,直接设置国内源即可;如果 在Linux系统中配置源,直接修改/etc/docker/daemon.json文件即可。详细请参考:https://docs.docker.com/registry/recipes/mirror/ 配置文件格式为JSON格式,例如:

1
2
3
{
"registry-mirrors": ["https://<my-docker-mirror-host>"]
}

常用的国内Docker如下: - docker官方中国区: https://registry.docker-cn.com - 网易: http://hub-mirror.c.163.com - ustc: http://docker.mirrors.ustc.edu.cn 可以同时配置多个源,例如:

1
2
3
4
5
6
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com"
]
}

重启Docker服务即可生效

在Linux执行如下命令:

1
2
sudo systemctl daemon-reload
sudo systemctl restart docker

如果重启提示错误可以可根据提示的命令定位错误原因。 > Job for docker.service failed because the control process exited with error code. > > See "systemctl status docker.service" and "journalctl -xe" for details.

查询配置是否生效

sudo docker info

MX Linux 安装及配置

前几天看头条上推荐MX Linux,MX Linux号称是DistroWatch排名第一的操作系统,大部分评论时易用性比较好,此时手上恰好有一块闲置的高速U盘,就是想将MX Linux安装到U盘上尝试使用一下。

  • 准备工作

    • 杂牌4G U盘:用于制作USB启动盘
    • ScanDisk 64G USB 3.0 高速U盘:安装MX Linux到此盘;
    • 从清华镜像站https://mirrors.tuna.tsinghua.edu.cn/下载最新对MX Linux IOS文件
  • 制作启动盘

    1. 使用fdisk命令清除了4G U盘的信息,再格式化成fat32(不格式化无法自动挂载,尝试着手工挂载unbootin工具均无法识别出U盘,于是放弃了使用unbootin工具制作启动U盘);
    2. 使用dd命令制作启动U盘,dd命令使用方法自行请百度 sudo dd if=/home/mxipp/Downloads/MX-19.2_x64.iso of=/dev/sdd > 由4G U盘是USB 2.0接口的杂牌U盘,写入速度极慢,大约用10分钟才制作好启动U盘
  • 安装MX Linux

    1. 安装MX Linux前设置PC的启动选项为U盘启动
    2. 如果PC只有一个USB 3.0接口,其他USB接口为USB 2.0接口,建议将USB启动盘插到USB 2.0接口(暂时不要插入64G U盘),重启PC当PC使用U盘启动盘启动时再插入64GU盘;
    3. 系统启动后按照Live USB 系统的安装指引完成系统开始安装
      1. 需要注意的是在设置安装盘时务必选择安装到64G U盘,如果错配成PC硬盘安装时会清除硬盘上的数据
      2. 引导程序也要选择安装到64G U盘上 > 如果不清楚64G U盘挂载信息可用 sudo fdisk -l 命令查询,或者简单用盘大小判断。

    整个安装过程都是图形化操作,其他安装设置这里就不赘述了。安装完成之后系统会要求重启,重启时请拔掉4G启动盘,系统启动时就会使用安装到U盘的MX Linux启动。

  • 设置MX Linux MX Linux是基于Debian 10稳定版的发行版本,相关Debian文档进行设置,本文只说明几个关键设置。

    • 设置国内源

      • 不建议使用MX Linux图形化的repo manager修改源,repo manager修改非security源,security 源还是使用debian,更新、安装还是很慢。
      • 建议按照清华镜像站的帮助https://mirrors.tuna.tsinghua.edu.cn/help/debian/直接修改/etc/apt/sources.list
    • 更新系统 sudo apt update & upgrade

    • 安装中文输入法 推荐使用rime中文输入法:http://www.rime.im。刚开始安装时直接按照rime官网指导使用如下命令安装rime输入法: sudo apt intall ibus-rime 安装成功后遇到2个折腾了很久的问题:

      1. rime部署时报错: rime提示部署失败,错误日志记录在/tmp/目录下,实际该目录下找不到错误文件,重试多次均无法使用

      2. Ibus不能随系统启动 首先按照系统提示在.bashrc中添加环境变量,实际并不能生效;

        1
        2
        3
        export XMODIFIERS=@im=ibus
        export GTK_IM_MODULE=ibus
        export QT_IM_MODULE=ibus
        于是又在百度查到有些人建议在/etc/environment或者/etc/profile中配置均无法正常工作,折腾了2个小时也无法解决问题,于是就想到在linxu系统自动启动程序中增加ibus-daemon -dx命令,保存了一下session貌似可以正常启动ibus了,但是rime仍然无法正确工作,还是放弃了此方法。最终通过bing搜索引擎在MX Linux的官网上查到配置中文输入法的wikihttps://mxlinux.org/wiki/other/chinese-simplified-input/,同时在archwiki查询ibus相关指导https://wiki.archlinux.org/index.php/IBus,最终按照指导配置,ibus 和rime均能够正常工作。

        • 具体设置如下:
        1. 在.xprofile和.bashrc中配置
          1
          2
          3
          4
          export XMODIFIERS=@im=ibus
          export GTK_IM_MODULE=ibus
          export QT_IM_MODULE=ibus
          ibus-daemon -drx
        2. 通过MX Package Installer安装chinese-ibus,系统在安装过程中会同步安装关联的im-config工具,执行im-config -n ibus
        3. 重启PC,ibus和rime均能够正常工作

      实际在输入的安装过程中,mxlinux wiki和archwiki配置如何时ibus和rime正常工作暂未深入研究,后续有机会补充Display Manager和profile文件bashrc文件之间关系后续再详细说明

  • 几点折腾感悟

    • 技术试用、学习过程中遇到阻塞性问题,尽量在官方英文文档中查找解决问题的方法;
    • 国内百度搜索出来的东西实在不敢恭维了,使用百度搜索即使用多个英文关键字也无法搜索出强管理的英文官方网址,使用bing搜索前5条即可找到官方后者权威技术材料;
    • Arch linux指导文档详细且全面,知识点之间的关联性非常好,而且文档指导性很强;
    • MX Linux并不适合初学者用,遇到问题常常的方案很难解决;
    • Debian稳定性比较好,在10年ThinkPad T400 + 64G U盘上运行的很流畅,没有出现在Manjaro、LinuxMint上出现卡死问题(基本上是由于浏览器、编辑器等软件要求硬件加速导致的)