התאמה אישית של תוכנית העברה לשרתי Tomcat
כדאי לבדוק את קובץ תוכנית ההעברה שנוצר בעקבות יצירת ההעברה. לפני שמבצעים את ההעברה, אפשר להתאים אישית את הקובץ. הפרטים של תוכנית ההעברה משמשים לחילוץ הארטיפקטים של מאגר עומס העבודה מהמקור.
בקטע הזה מתואר התוכן של ההעברה וסוגי ההתאמות האישיות שכדאי לשקול לפני שמבצעים את ההעברה ויוצרים את ארטיפקטים הפריסה.
לפני שמתחילים
במאמר הזה אנחנו מניחים שכבר יצרתם העברה ויש לכם את קובץ תוכנית ההעברה.
עריכת תוכנית ההעברה
אחרי שמעתיקים את מערכת הקבצים ומנתחים אותה, אפשר למצוא את תוכנית ההעברה בספרייה החדשה שנוצרת בנתיב הפלט שצוין: ANALYSIS_OUTPUT_PATH/config.yaml.
עורכים את תוכנית ההעברה לפי הצורך ושומרים את השינויים.
בודקים את פרטי תוכנית ההעברה ואת ההערות המנחות כדי להוסיף מידע לפי הצורך. חשוב במיוחד לשים לב לשינויים בקטעים הבאים.
ציון קובץ האימג' של Docker
בתוכנית המיגרציה, אנחנו יוצרים תג של קובץ אימג' של קהילת Docker על סמך גרסת Tomcat, גרסת Java וספק Java.
- גרסת Tomcat: הגרסה של Tomcat מזוהה ומומרת לגרסה ראשית (אין תמיכה בגרסאות משניות). אם לא הצלחנו לזהות את הגרסה של Tomcat, השדה
baseImage.nameיכיל מחרוזת ריקה. - גרסת Java: גרסת Java תלויה בפרמטר
java-version. כברירת המחדל, הערך שלו הוא11. - ספק Java: ספק Java מוגדר כקבוע:
temurin.
לדוגמה, תג האימג' של קהילת Docker שנוצר עבור Tomcat גרסה 9.0, Java גרסה 11 וספק Java temurin הוא tomcat:9.0-jre11-temurin.
בתוכנית ההעברה, השדה baseImage.name מייצג את התג של קובץ האימג' של Docker שמשמש כבסיס לקובץ האימג' של הקונטיינר.
הגרסאות המקוריות של Tomcat ו-Java שזוהו במכונה הווירטואלית של המקור כלולות ב-discovery-report.yaml שנוצר על ידי הגילוי הראשוני.
אם רוצים לשנות את תמונת הקהילה של Docker או לספק תמונת Docker משלכם, אפשר לשנות את baseImage.name בתוכנית ההעברה באמצעות הפורמט הבא:
tomcatServers: - name: latest . . . images: - name: tomcat-latest . . . baseImage: name: BASE_IMAGE_NAME
מחליפים את BASE_IMAGE_NAME בקובץ אימג' של Docker שרוצים להשתמש בו כבסיס לקובץ אימג' של קונטיינר.
עדכון נתיב ההתקנה של Tomcat
במהלך תהליך המיגרציה, אם לתמונת היעד יש נתיב CATALINA_HOME שאינו ברירת המחדל, אפשר לציין נתיב CATALINA_HOME מותאם אישית. עורכים את השדה catalinaHome של היעד ישירות בתוכנית ההעברה:
tomcatServers: - name: latest . . . images: - name: tomcat-latest . . . baseImage: name: BASE_IMAGE_NAME catalinaHome: PATH
מחליפים את PATH בנתיב ההתקנה של Tomcat.
התאמה אישית של משתמשים וקבוצות
במהלך תהליך ההעברה, אם תמונת היעד פועלת עם משתמש וקבוצה שונים מאלה של root:root, אפשר לציין משתמש וקבוצה מותאמים אישית שדרכם רוצים שהאפליקציה תפעל. עריכת המשתמש והקבוצה ישירות בתוכנית ההעברה:
tomcatServers: - name: latest . . . images: - name: tomcat-latest . . . userName: USERNAME groupName: GROUP_NAME
מחליפים את מה שכתוב בשדות הבאים:
- USERNAME: שם המשתמש שרוצים להשתמש בו
- GROUP_NAME: שם הקבוצה שרוצים להשתמש בה
הגדרת SSL
כשיוצרים העברה חדשה של Tomcat, תהליך גילוי סורק את השרת מול האפליקציות השונות שמתגלות.
אחרי הגילוי, השדות הבאים מאוכלסים אוטומטית בתוכנית ההעברה:
excludeFiles: רשימה של הקבצים והספריות שיוחרגו מההעברה.כברירת מחדל, כל הנתיבים והאישורים הרגישים שנמצאו במהלך הגילוי מתווספים אוטומטית לשדה הזה ומוחרגים מההעברה. אם מסירים נתיב מהרשימה הזו, הקובץ או הספרייה מועלים לקובץ אימג' של קונטיינר. כדי להחריג קובץ או ספרייה מתמונת המאגר, מוסיפים את הנתיב לרשימה הזו.
sensitiveDataPaths: רשימה של כל הנתיבים והאישורים הרגישים שאותרו בתהליך הגילוי.כדי להעלות את האישורים למאגר, מגדירים את השדה
includeSensitiveDataלערךtrue:# Sensitive data which will be filtered out of the container image. # If includeSensitiveData is set to true the sensitive data will be mounted on the container. includeSensitiveData: true tomcatServers: - name: latest catalinaBase: /opt/tomcat/latest catalinaHome: /opt/tomcat/latest # Exclude files from migration. excludeFiles: - /usr/local/ssl/server.pem - /usr/home/tomcat/keystore - /usr/home/tomcat/truststore images: - name: tomcat-latest ... # If set to true, sensitive data specified in sensitiveDataPaths will be uploaded to the artifacts repository. sensitiveDataPaths: - /usr/local/ssl/server.pem - /usr/home/tomcat/keystore - /usr/home/tomcat/truststoreאחרי שהמיגרציה תושלם, קובץ אובייקטים מסוג secret יתווסף לקובץ הסודות
secrets.yamlבמאגר הארטיפקטים.
רישום ביומן של אפליקציות אינטרנט
הכלי Migrate to Containers תומך ברישום ביומן באמצעות log4j v2, logback ו-log4j v1.x שנמצאים ב-CATALINA_HOME.
הכלי Migrate to Containers יוצר קובץ ארכיון נוסף עם הגדרות יומן ששונו, וממיר את כל סוגי הקבצים של רכיבי appender לרכיבי appender של קונסולה. אתם יכולים להשתמש בתוכן של הארכיון הזה כהפניה כדי להפעיל איסוף יומנים ולהזרים אותם לפתרון לאיסוף יומנים (כמו Cloud Logging של Google).
הקצאת זיכרון
במהלך תהליך ההעברה, אפשר לציין את מגבלות הזיכרון של אפליקציות שהועברו למאגרי נתונים נפרדים. אפשר לערוך את מגבלות הזיכרון ישירות בתוכנית ההעברה באמצעות הפורמט הבא:
tomcatServers:
- name: latest
. . .
images:
- name: tomcat-latest
. . .
resources:
memory:
limit: 2048M
requests: 1280M
הערך המומלץ של limit הוא 200% מ-Xmx, שהוא גודל ה-heap המקסימלי של Java. הערך המומלץ של requests הוא 150% מ-Xmx.
כדי לראות את הערך של Xmx, מריצים את הפקודה הבאה:
ps aux | grep catalina
אם הוגדרו מגבלות זיכרון בתוכנית ההעברה, קובץ ה-Dockerfile שנוצר לצד פריטים אחרים אחרי העברה מוצלחת משקף את ההצהרה שלכם:
FROM tomcat:8.5-jdk11-openjdk
# Add JVM environment variables for tomcat
ENV CATALINA_OPTS="${CATALINA_OPTS} -XX:MaxRAMPercentage=50.0 -XX:InitialRAMPercentage=50.0 -XX:+UseContainerSupport <additional variables>"
הגודל הראשוני והמקסימלי מוגדרים כ-50% מהערך המקסימלי. כך אפשר לשנות את גודל הקצאת הזיכרון בערימה (heap allocation) של ה-Tomcat Java בהתאם לשינוי במגבלת הזיכרון של ה-Pod.
הגדרת משתני סביבה של Tomcat
אם רוצים להגדיר את CATALINA_OPTS בקובץ Dockerfile שנוצר לצד פריטים אחרים אחרי העברה מוצלחת, אפשר קודם להוסיף לשדה catalinaOpts בתוכנית ההעברה. בדוגמה הבאה מוצג השדה catalinaOpts אחרי העדכון:
tomcatServers:
- name: latest
. . .
images:
- name: tomcat-latest
. . .
resources:
. . .
catalinaOpts: "-Xss10M"
הכלי Migrate to Containers מנתח את הנתונים של catalinaOpts ב-Dockerfile. בדוגמה הבאה אפשר לראות את הפלט של הניתוח:
FROM 8.5-jdk11-openjdk-slim
## setenv.sh script detected.
## Modify env variables on the script and add definitions to the migrated
## tomcat server, if needed (less recommended than adding env variables directly
## to CATALINA_OPTS) by uncomment the line below
#ADD --chown=root:root setenv.sh /usr/local/tomcat/bin/setenv.sh
# Add JVM environment variables for the tomcat server
ENV CATALINA_OPTS="${CATALINA_OPTS} -XX:MaxRAMPercentage=50.0 -XX:InitialRAMPercentage=50.0 -Xss10M"
אפשר גם להגדיר משתני סביבה של Tomcat באמצעות הסקריפט setenv.sh, שנמצא בתיקייה /bin בשרת Tomcat. מידע נוסף על משתני סביבה של Tomcat זמין במסמכי התיעוד של Tomcat.
אם בחרתם להשתמש ב-setenv.sh כדי להגדיר את משתני הסביבה של Tomcat, תצטרכו לערוך את קובץ ה-Dockerfile.
הגדרת בדיקות תקינות (probes) של Tomcat
אתם יכולים לעקוב אחרי זמן ההשבתה והסטטוס של המאגרים המנוהלים על ידי הגדרת בדיקות בתוכנית ההעברה של שרת האינטרנט Tomcat. מעקב באמצעות בדיקת תקינות יכול לעזור לצמצם את זמן ההשבתה של קונטיינרים שהועברו ולספק מעקב טוב יותר.
מצבי תקינות לא ידועים עלולים לגרום לירידה בזמינות, לזמינות חיובית כוזבת ולפוטנציאל לאובדן נתונים. בלי בדיקת תקינות, kubelet יכול רק להניח מה מצב התקינות של קונטיינר, ויכול להיות שהוא ישלח תנועה למופע של קונטיינר שלא מוכן. הדבר עלול לגרום לאובדן תנועה. יכול להיות ש-Kubelet לא יזהה קונטיינרים במצב קפוא ולא יפעיל אותם מחדש.
בדיקת תקינות פועלת על ידי הפעלת הצהרה קטנה מתוך סקריפט כשהקונטיינר מתחיל לפעול. הסקריפט בודק אם התנאים מתקיימים בכל תקופה. התנאים מוגדרים לפי סוג הבדיקה שבה נעשה שימוש. התקופה מוגדרת בשדה periodSeconds בתוכנית ההעברה. אפשר להריץ או להגדיר את הסקריפטים האלה באופן ידני.
מידע נוסף על בדיקות kubelet זמין במאמר Configure Liveness, Readiness and Startup Probes (הגדרת בדיקות פעילות, מוכנות והפעלה) במסמכי התיעוד של Kubernetes.
יש שני סוגים של בדיקות שאפשר להגדיר. שתי הבדיקות מוגדרות ב-probe-v1-core reference כ-probe-v1-core, והן חולקות את אותה פונקציה כמו השדות התואמים של container-v1-core
- בקשה לבדיקת תקינות (probe) מצב פעילות (liveness): בקשות לבדיקת תקינות (probe) מצב פעילות (liveness) משמשות כדי לדעת מתי להפעיל מחדש קונטיינר.
- בקשה לבדיקת תקינות (probe) מוכנות: בקשות לבדיקת תקינות (probe) מוכנות משמשות כדי לדעת מתי קונטיינר מוכן להתחיל לקבל תנועה. כדי להתחיל לשלוח תנועה ל-Pod רק כשבדיקת מוכנות מצליחה, צריך לציין בדיקת מוכנות. בקשה לבדיקת תקינות מוכנות יכולה לפעול באופן דומה לבקשה לבדיקת תקינות מצב פעילות, אבל בקשה לבדיקת תקינות מוכנות במפרטים מציינת ש-Pod מתחיל בלי לקבל תנועה ומתחיל לקבל תנועה רק אחרי שהבקשה לבדיקת תקינות מצליחה.
אחרי הגילוי, הגדרת הבדיקה מתווספת לתוכנית המיגרציה. אפשר להשתמש בבדיקות בהגדרת ברירת המחדל שלהן, כמו בדוגמה הבאה. כדי להשבית את הבדיקות, מסירים את הקטע probes מקובץ ה-YAML.
tomcatServers: - name: latest images: - name: tomcat-latest ports: - 8080 probes: livenessProbe: tcpSocket: port: 8080 readinessProbe: tcpSocket: port: 8080
אפשר לשנות את תוכנית ההעברה הזו כדי להשתמש בנקודת קצה קיימת של Tomcat HTTP.
tomcatServers: - name: latest images: - name: tomcat-latest ports: - 8080 probes: livenessProbe: httpGet: path: /healthz port: 8080 httpHeaders: - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3 readinessProbe: httpGet: tcpSocket: port: 8080
יש ארבע דרכים מוגדרות מראש לבדיקת מאגר תגים באמצעות בקשה לבדיקת תקינות (probe). כל בקשה לבדיקת תקינות (probe) צריכה להגדיר בדיוק אחד מארבעת המנגנונים האלה:
-
exec: מריץ פקודה שצוינה בתוך הקונטיינר. הביצוע נחשב מוצלח אם קוד סטטוס היציאה הוא 0. -
grpc: מבצע קריאה לשירות מרוחק באמצעות gRPC. בדיקות gRPC הן תכונת אלפא. -
httpGet: מבצע בקשת GET של HTTP מול כתובת ה-IP של ה-Pod ביציאה ובנתיב שצוינו. הבקשה נחשבת מוצלחת אם קוד הסטטוס גדול מ-200 או שווה לו, וקטן מ-400. -
tcpSocket: מבצע בדיקת TCP מול כתובת ה-IP של ה-Pod ביציאה שצוינה. האבחון נחשב מוצלח אם היציאה פתוחה.
כברירת מחדל, תוכנית ההעברה מפעילה את שיטת הבדיקה tcpSocket. אפשר להשתמש בהגדרה ידנית של תוכנית ההעברה כדי להשתמש בשיטות בדיקה שונות.
אפשר גם להגדיר פקודות וסקריפטים מותאמים אישית באמצעות תוכנית ההעברה.
כדי להוסיף תלות חיצונית לבדיקת המוכנות, כשמשתמשים בבדיקת הפעילות שמוגדרת כברירת מחדל, צריך להגדיר בדיקת מוכנות מסוג exec וסקריפט שמיישם את הלוגיקה.
אימות ההגדרה של אשכול Tomcat
האשכול Tomcat משמש לשכפול פרטי הסשן בכל צמתי Tomcat, וכך אפשר לקרוא לכל אחד משרתי האפליקציות של ה-Backend בלי לאבד את פרטי הסשן של הלקוח. מידע נוסף על הגדרת אשכולות זמין במאמר Clustering/Session Replication How-To במסמכי התיעוד של Tomcat.
הסיווג של Tomcat clustering נקרא SimpleTcpListener, והוא משתמש בהודעות פעימת לב (heartbeat) של שידור מרובה (multicast) כדי לגלות עמיתים. סביבות ענן לא תומכות בשידור מרובה משתתפים, ולכן צריך לשנות את הגדרת האשכול או להסיר אותה, אם אפשר.
כשמאזן עומסים מוגדר להפעלה ולתחזוקה של סשן קבוע בשרת Tomcat בקצה העורפי, הוא יכול להשתמש במאפיין jvmRoute שהוגדר בהגדרות של Engine.
אם בסביבת המקור שלכם נעשה שימוש בהגדרת אשכולות שלא נתמכת, צריך לשנות את הקובץ server.xml כדי להשבית את ההגדרה או להשתמש בהגדרה נתמכת.
- Tomcat גרסה 8.5 ואילך: צריך להשבית את הקיבוץ באשכולות ב-Tomcat גרסה 8.5.
כדי להשבית את האשכולות, צריך להוסיף הערה לקטע
<Cluster … />בקובץserver.xml. Tomcat בגרסה 9 ואילך: ב-Tomcat בגרסה 9 ואילך, אפשר להפעיל את המחלקה
ClusterבאמצעותKubernetesMembershipService. KubernetesMembershipServiceהוא מחלקה ספציפית ל-Kubernetes, שמשתמשת בממשקי ה-API של Kubernetes לגילוי עמיתים.ספק Kubernetes: בהמשך מופיעה דוגמה להגדרה של ספק Kubernetes:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.cloud.CloudMembershipService" membershipProviderClassName="org.apache.catalina.tribes.membership.cloud.KubernetesMembershipProvider"/> </Channel> </Cluster>ספק DNS: משתמשים ב-
DNSMembershipProviderכדי להשתמש בממשקי ה-API של DNS לאיתור עמיתים. ההגדרה הבאה היא דוגמה להגדרת ספק DNS:<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.cloud.CloudMembershipService" membershipProviderClassName="org.apache.catalina.tribes.membership.cloud.DNSMembershipProvider"/> </Channel> </Cluster>jvmRoute: אם מאזן העומסים מסתמך על ערך jvmRoute, צריך לשנות את הערך מסטטי לשימוש בשם ה-POD. ההגדרה הזו גורמת ל-Tomcat להוסיף סיומת לקובץ ה-cookie של הסשן עם שם ה-POD. מאזן העומסים של קצה קדמי יכול להשתמש בנתונים האלה כדי להפנות את התנועה אל ה-Pod הנכון של Tomcat. משנים את הערך בקובץ
server.xmlלערך הבא:<Engine name="Catalina" defaultHost="localhost" jvmRoute="${HOSTNAME}">
אימות הגדרות ה-Proxy של Tomcat
אם Tomcat מוגדר לפעול מאחורי שרת proxy הפוך, או באמצעות כמה הגדרות של שרת proxy בקטע Connector של server.xml, צריך לוודא שאותן הגדרות של שרת proxy עדיין רלוונטיות אחרי המעבר לפעולה ב-Kubernetes.
כדי להריץ אפליקציית Tomcat פונקציונלית בתוך קונטיינר, בוחרים אחד משינויי ההגדרות הבאים בהגדרת ה-reverse proxy:
- השבתת הגדרת שרת proxy: אם האפליקציה שהועברה כבר לא פועלת מאחורי שרת proxy הפוך, אפשר להשבית את הגדרת שרת ה-proxy על ידי הסרת
proxyNameו-proxyPortמהגדרת המחבר. - העברת ה-proxy: מעבירים את מכונת ה-VM של ה-proxy ושומרים את כל ההגדרות הקיימות של Tomcat.
הגדרת Ingress להחלפת ה-reverse proxy: אם לא הוטמעה לוגיקה מותאמת אישית או מורכבת ב-reverse proxy, אפשר להגדיר משאב Ingress כדי לחשוף את אפליקציית Tomcat שהועברה. התהליך הזה משתמש באותו שם דומיין מלא (FQDN) ששימש לפני ההעברה. כדי להגדיר Ingress, צריך לוודא ששירות Tomcat Kubernetes הוא מסוג
type: Nodeport. ההגדרה הבאה היא דוגמה להגדרת Ingress:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-tomcat-ingress spec: rules: - host: APP_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-tomcat-service port: name: my-tomcat-portהגדרת Cloud Service Mesh עם Cloud Load Balancing: אם אתם משתמשים ב-GKE Enterprise, אתם יכולים לחשוף את האפליקציה באמצעות Cloud Service Mesh. למידע נוסף על חשיפת אפליקציות של Service mesh, אפשר לעיין במאמר מגבול לרשת: חשיפת אפליקציות של Service mesh באמצעות GKE Ingress.
אימות הגדרות ה-Proxy של Java
כשעוברים לשימוש בקונטיינרים, צריך לוודא שהשרתים שלכם ל-proxy זמינים בסביבה החדשה. אם שרת ה-Proxy לא זמין, בוחרים באחד משינויי ההגדרה הבאים ל-Proxy:
- השבתת ה-Proxy: אם כבר לא משתמשים ב-Proxy המקורי, צריך להשבית את הגדרות ה-Proxy. מסירים את כל הגדרות לשרת proxy מהסקריפט
setenv.shאו מקובץ תצורה שבו הן נשמרות בשרת Tomcat. - שינוי הגדרות לשרת proxy: אם סביבת Kubernetes שלכם משתמשת ב-proxy אחר ליציאה, אתם יכולים לשנות את הגדרות לשרת proxy ב-
setenv.shאו בקובץ אחר, כדי להפנות ל-proxy החדש.