[k8s]args指令案例-徹底理解docker entrypoint
需求:
搞個鏡像,可以運行java -jar xxx.jar包,xxx.jar包名稱要用參數傳
- 思路1: 打對應運行jar包的jdk的image.
- 思路2: 打通用jdk
1, 運行指定jar的指定版的jdk
-
k8s運行該image遇到的問題
- kubectl create -f sms.yaml時報
rpc error: code = 2 desc = failed to start container "cffbbc3d295f7b5a8d497c8147f7222636b51647387cda491a89d292437c7e47": Error response from daemon: {"message":"invalid header field value \"oci runtime error: container_linux.go:247: starting container process caused \\\"exec: \\\\\\\"/tmp/sms-xx.jar\\\\\\\": permission denied\\\"\\n\""}
- 1
- 等了一會pod奔潰了,報錯
failed to open log file "/var/log/pods/6533426e-aeec-11e7-b1c6-025622f1d9fa/sms-test_3.log": open /var/log/pods/6533426e-aeec-11e7-b1c6-025622f1d9fa/sms-test_3.log: no such file or directory
- 1
gg了好一陣,沒發現方法解決
- 這是我的yaml
sms.yaml
apiVersion: v1
kind: Pod
metadata:
name: sms-test
labels:
app: sms-test
spec:
containers:
- name: sms-test image: sms imagePullPolicy: IfNotPresent command: ["/tmp/sms-xxx.jar"] volumeMounts: - mountPath: /tmp name: test-volume volumes: - name: test-volume hostPath: path: /tmp
報錯問題見上!
- 但是我這樣啟鏡像是正常的
#vm的tmp下放xxx.jar,掛到容器里 docker run -v /tmp:/tmp -itd sms '/tmp/sms-xxx.jar'
- 1
- 2
我一般處理容器化業務思路:
0,物理vm先打通該服務. 1. 打docker鏡像.docker run先跑起來. 2.寫yaml改造成k8s
- 我安裝思路1定義運行jar包的jdk:的dockerfile
Dockerfile
FROM airdock/base:jessie
RUN mkdir -p /srv/java/
# Add java dynamic memory script COPY java-dynamic-memory-opts /srv/java/ # Install Oracle JDK 8u25 RUN cd /tmp && \ curl -L -O "http://xxx/jdk-8u25-linux-x64.gz" && \ tar xf jdk-8u25-linux-x64.gz -C /srv/java && \ rm -f jdk-8u25-linux-x64.gz && \ ln -s /srv/java/jdk* /srv/java/jdk && \ ln -s /srv/java/jdk /srv/java/jvm && \ chown -R java:java /srv/java && \ /root/post-install # Define commonly used JAVA_HOME variable # Add /srv/java and jdk on PATH variable ENV JAVA_HOME=/srv/java/jdk \ PATH=${PATH}:/srv/java/jdk/bin:/srv/java COPY docker-entrypoint.sh /bin/ ENTRYPOINT ["docker-entrypoint.sh"]
docker-entrypoint.sh
#!/bin/bash java -jar $1
嗯哼? 沒毛病.
解決k8s運行定制jdk環境的問題:
方法: yaml里command換args指令即可.
sms.yaml
... spec: containers: - name: sms-test image: sms imagePullPolicy: IfNotPresent args: ["/tmp/sms-xxx.jar"] ...
docker run -v /tmp:/tmp -itd sms '/tmp/sms-xxx.jar' 這里args,而非commands
- 1
- 2
2, 使jdk環境通用化
想想為了運行一個jar包,定義個運行jar的jdk環境,有點得不償失.思路:為了通用性,搞個指定版本jdk image,管他運行什么呢.
Dockerfile FROM airdock/base:jessie RUN mkdir -p /srv/java/ # Add java dynamic memory script COPY java-dynamic-memory-opts /srv/java/ # timezone 這里把時區改掉 COPY localtime /etc/localtime # Install Oracle JDK 8u25 RUN cd /tmp && \ curl -L -O "http://xxx/jdk-8u25-linux-x64.gz" && \ tar xf jdk-8u25-linux-x64.gz -C /srv/java && \ rm -f jdk-8u25-linux-x64.gz && \ ln -s /srv/java/jdk* /srv/java/jdk && \ ln -s /srv/java/jdk /srv/java/jvm && \ chown -R java:java /srv/java && \ /root/post-install # Define commonly used JAVA_HOME variable # Add /srv/java and jdk on PATH variable ENV JAVA_HOME=/srv/java/jdk \ PATH=${PATH}:/srv/java/jdk/bin:/srv/java
apiVersion: v1 kind: Pod metadata: name: sms-test labels: app: sms-test spec: containers: - name: sms-test image: jdk8u25-ori imagePullPolicy: IfNotPresent command: ["java","-jar","/tmp/sms-xxx.jar"] volumeMounts: - mountPath: /tmp name: test-volume volumes: - name: test-volume hostPath: path: /data
經過觀察jar包運行良好.
可見理解k8s yaml指令還是有點必要的.不然天天閑的蛋疼,沒事干. 人生最大的敵人是無聊.
徹底理解entrypiont-命令行揉搓擠捏
指定entrypiont
- 錯誤的姿勢
docker run -itd -v /tmp/:/tmp/ jdk-ori 'java -jar /tmp/sms.jar'
- 正確的姿勢1
docker run -itd -v /tmp/:/tmp/ jdk-ori java -jar '/tmp/sms.jar'
- 正確姿勢2:
docker run -it -itd -v /tmp/:/tmp/ --entrypoint /srv/java/jdk/bin/java jdk-ori -jar /tmp/sms.jar --entrypoint "/srv/java/jdk/bin/java -jar" 這樣是不支持的, 這個傳參方式不能加參數 ,而dockerfile里則可以
- 正確姿勢3: 掛腳本方式
$ cat /tmp/entry.sh
#!/bin/bash java -jar $1 docker run -it --rm -v /tmp/:/tmp/ --entrypoint "/tmp/entry.sh" jdk-ori /tmp/sms.jar
也可以指定這些:
https://docs.docker.com/engine/reference/run/#entrypoint-default-command-to-execute-at-runtime
CMD (Default Command or Options) ENTRYPOINT (Default Command to Execute at Runtime) EXPOSE (Incoming Ports) ENV (Environment Variables) HEALTHCHECK VOLUME (Shared Filesystems) USER WORKDIR
如何在k8s里指定docker run -w 的workdir
思路: 可以通過env方式
[root@k8s-master01 ma]# cat centos.yaml apiVersion: v1 kind: Pod metadata: name: my-centos labels: app: centos spec: containers: - name: my-centos image: centos:6.8 imagePullPolicy: IfNotPresent command: ["top","-b"] env: - name: PWD value: "/tmp"
一個計時的pod
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
https://k8smeetup.github.io/docs/concepts/cluster-administration/logging/