构建 Alpine + Supervisor 基础镜像
Dockerfile
FROM alpine:3.18
RUN apk add --update supervisor && rm -rf /tmp/* /var/cache/apk/*
ENTRYPOINT ["supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]
构建
$ docker build -t supine .
推送镜像
# 登录
$ docker login --username=your-name instance7-registry.cn-beijing.cr.aliyuncs.com
# 打 Tag
$ docker tag supine:latest instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/supine:1.0.0
# 推送
$ docker push instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/supine:1.0.0
注意事项
docker login
登录的时候提示输入的密码非阿里云账号密码,可以在「实例管理」-「访问凭证」处进行设置。- 如果是阿里云 ECS 机器访问镜像,可以使用内网地址,另外设置不可变镜像后,重复推送回失败。
命令行拉取镜像
$ docker pull instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/supine:1.0.0
从 K8S 中拉取镜像
配置密钥
有两种方式,一种是创建后在配置文件中指定密钥,另外一种是绑定在命名空间上,这样无需在配置文件中指定。
$ kubectl create secret docker-registry registry-secret --docker-server=instance7-registry.cn-beijing.cr.aliyuncs.com --docker-username=your-name --docker-password=your-passwd
绑定在命名空间
$ kubectl create secret docker-registry registry-secret --docker-server=instance7-registry.cn-beijing.cr.aliyuncs.com --docker-username=your-name --docker-password=your-passwd -n default
生成测试 Pod 配置
$ kubectl run test --image=instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/sidecar:0.0.1 --restart=Never --dry-run=client -o yaml > pod.yaml
在配置上补充密码
我这里使用的是第一种方式,未绑定到整个命名空间,所以需要在配置中指定 Secrets
spec:
imagePullSecrets:
- name: registry-secret
创建 Pod
$ kubectl apply -f pod.yaml
查看详细输出
可以使用 kubectl get pod test
查看 Pod 状态,如果拉取成功,则会显示 Complated
状态,否则是用如下命令查看详细信息
kubectl describe pod test
输出节选
Warning Failed 12s (x2 over 25s) kubelet Failed to pull image "instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/sidecar:0.0.1": rpc error: code = Unknown desc = failed to pull and unpack image "instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/sidecar:0.0.1": failed to resolve reference "instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/sidecar:0.0.1": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
这是未指定密钥时的报错,问题修复后,再次 apply 配置。
需要注意:在测试期间,镜像每次都打同一个 Tag,K8S 中会缓存导致新制作的镜像使用不上。
Normal Pulled 76s kubelet Container image "instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/sidecar:0.0.1" already present on machine
Pod 含有两个容器的示例
这里列出的配置仅作参考,所描述的场景是 Pos 启动时首先使用 initContainers 拉取 config-sidecar 镜像运行,它用来拉取配置,拉取成功后退出,而后启动 diamond 服务,在同一个 Pod 中,可以通过 volumeMounts 让不同容器间共享资源。
apiVersion: apps/v1
kind: Deployment
metadata:
name: diamond-sidecar
spec:
replicas: 1
selector:
matchLabels:
app: diamond-sidecar
template:
metadata:
labels:
app: diamond-sidecar
spec:
imagePullSecrets:
- name: registry-secret
initContainers:
- name: config-sidecar
image: instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/sidecar:0.0.2
command: ["./config_sidecar.sh"]
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- name: config-volume
mountPath: /config
containers:
- name: diamond
image: instance7-registry.cn-beijing.cr.aliyuncs.com/appserver/diamond:1.5.27
volumeMounts:
- name: config-volume
mountPath: /config
resources:
limits:
cpu: "256m"
memory: "256Mi"
volumes:
- name: config-volume
emptyDir: {}
进入到容器内部
最后,如果我们需要到容器内部确认服务状态或配置是否正确被放置,可以使用如下命令进入到容器内部。
# kubectl exec -it <pod_name> -c <container_name> -- bash
# 如果使用的 alpine 基础镜像,那么应用 sh 而非 bash
$ kubectl exec -it diamond-sidecar-689d756489-tjsdk -c diamond -- sh